33 |
33 |
34 /* |
34 /* |
35 * @test |
35 * @test |
36 * @bug 8022642 8065320 8129861 |
36 * @bug 8022642 8065320 8129861 |
37 * @summary Ensure relative sanity when zero core threads |
37 * @summary Ensure relative sanity when zero core threads |
|
38 * @library /lib/testlibrary/ |
38 */ |
39 */ |
39 |
40 |
40 import static java.util.concurrent.TimeUnit.HOURS; |
41 import static java.util.concurrent.TimeUnit.HOURS; |
|
42 import static java.util.concurrent.TimeUnit.MILLISECONDS; |
41 import static java.util.concurrent.TimeUnit.SECONDS; |
43 import static java.util.concurrent.TimeUnit.SECONDS; |
42 |
44 |
43 import java.lang.reflect.Field; |
45 import java.lang.reflect.Field; |
44 import java.util.concurrent.BlockingQueue; |
46 import java.util.concurrent.BlockingQueue; |
45 import java.util.concurrent.ScheduledThreadPoolExecutor; |
47 import java.util.concurrent.ScheduledThreadPoolExecutor; |
46 import java.util.concurrent.locks.Condition; |
48 import java.util.concurrent.locks.Condition; |
47 import java.util.concurrent.locks.ReentrantLock; |
49 import java.util.concurrent.locks.ReentrantLock; |
|
50 import java.util.function.BooleanSupplier; |
|
51 import jdk.testlibrary.Utils; |
48 |
52 |
49 public class ZeroCoreThreads { |
53 public class ZeroCoreThreads { |
|
54 static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000); |
|
55 |
|
56 static long millisElapsedSince(long startTime) { |
|
57 return (System.nanoTime() - startTime) / (1000L * 1000L); |
|
58 } |
|
59 |
|
60 static void spinWaitUntil(BooleanSupplier predicate, long timeoutMillis) { |
|
61 long startTime = -1L; |
|
62 while (!predicate.getAsBoolean()) { |
|
63 if (startTime == -1L) |
|
64 startTime = System.nanoTime(); |
|
65 else if (millisElapsedSince(startTime) > timeoutMillis) |
|
66 throw new AssertionError( |
|
67 String.format("timed out after %s ms", timeoutMillis)); |
|
68 Thread.yield(); |
|
69 } |
|
70 } |
|
71 |
50 static boolean hasWaiters(ReentrantLock lock, Condition condition) { |
72 static boolean hasWaiters(ReentrantLock lock, Condition condition) { |
51 lock.lock(); |
73 lock.lock(); |
52 try { |
74 try { |
53 return lock.hasWaiters(condition); |
75 return lock.hasWaiters(condition); |
54 } finally { |
76 } finally { |
55 lock.unlock(); |
77 lock.unlock(); |
56 } |
78 } |
|
79 } |
|
80 |
|
81 static void awaitHasWaiters(ReentrantLock lock, Condition condition, |
|
82 long timeoutMillis) { |
|
83 spinWaitUntil(() -> hasWaiters(lock, condition), timeoutMillis); |
57 } |
84 } |
58 |
85 |
59 static <T> T getField(Object x, String fieldName) { |
86 static <T> T getField(Object x, String fieldName) { |
60 try { |
87 try { |
61 Field field = x.getClass().getDeclaredField(fieldName); |
88 Field field = x.getClass().getDeclaredField(fieldName); |
87 equal(0, p.getLargestPoolSize()); |
114 equal(0, p.getLargestPoolSize()); |
88 equal(0L, p.getTaskCount()); |
115 equal(0L, p.getTaskCount()); |
89 equal(0L, p.getCompletedTaskCount()); |
116 equal(0L, p.getCompletedTaskCount()); |
90 p.schedule(dummy, 1L, HOURS); |
117 p.schedule(dummy, 1L, HOURS); |
91 // Ensure one pool thread actually waits in timed queue poll |
118 // Ensure one pool thread actually waits in timed queue poll |
92 long t0 = System.nanoTime(); |
119 awaitHasWaiters(lock, available, LONG_DELAY_MS); |
93 while (!hasWaiters(lock, available)) { |
|
94 if (System.nanoTime() - t0 > SECONDS.toNanos(10L)) |
|
95 throw new AssertionError |
|
96 ("timed out waiting for a waiter to show up"); |
|
97 Thread.yield(); |
|
98 } |
|
99 equal(1, p.getPoolSize()); |
120 equal(1, p.getPoolSize()); |
100 equal(1, p.getLargestPoolSize()); |
121 equal(1, p.getLargestPoolSize()); |
101 equal(1L, p.getTaskCount()); |
122 equal(1L, p.getTaskCount()); |
102 equal(0L, p.getCompletedTaskCount()); |
123 equal(0L, p.getCompletedTaskCount()); |
103 } |
124 } |