Skip to content

Commit 45e4c2d

Browse files
committed
Fix: Polybench MemoryUsageInstrument should use TruffleInstrument.createSystemThread
1 parent a654722 commit 45e4c2d

File tree

1 file changed

+37
-21
lines changed

1 file changed

+37
-21
lines changed

truffle/src/org.graalvm.polybench.instruments/src/org/graalvm/polybench/instruments/MemoryUsageInstrument.java

Lines changed: 37 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@
3030
import java.util.LongSummaryStatistics;
3131
import java.util.Map;
3232
import java.util.Set;
33-
import java.util.Timer;
34-
import java.util.TimerTask;
3533
import java.util.concurrent.CancellationException;
3634
import java.util.concurrent.ConcurrentHashMap;
3735
import java.util.concurrent.Future;
@@ -46,6 +44,7 @@
4644
import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary;
4745
import com.oracle.truffle.api.Option;
4846
import com.oracle.truffle.api.TruffleContext;
47+
import com.oracle.truffle.api.TruffleSafepoint;
4948
import com.oracle.truffle.api.instrumentation.ContextsListener;
5049
import com.oracle.truffle.api.instrumentation.ThreadsListener;
5150
import com.oracle.truffle.api.instrumentation.TruffleInstrument;
@@ -94,13 +93,6 @@ protected OptionDescriptors getOptionDescriptors() {
9493
return new MemoryUsageInstrumentOptionDescriptors();
9594
}
9695

97-
@TruffleBoundary
98-
public long getContextHeapSize() {
99-
TruffleContext context = currentEnv.getEnteredContext();
100-
AtomicBoolean b = new AtomicBoolean();
101-
return currentEnv.calculateContextHeapSize(context, Long.MAX_VALUE, b);
102-
}
103-
10496
@Override
10597
protected synchronized void onCreate(Env env) {
10698
this.currentEnv = env;
@@ -202,15 +194,19 @@ Object call(Node node) {
202194
}
203195

204196
tracking.previousProperties = null;
205-
tracking.task = new ContextHeapSizeThreadLocalTask(tracking);
197+
tracking.task = new ContextHeapSizeThreadLocalTask(tracking, 1);
206198
// force update on start
207199
tracking.task.computeUpdate(true);
208-
tracking.timer = new Timer();
209-
tracking.timer.schedule(tracking.task, 0L, 1L);
200+
startWorkerThread(tracking);
210201

211202
return NullValue.NULL;
212203
}
213204
}
205+
206+
private void startWorkerThread(MemoryTracking tracking) {
207+
tracking.workerThread = currentEnv.createSystemThread(tracking.task);
208+
tracking.workerThread.start();
209+
}
214210
}
215211

216212
final class StopContextMemoryTrackingFunction extends BaseFunction {
@@ -223,12 +219,11 @@ Object call(Node node) {
223219
if (tracking.previousProperties != null) {
224220
return tracking.previousProperties;
225221
}
226-
if (tracking.timer == null) {
222+
if (tracking.task == null) {
227223
return NullValue.NULL;
228224
}
229-
tracking.task.cancel();
230-
tracking.timer.cancel();
231-
tracking.timer = null;
225+
226+
stopWorkerThread(node, tracking);
232227

233228
Map<String, Object> properties = new HashMap<>();
234229

@@ -243,12 +238,20 @@ Object call(Node node) {
243238

244239
// stop running actions for other threads
245240
tracking.previousProperties = new ReadOnlyProperties(properties);
246-
tracking.task.cancelled.set(true);
247241
tracking.task = null;
248242

249243
}
250244
return tracking.previousProperties;
251245
}
246+
247+
private void stopWorkerThread(Node node, MemoryTracking tracking) {
248+
// Disable the loop condition so the worker will exit.
249+
tracking.task.stop();
250+
// Wake the thread in case it's sleeping.
251+
tracking.workerThread.interrupt();
252+
// Wait until the thread has terminated.
253+
TruffleSafepoint.setBlockedThreadInterruptible(node, Thread::join, tracking.workerThread);
254+
}
252255
}
253256

254257
static class MemoryTracking {
@@ -257,14 +260,14 @@ static class MemoryTracking {
257260

258261
volatile ContextHeapSizeThreadLocalTask task;
259262
ReadOnlyProperties previousProperties;
260-
Timer timer;
263+
Thread workerThread;
261264

262265
MemoryTracking(TruffleContext context) {
263266
this.context = context;
264267
}
265268
}
266269

267-
final class ContextHeapSizeThreadLocalTask extends TimerTask {
270+
final class ContextHeapSizeThreadLocalTask implements Runnable {
268271

269272
final LongSummaryStatistics statistics = new LongSummaryStatistics();
270273
final AtomicBoolean cancelled = new AtomicBoolean();
@@ -276,14 +279,27 @@ final class ContextHeapSizeThreadLocalTask extends TimerTask {
276279

277280
long totalAllocatedMemory;
278281
final MemoryTracking tracking;
282+
final long intervalMillis;
279283

280-
ContextHeapSizeThreadLocalTask(MemoryTracking tracking) {
284+
ContextHeapSizeThreadLocalTask(MemoryTracking tracking, long intervalMillis) {
281285
this.tracking = tracking;
286+
this.intervalMillis = intervalMillis;
282287
}
283288

284289
@Override
285290
public void run() {
286-
computeUpdate(false);
291+
while (!cancelled.get()) {
292+
try {
293+
computeUpdate(false);
294+
Thread.sleep(intervalMillis);
295+
} catch (InterruptedException e) {
296+
break; // exit the loop if interrupted
297+
}
298+
}
299+
}
300+
301+
public void stop() {
302+
cancelled.set(true);
287303
}
288304

289305
void computeUpdate(boolean force) {

0 commit comments

Comments
 (0)