27 * @summary Basic unit test of ThreadInfo.getLockName() |
27 * @summary Basic unit test of ThreadInfo.getLockName() |
28 * and ThreadInfo.getLockOwnerName() |
28 * and ThreadInfo.getLockOwnerName() |
29 * @author Mandy Chung |
29 * @author Mandy Chung |
30 * @author Jaroslav Bachorik |
30 * @author Jaroslav Bachorik |
31 * |
31 * |
|
32 * @library /lib/testlibrary |
|
33 * @build jdk.testlibrary.* |
32 * @run main/othervm Locks |
34 * @run main/othervm Locks |
33 */ |
35 */ |
34 |
36 |
35 import java.lang.management.*; |
37 import java.lang.management.*; |
36 import java.util.concurrent.Phaser; |
38 import java.util.concurrent.Phaser; |
|
39 import jdk.testlibrary.LockFreeLogManager; |
37 |
40 |
38 public class Locks { |
41 public class Locks { |
39 private static final Object objA = new Object(); |
42 private static final Object objA = new Object(); |
40 private static final Object objB = new Object(); |
43 private static final Object objB = new Object(); |
41 private static final Object objC = new Object(); |
44 private static final Object objC = new Object(); |
42 private static final ThreadMXBean tm = ManagementFactory.getThreadMXBean(); |
45 private static final ThreadMXBean tm = ManagementFactory.getThreadMXBean(); |
|
46 private static final LockFreeLogManager logger = new LockFreeLogManager(); |
43 |
47 |
44 private static boolean testFailed = false; |
48 private static boolean testFailed = false; |
45 |
49 |
46 private static String getLockName(Object lock) { |
50 private static String getLockName(Object lock) { |
47 if (lock == null) return null; |
51 if (lock == null) return null; |
145 super("LockBThread"); |
149 super("LockBThread"); |
146 this.p = p; |
150 this.p = p; |
147 } |
151 } |
148 public void run() { |
152 public void run() { |
149 synchronized(objB) { |
153 synchronized(objB) { |
150 System.out.println("LockBThread about to block on objC"); |
154 log("LockBThread about to block on objC"); |
151 p.arriveAndAwaitAdvance(); // Phase 1 (blocking) |
155 p.arriveAndAwaitAdvance(); // Phase 1 (blocking) |
152 // Signal main thread about to block on objC |
156 // Signal main thread about to block on objC |
153 synchronized(objC) { |
157 synchronized(objC) { |
154 dummyCounter++; |
158 dummyCounter++; |
155 }; |
159 }; |
156 } |
160 } |
157 p.arriveAndAwaitAdvance(); // Phase 2 (blocking) |
161 p.arriveAndAwaitAdvance(); // Phase 2 (blocking) |
158 System.out.println("LockBThread about to exit"); |
162 log("LockBThread about to exit"); |
159 // Make sure the current thread is not holding any lock |
163 // Make sure the current thread is not holding any lock |
160 assertNoLock(this); |
164 assertNoLock(this); |
161 } |
165 } |
162 } |
166 } |
163 |
167 |
164 private static WaitingThread waiter; |
168 private static WaitingThread waiter; |
165 private static Object ready = new Object(); |
169 private static final Object ready = new Object(); |
166 private static CheckerThread checker; |
170 private static CheckerThread checker; |
167 static class WaitingThread extends Thread { |
171 static class WaitingThread extends Thread { |
168 private final Phaser p; |
172 private final Phaser p; |
169 |
173 |
170 volatile boolean waiting = false; |
174 volatile boolean waiting = false; |
171 |
175 |
172 public WaitingThread(Phaser p) { |
176 public WaitingThread(Phaser p) { |
173 super("WaitingThread"); |
177 super("WaitingThread"); |
174 this.p = p; |
178 this.p = p; |
175 } |
179 } |
|
180 @Override |
176 public void run() { |
181 public void run() { |
177 synchronized(objC) { |
182 synchronized(objC) { |
178 System.out.println("WaitingThread about to wait on objC"); |
183 log("WaitingThread about to wait on objC"); |
179 try { |
184 try { |
180 // Signal checker thread, about to wait on objC. |
185 // Signal checker thread, about to wait on objC. |
181 waiting = false; |
186 waiting = false; |
182 p.arriveAndAwaitAdvance(); // Phase 1 (waiting) |
187 p.arriveAndAwaitAdvance(); // Phase 1 (waiting) |
183 waiting = true; |
188 waiting = true; |
319 } |
324 } |
320 |
325 |
321 private static ThreadInfo findOwnerInfo(ThreadInfo[] infos, String lock) |
326 private static ThreadInfo findOwnerInfo(ThreadInfo[] infos, String lock) |
322 throws Exception { |
327 throws Exception { |
323 ThreadInfo ownerInfo = null; |
328 ThreadInfo ownerInfo = null; |
324 for (int i = 0; i < infos.length; i++) { |
329 for (ThreadInfo info : infos) { |
325 String blockedLock = infos[i].getLockName(); |
330 String blockedLock = info.getLockName(); |
326 if (lock.equals(blockedLock)) { |
331 if (lock.equals(blockedLock)) { |
327 long threadId = infos[i].getLockOwnerId(); |
332 long threadId = info.getLockOwnerId(); |
328 if (threadId == -1) { |
333 if (threadId == -1) { |
329 throw new RuntimeException("TEST FAILED: " + |
334 throw new RuntimeException("TEST FAILED: " + |
330 lock + " expected to have owner"); |
335 lock + " expected to have owner"); |
331 } |
336 } |
332 for (int j = 0; j < infos.length; j++) { |
337 for (int j = 0; j < infos.length; j++) { |
353 |
358 |
354 private static void doCheck(ThreadInfo[] infos, String lock, long[] expectedThreads) |
359 private static void doCheck(ThreadInfo[] infos, String lock, long[] expectedThreads) |
355 throws Exception { |
360 throws Exception { |
356 ThreadInfo ownerInfo = null; |
361 ThreadInfo ownerInfo = null; |
357 // Find the thread who is blocking on lock |
362 // Find the thread who is blocking on lock |
358 for (int i = 0; i < infos.length; i++) { |
363 for (ThreadInfo info : infos) { |
359 String blockedLock = infos[i].getLockName(); |
364 String blockedLock = info.getLockName(); |
360 if (lock.equals(blockedLock)) { |
365 if (lock.equals(blockedLock)) { |
361 System.out.print(infos[i].getThreadName() + |
366 log("%s blocked on %s", info.getThreadName(), blockedLock); |
362 " blocked on " + blockedLock); |
367 ownerInfo = info; |
363 ownerInfo = infos[i]; |
368 } |
364 } |
369 } |
|
370 if (ownerInfo == null) { |
|
371 throw new RuntimeException("TEST FAILED: " + |
|
372 "Can't retrieve ThreadInfo for the blocked thread"); |
365 } |
373 } |
366 |
374 |
367 long[] threads = new long[10]; |
375 long[] threads = new long[10]; |
368 int count = 0; |
376 int count = 0; |
369 threads[count++] = ownerInfo.getThreadId(); |
377 threads[count++] = ownerInfo.getThreadId(); |
370 while (ownerInfo != null && ownerInfo.getThreadState() == Thread.State.BLOCKED) { |
378 while (ownerInfo != null && ownerInfo.getThreadState() == Thread.State.BLOCKED) { |
371 ownerInfo = findOwnerInfo(infos, lock); |
379 ownerInfo = findOwnerInfo(infos, lock); |
372 threads[count++] = ownerInfo.getThreadId(); |
380 threads[count++] = ownerInfo.getThreadId(); |
373 System.out.println(" Owner = " + ownerInfo.getThreadName() + |
381 log(" Owner = %s id = %d", |
374 " id = " + ownerInfo.getThreadId()); |
382 ownerInfo.getThreadName(), |
|
383 ownerInfo.getThreadId() |
|
384 ); |
375 lock = ownerInfo.getLockName(); |
385 lock = ownerInfo.getLockName(); |
376 System.out.print(ownerInfo.getThreadName() + " Id = " + |
386 log("%s Id = %d blocked on %s", |
377 ownerInfo.getThreadId() + |
387 ownerInfo.getThreadName(), |
378 " blocked on " + lock); |
388 ownerInfo.getThreadId(), |
379 } |
389 lock |
380 System.out.println(); |
390 ); |
|
391 } |
|
392 log(""); |
381 |
393 |
382 if (count != expectedThreads.length) { |
394 if (count != expectedThreads.length) { |
383 throw new RuntimeException("TEST FAILED: " + |
395 throw new RuntimeException("TEST FAILED: " + |
384 "Expected chain of threads not matched; current count =" + count); |
396 "Expected chain of threads not matched; current count =" + count); |
385 } |
397 } |
386 for (int i = 0; i < count; i++) { |
398 for (int i = 0; i < count; i++) { |
387 if (threads[i] != expectedThreads[i]) { |
399 if (threads[i] != expectedThreads[i]) { |
388 System.out.println("TEST FAILED: " + |
400 log("TEST FAILED: Unexpected thread in the chain %s expected to be %s", |
389 "Unexpected thread in the chain " + threads[i] + |
401 threads[i], |
390 " expected to be " + expectedThreads[i]); |
402 expectedThreads[i] |
391 } |
403 ); |
392 } |
404 } |
|
405 } |
|
406 } |
|
407 |
|
408 private static void log(String format, Object ... args) { |
|
409 logger.log(format + "%n", args); |
393 } |
410 } |
394 } |
411 } |