Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/test/hotspot/jtreg/vmTestbase/nsk/share/Wicket.java
40948 views
1
/*
2
* Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
3
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
*
5
* This code is free software; you can redistribute it and/or modify it
6
* under the terms of the GNU General Public License version 2 only, as
7
* published by the Free Software Foundation.
8
*
9
* This code is distributed in the hope that it will be useful, but WITHOUT
10
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12
* version 2 for more details (a copy is included in the LICENSE file that
13
* accompanied this code).
14
*
15
* You should have received a copy of the GNU General Public License version
16
* 2 along with this work; if not, write to the Free Software Foundation,
17
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
*
19
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
* or visit www.oracle.com if you need additional information or have any
21
* questions.
22
*/
23
24
package nsk.share;
25
26
import java.io.PrintStream;
27
import java.util.concurrent.TimeUnit;
28
import java.util.concurrent.locks.Condition;
29
import java.util.concurrent.locks.Lock;
30
import java.util.concurrent.locks.ReentrantLock;
31
32
/**
33
* Wicket provides a means for one or more threads to suspend execution
34
* (to wait) until notified by one or more other threads that some set
35
* of locks is now open.
36
*
37
* <p>Wicket instances are intended to be used generally in the following
38
* scenarios:
39
*
40
* <ul><li>One thread starts one or more child threads and waits until the
41
* child threads to be started.
42
*
43
* <li>One thread starts one or more child threads and waits until at least
44
* one of the child threads to be started.
45
*
46
* <li>One or more child threads wait until a main thread lets them
47
* to finish.
48
*
49
* <li>Disable the current thread for thread scheduling purposes, for up to
50
* the specified waiting time.</ul>
51
*/
52
53
public class Wicket {
54
55
/** Number of closed locks, can be greater or equal to zero */
56
private int count;
57
58
/** Number of waiters **/
59
private int waiters = 0;
60
61
/** Enable debug output */
62
private PrintStream debugOutput = null;
63
64
/** Wicket's string identifier */
65
private String name = "";
66
67
private final Lock lock = new ReentrantLock();
68
private final Condition condition = lock.newCondition();
69
70
/**
71
* Construct a Wicket with only one closed lock.
72
*/
73
public Wicket() {
74
this(1);
75
}
76
77
/**
78
* Construct a Wicket with the given number of closed locks.
79
*
80
* @param _name Wicket's identifier
81
* @param _count the initial number of closed locks
82
* @param _debugOutput whether to print debug info or not
83
* @throws IllegalArgumentException if count is less than 1
84
*/
85
public Wicket(String _name, int _count, PrintStream _debugOutput) {
86
this(_count);
87
name = _name;
88
debugOutput = _debugOutput;
89
}
90
91
/**
92
* Construct a Wicket with the given number of closed locks.
93
*
94
* @param count the initial number of closed locks
95
* @throws IllegalArgumentException if count is less than 1
96
*/
97
public Wicket(int count) {
98
if (count < 1)
99
throw new IllegalArgumentException(
100
"count is less than one: " + count);
101
this.count = count;
102
}
103
104
/**
105
* Wait for all locks of this Wicket to be open.
106
*
107
* <p>If all locks are already open then returns immediately.
108
*
109
* <p>If at least one lock is still closed then the current thread becomes
110
* disabled for thread scheduling purposes and lies dormant until all
111
* the locks will be open by some other threads. One lock can be open
112
* by invoking the unlock method for this Wicket.
113
*
114
* <p>Please note, that the method would ignore Thread.interrupt() requests.
115
*/
116
public void waitFor() {
117
long id = System.currentTimeMillis();
118
119
lock.lock();
120
try {
121
++waiters;
122
if (debugOutput != null) {
123
debugOutput.printf("Wicket %d %s: waitFor(). There are %d waiters totally now.\n", id, name, waiters);
124
}
125
126
while (count > 0) {
127
try {
128
condition.await();
129
} catch (InterruptedException e) {
130
}
131
}
132
--waiters;
133
} finally {
134
lock.unlock();
135
}
136
}
137
138
/**
139
* Wait for all locks of this Wicket to be open within the given
140
* period of time.
141
*
142
* <p>If all locks are already open then returns immediately with zero.
143
*
144
* <p>If the time is equal to zero, the method will not
145
* wait and returns a number of closed locks,
146
* if all locks are open, the return value is zero.
147
*
148
* <p>If at least one lock is still closed then the current thread becomes
149
* disabled for thread scheduling purposes and lies dormant until
150
* of the two things happens:
151
*
152
* <ul><li>Some other threads invoke the unlock method for this Wicket
153
* to open all the closed locks; or
154
*
155
* <li>The specified waiting time elapses.</ul>
156
*
157
* <p>If all locks are open then the return value is 0.
158
*
159
* <p>If the specified waiting time elapses and some locks are still closed
160
* then the return value is equal to number of closed locks.
161
*
162
* <p>Please note, that the method would ignore Thread.interrupt() requests.
163
*
164
* @param timeout the maximum time to wait in milliseconds
165
* @return the number of closed locks
166
* @throws IllegalArgumentException if timeout is less than 0
167
*/
168
public int waitFor(long timeout) {
169
if (timeout < 0)
170
throw new IllegalArgumentException(
171
"timeout value is negative: " + timeout);
172
173
long id = System.currentTimeMillis();
174
175
lock.lock();
176
try {
177
++waiters;
178
if (debugOutput != null) {
179
debugOutput.printf("Wicket %d %s: waitFor(). There are %d waiters totally now.\n", id, name, waiters);
180
}
181
182
long waitTime = timeout;
183
long startTime = System.currentTimeMillis();
184
185
while (count > 0 && waitTime > 0) {
186
try {
187
condition.await(waitTime, TimeUnit.MILLISECONDS);
188
} catch (InterruptedException e) {
189
}
190
waitTime = timeout - (System.currentTimeMillis() - startTime);
191
}
192
--waiters;
193
return count;
194
} finally {
195
lock.unlock();
196
}
197
}
198
199
/**
200
* Unlock one closed lock.
201
*
202
* <p>Open a lock, reducing the number of closed locks by one.
203
*
204
* <p>If last closed lock is opened then all of the threads waiting
205
* by invoking the waitFor method for this Wicket will be released
206
* and re-enabled for thread scheduling purposes.
207
*
208
* @throws IllegalStateException if there is no one closed lock
209
*/
210
public void unlock() {
211
212
lock.lock();
213
try {
214
if (count == 0)
215
throw new IllegalStateException("locks are already open");
216
217
--count;
218
if (debugOutput != null) {
219
debugOutput.printf("Wicket %s: unlock() the count is now %d\n", name, count);
220
}
221
222
if (count == 0) {
223
condition.signalAll();
224
}
225
} finally {
226
lock.unlock();
227
}
228
}
229
230
/**
231
* Unlock all closed locks.
232
*
233
* <p>Open all closed locks, setting the number of closed locks to zero.
234
*
235
* <p>If any threads are waiting by invoking the waitFor method for
236
* this Wicket then they will be released and re-enabled for thread
237
* scheduling purposes.
238
*/
239
public void unlockAll() {
240
if (debugOutput != null) {
241
debugOutput.printf("Wicket %s: unlockAll()\n", name);
242
}
243
244
lock.lock();
245
try {
246
count = 0;
247
condition.signalAll();
248
} finally {
249
lock.unlock();
250
}
251
}
252
253
/**
254
* Return current number of waiters - threads that are currently
255
* waiting using one of waitFor methods.
256
*
257
* @return number of waiters
258
*/
259
public int getWaiters() {
260
261
lock.lock();
262
try {
263
if (debugOutput != null) {
264
debugOutput.printf("Wicket %s: getWaiters()\n", name);
265
}
266
return waiters;
267
} finally {
268
lock.unlock();
269
}
270
}
271
}
272
273