Harden monitor tests against spurious wakeups.

The monitor tests (1930 - 1934) were slightly flakey due to spurious
wake-ups. This makes them less susceptible to the issue by making
threads go back to sleep if the wake-up seems spurious.

Test: ./test.py --host -j50
Test: stress --cpu 60
Test: while ./test/run-test --host 1933; do; done
Change-Id: I895827e6433f9ab3d2bd5cc3bf10ad0e242ac89d
diff --git a/test/1930-monitor-info/src/art/Monitors.java b/test/1930-monitor-info/src/art/Monitors.java
index b28a3ee..7fe2b60 100644
--- a/test/1930-monitor-info/src/art/Monitors.java
+++ b/test/1930-monitor-info/src/art/Monitors.java
@@ -36,12 +36,40 @@
 
   public static class NamedLock {
     public final String name;
+    private volatile int calledNotify;
     public NamedLock(String name) {
       this.name = name;
+      calledNotify = 0;
     }
+
     public String toString() {
       return String.format("NamedLock[%s]", name);
     }
+
+    public final void DoWait() throws Exception {
+      final int v = calledNotify;
+      while (v == calledNotify) {
+        wait();
+      }
+    }
+
+    public final void DoWait(long t) throws Exception {
+      final int v = calledNotify;
+      final long target = System.currentTimeMillis() + (t / 2);
+      while (v == calledNotify && (t < 0 || System.currentTimeMillis() < target)) {
+        wait(t);
+      }
+    }
+
+    public final void DoNotifyAll() throws Exception {
+      calledNotify++;
+      notifyAll();
+    }
+
+    public final void DoNotify() throws Exception {
+      calledNotify++;
+      notify();
+    }
   }
 
   public static final class MonitorUsage {
@@ -91,7 +119,7 @@
   public static class LockController {
     private static enum Action { HOLD, RELEASE, NOTIFY, NOTIFY_ALL, WAIT, TIMED_WAIT }
 
-    public final Object lock;
+    public final NamedLock lock;
     public final long timeout;
     private final AtomicStampedReference<Action> action;
     private volatile Thread runner = null;
@@ -100,10 +128,10 @@
     private static final AtomicInteger cnt = new AtomicInteger(0);
     private volatile Throwable exe;
 
-    public LockController(Object lock) {
+    public LockController(NamedLock lock) {
       this(lock, 10 * 1000);
     }
-    public LockController(Object lock, long timeout) {
+    public LockController(NamedLock lock, long timeout) {
       this.lock = lock;
       this.timeout = timeout;
       this.action = new AtomicStampedReference(Action.HOLD, 0);
@@ -177,16 +205,16 @@
                       Thread.yield();
                       break;
                     case NOTIFY:
-                      lock.notify();
+                      lock.DoNotify();
                       break;
                     case NOTIFY_ALL:
-                      lock.notifyAll();
+                      lock.DoNotifyAll();
                       break;
                     case TIMED_WAIT:
-                      lock.wait(timeout);
+                      lock.DoWait(timeout);
                       break;
                     case WAIT:
-                      lock.wait();
+                      lock.DoWait();
                       break;
                     default:
                       throw new Error("Unknown action " + action);
diff --git a/test/1930-monitor-info/src/art/Test1930.java b/test/1930-monitor-info/src/art/Test1930.java
index a7fa1c7..ee03d73 100644
--- a/test/1930-monitor-info/src/art/Test1930.java
+++ b/test/1930-monitor-info/src/art/Test1930.java
@@ -96,7 +96,7 @@
         printMonitorUsage(lk);
         sem.release();
         try {
-          lk.wait();
+          lk.DoWait();
         } catch (Exception e) {
           throw new Error("Error waiting!", e);
         }
@@ -107,7 +107,7 @@
     sem.acquire();
     synchronized (lk) {
       printMonitorUsage(lk);
-      lk.notifyAll();
+      lk.DoNotifyAll();
     }
     t.join();
     printMonitorUsage(lk);
diff --git a/test/1931-monitor-events/src/art/Monitors.java b/test/1931-monitor-events/src/art/Monitors.java
index b28a3ee..7fe2b60 100644
--- a/test/1931-monitor-events/src/art/Monitors.java
+++ b/test/1931-monitor-events/src/art/Monitors.java
@@ -36,12 +36,40 @@
 
   public static class NamedLock {
     public final String name;
+    private volatile int calledNotify;
     public NamedLock(String name) {
       this.name = name;
+      calledNotify = 0;
     }
+
     public String toString() {
       return String.format("NamedLock[%s]", name);
     }
+
+    public final void DoWait() throws Exception {
+      final int v = calledNotify;
+      while (v == calledNotify) {
+        wait();
+      }
+    }
+
+    public final void DoWait(long t) throws Exception {
+      final int v = calledNotify;
+      final long target = System.currentTimeMillis() + (t / 2);
+      while (v == calledNotify && (t < 0 || System.currentTimeMillis() < target)) {
+        wait(t);
+      }
+    }
+
+    public final void DoNotifyAll() throws Exception {
+      calledNotify++;
+      notifyAll();
+    }
+
+    public final void DoNotify() throws Exception {
+      calledNotify++;
+      notify();
+    }
   }
 
   public static final class MonitorUsage {
@@ -91,7 +119,7 @@
   public static class LockController {
     private static enum Action { HOLD, RELEASE, NOTIFY, NOTIFY_ALL, WAIT, TIMED_WAIT }
 
-    public final Object lock;
+    public final NamedLock lock;
     public final long timeout;
     private final AtomicStampedReference<Action> action;
     private volatile Thread runner = null;
@@ -100,10 +128,10 @@
     private static final AtomicInteger cnt = new AtomicInteger(0);
     private volatile Throwable exe;
 
-    public LockController(Object lock) {
+    public LockController(NamedLock lock) {
       this(lock, 10 * 1000);
     }
-    public LockController(Object lock, long timeout) {
+    public LockController(NamedLock lock, long timeout) {
       this.lock = lock;
       this.timeout = timeout;
       this.action = new AtomicStampedReference(Action.HOLD, 0);
@@ -177,16 +205,16 @@
                       Thread.yield();
                       break;
                     case NOTIFY:
-                      lock.notify();
+                      lock.DoNotify();
                       break;
                     case NOTIFY_ALL:
-                      lock.notifyAll();
+                      lock.DoNotifyAll();
                       break;
                     case TIMED_WAIT:
-                      lock.wait(timeout);
+                      lock.DoWait(timeout);
                       break;
                     case WAIT:
-                      lock.wait();
+                      lock.DoWait();
                       break;
                     default:
                       throw new Error("Unknown action " + action);
diff --git a/test/1932-monitor-events-misc/src/art/Monitors.java b/test/1932-monitor-events-misc/src/art/Monitors.java
index b28a3ee..7fe2b60 100644
--- a/test/1932-monitor-events-misc/src/art/Monitors.java
+++ b/test/1932-monitor-events-misc/src/art/Monitors.java
@@ -36,12 +36,40 @@
 
   public static class NamedLock {
     public final String name;
+    private volatile int calledNotify;
     public NamedLock(String name) {
       this.name = name;
+      calledNotify = 0;
     }
+
     public String toString() {
       return String.format("NamedLock[%s]", name);
     }
+
+    public final void DoWait() throws Exception {
+      final int v = calledNotify;
+      while (v == calledNotify) {
+        wait();
+      }
+    }
+
+    public final void DoWait(long t) throws Exception {
+      final int v = calledNotify;
+      final long target = System.currentTimeMillis() + (t / 2);
+      while (v == calledNotify && (t < 0 || System.currentTimeMillis() < target)) {
+        wait(t);
+      }
+    }
+
+    public final void DoNotifyAll() throws Exception {
+      calledNotify++;
+      notifyAll();
+    }
+
+    public final void DoNotify() throws Exception {
+      calledNotify++;
+      notify();
+    }
   }
 
   public static final class MonitorUsage {
@@ -91,7 +119,7 @@
   public static class LockController {
     private static enum Action { HOLD, RELEASE, NOTIFY, NOTIFY_ALL, WAIT, TIMED_WAIT }
 
-    public final Object lock;
+    public final NamedLock lock;
     public final long timeout;
     private final AtomicStampedReference<Action> action;
     private volatile Thread runner = null;
@@ -100,10 +128,10 @@
     private static final AtomicInteger cnt = new AtomicInteger(0);
     private volatile Throwable exe;
 
-    public LockController(Object lock) {
+    public LockController(NamedLock lock) {
       this(lock, 10 * 1000);
     }
-    public LockController(Object lock, long timeout) {
+    public LockController(NamedLock lock, long timeout) {
       this.lock = lock;
       this.timeout = timeout;
       this.action = new AtomicStampedReference(Action.HOLD, 0);
@@ -177,16 +205,16 @@
                       Thread.yield();
                       break;
                     case NOTIFY:
-                      lock.notify();
+                      lock.DoNotify();
                       break;
                     case NOTIFY_ALL:
-                      lock.notifyAll();
+                      lock.DoNotifyAll();
                       break;
                     case TIMED_WAIT:
-                      lock.wait(timeout);
+                      lock.DoWait(timeout);
                       break;
                     case WAIT:
-                      lock.wait();
+                      lock.DoWait();
                       break;
                     default:
                       throw new Error("Unknown action " + action);
diff --git a/test/1933-monitor-current-contended/src/art/Monitors.java b/test/1933-monitor-current-contended/src/art/Monitors.java
index b28a3ee..7fe2b60 100644
--- a/test/1933-monitor-current-contended/src/art/Monitors.java
+++ b/test/1933-monitor-current-contended/src/art/Monitors.java
@@ -36,12 +36,40 @@
 
   public static class NamedLock {
     public final String name;
+    private volatile int calledNotify;
     public NamedLock(String name) {
       this.name = name;
+      calledNotify = 0;
     }
+
     public String toString() {
       return String.format("NamedLock[%s]", name);
     }
+
+    public final void DoWait() throws Exception {
+      final int v = calledNotify;
+      while (v == calledNotify) {
+        wait();
+      }
+    }
+
+    public final void DoWait(long t) throws Exception {
+      final int v = calledNotify;
+      final long target = System.currentTimeMillis() + (t / 2);
+      while (v == calledNotify && (t < 0 || System.currentTimeMillis() < target)) {
+        wait(t);
+      }
+    }
+
+    public final void DoNotifyAll() throws Exception {
+      calledNotify++;
+      notifyAll();
+    }
+
+    public final void DoNotify() throws Exception {
+      calledNotify++;
+      notify();
+    }
   }
 
   public static final class MonitorUsage {
@@ -91,7 +119,7 @@
   public static class LockController {
     private static enum Action { HOLD, RELEASE, NOTIFY, NOTIFY_ALL, WAIT, TIMED_WAIT }
 
-    public final Object lock;
+    public final NamedLock lock;
     public final long timeout;
     private final AtomicStampedReference<Action> action;
     private volatile Thread runner = null;
@@ -100,10 +128,10 @@
     private static final AtomicInteger cnt = new AtomicInteger(0);
     private volatile Throwable exe;
 
-    public LockController(Object lock) {
+    public LockController(NamedLock lock) {
       this(lock, 10 * 1000);
     }
-    public LockController(Object lock, long timeout) {
+    public LockController(NamedLock lock, long timeout) {
       this.lock = lock;
       this.timeout = timeout;
       this.action = new AtomicStampedReference(Action.HOLD, 0);
@@ -177,16 +205,16 @@
                       Thread.yield();
                       break;
                     case NOTIFY:
-                      lock.notify();
+                      lock.DoNotify();
                       break;
                     case NOTIFY_ALL:
-                      lock.notifyAll();
+                      lock.DoNotifyAll();
                       break;
                     case TIMED_WAIT:
-                      lock.wait(timeout);
+                      lock.DoWait(timeout);
                       break;
                     case WAIT:
-                      lock.wait();
+                      lock.DoWait();
                       break;
                     default:
                       throw new Error("Unknown action " + action);
diff --git a/test/1933-monitor-current-contended/src/art/Test1933.java b/test/1933-monitor-current-contended/src/art/Test1933.java
index e21c395..194a043 100644
--- a/test/1933-monitor-current-contended/src/art/Test1933.java
+++ b/test/1933-monitor-current-contended/src/art/Test1933.java
@@ -34,9 +34,13 @@
      controller1.waitForLockToBeHeld();
      controller1.DoWait();
      controller1.waitForNotifySleep();
-     System.out.println("c1 is contending for monitor: " + controller1.getWorkerContendedMonitor());
+     // Spurious wakeups can hurt us here. Just retry until we get the result we expect. The test
+     // will timeout eventually.
+     Object mon = controller1.getWorkerContendedMonitor();
+     for (; mon == null; mon = controller1.getWorkerContendedMonitor()) { Thread.yield(); }
+     System.out.println("c1 is contending for monitor: " + mon);
      synchronized (lk) {
-       lk.notifyAll();
+       lk.DoNotifyAll();
      }
      controller1.DoUnlock();
   }