* tests/threads/waitAndInterrupt.java: New test hanging CACAO.
[cacao.git] / tests / threads / waitAndInterrupt.java
1 // This test grew a bit more elaborate than anticipated...
2 // It verifies that the JVM handles properly the case of a thread being
3 // interrupted and notified at the same time.
4
5 public class waitAndInterrupt {
6         private class semaphore {
7                 private int v;
8                 public semaphore(int v) {
9                         this.v = v;
10                 }
11                 public synchronized void semwait() {
12                         while (v == 0)
13                                 try {
14                                         wait();
15                                 } catch (InterruptedException e) {
16                                 }
17                         v--;
18                 }
19                 public synchronized void sempost() {
20                         if (v == 0)
21                                 notify();
22                         v++;
23                 }
24         }
25
26         public static class firstthread implements Runnable {
27                 private waitAndInterrupt s;
28
29                 public firstthread(waitAndInterrupt s_) {
30                         s = s_;
31                 }
32                 public void run() {
33                         boolean iAmFirst = Thread.currentThread() == s.t1;
34                         try {
35                                 int i = 0;
36                                 int count_not = 0;
37                                 int count_int = 0;
38                                 for (;;) {
39                                         if (iAmFirst) {
40                                                 if (++i == 100) {
41                                                         i = 0;
42                                                         System.out.println(Thread.currentThread().getName() + " still running, notified " + Integer.toString(count_not) + ", interrupted " + Integer.toString(count_int));
43                                                 }
44                                                 synchronized (s) {
45                                                         s.sem1.sempost();
46                                                         try {
47                                                                 while (!s.notified)
48                                                                         s.wait();
49                                                                 try {
50                                                                         s.wait();
51                                                                 } catch (InterruptedException e) {
52                                                                         s.notify(); // wake t2
53                                                                 }
54                                                                 count_not++;
55                                                         } catch (InterruptedException e) {
56                                                                 count_int++;
57                                                         }
58                                                 }
59
60                                                 s.sem5.sempost();
61                                                 s.sem8.semwait();
62                                         } else {
63                                                 s.sem1.semwait();
64                                                 if (++i == 100) {
65                                                         i = 0;
66                                                         System.out.println(Thread.currentThread().getName() + " still running");
67                                                 }
68                                                 synchronized (s) {
69                                                         s.sem2.sempost();
70                                                         try {
71                                                                 while (!s.notified)
72                                                                         s.wait();
73                                                                 s.notified = false;
74                                                                 count_not++;
75                                                         } catch (InterruptedException e) {
76                                                                 count_int++;
77                                                         }
78                                                 }
79
80                                                 s.sem6.sempost();
81                                         }
82                                 }
83                         } catch (Exception e) {
84                                 e.printStackTrace();
85                         }
86                 }
87         }
88
89         public static class otherthread implements Runnable {
90                 private waitAndInterrupt s;
91
92                 public otherthread(waitAndInterrupt s_) {
93                         s = s_;
94                 }
95                 public void run() {
96                         boolean iAmFirst = Thread.currentThread() == s.t3;
97                         try {
98                                 int i = 0;
99                                 for (;;) {
100                                         if (iAmFirst) {
101                                                 s.sem3.semwait();
102                                                 if (++i == 100) {
103                                                         i = 0;
104                                                         System.out.println(Thread.currentThread().getName() + " still running");
105                                                 }
106                                                 synchronized (s) {
107                                                         s.sem4.sempost();
108                                                 }
109                                                 s.t1.interrupt();
110                                                 s.sem5.semwait();
111                                         } else {
112                                                 s.sem4.semwait();
113                                                 if (++i == 100) {
114                                                         i = 0;
115                                                         System.out.println(Thread.currentThread().getName() + " still running");
116                                                 }
117                                                 synchronized (s) {
118                                                         if (s.notified)
119                                                                 System.out.println("shouldn't happen (1)");
120                                                         s.notified = true;
121                                                         s.notify();
122                                                 }
123                                                 s.sem6.semwait();
124                                         }
125                                         s.sem7.sempost();
126                                 }
127                         } catch (Exception e) {
128                                 e.printStackTrace();
129                         }
130                 }
131         }
132
133         public static class controlthread implements Runnable {
134                 private waitAndInterrupt s;
135
136                 public controlthread(waitAndInterrupt s_) {
137                         s = s_;
138                 }
139                 public void run() {
140                         try {
141                                 for (;;) {
142                                         s.sem2.semwait();
143                                         synchronized (s) {
144                                         }
145                                         s.sem3.sempost();
146                                         s.sem7.semwait();
147                                         s.sem7.semwait();
148                                         s.sem8.sempost(); // wake first
149                                 }
150                         } catch (Exception e) {
151                                 e.printStackTrace();
152                         }
153                 }
154         }
155
156         public Thread t1 = null;
157         public Thread t2 = null;
158         public Thread t3 = null;
159         public Thread t4 = null;
160         public semaphore sem1 = new semaphore(0);
161         public semaphore sem2 = new semaphore(0);
162         public semaphore sem3 = new semaphore(0);
163         public semaphore sem4 = new semaphore(0);
164         public semaphore sem5 = new semaphore(0);
165         public semaphore sem6 = new semaphore(0);
166         public semaphore sem7 = new semaphore(0);
167         public semaphore sem8 = new semaphore(0);
168         public boolean notified = false;
169
170         public static void main(String args[]) {
171                 waitAndInterrupt s = new waitAndInterrupt();
172                 firstthread r1 = new firstthread(s);
173                 firstthread r2 = new firstthread(s);
174                 otherthread r3 = new otherthread(s);
175                 controlthread r5 = new controlthread(s);
176
177                 s.t1 = new Thread(r1, "a");
178                 s.t2 = new Thread(r2, "b");
179                 s.t3 = new Thread(r3, "c");
180                 s.t4 = new Thread(r3, "d");
181                 Thread t5 = new Thread(r5, "e");
182                 s.t1.start();
183                 s.t2.start();
184                 s.t3.start();
185                 s.t4.start();
186                 t5.start();
187         }
188 }
189
190 /*
191  * These are local overrides for various environment variables in Emacs.
192  * Please do not remove this and leave it at the end of the file, where
193  * Emacs will automagically detect them.
194  * ---------------------------------------------------------------------
195  * Local variables:
196  * mode: java
197  * indent-tabs-mode: t
198  * c-basic-offset: 4
199  * tab-width: 4
200  * End:
201  * vim:noexpandtab:sw=4:ts=4:
202  */