equal
deleted
inserted
replaced
1 /* |
1 /* |
2 * Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2004, 2019, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
22 */ |
22 */ |
23 |
23 |
24 package nsk.jvmti.scenarios.contention.TC04; |
24 package nsk.jvmti.scenarios.contention.TC04; |
25 |
25 |
26 import java.io.PrintStream; |
26 import java.io.PrintStream; |
|
27 import java.util.concurrent.*; |
27 |
28 |
28 import nsk.share.*; |
29 import nsk.share.*; |
29 import nsk.share.jvmti.*; |
30 import nsk.share.jvmti.*; |
30 |
31 |
31 public class tc04t001 extends DebugeeClass { |
32 public class tc04t001 extends DebugeeClass { |
32 |
33 |
33 final static int THREADS_LIMIT = 2; |
34 final static int THREADS_LIMIT = 2; |
|
35 final static CountDownLatch threadsDoneSignal = new CountDownLatch(THREADS_LIMIT); |
34 |
36 |
35 // run test from command line |
37 // run test from command line |
36 public static void main(String argv[]) { |
38 public static void main(String argv[]) { |
37 argv = nsk.share.jvmti.JVMTITest.commonInit(argv); |
39 argv = nsk.share.jvmti.JVMTITest.commonInit(argv); |
38 |
40 |
66 threads[i] = new tc04t001Thread(i); |
68 threads[i] = new tc04t001Thread(i); |
67 threads[i].start(); |
69 threads[i].start(); |
68 } |
70 } |
69 |
71 |
70 try { |
72 try { |
71 for (int i = 0; i < THREADS_LIMIT; i++) { |
73 if (!threadsDoneSignal.await(timeout, TimeUnit.MILLISECONDS)) { |
72 threads[i].join(timeout/THREADS_LIMIT); |
74 throw new RuntimeException("Threads timeout"); |
73 } |
75 } |
74 } catch (InterruptedException e) { |
76 } catch (InterruptedException e) { |
75 throw new Failure(e); |
77 throw new Failure(e); |
76 } |
78 } |
77 |
79 |
82 THREADS_LIMIT*tc04t001Thread.INCREMENT_LIMIT) { |
84 THREADS_LIMIT*tc04t001Thread.INCREMENT_LIMIT) { |
83 log.complain("Wrong value: " + tc04t001Thread.value + |
85 log.complain("Wrong value: " + tc04t001Thread.value + |
84 ", expected: " + THREADS_LIMIT*tc04t001Thread.INCREMENT_LIMIT); |
86 ", expected: " + THREADS_LIMIT*tc04t001Thread.INCREMENT_LIMIT); |
85 status = Consts.TEST_FAILED; |
87 status = Consts.TEST_FAILED; |
86 } |
88 } |
87 |
|
88 /* DEBUG -- to check if the threads taking turns in right order |
|
89 boolean race = false; |
|
90 for (int i = 1; i < 2*tc04t001Thread.INCREMENT_LIMIT; i++) { |
|
91 if (tc04t001Thread.passOrder[i] == tc04t001Thread.passOrder[i-1]) { |
|
92 race = true; |
|
93 System.out.println("Race condition in the test:"); |
|
94 System.out.println("passOrder[" + (i-1) + "]:" |
|
95 + tc04t001Thread.passOrder[i-1]); |
|
96 System.out.println("passOrder[" + (i) + "]:" |
|
97 + tc04t001Thread.passOrder[i]); |
|
98 } |
|
99 } |
|
100 if (race) |
|
101 System.out.println("There was a race condition in the test."); |
|
102 */ |
|
103 |
|
104 return status; |
89 return status; |
105 } |
90 } |
106 } |
91 } |
107 |
92 |
108 /* =================================================================== */ |
93 /* =================================================================== */ |
113 final static int DELAY = 1000; |
98 final static int DELAY = 1000; |
114 |
99 |
115 static volatile int value = 0; |
100 static volatile int value = 0; |
116 |
101 |
117 static Flicker flicker = new Flicker(); |
102 static Flicker flicker = new Flicker(); |
118 /* DEBUG -- to check if the threads taking turns in right order |
|
119 static volatile int iter = 0; |
|
120 static volatile int passOrder[] = |
|
121 new int[INCREMENT_LIMIT*tc04t001.THREADS_LIMIT]; |
|
122 */ |
|
123 |
103 |
124 private int id; |
104 private int id; |
|
105 private static volatile int lastEnterEventsCount; |
|
106 private static native int enterEventsCount(); |
125 |
107 |
126 public tc04t001Thread(int i) { |
108 public tc04t001Thread(int i) { |
127 super("Debuggee Thread " + i); |
109 super("Debuggee Thread " + i); |
128 id = i; |
110 id = i; |
129 } |
111 } |
134 increment(id); |
116 increment(id); |
135 try { |
117 try { |
136 wait(1); |
118 wait(1); |
137 } catch (InterruptedException e) {} |
119 } catch (InterruptedException e) {} |
138 } |
120 } |
|
121 tc04t001.threadsDoneSignal.countDown(); |
139 } |
122 } |
140 |
123 |
141 static synchronized void increment(int i) { |
124 static synchronized void increment(int i) { |
142 /* DEBUG -- to check if the threads taking turns in right order |
|
143 passOrder[iter++] = i; |
|
144 */ |
|
145 flicker.unlock(i); |
125 flicker.unlock(i); |
146 int temp = value; |
126 int temp = value; |
147 for (int j = 0; j < DELAY; j++) ; |
127 boolean done = false; |
148 try { |
128 |
149 sleep(500); |
129 // Wait in a loop for a MonitorContendedEnter event. |
150 } catch (InterruptedException e) {} |
130 // Timeout is: 20ms * DELAY. |
|
131 for (int j = 0; j < DELAY; j++) { |
|
132 try { |
|
133 sleep(20); |
|
134 } catch (InterruptedException e) {} |
|
135 |
|
136 done = (tc04t001.threadsDoneSignal.getCount() == 1); |
|
137 if (done) { |
|
138 break; // This thread is the only remaining thread, no more contention |
|
139 } |
|
140 if (enterEventsCount() > lastEnterEventsCount) { |
|
141 System.out.println("Thread-" + i + ": increment event: " + enterEventsCount()); |
|
142 break; // Got an expected MonitorContendedEnter event |
|
143 } |
|
144 } |
|
145 |
|
146 if (!done && enterEventsCount() == lastEnterEventsCount) { |
|
147 String msg = "Timeout in waiting for a MonitorContendedEnter event"; |
|
148 throw new RuntimeException(msg); |
|
149 } |
151 value = temp + 1; |
150 value = temp + 1; |
|
151 lastEnterEventsCount = enterEventsCount(); |
152 } |
152 } |
153 } |
153 } |
154 |
154 |
155 class Flicker { |
155 class Flicker { |
156 |
156 |