preventive waits -> busylooping.
authorlace <>
Wed, 11 Apr 2007 21:21:54 +0000 (21:21 +0000)
committerlace <>
Wed, 11 Apr 2007 21:21:54 +0000 (21:21 +0000)
debugger.c

index 7aa80cf..81a3bd4 100644 (file)
 #include <sys/wait.h>
 #include <limits.h>
 #include <string.h>
+#include <time.h>
 
 #include "debugger.h"
 
 
+#if 0
 #define USLEEP (1000000 / 2)
+#endif
+#define TIMEOUT_SECS 10
 
 
 #define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
@@ -57,6 +61,7 @@ enum state
   {
     /* Separate the valid `1 << enum state' and `enum state' ranges.  */
     STATE_FIRST = 4,
+    STATE_INSTABLE,
     STATE_ENOENT,
     STATE_SLEEPING,
     STATE_RUNNING,
@@ -70,6 +75,7 @@ static const char *state_to_name (enum state state)
 {
   switch (state)
     {
+      case STATE_INSTABLE: return "STATE_INSTABLE";
       case STATE_ENOENT:   return "STATE_ENOENT";
       case STATE_SLEEPING: return "STATE_SLEEPING";
       case STATE_RUNNING:  return "STATE_RUNNING";
@@ -82,9 +88,7 @@ static const char *state_to_name (enum state state)
   crash ();
 }
 
-#define STATE(pid, expect_mask) state ((pid), (expect_mask), #expect_mask )
-
-static enum state state (pid_t pid, unsigned expect_mask, const char *expect_mask_string)
+static enum state state_get (pid_t pid)
 {
   char status_name[32];
   char line[LINE_MAX];
@@ -93,16 +97,6 @@ static enum state state (pid_t pid, unsigned expect_mask, const char *expect_mas
 
   delay ();
 
-  /* Sanity check `1 << enum state' was not misplaced with `enum state'.  */
-  assert (1 << (STATE_FIRST + 1) >= STATE_LAST);
-  assert (expect_mask != 0);
-#define MASK_UNDER_EXCLUSIVE(bit) ((1 << (bit)) - 1)
-#define MASK_ABOVE_INCLUSIVE(bit) (~MASK_UNDER_EXCLUSIVE (bit))
-  assert ((expect_mask & MASK_UNDER_EXCLUSIVE (STATE_FIRST + 1)) == 0);
-  assert ((expect_mask & MASK_ABOVE_INCLUSIVE (STATE_LAST)) == 0);
-#undef MASK_ABOVE_INCLUSIVE
-#undef MASK_UNDER_EXCLUSIVE
-
   snprintf (status_name, sizeof (status_name), "/proc/%d/status", (int) pid);
   f = fopen (status_name, "r");
   if (f == NULL && errno == ENOENT)
@@ -113,7 +107,7 @@ static enum state state (pid_t pid, unsigned expect_mask, const char *expect_mas
     {
       int i;
 
-      found = STATE_ENOENT;
+      found = STATE_INSTABLE;
       while (errno = 0, fgets (line, sizeof (line), f) != NULL)
        {
          const char *const string = "State:\t";
@@ -137,17 +131,44 @@ static enum state state (pid_t pid, unsigned expect_mask, const char *expect_mas
              crash ();
            }
        }
-      assert (found != STATE_ENOENT);
+      if (errno == ESRCH)
+        return found;
+      assert (found != STATE_INSTABLE);
       i = fclose (f);
       assert (i == 0);
     }
-  if (((1 << found) & expect_mask) == 0)
+  return found;
+}
+
+#define STATE(pid, expect_mask) state ((pid), (expect_mask), #expect_mask )
+
+static enum state state (pid_t pid, unsigned expect_mask, const char *expect_mask_string)
+{
+  enum state found;
+  time_t timeout = time (NULL) + TIMEOUT_SECS;
+
+  /* Sanity check `1 << enum state' was not misplaced with `enum state'.  */
+  assert (1 << (STATE_FIRST + 1) >= STATE_LAST);
+  assert (expect_mask != 0);
+#define MASK_UNDER_EXCLUSIVE(bit) ((1 << (bit)) - 1)
+#define MASK_ABOVE_INCLUSIVE(bit) (~MASK_UNDER_EXCLUSIVE (bit))
+  assert ((expect_mask & MASK_UNDER_EXCLUSIVE (STATE_FIRST + 1)) == 0);
+  assert ((expect_mask & MASK_ABOVE_INCLUSIVE (STATE_LAST)) == 0);
+#undef MASK_ABOVE_INCLUSIVE
+#undef MASK_UNDER_EXCLUSIVE
+
+  do
     {
-      fprintf (stderr, "Found for PID %d state %s but expecting (%s)\n",
-              (int) pid, state_to_name (found), expect_mask_string);
-      crash ();
+      found = state_get (pid);
+
+      if (((1 << found) & expect_mask) != 0)
+        return found;
     }
-  return found;
+  while (time (NULL) < timeout);
+
+  fprintf (stderr, "Found for PID %d state %s but expecting (%s)\n",
+          (int) pid, state_to_name (found), expect_mask_string);
+  crash ();
 }
 
 /* Debugging only: Number of signal needing redelivery on PTRACE_ATTACH.  */