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