chiark / gitweb /
realtime: new check_rusage feature
authorIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sun, 9 Jan 2011 02:18:01 +0000 (02:18 +0000)
committerIan Jackson <ian@liberator.relativity.greenend.org.uk>
Sun, 9 Jan 2011 02:18:01 +0000 (02:18 +0000)
hostside/realtime.c
hostside/realtime.h
hostside/startup.c

index a2be33d17ee7af742eee4fe2d80297dd2631610d..ae26852e21cb0128b0a8b86c989b7b40e824b6ce 100644 (file)
@@ -2,6 +2,8 @@
  * main program for realtime control
  */
 
+#include <sys/resource.h>
+
 #include "realtime.h"
 
 const char *progname= "realtime";
@@ -325,6 +327,52 @@ void serial_transmit(const PicInsn *pi) {
   serial_transmit_now(pi->d, pi->l);
 }
 
+/*---------- reporting page faults etc. ----------*/
+
+#define CHECK_RUSAGE_FIELDS(F)                 \
+  F(ru_majflt)                                 \
+  F(ru_nswap)                                  \
+  F(ru_nivcsw)
+
+/*  F(ru_minflt)                                       \
+ */
+
+#define CRF_DECL(f) static long check_rusage_last_##f;
+CHECK_RUSAGE_FIELDS(CRF_DECL)
+
+static void getru(struct rusage *ru) {
+  int r= getrusage(RUSAGE_SELF, ru);  if (r) diee("getrusage");
+}
+
+void check_rusage_baseline(void) {
+  struct rusage ru;
+  getru(&ru);
+  #define CRF_BASE(f) check_rusage_last_##f= ru.f;
+  CHECK_RUSAGE_FIELDS(CRF_BASE)
+}
+
+static void check_rusage_field(const char *f, long *last, long this, int alw) {
+  long diff= this - *last;
+  if (alw || diff) {
+    ouprintf(" %s+=%ld", f, diff);
+    *last= diff;
+  }
+}
+
+void check_rusage_check(int always_report) {
+  struct rusage ru;
+  getru(&ru);
+  #define CRF_CHANGED(f) || ru.f != check_rusage_last_##f
+  if (always_report
+      CHECK_RUSAGE_FIELDS(CRF_CHANGED)) {
+    ouprintf("info rusage :");
+    #define CRF_SHOW(f) \
+    check_rusage_field(STR(f), &check_rusage_last_##f, ru.f, always_report);
+    CHECK_RUSAGE_FIELDS(CRF_SHOW);
+    ouprintf(".\n");
+  }
+}
+
 /*---------- debugging ----------*/
 
 unsigned long eventcounter;
@@ -486,6 +534,7 @@ int main(int argc, const char **argv) {
          case 'P': rtfeats_use |= RTFEAT_ALL(CPU);     break;
          case 'm': rtfeats_use |= RTFEAT_MEM;          break;
          case 'M': rtfeats_use |= RTFEAT_ALL(MEM);     break;
+         case 'r': rtfeats_use |= RTFEAT_RUSAGE;       break;
          default: badusage("unknown -R suboption");
          }
        }
@@ -519,7 +568,7 @@ int main(int argc, const char **argv) {
     events->on_fd(events, serial_fd, OOP_EXCEPTION, read_exception, 0);
 
     if (rtfeats_use & RTFEAT_DEFAULTS)
-      rtfeats_use |= RTFEAT_CPU | RTFEAT_MEM;
+      rtfeats_use |= RTFEAT_CPU | RTFEAT_MEM | RTFEAT_RUSAGE;
   } else {
     sim_initialise(logcopy_fn);
     sys_events= 0;
index 83e53627d028592f3a3e7146d18e6b3c888fc75e..3624c754a72e7c2fb3f13bbf85723975d16f0dfe 100644 (file)
@@ -156,6 +156,9 @@ void serial_transmit(const PicInsn *pi);
 void command_doline(ParseState *ps, CommandInput *cmdi_arg);
 const CmdInfo *current_cmd;
 
+void check_rusage_baseline(void);
+void check_rusage_check(int always_report);
+
 /*---------- for/from simulate.c ----------*/
 
 void serial_indata_process(int buf_used);
@@ -223,9 +226,10 @@ void toev_stop(TimeoutEvent*);    /* IR -> I */
 
 void realtime_priority(void);
 
-#define RTFEAT_DEFAULTS  0100u /* turns on MLOCK and SCHEDPRIO iff not sim */
+#define RTFEAT_DEFAULTS  0100u /* turns things on iff not sim */
 #define RTFEAT_MEM       0001u /* mlock */
 #define RTFEAT_CPU       0002u /* hard CPU scheduling priority */
+#define RTFEAT_RUSAGE    0004u /* check up on faults etc. in getrusage */
 
 #define RTFEAT_ALL_SHIFT 16
 #define RTFEAT_ALL(x) (RTFEAT_##x << RTFEAT_ALL_SHIFT)
index 460c789d0208a18e5586b9883078ae03b366c70f..0688d9a33525b61e6ae22e9e9adead4fc299c2a4 100644 (file)
@@ -51,11 +51,13 @@ static TimeoutEvent watchdog_toev= {
 static PicInsn watchdog_piob;
 
 static void watchdog_transmit(TimeoutEvent *toev) {
+  check_rusage_check(0);
   toev_start(&watchdog_toev);
   serial_transmit(&watchdog_piob);
 }
 
 static void watchdog_start(void) {
+  check_rusage_baseline();
   watchdog_toev.callback= watchdog_transmit;
   enco_pic_watchdog(&watchdog_piob, UNMARGIN_WATCHDOG_16);
   watchdog_transmit(0);
@@ -66,6 +68,7 @@ static void watchdog_stop(void) {
   toev_stop(&watchdog_toev);
   enco_pic_watchdog(&watchdog_piob, 0);
   serial_transmit(&watchdog_piob);
+  check_rusage_check(1);
 }
 
 /*---------- main startup algorithm ----------*/
@@ -270,6 +273,7 @@ void on_pic_fault(const PicInsnInfo *pii, const PicInsn *pi, int objnum) {
 
 void on_pic_wtimeout(const PicInsnInfo *pii, const PicInsn *pi, int objnum) {
   if (sta_state <= Sta_Settling) return;
+  check_rusage_check(1);
   die("microcontrollers' watchdog timer triggered\n");
 }