Skip to content

Commit a31f1a6

Browse files
[GR-33985] Make the safepoint thread more patient.
PullRequest: graal/10020
2 parents 5476f19 + e0c9201 commit a31f1a6

File tree

10 files changed

+152
-115
lines changed

10 files changed

+152
-115
lines changed

substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/headers/Sched.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,4 +37,9 @@ public class Sched {
3737

3838
@CFunction
3939
public static native int sched_yield();
40+
41+
public static class NoTransitions {
42+
@CFunction(transition = CFunction.Transition.NO_TRANSITION)
43+
public static native int sched_yield();
44+
}
4045
}

substratevm/src/com.oracle.svm.core.posix/src/com/oracle/svm/core/posix/thread/PosixVMThreads.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
*/
2525
package com.oracle.svm.core.posix.thread;
2626

27+
import com.oracle.svm.core.posix.headers.Sched;
2728
import org.graalvm.nativeimage.ImageSingletons;
2829
import org.graalvm.nativeimage.StackValue;
2930
import org.graalvm.nativeimage.c.function.CFunction;
@@ -76,6 +77,17 @@ public void nativeSleep(int milliseconds) {
7677
Time.NoTransitions.nanosleep(ts, WordFactory.nullPointer());
7778
}
7879

80+
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
81+
@Override
82+
public void yield() {
83+
Sched.NoTransitions.sched_yield();
84+
}
85+
86+
@Override
87+
public boolean supportsPatientSafepoints() {
88+
return true;
89+
}
90+
7991
@Uninterruptible(reason = "Thread state not set up.")
8092
@Override
8193
protected boolean initializeOnce() {

substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsProcessPropertiesSupport.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public void exec(Path executable, String[] args) {
8585

8686
@Override
8787
public long getProcessID() {
88-
return Process.GetCurrentProcessId();
88+
return Process.NoTransitions.GetCurrentProcessId();
8989
}
9090

9191
@Override
@@ -135,11 +135,11 @@ public boolean destroy(long processID) {
135135

136136
@Override
137137
public boolean destroyForcibly(long processID) {
138-
HANDLE handle = Process.OpenProcess(Process.PROCESS_TERMINATE(), 0, (int) processID);
138+
HANDLE handle = Process.NoTransitions.OpenProcess(Process.PROCESS_TERMINATE(), 0, (int) processID);
139139
if (handle.isNull()) {
140140
return false;
141141
}
142-
boolean result = Process.TerminateProcess(handle, 1) != 0;
142+
boolean result = Process.NoTransitions.TerminateProcess(handle, 1) != 0;
143143
WinBase.CloseHandle(handle);
144144
return result;
145145
}

substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsSystemPropertiesSupport.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ protected String userNameValue() {
9292
@Override
9393
protected String userHomeValue() {
9494
WinBase.LPHANDLE tokenHandle = StackValue.get(WinBase.LPHANDLE.class);
95-
if (Process.OpenProcessToken(Process.GetCurrentProcess(), Process.TOKEN_QUERY(), tokenHandle) == 0) {
95+
if (Process.NoTransitions.OpenProcessToken(Process.NoTransitions.GetCurrentProcess(), Process.TOKEN_QUERY(), tokenHandle) == 0) {
9696
return "C:\\"; // matches openjdk
9797
}
9898

substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsUtils.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ private static final class Target_java_lang_ProcessImpl {
6161

6262
public static int getpid(java.lang.Process process) {
6363
Target_java_lang_ProcessImpl processImpl = SubstrateUtil.cast(process, Target_java_lang_ProcessImpl.class);
64-
return com.oracle.svm.core.windows.headers.Process.GetProcessId(WordFactory.pointer(processImpl.handle));
64+
return com.oracle.svm.core.windows.headers.Process.NoTransitions.GetProcessId(WordFactory.pointer(processImpl.handle));
6565
}
6666

6767
@TargetClass(java.io.FileDescriptor.class)

substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsVMLockSupport.java

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -147,10 +147,10 @@ public static void initialize() {
147147
WindowsVMLockSupport support = WindowsVMLockSupport.singleton();
148148
for (WindowsVMMutex mutex : support.mutexes) {
149149
// critical sections on windows always support recursive locking
150-
Process.InitializeCriticalSection(mutex.getStructPointer());
150+
Process.NoTransitions.InitializeCriticalSection(mutex.getStructPointer());
151151
}
152152
for (WindowsVMCondition condition : support.conditions) {
153-
Process.InitializeConditionVariable(condition.getStructPointer());
153+
Process.NoTransitions.InitializeConditionVariable(condition.getStructPointer());
154154
}
155155
}
156156

@@ -205,35 +205,35 @@ public VMMutex lock() {
205205
@Uninterruptible(reason = "Called from uninterruptible code.", callerMustBe = true)
206206
public void lockNoTransition() {
207207
assertNotOwner("Recursive locking is not supported");
208-
Process.EnterCriticalSectionNoTrans(getStructPointer());
208+
Process.NoTransitions.EnterCriticalSection(getStructPointer());
209209
setOwnerToCurrentThread();
210210
}
211211

212212
@Override
213213
@Uninterruptible(reason = "Called from uninterruptible code.", callerMustBe = true)
214214
public void lockNoTransitionUnspecifiedOwner() {
215-
Process.EnterCriticalSectionNoTrans(getStructPointer());
215+
Process.NoTransitions.EnterCriticalSection(getStructPointer());
216216
setOwnerToUnspecified();
217217
}
218218

219219
@Override
220220
@Uninterruptible(reason = "Called from uninterruptible code.")
221221
public void unlock() {
222222
clearCurrentThreadOwner();
223-
Process.LeaveCriticalSection(getStructPointer());
223+
Process.NoTransitions.LeaveCriticalSection(getStructPointer());
224224
}
225225

226226
@Override
227227
@Uninterruptible(reason = "Called from uninterruptible code.")
228228
public void unlockNoTransitionUnspecifiedOwner() {
229229
clearUnspecifiedOwner();
230-
Process.LeaveCriticalSection(getStructPointer());
230+
Process.NoTransitions.LeaveCriticalSection(getStructPointer());
231231
}
232232

233233
@Override
234234
public void unlockWithoutChecks() {
235235
clearCurrentThreadOwner();
236-
Process.LeaveCriticalSectionNoTrans(getStructPointer());
236+
Process.NoTransitions.LeaveCriticalSection(getStructPointer());
237237
}
238238
}
239239

@@ -262,7 +262,7 @@ public void block() {
262262
@Uninterruptible(reason = "Called from uninterruptible code.", callerMustBe = true)
263263
public void blockNoTransition() {
264264
mutex.clearCurrentThreadOwner();
265-
WindowsVMLockSupport.checkResult(Process.SleepConditionVariableCSNoTrans(getStructPointer(), ((WindowsVMMutex) getMutex()).getStructPointer(), SynchAPI.INFINITE()),
265+
WindowsVMLockSupport.checkResult(Process.NoTransitions.SleepConditionVariableCS(getStructPointer(), ((WindowsVMMutex) getMutex()).getStructPointer(), SynchAPI.INFINITE()),
266266
"SleepConditionVariableCS");
267267
mutex.setOwnerToCurrentThread();
268268
}
@@ -271,7 +271,7 @@ public void blockNoTransition() {
271271
@Uninterruptible(reason = "Called from uninterruptible code.", callerMustBe = true)
272272
public void blockNoTransitionUnspecifiedOwner() {
273273
mutex.clearUnspecifiedOwner();
274-
WindowsVMLockSupport.checkResult(Process.SleepConditionVariableCSNoTrans(getStructPointer(), ((WindowsVMMutex) getMutex()).getStructPointer(), SynchAPI.INFINITE()),
274+
WindowsVMLockSupport.checkResult(Process.NoTransitions.SleepConditionVariableCS(getStructPointer(), ((WindowsVMMutex) getMutex()).getStructPointer(), SynchAPI.INFINITE()),
275275
"SleepConditionVariableCS");
276276
mutex.setOwnerToUnspecified();
277277
}
@@ -308,7 +308,7 @@ public long blockNoTransition(long waitNanos) {
308308
int dwMilliseconds = (int) (waitNanos / WindowsUtils.NANOSECS_PER_MILLISEC);
309309

310310
mutex.clearCurrentThreadOwner();
311-
final int timedwaitResult = Process.SleepConditionVariableCSNoTrans(getStructPointer(), ((WindowsVMMutex) getMutex()).getStructPointer(), dwMilliseconds);
311+
final int timedwaitResult = Process.NoTransitions.SleepConditionVariableCS(getStructPointer(), ((WindowsVMMutex) getMutex()).getStructPointer(), dwMilliseconds);
312312
mutex.setOwnerToCurrentThread();
313313

314314
/* If the timed wait timed out, then I am done blocking. */
@@ -325,12 +325,12 @@ public long blockNoTransition(long waitNanos) {
325325

326326
@Override
327327
public void signal() {
328-
Process.WakeConditionVariable(getStructPointer());
328+
Process.NoTransitions.WakeConditionVariable(getStructPointer());
329329
}
330330

331331
@Override
332332
@Uninterruptible(reason = "Called from uninterruptible code.")
333333
public void broadcast() {
334-
Process.WakeAllConditionVariable(getStructPointer());
334+
Process.NoTransitions.WakeAllConditionVariable(getStructPointer());
335335
}
336336
}

substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/WindowsVMThreads.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,8 @@ public final class WindowsVMThreads extends VMThreads {
4646
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
4747
@Override
4848
public OSThreadHandle getCurrentOSThreadHandle() {
49-
WinBase.HANDLE pseudoThreadHandle = Process.GetCurrentThread();
50-
WinBase.HANDLE pseudoProcessHandle = Process.GetCurrentProcess();
49+
WinBase.HANDLE pseudoThreadHandle = Process.NoTransitions.GetCurrentThread();
50+
WinBase.HANDLE pseudoProcessHandle = Process.NoTransitions.GetCurrentProcess();
5151

5252
// convert the thread pseudo handle to a real handle using DuplicateHandle
5353
WinBase.LPHANDLE pointerToResult = StackValue.get(WinBase.LPHANDLE.class);
@@ -61,7 +61,7 @@ public OSThreadHandle getCurrentOSThreadHandle() {
6161
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
6262
@Override
6363
protected OSThreadId getCurrentOSThreadId() {
64-
return WordFactory.unsigned(Process.GetCurrentThreadId());
64+
return WordFactory.unsigned(Process.NoTransitions.GetCurrentThreadId());
6565
}
6666

6767
@Uninterruptible(reason = "Called from uninterruptible code.")
@@ -80,6 +80,17 @@ public void nativeSleep(int milliseconds) {
8080
SynchAPI.NoTransitions.Sleep(milliseconds);
8181
}
8282

83+
@Uninterruptible(reason = "Called from uninterruptible code.", mayBeInlined = true)
84+
@Override
85+
public void yield() {
86+
Process.NoTransitions.SwitchToThread();
87+
}
88+
89+
@Override
90+
public boolean supportsPatientSafepoints() {
91+
return true;
92+
}
93+
8394
/**
8495
* Make sure the runtime is initialized for threading.
8596
*/

substratevm/src/com.oracle.svm.core.windows/src/com/oracle/svm/core/windows/headers/Process.java

Lines changed: 51 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -44,27 +44,9 @@
4444
@CContext(WindowsDirectives.class)
4545
public class Process {
4646

47-
@CFunction(transition = Transition.NO_TRANSITION)
48-
public static native HANDLE GetCurrentProcess();
49-
50-
@CFunction(transition = Transition.NO_TRANSITION)
51-
public static native HANDLE OpenProcess(int dwDesiredAccess, int bInheritHandle, int dwProcessId);
52-
5347
@CConstant
5448
public static native int PROCESS_TERMINATE();
5549

56-
@CFunction(transition = Transition.NO_TRANSITION)
57-
public static native int TerminateProcess(HANDLE hProcess, int uExitCode);
58-
59-
@CFunction(transition = Transition.NO_TRANSITION)
60-
public static native int GetCurrentProcessId();
61-
62-
@CFunction(transition = Transition.NO_TRANSITION)
63-
public static native int GetProcessId(HANDLE hProcess);
64-
65-
@CFunction(transition = Transition.NO_TRANSITION)
66-
public static native int OpenProcessToken(HANDLE processHandle, int desiredAccess, LPHANDLE tokenHandle);
67-
6850
@CConstant
6951
public static native int TOKEN_QUERY();
7052

@@ -81,18 +63,9 @@ public static native HANDLE _beginthreadex(PointerBase security, int stacksize,
8163
@CFunction
8264
public static native int ResumeThread(HANDLE hThread);
8365

84-
@CFunction(transition = Transition.NO_TRANSITION)
85-
public static native int GetExitCodeThread(HANDLE hThread, CIntPointer lpExitCode);
86-
8766
@CFunction
8867
public static native int SwitchToThread();
8968

90-
@CFunction(transition = Transition.NO_TRANSITION)
91-
public static native int GetCurrentThreadId();
92-
93-
@CFunction(transition = Transition.NO_TRANSITION)
94-
public static native HANDLE GetCurrentThread();
95-
9669
@CConstant
9770
public static native int SYNCHRONIZE();
9871

@@ -104,21 +77,9 @@ public interface PCRITICAL_SECTION extends PointerBase {
10477
public interface CRITICAL_SECTION extends PointerBase {
10578
}
10679

107-
@CFunction(transition = Transition.NO_TRANSITION)
108-
public static native void InitializeCriticalSection(PCRITICAL_SECTION mutex);
109-
110-
@CFunction(transition = Transition.TO_NATIVE)
80+
@CFunction
11181
public static native void EnterCriticalSection(PCRITICAL_SECTION mutex);
11282

113-
@CFunction(value = "EnterCriticalSection", transition = Transition.NO_TRANSITION)
114-
public static native void EnterCriticalSectionNoTrans(PCRITICAL_SECTION mutex);
115-
116-
@CFunction(transition = Transition.NO_TRANSITION)
117-
public static native void LeaveCriticalSection(PCRITICAL_SECTION mutex);
118-
119-
@CFunction(value = "LeaveCriticalSection", transition = Transition.NO_TRANSITION)
120-
public static native void LeaveCriticalSectionNoTrans(PCRITICAL_SECTION mutex);
121-
12283
@CStruct
12384
public interface PCONDITION_VARIABLE extends PointerBase {
12485
}
@@ -127,18 +88,59 @@ public interface PCONDITION_VARIABLE extends PointerBase {
12788
public interface CONDITION_VARIABLE extends PointerBase {
12889
}
12990

130-
@CFunction(transition = Transition.NO_TRANSITION)
131-
public static native void InitializeConditionVariable(PCONDITION_VARIABLE cond);
132-
13391
@CFunction
13492
public static native int SleepConditionVariableCS(PCONDITION_VARIABLE cond, PCRITICAL_SECTION mutex, int dwMilliseconds);
13593

136-
@CFunction(value = "SleepConditionVariableCS", transition = Transition.NO_TRANSITION)
137-
public static native int SleepConditionVariableCSNoTrans(PCONDITION_VARIABLE cond, PCRITICAL_SECTION mutex, int dwMilliseconds);
94+
public static class NoTransitions {
95+
@CFunction(transition = Transition.NO_TRANSITION)
96+
public static native HANDLE GetCurrentProcess();
13897

139-
@CFunction(transition = Transition.NO_TRANSITION)
140-
public static native void WakeConditionVariable(PCONDITION_VARIABLE cond);
98+
@CFunction(transition = Transition.NO_TRANSITION)
99+
public static native HANDLE OpenProcess(int dwDesiredAccess, int bInheritHandle, int dwProcessId);
141100

142-
@CFunction(transition = Transition.NO_TRANSITION)
143-
public static native void WakeAllConditionVariable(PCONDITION_VARIABLE cond);
101+
@CFunction(transition = Transition.NO_TRANSITION)
102+
public static native int TerminateProcess(HANDLE hProcess, int uExitCode);
103+
104+
@CFunction(transition = Transition.NO_TRANSITION)
105+
public static native int GetCurrentProcessId();
106+
107+
@CFunction(transition = Transition.NO_TRANSITION)
108+
public static native int GetProcessId(HANDLE hProcess);
109+
110+
@CFunction(transition = Transition.NO_TRANSITION)
111+
public static native int OpenProcessToken(HANDLE processHandle, int desiredAccess, LPHANDLE tokenHandle);
112+
113+
@CFunction(transition = Transition.NO_TRANSITION)
114+
public static native int GetExitCodeThread(HANDLE hThread, CIntPointer lpExitCode);
115+
116+
@CFunction(transition = Transition.NO_TRANSITION)
117+
public static native int SwitchToThread();
118+
119+
@CFunction(transition = Transition.NO_TRANSITION)
120+
public static native int GetCurrentThreadId();
121+
122+
@CFunction(transition = Transition.NO_TRANSITION)
123+
public static native HANDLE GetCurrentThread();
124+
125+
@CFunction(transition = Transition.NO_TRANSITION)
126+
public static native void InitializeCriticalSection(PCRITICAL_SECTION mutex);
127+
128+
@CFunction(transition = Transition.NO_TRANSITION)
129+
public static native void EnterCriticalSection(PCRITICAL_SECTION mutex);
130+
131+
@CFunction(transition = Transition.NO_TRANSITION)
132+
public static native void LeaveCriticalSection(PCRITICAL_SECTION mutex);
133+
134+
@CFunction(transition = Transition.NO_TRANSITION)
135+
public static native void InitializeConditionVariable(PCONDITION_VARIABLE cond);
136+
137+
@CFunction(transition = Transition.NO_TRANSITION)
138+
public static native int SleepConditionVariableCS(PCONDITION_VARIABLE cond, PCRITICAL_SECTION mutex, int dwMilliseconds);
139+
140+
@CFunction(transition = Transition.NO_TRANSITION)
141+
public static native void WakeConditionVariable(PCONDITION_VARIABLE cond);
142+
143+
@CFunction(transition = Transition.NO_TRANSITION)
144+
public static native void WakeAllConditionVariable(PCONDITION_VARIABLE cond);
145+
}
144146
}

0 commit comments

Comments
 (0)