Skip to content

Commit f86b96f

Browse files
committed
Disable pinning detection for Virtual Threads on Semeru
It uses JFR and JFR is not available in the versions of Semeru we are testing.
1 parent 74ed609 commit f86b96f

File tree

7 files changed

+266
-165
lines changed

7 files changed

+266
-165
lines changed
Lines changed: 13 additions & 162 deletions
Original file line numberDiff line numberDiff line change
@@ -1,183 +1,34 @@
11
package io.quarkus.test.junit5.virtual.internal;
22

3-
import java.util.ArrayList;
43
import java.util.List;
5-
import java.util.UUID;
6-
import java.util.concurrent.CopyOnWriteArrayList;
7-
import java.util.concurrent.CountDownLatch;
8-
import java.util.concurrent.TimeUnit;
94
import java.util.function.Consumer;
10-
import java.util.function.Function;
11-
import java.util.logging.Level;
12-
import java.util.logging.Logger;
135

14-
import io.smallrye.common.annotation.SuppressForbidden;
156
import jdk.jfr.consumer.RecordedEvent;
16-
import jdk.jfr.consumer.RecordingStream;
177

18-
public class Collector implements Consumer<RecordedEvent> {
19-
public static final String CARRIER_PINNED_EVENT_NAME = "jdk.VirtualThreadPinned";
20-
private static final Logger LOGGER = Logger.getLogger(Collector.class.getName());
8+
public interface Collector extends Consumer<RecordedEvent> {
219

22-
private final List<Function<RecordedEvent, Boolean>> observers = new CopyOnWriteArrayList<>();
10+
String CARRIER_PINNED_EVENT_NAME = "jdk.VirtualThreadPinned";
2311

24-
private final List<RecordedEvent> events = new CopyOnWriteArrayList<>();
25-
26-
private final RecordingStream recordingStream;
27-
28-
volatile State state = State.INIT;
29-
30-
public Collector() {
31-
recordingStream = new RecordingStream();
32-
recordingStream.enable(CARRIER_PINNED_EVENT_NAME).withStackTrace();
33-
recordingStream.enable(InternalEvents.SHUTDOWN_EVENT_NAME).withoutStackTrace();
34-
recordingStream.enable(InternalEvents.CAPTURING_STARTED_EVENT_NAME).withoutStackTrace();
35-
recordingStream.enable(InternalEvents.CAPTURING_STOPPED_EVENT_NAME).withoutStackTrace();
36-
recordingStream.enable(InternalEvents.INITIALIZATION_EVENT_NAME).withoutStackTrace();
37-
recordingStream.setOrdered(true);
38-
recordingStream.setMaxSize(100);
39-
recordingStream.onEvent(this);
40-
}
41-
42-
@SuppressForbidden(reason = "java.util.logging is authorized here")
43-
public void init() {
44-
long begin = System.nanoTime();
45-
CountDownLatch latch = new CountDownLatch(1);
46-
observers.add(re -> {
47-
if (re.getEventType().getName().equals(InternalEvents.INITIALIZATION_EVENT_NAME)) {
48-
latch.countDown();
49-
return true;
50-
}
51-
return false;
52-
});
53-
recordingStream.startAsync();
54-
new InternalEvents.InitializationEvent().commit();
55-
try {
56-
if (latch.await(10, TimeUnit.SECONDS)) {
57-
long end = System.nanoTime();
58-
state = State.STARTED;
59-
LOGGER.log(Level.FINE, "Event collection started in {0}s", (end - begin) / 1000000);
60-
} else {
61-
throw new IllegalStateException(
62-
"Unable to start JFR collection, RecordingStartedEvent event not received after 10s");
63-
}
64-
} catch (InterruptedException e) {
65-
Thread.currentThread().interrupt();
66-
throw new RuntimeException(e);
12+
static Collector create() {
13+
if (Boolean.getBoolean("jfr.unsupported.vm")) {
14+
return new NoJfrCollector();
6715
}
68-
}
69-
70-
@SuppressForbidden(reason = "java.util.logging is authorized here")
71-
public void start() {
72-
CountDownLatch latch = new CountDownLatch(1);
73-
String id = UUID.randomUUID().toString();
74-
long begin = System.nanoTime();
75-
observers.add(re -> {
76-
if (re.getEventType().getName().equals(InternalEvents.CAPTURING_STARTED_EVENT_NAME)) {
77-
if (id.equals(re.getString("id"))) {
78-
events.clear();
79-
state = State.COLLECTING;
80-
latch.countDown();
81-
return true;
82-
}
83-
}
84-
return false;
85-
});
8616

87-
new InternalEvents.CapturingStartedEvent(id).commit();
88-
89-
try {
90-
if (!latch.await(10, TimeUnit.SECONDS)) {
91-
throw new IllegalStateException("Unable to start JFR collection, START_EVENT event not received after 10s");
92-
}
93-
long end = System.nanoTime();
94-
LOGGER.log(Level.FINE, "Event capturing started in {0}s", (end - begin) / 1000000);
95-
} catch (InterruptedException e) {
96-
Thread.currentThread().interrupt();
97-
throw new RuntimeException(e);
98-
}
17+
return new JfrCollector();
9918
}
10019

101-
@SuppressForbidden(reason = "java.util.logging is authorized here")
102-
public List<RecordedEvent> stop() {
103-
CountDownLatch latch = new CountDownLatch(1);
104-
String id = UUID.randomUUID().toString();
105-
var begin = System.nanoTime();
106-
observers.add(re -> {
107-
if (re.getEventType().getName().equals(InternalEvents.CAPTURING_STOPPED_EVENT_NAME)) {
108-
state = State.STARTED;
109-
latch.countDown();
110-
return true;
111-
}
112-
return false;
113-
});
20+
void init();
11421

115-
new InternalEvents.CapturingStoppedEvent(id).commit();
22+
void start();
11623

117-
try {
118-
if (!latch.await(10, TimeUnit.SECONDS)) {
119-
throw new IllegalStateException("Unable to start JFR collection, STOP_EVENT event not received after 10s");
120-
}
121-
var end = System.nanoTime();
122-
LOGGER.log(Level.FINE, "Event collection stopped in {0}s", (end - begin) / 1000000);
123-
return new ArrayList<>(events);
124-
} catch (InterruptedException e) {
125-
Thread.currentThread().interrupt();
126-
throw new RuntimeException(e);
127-
}
128-
}
24+
List<RecordedEvent> stop();
12925

130-
@SuppressForbidden(reason = "java.util.logging is authorized here")
131-
public void shutdown() {
132-
CountDownLatch latch = new CountDownLatch(1);
133-
var begin = System.nanoTime();
134-
observers.add(re -> {
135-
if (re.getEventType().getName().equals(InternalEvents.SHUTDOWN_EVENT_NAME)) {
136-
latch.countDown();
137-
return true;
138-
}
139-
return false;
140-
});
141-
InternalEvents.ShutdownEvent event = new InternalEvents.ShutdownEvent();
142-
event.commit();
143-
try {
144-
if (latch.await(10, TimeUnit.SECONDS)) {
145-
state = State.INIT;
146-
var end = System.nanoTime();
147-
LOGGER.log(Level.FINE, "Event collector shutdown in {0}s", (end - begin) / 1000000);
148-
recordingStream.close();
149-
} else {
150-
throw new IllegalStateException(
151-
"Unable to stop JFR collection, RecordingStoppedEvent event not received at 10s");
152-
}
153-
} catch (InterruptedException e) {
154-
Thread.currentThread().interrupt();
155-
throw new RuntimeException(e);
156-
}
157-
}
26+
void shutdown();
15827

15928
@Override
160-
public void accept(RecordedEvent re) {
161-
if (state == State.COLLECTING) {
162-
events.add(re);
163-
}
164-
List<Function<RecordedEvent, Boolean>> toBeRemoved = new ArrayList<>();
165-
observers.forEach(c -> {
166-
if (c.apply(re)) {
167-
toBeRemoved.add(c);
168-
}
169-
});
170-
observers.removeAll(toBeRemoved);
171-
}
172-
173-
public List<RecordedEvent> getEvents() {
174-
return new ArrayList<>(events);
175-
}
29+
void accept(RecordedEvent re);
17630

177-
enum State {
178-
INIT,
179-
STARTED,
180-
COLLECTING
181-
}
31+
List<RecordedEvent> getEvents();
18232

33+
boolean isRecording();
18334
}
Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
package io.quarkus.test.junit5.virtual.internal;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.UUID;
6+
import java.util.concurrent.CopyOnWriteArrayList;
7+
import java.util.concurrent.CountDownLatch;
8+
import java.util.concurrent.TimeUnit;
9+
import java.util.function.Function;
10+
import java.util.logging.Level;
11+
import java.util.logging.Logger;
12+
13+
import io.smallrye.common.annotation.SuppressForbidden;
14+
import jdk.jfr.consumer.RecordedEvent;
15+
import jdk.jfr.consumer.RecordingStream;
16+
17+
public class JfrCollector implements Collector {
18+
private static final Logger LOGGER = Logger.getLogger(JfrCollector.class.getName());
19+
20+
private final List<Function<RecordedEvent, Boolean>> observers = new CopyOnWriteArrayList<>();
21+
22+
private final List<RecordedEvent> events = new CopyOnWriteArrayList<>();
23+
24+
private final RecordingStream recordingStream;
25+
26+
volatile State state = State.INIT;
27+
28+
public JfrCollector() {
29+
recordingStream = new RecordingStream();
30+
recordingStream.enable(CARRIER_PINNED_EVENT_NAME).withStackTrace();
31+
recordingStream.enable(InternalEvents.SHUTDOWN_EVENT_NAME).withoutStackTrace();
32+
recordingStream.enable(InternalEvents.CAPTURING_STARTED_EVENT_NAME).withoutStackTrace();
33+
recordingStream.enable(InternalEvents.CAPTURING_STOPPED_EVENT_NAME).withoutStackTrace();
34+
recordingStream.enable(InternalEvents.INITIALIZATION_EVENT_NAME).withoutStackTrace();
35+
recordingStream.setOrdered(true);
36+
recordingStream.setMaxSize(100);
37+
recordingStream.onEvent(this);
38+
}
39+
40+
@Override
41+
public boolean isRecording() {
42+
return true;
43+
}
44+
45+
@SuppressForbidden(reason = "java.util.logging is authorized here")
46+
@Override
47+
public void init() {
48+
long begin = System.nanoTime();
49+
CountDownLatch latch = new CountDownLatch(1);
50+
observers.add(re -> {
51+
if (re.getEventType().getName().equals(InternalEvents.INITIALIZATION_EVENT_NAME)) {
52+
latch.countDown();
53+
return true;
54+
}
55+
return false;
56+
});
57+
recordingStream.startAsync();
58+
new InternalEvents.InitializationEvent().commit();
59+
try {
60+
if (latch.await(10, TimeUnit.SECONDS)) {
61+
long end = System.nanoTime();
62+
state = State.STARTED;
63+
LOGGER.log(Level.FINE, "Event collection started in {0}s", (end - begin) / 1000000);
64+
} else {
65+
throw new IllegalStateException(
66+
"Unable to start JFR collection, RecordingStartedEvent event not received after 10s");
67+
}
68+
} catch (InterruptedException e) {
69+
Thread.currentThread().interrupt();
70+
throw new RuntimeException(e);
71+
}
72+
}
73+
74+
@SuppressForbidden(reason = "java.util.logging is authorized here")
75+
@Override
76+
public void start() {
77+
CountDownLatch latch = new CountDownLatch(1);
78+
String id = UUID.randomUUID().toString();
79+
long begin = System.nanoTime();
80+
observers.add(re -> {
81+
if (re.getEventType().getName().equals(InternalEvents.CAPTURING_STARTED_EVENT_NAME)) {
82+
if (id.equals(re.getString("id"))) {
83+
events.clear();
84+
state = State.COLLECTING;
85+
latch.countDown();
86+
return true;
87+
}
88+
}
89+
return false;
90+
});
91+
92+
new InternalEvents.CapturingStartedEvent(id).commit();
93+
94+
try {
95+
if (!latch.await(10, TimeUnit.SECONDS)) {
96+
throw new IllegalStateException("Unable to start JFR collection, START_EVENT event not received after 10s");
97+
}
98+
long end = System.nanoTime();
99+
LOGGER.log(Level.FINE, "Event capturing started in {0}s", (end - begin) / 1000000);
100+
} catch (InterruptedException e) {
101+
Thread.currentThread().interrupt();
102+
throw new RuntimeException(e);
103+
}
104+
}
105+
106+
@SuppressForbidden(reason = "java.util.logging is authorized here")
107+
@Override
108+
public List<RecordedEvent> stop() {
109+
CountDownLatch latch = new CountDownLatch(1);
110+
String id = UUID.randomUUID().toString();
111+
var begin = System.nanoTime();
112+
observers.add(re -> {
113+
if (re.getEventType().getName().equals(InternalEvents.CAPTURING_STOPPED_EVENT_NAME)) {
114+
state = State.STARTED;
115+
latch.countDown();
116+
return true;
117+
}
118+
return false;
119+
});
120+
121+
new InternalEvents.CapturingStoppedEvent(id).commit();
122+
123+
try {
124+
if (!latch.await(10, TimeUnit.SECONDS)) {
125+
throw new IllegalStateException("Unable to start JFR collection, STOP_EVENT event not received after 10s");
126+
}
127+
var end = System.nanoTime();
128+
LOGGER.log(Level.FINE, "Event collection stopped in {0}s", (end - begin) / 1000000);
129+
return new ArrayList<>(events);
130+
} catch (InterruptedException e) {
131+
Thread.currentThread().interrupt();
132+
throw new RuntimeException(e);
133+
}
134+
}
135+
136+
@SuppressForbidden(reason = "java.util.logging is authorized here")
137+
@Override
138+
public void shutdown() {
139+
CountDownLatch latch = new CountDownLatch(1);
140+
var begin = System.nanoTime();
141+
observers.add(re -> {
142+
if (re.getEventType().getName().equals(InternalEvents.SHUTDOWN_EVENT_NAME)) {
143+
latch.countDown();
144+
return true;
145+
}
146+
return false;
147+
});
148+
InternalEvents.ShutdownEvent event = new InternalEvents.ShutdownEvent();
149+
event.commit();
150+
try {
151+
if (latch.await(10, TimeUnit.SECONDS)) {
152+
state = State.INIT;
153+
var end = System.nanoTime();
154+
LOGGER.log(Level.FINE, "Event collector shutdown in {0}s", (end - begin) / 1000000);
155+
recordingStream.close();
156+
} else {
157+
throw new IllegalStateException(
158+
"Unable to stop JFR collection, RecordingStoppedEvent event not received at 10s");
159+
}
160+
} catch (InterruptedException e) {
161+
Thread.currentThread().interrupt();
162+
throw new RuntimeException(e);
163+
}
164+
}
165+
166+
@Override
167+
public void accept(RecordedEvent re) {
168+
if (state == State.COLLECTING) {
169+
events.add(re);
170+
}
171+
List<Function<RecordedEvent, Boolean>> toBeRemoved = new ArrayList<>();
172+
observers.forEach(c -> {
173+
if (c.apply(re)) {
174+
toBeRemoved.add(c);
175+
}
176+
});
177+
observers.removeAll(toBeRemoved);
178+
}
179+
180+
@Override
181+
public List<RecordedEvent> getEvents() {
182+
return new ArrayList<>(events);
183+
}
184+
185+
enum State {
186+
INIT,
187+
STARTED,
188+
COLLECTING
189+
}
190+
}

0 commit comments

Comments
 (0)