File tree Expand file tree Collapse file tree 4 files changed +17
-4
lines changed Expand file tree Collapse file tree 4 files changed +17
-4
lines changed Original file line number Diff line number Diff line change @@ -211,7 +211,10 @@ class PlatformParker : public CHeapObj<mtSynchronizer> {
211
211
#define PLATFORM_MONITOR_IMPL_INDIRECT 0
212
212
#endif
213
213
214
- // Platform specific implementations that underpin VM Mutex/Monitor classes
214
+ // Platform specific implementations that underpin VM Mutex/Monitor classes.
215
+ // Note that we use "normal" pthread_mutex_t attributes so that recursive
216
+ // locking is not supported, which matches the expected semantics of the
217
+ // VM Mutex class.
215
218
216
219
class PlatformMutex : public CHeapObj <mtSynchronizer> {
217
220
#if PLATFORM_MONITOR_IMPL_INDIRECT
Original file line number Diff line number Diff line change @@ -187,7 +187,10 @@ class PlatformParker : public CHeapObj<mtSynchronizer> {
187
187
188
188
} ;
189
189
190
- // Platform specific implementations that underpin VM Mutex/Monitor classes
190
+ // Platform specific implementations that underpin VM Mutex/Monitor classes.
191
+ // Note that CRITICAL_SECTION supports recursive locking, while the semantics
192
+ // of the VM Mutex class does not. It is up to the Mutex class to hide this
193
+ // difference in behaviour.
191
194
192
195
class PlatformMutex : public CHeapObj <mtSynchronizer> {
193
196
NONCOPYABLE (PlatformMutex);
Original file line number Diff line number Diff line change @@ -137,13 +137,14 @@ void Mutex::lock_without_safepoint_check() {
137
137
138
138
139
139
// Returns true if thread succeeds in grabbing the lock, otherwise false.
140
-
141
140
bool Mutex::try_lock () {
142
141
Thread * const self = Thread::current ();
143
142
// Some safepoint_check_always locks use try_lock, so cannot check
144
143
// safepoint state, but can check blocking state.
145
144
check_block_state (self);
146
- if (_lock.try_lock ()) {
145
+ // Checking the owner hides the potential difference in recursive locking behaviour
146
+ // on some platforms.
147
+ if (_owner != self && _lock.try_lock ()) {
147
148
assert_owner (NULL );
148
149
set_owner (self);
149
150
return true ;
Original file line number Diff line number Diff line change 32
32
// variable that supports lock ownership tracking, lock ranking for deadlock
33
33
// detection and coordinates with the safepoint protocol.
34
34
35
+ // Locking is non-recursive: if you try to lock a mutex you already own then you
36
+ // will get an assertion failure in a debug build (which should suffice to expose
37
+ // usage bugs). If you call try_lock on a mutex you already own it will return false.
38
+ // The underlying PlatformMutex may support recursive locking but this is not exposed
39
+ // and we account for that possibility in try_lock.
40
+
35
41
// The default length of mutex name was originally chosen to be 64 to avoid
36
42
// false sharing. Now, PaddedMutex and PaddedMonitor are available for this purpose.
37
43
// TODO: Check if _name[MUTEX_NAME_LEN] should better get replaced by const char*.
You can’t perform that action at this time.
0 commit comments