26
26
27
27
import static com .oracle .svm .core .heap .RestrictHeapAccess .Access .NO_ALLOCATION ;
28
28
29
- import com .oracle .svm .core .heap .UnknownPrimitiveField ;
30
29
import org .graalvm .compiler .api .replacements .Fold ;
31
- import org .graalvm .compiler .core .common .NumUtil ;
32
- import org .graalvm .compiler .word .Word ;
33
30
import org .graalvm .nativeimage .ImageSingletons ;
34
31
import org .graalvm .nativeimage .LogHandler ;
35
32
import org .graalvm .nativeimage .Platform ;
36
33
import org .graalvm .nativeimage .Platforms ;
37
- import org .graalvm .nativeimage .c .struct .SizeOf ;
38
- import org .graalvm .word .UnsignedWord ;
39
34
import org .graalvm .word .WordFactory ;
40
35
41
- import com .oracle .svm .core .BuildPhaseProvider .ReadyForCompilation ;
42
36
import com .oracle .svm .core .SubstrateOptions ;
43
37
import com .oracle .svm .core .Uninterruptible ;
44
- import com .oracle .svm .core .config .ConfigurationValues ;
45
- import com .oracle .svm .core .config .ObjectLayout ;
38
+ import com .oracle .svm .core .BuildPhaseProvider .ReadyForCompilation ;
39
+ import com .oracle .svm .core .c .CIsolateData ;
40
+ import com .oracle .svm .core .c .CIsolateDataFactory ;
46
41
import com .oracle .svm .core .feature .AutomaticallyRegisteredFeature ;
47
42
import com .oracle .svm .core .feature .InternalFeature ;
48
43
import com .oracle .svm .core .graal .stackvalue .UnsafeStackValue ;
49
44
import com .oracle .svm .core .heap .RestrictHeapAccess ;
45
+
50
46
import com .oracle .svm .core .heap .UnknownObjectField ;
51
47
import com .oracle .svm .core .jdk .UninterruptibleUtils ;
52
48
import com .oracle .svm .core .locks .ClassInstanceReplacer ;
62
58
import com .oracle .svm .core .stack .StackOverflowCheck ;
63
59
import com .oracle .svm .core .thread .VMThreads .SafepointBehavior ;
64
60
65
- import jdk .vm .ci .meta .JavaKind ;
66
-
67
61
/**
68
62
* Support of {@link VMMutex} and {@link VMCondition} in multi-threaded environments. Locking is
69
63
* implemented via pthreads.
@@ -81,7 +75,7 @@ protected VMMutex createReplacement(VMMutex source) {
81
75
private final ClassInstanceReplacer <VMCondition , VMCondition > conditionReplacer = new ClassInstanceReplacer <>(VMCondition .class ) {
82
76
@ Override
83
77
protected VMCondition createReplacement (VMCondition source ) {
84
- return new PthreadVMCondition ((PthreadVMMutex ) mutexReplacer .apply (source .getMutex ()));
78
+ return new PthreadVMCondition ((PthreadVMMutex ) mutexReplacer .apply (source .getMutex ()), source . getConditionName () );
85
79
}
86
80
};
87
81
@@ -100,67 +94,23 @@ public void duringSetup(DuringSetupAccess access) {
100
94
101
95
@ Override
102
96
public void beforeCompilation (BeforeCompilationAccess access ) {
103
- final int wordSize = ConfigurationValues .getTarget ().wordSize ;
104
-
105
- // `alignment` should actually be: `max(alignof(pthread_mutex_t), alignof(pthread_cond_t))`.
106
- //
107
- // Until `alignof()` can be queried from the C compiler, we hard-code this alignment to:
108
- // - One word on 64-bit architectures.
109
- // - Two words on 32-bit architectures.
110
- //
111
- // This split is arbitrary. Actual alignment requirements depend on the architecture,
112
- // the Pthread library implementation, and the C compiler.
113
- // These hard-coded values will need to be adjusted to higher values if we find out
114
- // that `pthread_mutex_t` or `pthread_cond_t` have higher alignment requirements on some
115
- // particular architecture.
116
- assert wordSize == 8 || wordSize == 4 : "Unsupported architecture bit width" ;
117
- final int alignment = (wordSize == 8 ) ? wordSize : (2 * wordSize );
118
-
119
- ObjectLayout layout = ConfigurationValues .getObjectLayout ();
120
- final int baseOffset = layout .getArrayBaseOffset (JavaKind .Byte );
121
-
122
- // Align the first element to word boundary.
123
- int nextIndex = NumUtil .roundUp (baseOffset , alignment ) - baseOffset ;
124
-
125
97
PthreadVMMutex [] mutexes = mutexReplacer .getReplacements ().toArray (new PthreadVMMutex [0 ]);
126
- int mutexSize = NumUtil .roundUp (SizeOf .get (Pthread .pthread_mutex_t .class ), alignment );
127
- for (PthreadVMMutex mutex : mutexes ) {
128
- long offset = layout .getArrayElementOffset (JavaKind .Byte , nextIndex );
129
- assert offset % alignment == 0 ;
130
- mutex .structOffset = WordFactory .unsigned (offset );
131
- nextIndex += mutexSize ;
132
- }
133
-
134
98
PthreadVMCondition [] conditions = conditionReplacer .getReplacements ().toArray (new PthreadVMCondition [0 ]);
135
- int conditionSize = NumUtil .roundUp (SizeOf .get (Pthread .pthread_cond_t .class ), alignment );
136
- for (PthreadVMCondition condition : conditions ) {
137
- long offset = layout .getArrayElementOffset (JavaKind .Byte , nextIndex );
138
- assert offset % alignment == 0 ;
139
- condition .structOffset = WordFactory .unsigned (offset );
140
- nextIndex += conditionSize ;
141
- }
142
99
143
100
PthreadVMLockSupport lockSupport = PthreadVMLockSupport .singleton ();
144
101
lockSupport .mutexes = mutexes ;
145
102
lockSupport .conditions = conditions ;
146
- lockSupport .pthreadStructs = new byte [nextIndex ];
147
103
}
148
104
}
149
105
150
106
public final class PthreadVMLockSupport extends VMLockSupport {
151
107
/** All mutexes, so that we can initialize them at run time when the VM starts. */
152
- @ UnknownObjectField (availability = ReadyForCompilation .class ) PthreadVMMutex [] mutexes ;
108
+ @ UnknownObjectField (availability = ReadyForCompilation .class ) //
109
+ PthreadVMMutex [] mutexes ;
153
110
154
111
/** All conditions, so that we can initialize them at run time when the VM starts. */
155
- @ UnknownObjectField (availability = ReadyForCompilation .class ) PthreadVMCondition [] conditions ;
156
-
157
- /**
158
- * Raw memory for the pthread lock structures. Since we know that native image objects are never
159
- * moved, we can safely hand out pointers into the middle of this array to C code. The offset
160
- * into this array is stored in {@link PthreadVMMutex#structOffset} and
161
- * {@link PthreadVMCondition#structOffset}.
162
- */
163
- @ UnknownObjectField (availability = ReadyForCompilation .class ) byte [] pthreadStructs ;
112
+ @ UnknownObjectField (availability = ReadyForCompilation .class ) //
113
+ PthreadVMCondition [] conditions ;
164
114
165
115
@ Fold
166
116
public static PthreadVMLockSupport singleton () {
@@ -227,17 +177,17 @@ public VMSemaphore[] getSemaphores() {
227
177
228
178
final class PthreadVMMutex extends VMMutex {
229
179
230
- @ UnknownPrimitiveField (availability = ReadyForCompilation .class )//
231
- UnsignedWord structOffset ;
180
+ private final CIsolateData <Pthread .pthread_mutex_t > structPointer ;
232
181
233
182
@ Platforms (Platform .HOSTED_ONLY .class )
234
183
PthreadVMMutex (String name ) {
235
184
super (name );
185
+ structPointer = CIsolateDataFactory .createStruct ("pthreadMutex_" + name , Pthread .pthread_mutex_t .class );
236
186
}
237
187
238
188
@ Uninterruptible (reason = "Called from uninterruptible code." , mayBeInlined = true )
239
189
Pthread .pthread_mutex_t getStructPointer () {
240
- return ( Pthread . pthread_mutex_t ) Word . objectToUntrackedPointer ( PthreadVMLockSupport . singleton (). pthreadStructs ). add ( structOffset );
190
+ return structPointer . get ( );
241
191
}
242
192
243
193
@ Override
@@ -280,17 +230,16 @@ public void unlockNoTransitionUnspecifiedOwner() {
280
230
281
231
final class PthreadVMCondition extends VMCondition {
282
232
283
- @ UnknownPrimitiveField (availability = ReadyForCompilation .class )//
284
- UnsignedWord structOffset ;
233
+ private final CIsolateData <Pthread .pthread_cond_t > structPointer ;
285
234
286
- @ Platforms ( Platform . HOSTED_ONLY . class )
287
- PthreadVMCondition ( PthreadVMMutex mutex ) {
288
- super ( mutex );
235
+ PthreadVMCondition ( PthreadVMMutex mutex , String name ) {
236
+ super ( mutex , name );
237
+ structPointer = CIsolateDataFactory . createStruct ( "pthreadCondition_" + getName (), Pthread . pthread_cond_t . class );
289
238
}
290
239
291
240
@ Uninterruptible (reason = "Called from uninterruptible code." , mayBeInlined = true )
292
241
Pthread .pthread_cond_t getStructPointer () {
293
- return ( Pthread . pthread_cond_t ) Word . objectToUntrackedPointer ( PthreadVMLockSupport . singleton (). pthreadStructs ). add ( structOffset );
242
+ return structPointer . get ( );
294
243
}
295
244
296
245
@ Override
0 commit comments