* tests/threads/waitAndInterrupt.java: New test hanging CACAO.
authorStefan Ring <stefan@complang.tuwien.ac.at>
Mon, 3 Mar 2008 21:13:28 +0000 (22:13 +0100)
committerStefan Ring <stefan@complang.tuwien.ac.at>
Mon, 3 Mar 2008 21:13:28 +0000 (22:13 +0100)
tests/threads/waitAndInterrupt.java [new file with mode: 0644]

diff --git a/tests/threads/waitAndInterrupt.java b/tests/threads/waitAndInterrupt.java
new file mode 100644 (file)
index 0000000..2f68b75
--- /dev/null
@@ -0,0 +1,202 @@
+// This test grew a bit more elaborate than anticipated...
+// It verifies that the JVM handles properly the case of a thread being
+// interrupted and notified at the same time.
+
+public class waitAndInterrupt {
+       private class semaphore {
+               private int v;
+               public semaphore(int v) {
+                       this.v = v;
+               }
+               public synchronized void semwait() {
+                       while (v == 0)
+                               try {
+                                       wait();
+                               } catch (InterruptedException e) {
+                               }
+                       v--;
+               }
+               public synchronized void sempost() {
+                       if (v == 0)
+                               notify();
+                       v++;
+               }
+       }
+
+       public static class firstthread implements Runnable {
+               private waitAndInterrupt s;
+
+               public firstthread(waitAndInterrupt s_) {
+                       s = s_;
+               }
+               public void run() {
+                       boolean iAmFirst = Thread.currentThread() == s.t1;
+                       try {
+                               int i = 0;
+                               int count_not = 0;
+                               int count_int = 0;
+                               for (;;) {
+                                       if (iAmFirst) {
+                                               if (++i == 100) {
+                                                       i = 0;
+                                                       System.out.println(Thread.currentThread().getName() + " still running, notified " + Integer.toString(count_not) + ", interrupted " + Integer.toString(count_int));
+                                               }
+                                               synchronized (s) {
+                                                       s.sem1.sempost();
+                                                       try {
+                                                               while (!s.notified)
+                                                                       s.wait();
+                                                               try {
+                                                                       s.wait();
+                                                               } catch (InterruptedException e) {
+                                                                       s.notify(); // wake t2
+                                                               }
+                                                               count_not++;
+                                                       } catch (InterruptedException e) {
+                                                               count_int++;
+                                                       }
+                                               }
+
+                                               s.sem5.sempost();
+                                               s.sem8.semwait();
+                                       } else {
+                                               s.sem1.semwait();
+                                               if (++i == 100) {
+                                                       i = 0;
+                                                       System.out.println(Thread.currentThread().getName() + " still running");
+                                               }
+                                               synchronized (s) {
+                                                       s.sem2.sempost();
+                                                       try {
+                                                               while (!s.notified)
+                                                                       s.wait();
+                                                               s.notified = false;
+                                                               count_not++;
+                                                       } catch (InterruptedException e) {
+                                                               count_int++;
+                                                       }
+                                               }
+
+                                               s.sem6.sempost();
+                                       }
+                               }
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                       }
+               }
+       }
+
+       public static class otherthread implements Runnable {
+               private waitAndInterrupt s;
+
+               public otherthread(waitAndInterrupt s_) {
+                       s = s_;
+               }
+               public void run() {
+                       boolean iAmFirst = Thread.currentThread() == s.t3;
+                       try {
+                               int i = 0;
+                               for (;;) {
+                                       if (iAmFirst) {
+                                               s.sem3.semwait();
+                                               if (++i == 100) {
+                                                       i = 0;
+                                                       System.out.println(Thread.currentThread().getName() + " still running");
+                                               }
+                                               synchronized (s) {
+                                                       s.sem4.sempost();
+                                               }
+                                               s.t1.interrupt();
+                                               s.sem5.semwait();
+                                       } else {
+                                               s.sem4.semwait();
+                                               if (++i == 100) {
+                                                       i = 0;
+                                                       System.out.println(Thread.currentThread().getName() + " still running");
+                                               }
+                                               synchronized (s) {
+                                                       if (s.notified)
+                                                               System.out.println("shouldn't happen (1)");
+                                                       s.notified = true;
+                                                       s.notify();
+                                               }
+                                               s.sem6.semwait();
+                                       }
+                                       s.sem7.sempost();
+                               }
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                       }
+               }
+       }
+
+       public static class controlthread implements Runnable {
+               private waitAndInterrupt s;
+
+               public controlthread(waitAndInterrupt s_) {
+                       s = s_;
+               }
+               public void run() {
+                       try {
+                               for (;;) {
+                                       s.sem2.semwait();
+                                       synchronized (s) {
+                                       }
+                                       s.sem3.sempost();
+                                       s.sem7.semwait();
+                                       s.sem7.semwait();
+                                       s.sem8.sempost(); // wake first
+                               }
+                       } catch (Exception e) {
+                               e.printStackTrace();
+                       }
+               }
+       }
+
+       public Thread t1 = null;
+       public Thread t2 = null;
+       public Thread t3 = null;
+       public Thread t4 = null;
+       public semaphore sem1 = new semaphore(0);
+       public semaphore sem2 = new semaphore(0);
+       public semaphore sem3 = new semaphore(0);
+       public semaphore sem4 = new semaphore(0);
+       public semaphore sem5 = new semaphore(0);
+       public semaphore sem6 = new semaphore(0);
+       public semaphore sem7 = new semaphore(0);
+       public semaphore sem8 = new semaphore(0);
+       public boolean notified = false;
+
+       public static void main(String args[]) {
+               waitAndInterrupt s = new waitAndInterrupt();
+               firstthread r1 = new firstthread(s);
+               firstthread r2 = new firstthread(s);
+               otherthread r3 = new otherthread(s);
+               controlthread r5 = new controlthread(s);
+
+               s.t1 = new Thread(r1, "a");
+               s.t2 = new Thread(r2, "b");
+               s.t3 = new Thread(r3, "c");
+               s.t4 = new Thread(r3, "d");
+               Thread t5 = new Thread(r5, "e");
+               s.t1.start();
+               s.t2.start();
+               s.t3.start();
+               s.t4.start();
+               t5.start();
+       }
+}
+
+/*
+ * These are local overrides for various environment variables in Emacs.
+ * Please do not remove this and leave it at the end of the file, where
+ * Emacs will automagically detect them.
+ * ---------------------------------------------------------------------
+ * Local variables:
+ * mode: java
+ * indent-tabs-mode: t
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ * vim:noexpandtab:sw=4:ts=4:
+ */