2525
2626package com .oracle .svm .core .posix .linux ;
2727
28+ import static com .oracle .svm .core .Uninterruptible .CALLED_FROM_UNINTERRUPTIBLE_CODE ;
29+
30+ import org .graalvm .nativeimage .CurrentIsolate ;
2831import org .graalvm .nativeimage .IsolateThread ;
2932import org .graalvm .nativeimage .Platform ;
3033import org .graalvm .nativeimage .Platforms ;
3134import org .graalvm .nativeimage .StackValue ;
3235import org .graalvm .word .WordFactory ;
3336
3437import com .oracle .svm .core .Uninterruptible ;
35- import com .oracle .svm .core .feature .AutomaticallyRegisteredFeature ;
3638import com .oracle .svm .core .graal .stackvalue .UnsafeStackValue ;
37- import com .oracle .svm .core .jfr .JfrThreadLocal ;
3839import com .oracle .svm .core .posix .PosixSubstrateSigprofHandler ;
39- import com .oracle .svm .core .posix .PosixSubstrateSigprofHandlerFeature ;
4040import com .oracle .svm .core .posix .PosixUtils ;
4141import com .oracle .svm .core .posix .headers .Signal ;
4242import com .oracle .svm .core .posix .headers .linux .LinuxTime ;
43- import com .oracle .svm .core .sampler . SubstrateSigprofHandler ;
43+ import com .oracle .svm .core .thread . VMOperation ;
4444import com .oracle .svm .core .thread .VMThreads ;
45+ import com .oracle .svm .core .threadlocal .FastThreadLocalFactory ;
46+ import com .oracle .svm .core .threadlocal .FastThreadLocalWord ;
4547import com .oracle .svm .core .util .TimeUtils ;
4648
47- final class LinuxSubstrateSigprofHandler extends PosixSubstrateSigprofHandler {
49+ public final class LinuxSubstrateSigprofHandler extends PosixSubstrateSigprofHandler {
50+
51+ private static final int INITIAL_SAMPLER_TIMER_ID = -1 ;
52+ private static final FastThreadLocalWord <LinuxTime .timer_t > samplerTimerId = FastThreadLocalFactory .createWord ("LinuxSubstrateSigprofHandler.samplerTimerId" );
4853
4954 @ Platforms (Platform .HOSTED_ONLY .class )
50- LinuxSubstrateSigprofHandler () {
55+ public LinuxSubstrateSigprofHandler () {
56+ }
57+
58+ @ Override
59+ @ Uninterruptible (reason = "Prevent VM operations that modify thread-local execution sampler state." )
60+ public void beforeThreadStart (IsolateThread isolateThread , Thread javaThread ) {
61+ setSamplerTimerId (isolateThread , WordFactory .signed (INITIAL_SAMPLER_TIMER_ID ));
5162 }
5263
5364 @ Override
@@ -60,7 +71,7 @@ protected void updateInterval() {
6071 @ Override
6172 @ Uninterruptible (reason = "Prevent VM operations that modify thread-local execution sampler state." )
6273 protected void install0 (IsolateThread thread ) {
63- assert !JfrThreadLocal . isSamplerTimerSet (thread );
74+ assert !isSamplerTimerSet (thread );
6475
6576 Signal .sigevent sigevent = StackValue .get (Signal .sigevent .class );
6677 sigevent .sigev_notify (Signal .SIGEV_SIGNAL ());
@@ -69,28 +80,23 @@ protected void install0(IsolateThread thread) {
6980
7081 int status = LinuxTime .NoTransitions .timer_create (LinuxTime .CLOCK_MONOTONIC (), sigevent , timerPointer );
7182 PosixUtils .checkStatusIs0 (status , "timer_create(clockid, sevp, timerid): wrong arguments." );
72- JfrThreadLocal . setSamplerTimerId (thread , timerPointer .read ());
83+ setSamplerTimerId (thread , timerPointer .read ());
7384 updateInterval (thread );
7485 }
7586
7687 @ Override
7788 @ Uninterruptible (reason = "Prevent VM operations that modify thread-local execution sampler state." )
7889 protected void uninstall0 (IsolateThread thread ) {
79- assert JfrThreadLocal . isSamplerTimerSet (thread );
90+ assert isSamplerTimerSet (thread );
8091
81- LinuxTime .timer_t samplerTimerId = (LinuxTime .timer_t ) JfrThreadLocal .getSamplerTimerId (thread );
82- int status = LinuxTime .NoTransitions .timer_delete (samplerTimerId );
92+ int status = LinuxTime .NoTransitions .timer_delete (getSamplerTimerId (thread ));
8393 PosixUtils .checkStatusIs0 (status , "timer_delete(clockid): wrong arguments." );
84- JfrThreadLocal .setSamplerTimerId (thread , WordFactory .nullPointer ());
85- }
86-
87- @ Override
88- protected void uninstallSignalHandler () {
94+ setSamplerTimerId (thread , WordFactory .signed (INITIAL_SAMPLER_TIMER_ID ));
8995 }
9096
9197 @ Uninterruptible (reason = "Prevent VM operations that modify thread-local execution sampler state." )
9298 private void updateInterval (IsolateThread thread ) {
93- assert JfrThreadLocal . isSamplerTimerSet (thread );
99+ assert isSamplerTimerSet (thread );
94100
95101 long ns = TimeUtils .millisToNanos (newIntervalMillis );
96102 LinuxTime .itimerspec newTimerSpec = UnsafeStackValue .get (LinuxTime .itimerspec .class );
@@ -99,16 +105,24 @@ private void updateInterval(IsolateThread thread) {
99105 newTimerSpec .it_interval ().set_tv_sec (ns / TimeUtils .nanosPerSecond );
100106 newTimerSpec .it_interval ().set_tv_nsec (ns % TimeUtils .nanosPerSecond );
101107
102- LinuxTime .timer_t samplerTimerId = (LinuxTime .timer_t ) JfrThreadLocal .getSamplerTimerId (thread );
103- int status = LinuxTime .NoTransitions .timer_settime (samplerTimerId , 0 , newTimerSpec , WordFactory .nullPointer ());
108+ int status = LinuxTime .NoTransitions .timer_settime (getSamplerTimerId (thread ), 0 , newTimerSpec , WordFactory .nullPointer ());
104109 PosixUtils .checkStatusIs0 (status , "timer_settime(timerid, flags, newTimerSpec, oldValue): wrong arguments." );
105110 }
106- }
107111
108- @ AutomaticallyRegisteredFeature
109- final class LinuxSubstrateSigprofHandlerFeature extends PosixSubstrateSigprofHandlerFeature {
110- @ Override
111- protected SubstrateSigprofHandler makeNewSigprofHandler () {
112- return new LinuxSubstrateSigprofHandler ();
112+ @ Uninterruptible (reason = CALLED_FROM_UNINTERRUPTIBLE_CODE , mayBeInlined = true )
113+ private static boolean isSamplerTimerSet (IsolateThread thread ) {
114+ return getSamplerTimerId (thread ).notEqual (WordFactory .signed (INITIAL_SAMPLER_TIMER_ID ));
115+ }
116+
117+ @ Uninterruptible (reason = CALLED_FROM_UNINTERRUPTIBLE_CODE , mayBeInlined = true )
118+ private static LinuxTime .timer_t getSamplerTimerId (IsolateThread thread ) {
119+ assert CurrentIsolate .getCurrentThread () == thread || VMOperation .isInProgressAtSafepoint ();
120+ return samplerTimerId .get (thread );
121+ }
122+
123+ @ Uninterruptible (reason = CALLED_FROM_UNINTERRUPTIBLE_CODE , mayBeInlined = true )
124+ private static void setSamplerTimerId (IsolateThread thread , LinuxTime .timer_t timerId ) {
125+ assert CurrentIsolate .getCurrentThread () == thread || VMOperation .isInProgressAtSafepoint ();
126+ samplerTimerId .set (thread , timerId );
113127 }
114128}
0 commit comments