29package com.jogamp.common.util.locks;
31import java.io.IOException;
33import org.junit.Assert;
36import com.jogamp.common.os.Platform;
37import com.jogamp.common.util.InterruptSource;
38import com.jogamp.junit.util.SingletonJunitCase;
40import org.junit.FixMethodOrder;
41import org.junit.runners.MethodSorters;
43@FixMethodOrder(MethodSorters.NAME_ASCENDING)
47 NONE(0), YIELD(1), SLEEP(2);
56 static void yield_thread(
final YieldMode mode) {
64 }
catch (
final InterruptedException ie) {
74 static class LockedObject {
75 static final boolean DEBUG =
false;
77 private final RecursiveThreadGroupLock locker;
78 private volatile int slaveCounter;
80 public LockedObject() {
81 locker = LockFactory.createRecursiveThreadGroupLock();
85 public final void masterAction(
final String tab,
final String name,
final Thread[] slaves,
final int loops,
final int mark,
final YieldMode yieldMode) {
88 System.err.println(tab+
"<"+name+
" c "+slaveCounter);
90 Assert.assertTrue(mark>loops);
91 Assert.assertTrue(loops*loops>mark);
93 if(slaveCounter<mark) {
94 for(
int i=0; i<slaves.length; i++) {
95 locker.addOwner(slaves[i]);
98 while(slaveCounter<mark) {
99 yield_thread(yieldMode);
104 System.err.println(tab+
" "+name+
" c "+slaveCounter+
">");
111 public final void slaveAction(
final String tab,
final String name,
int loops,
final int mark,
final YieldMode yieldMode) {
112 if(slaveCounter>=mark) {
114 System.err.println(tab+
"["+name+
" c "+slaveCounter+
" - NOP]");
120 System.err.println(tab+
"["+name+
" c "+slaveCounter);
122 Assert.assertTrue(mark>loops);
123 Assert.assertTrue(loops*loops>mark);
125 while(loops>0 && slaveCounter<mark) {
133 yield_thread(yieldMode);
136 System.err.println(tab+
" "+name+
" c "+slaveCounter+
"]");
142 public final boolean isLocked() {
143 return locker.isLocked();
148 interface LockedObjectRunner
extends Runnable {
152 void waitUntilStopped();
155 class LockedObjectRunner1
implements LockedObjectRunner {
156 volatile boolean shouldStop;
157 volatile boolean stopped;
158 volatile boolean started;
167 public LockedObjectRunner1(
final String tab,
final String name,
final LockedObject lo,
final Thread[] slaves,
final int loops,
final int mark,
final YieldMode yieldMode) {
171 this.slaves = slaves;
174 this.shouldStop =
false;
175 this.stopped =
false;
176 this.yieldMode = yieldMode;
177 Assert.assertTrue(mark>loops);
178 Assert.assertTrue(loops*loops>mark);
182 public LockedObjectRunner1(
final String tab,
final String name,
final LockedObject lo,
final int loops,
final int mark,
final YieldMode yieldMode) {
189 this.shouldStop =
false;
190 this.stopped =
false;
191 this.yieldMode = yieldMode;
192 Assert.assertTrue(mark>loops);
193 Assert.assertTrue(loops*loops>mark);
196 public final void stop() {
200 public final boolean isStarted() {
203 public final boolean isStopped() {
207 public void waitUntilStopped() {
212 }
catch (
final InterruptedException e) {
223 for(
int i=0; !shouldStop && i<loops; i++) {
225 lo.masterAction(tab, name, slaves, loops, mark, yieldMode);
227 lo.slaveAction(tab, name, loops, mark, yieldMode);
237 final int slaveThreadNum,
final int concurrentThreadNum,
238 final int loops,
final int mark,
final YieldMode yieldMode)
throws InterruptedException {
239 final long t0 = System.currentTimeMillis();
240 final LockedObject lo =
new LockedObject();
241 final LockedObjectRunner[] concurrentRunners =
new LockedObjectRunner[concurrentThreadNum];
242 final LockedObjectRunner[] slaveRunners =
new LockedObjectRunner[slaveThreadNum];
248 for(i=0; i<slaveThreadNum; i++) {
249 slaveRunners[i] =
new LockedObjectRunner1(
" ",
"s"+i, lo, loops, mark, yieldMode);
250 final String name =
"ActionThread-Slaves-"+i+
"_of_"+slaveThreadNum;
253 for(i=0; i<concurrentThreadNum; i++) {
256 concurrentRunners[i] =
new LockedObjectRunner1(
"",
"M0", lo, slaveThreads, loops, mark, yieldMode);
257 name =
"ActionThread-Master-"+i+
"_of_"+concurrentThreadNum;
259 concurrentRunners[i] =
new LockedObjectRunner1(
" ",
"O"+i, lo, noCoOwnerThreads, loops, mark, yieldMode);
260 name =
"ActionThread-Others-"+i+
"_of_"+concurrentThreadNum;
263 concurrentThreads[i].start();
266 while(!concurrentRunners[i].isStarted()) {
272 for( i=0; i<slaveThreadNum; i++ ) {
273 slaveRunners[i].waitUntilStopped();
275 for( i=0; i<concurrentThreadNum; i++ ) {
276 concurrentRunners[i].waitUntilStopped();
278 Assert.assertEquals(0, lo.locker.getHoldCount());
279 Assert.assertEquals(
false, lo.locker.isLocked());
281 final long dt = System.currentTimeMillis()-t0;
283 System.err.println();
284 final String fair_S = fair ?
"fair " :
"unfair" ;
285 System.err.printf(
"---- TestRecursiveLock01.testLockedObjectThreading: i %5s, %s, threads %2d, loops-outter %6d, loops-inner %6d, yield %5s - dt %6d ms",
286 implType, fair_S, concurrentThreadNum, loops, mark, yieldMode, dt);
287 System.err.println();
294 final boolean fair=
true;
295 final int coOwnerThreadNum=2;
296 final int threadNum=5;
305 testLockedObjectImpl(t, fair, coOwnerThreadNum, threadNum, loops, mark, yieldMode);
308 public static void main(
final String args[])
throws IOException, InterruptedException {
310 org.junit.runner.JUnitCore.
main(tstname);
java.lang.Thread specialization implementing InterruptSource to track java.lang.Thread#interrupt() ca...
void testTwoThreadsInGroup()
static void main(final String args[])
long testLockedObjectImpl(final LockFactory.ImplType implType, final boolean fair, final int slaveThreadNum, final int concurrentThreadNum, final int loops, final int mark, final YieldMode yieldMode)
Interface exposing java.lang.Thread#interrupt() source, intended for java.lang.Thread specializations...