23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 |
25 |
26 package jdk.jfr.event.runtime; |
26 package jdk.jfr.event.runtime; |
27 |
27 |
28 import static jdk.test.lib.Asserts.assertFalse; |
|
29 import static jdk.test.lib.Asserts.assertTrue; |
28 import static jdk.test.lib.Asserts.assertTrue; |
30 |
29 |
|
30 import java.nio.file.Files; |
|
31 import java.nio.file.Paths; |
31 import java.time.Duration; |
32 import java.time.Duration; |
|
33 import java.time.Instant; |
32 import java.util.List; |
34 import java.util.List; |
33 import java.util.concurrent.CountDownLatch; |
35 import java.util.concurrent.CountDownLatch; |
34 import java.util.concurrent.locks.LockSupport; |
36 import java.util.concurrent.locks.LockSupport; |
|
37 import java.util.function.Consumer; |
35 |
38 |
36 import jdk.jfr.Recording; |
39 import jdk.jfr.Recording; |
37 import jdk.jfr.consumer.RecordedEvent; |
40 import jdk.jfr.consumer.RecordedEvent; |
|
41 import jdk.test.lib.Asserts; |
38 import jdk.test.lib.jfr.EventNames; |
42 import jdk.test.lib.jfr.EventNames; |
39 import jdk.test.lib.jfr.Events; |
43 import jdk.test.lib.jfr.Events; |
40 import jdk.test.lib.management.ThreadMXBeanTool; |
44 import jdk.test.lib.management.ThreadMXBeanTool; |
41 import jdk.test.lib.thread.TestThread; |
45 import jdk.test.lib.thread.TestThread; |
42 |
|
43 |
46 |
44 /** |
47 /** |
45 * @test |
48 * @test |
46 * @key jfr |
49 * @key jfr |
47 * @requires vm.hasJFR |
50 * @requires vm.hasJFR |
56 |
59 |
57 static class Blocker { |
60 static class Blocker { |
58 } |
61 } |
59 |
62 |
60 public static void main(String[] args) throws Throwable { |
63 public static void main(String[] args) throws Throwable { |
|
64 testParkNoTimeout(); |
|
65 testParkTimeout(); |
|
66 testParkUntil(); |
|
67 } |
|
68 |
|
69 private static void testParkNoTimeout() throws Exception { |
|
70 RecordedEvent event = testPark(x -> LockSupport.park(x), Thread.State.WAITING); |
|
71 Events.assertMissingValue(event, "timeout"); |
|
72 Events.assertMissingValue(event, "until"); |
|
73 } |
|
74 |
|
75 private static void testParkTimeout() throws Exception { |
|
76 Duration expected = Duration.ofNanos(1_234_567_890_123L); |
|
77 RecordedEvent event = testPark(x -> LockSupport.parkNanos(x, expected.toNanos()), Thread.State.TIMED_WAITING); |
|
78 Events.assertDuration(event, "timeout", expected); |
|
79 Events.assertMissingValue(event, "until"); |
|
80 } |
|
81 |
|
82 private static void testParkUntil() throws Exception { |
|
83 long epochMillis = Instant.now().plusSeconds(1000000).toEpochMilli(); |
|
84 RecordedEvent event = testPark(x -> LockSupport.parkUntil(x, epochMillis), Thread.State.TIMED_WAITING); |
|
85 Events.assertMissingValue(event, "timeout"); |
|
86 Events.assertInstant(event, "until", Instant.ofEpochMilli(epochMillis)); |
|
87 } |
|
88 |
|
89 static RecordedEvent testPark(Consumer<Blocker> parkOperation, Thread.State threadState) throws Exception { |
|
90 |
61 final CountDownLatch stop = new CountDownLatch(1); |
91 final CountDownLatch stop = new CountDownLatch(1); |
62 final Blocker blocker = new Blocker(); |
92 final Blocker blocker = new Blocker(); |
63 TestThread parkThread = new TestThread(new Runnable() { |
93 TestThread parkThread = new TestThread(new Runnable() { |
64 public void run() { |
94 public void run() { |
65 while (stop.getCount() > 0) { |
95 while (stop.getCount() > 0) { |
66 LockSupport.park(blocker); |
96 parkOperation.accept(blocker); |
67 } |
97 } |
68 } |
98 } |
69 }); |
99 }); |
70 |
100 |
71 Recording recording = new Recording(); |
101 Recording recording = new Recording(); |
72 recording.enable(EVENT_NAME).withThreshold(Duration.ofMillis(THRESHOLD_MILLIS)); |
102 recording.enable(EVENT_NAME).withThreshold(Duration.ofMillis(THRESHOLD_MILLIS)); |
73 try { |
103 try { |
74 recording.start(); |
104 recording.start(); |
75 parkThread.start(); |
105 parkThread.start(); |
76 ThreadMXBeanTool.waitUntilBlockingOnObject(parkThread, Thread.State.WAITING, blocker); |
106 ThreadMXBeanTool.waitUntilBlockingOnObject(parkThread, threadState, blocker); |
77 // sleep so we know the event is recorded |
107 // sleep so we know the event is recorded |
78 Thread.sleep(2 * THRESHOLD_MILLIS); |
108 Thread.sleep(2 * THRESHOLD_MILLIS); |
79 } finally { |
109 } finally { |
80 stop.countDown(); |
110 stop.countDown(); |
81 LockSupport.unpark(parkThread); |
111 LockSupport.unpark(parkThread); |
82 parkThread.join(); |
112 parkThread.join(); |
83 recording.stop(); |
113 recording.stop(); |
84 } |
114 } |
85 |
|
86 List<RecordedEvent> events = Events.fromRecording(recording); |
115 List<RecordedEvent> events = Events.fromRecording(recording); |
87 Events.hasEvents(events); |
116 Events.hasEvents(events); |
88 boolean isAnyFound = false; |
117 RecordedEvent foundEvent = null; |
89 for (RecordedEvent event : events) { |
118 for (RecordedEvent event : events) { |
90 System.out.println("Event:" + event); |
119 System.out.println("Event:" + event); |
91 String klassName = Events.assertField(event, "parkedClass.name").notNull().getValue(); |
120 String klassName = Events.assertField(event, "parkedClass.name").notNull().getValue(); |
92 if (klassName.equals(blocker.getClass().getName().replace('.', '/'))) { |
121 if (klassName.equals(blocker.getClass().getName().replace('.', '/'))) { |
93 assertFalse(isAnyFound, "Found more than 1 event"); |
122 Asserts.assertNull(foundEvent , "Found more than 1 event"); |
94 isAnyFound = true; |
|
95 Events.assertField(event, "timeout").equal(0L); |
|
96 Events.assertField(event, "address").notEqual(0L); |
123 Events.assertField(event, "address").notEqual(0L); |
97 Events.assertEventThread(event, parkThread); |
124 Events.assertEventThread(event, parkThread); |
|
125 foundEvent = event; |
98 } |
126 } |
99 } |
127 } |
100 assertTrue(isAnyFound, "Correct event not found"); |
128 Asserts.assertNotNull(foundEvent, "Correct event not found"); |
|
129 return foundEvent; |
101 } |
130 } |
102 |
131 |
103 } |
132 } |