@@ -100,10 +100,11 @@ void Mutex::lock_contended(Thread* self) {
100
100
}
101
101
102
102
void Mutex::lock (Thread* self) {
103
- check_safepoint_state (self);
104
-
105
103
assert (_owner != self, " invariant" );
106
104
105
+ check_safepoint_state (self);
106
+ check_rank (self);
107
+
107
108
if (!_lock.try_lock ()) {
108
109
// The lock is contended, use contended slow-path function to lock
109
110
lock_contended (self);
@@ -124,8 +125,11 @@ void Mutex::lock() {
124
125
// in the wrong way this can lead to a deadlock with the safepoint code.
125
126
126
127
void Mutex::lock_without_safepoint_check (Thread * self) {
127
- check_no_safepoint_state (self);
128
128
assert (_owner != self, " invariant" );
129
+
130
+ check_no_safepoint_state (self);
131
+ check_rank (self);
132
+
129
133
_lock.lock ();
130
134
assert_owner (NULL );
131
135
set_owner (self);
@@ -137,21 +141,39 @@ void Mutex::lock_without_safepoint_check() {
137
141
138
142
139
143
// Returns true if thread succeeds in grabbing the lock, otherwise false.
140
- bool Mutex::try_lock ( ) {
144
+ bool Mutex::try_lock_inner ( bool do_rank_checks ) {
141
145
Thread * const self = Thread::current ();
146
+ // Checking the owner hides the potential difference in recursive locking behaviour
147
+ // on some platforms.
148
+ if (_owner == self) {
149
+ return false ;
150
+ }
151
+
152
+ if (do_rank_checks) {
153
+ check_rank (self);
154
+ }
142
155
// Some safepoint_check_always locks use try_lock, so cannot check
143
156
// safepoint state, but can check blocking state.
144
157
check_block_state (self);
145
- // Checking the owner hides the potential difference in recursive locking behaviour
146
- // on some platforms.
147
- if (_owner != self && _lock.try_lock ()) {
158
+
159
+ if (_lock.try_lock ()) {
148
160
assert_owner (NULL );
149
161
set_owner (self);
150
162
return true ;
151
163
}
152
164
return false ;
153
165
}
154
166
167
+ bool Mutex::try_lock () {
168
+ return try_lock_inner (true /* do_rank_checks */ );
169
+ }
170
+
171
+ bool Mutex::try_lock_without_rank_check () {
172
+ bool res = try_lock_inner (false /* do_rank_checks */ );
173
+ DEBUG_ONLY (if (res) _skip_rank_check = true ;)
174
+ return res;
175
+ }
176
+
155
177
void Mutex::release_for_safepoint () {
156
178
assert_owner (NULL );
157
179
_lock.unlock ();
@@ -173,31 +195,18 @@ void Monitor::notify_all() {
173
195
_lock.notify_all ();
174
196
}
175
197
176
- #ifdef ASSERT
177
- void Monitor::assert_wait_lock_state (Thread* self) {
178
- Mutex* least = get_least_ranked_lock_besides_this (self->owned_locks ());
179
- assert (least != this , " Specification of get_least_... call above" );
180
- if (least != NULL && least->rank () <= special) {
181
- ::tty->print (" Attempting to wait on monitor %s/%d while holding"
182
- " lock %s/%d -- possible deadlock" ,
183
- name (), rank (), least->name (), least->rank ());
184
- assert (false , " Shouldn't block(wait) while holding a lock of rank special" );
185
- }
186
- }
187
- #endif // ASSERT
188
-
189
198
bool Monitor::wait_without_safepoint_check (int64_t timeout) {
190
199
Thread* const self = Thread::current ();
191
200
192
201
// timeout is in milliseconds - with zero meaning never timeout
193
202
assert (timeout >= 0 , " negative timeout" );
194
-
195
203
assert_owner (self);
196
- assert_wait_lock_state (self);
204
+ check_rank (self);
197
205
198
206
// conceptually set the owner to NULL in anticipation of
199
207
// abdicating the lock in wait
200
208
set_owner (NULL );
209
+
201
210
// Check safepoint state after resetting owner and possible NSV.
202
211
check_no_safepoint_state (self);
203
212
@@ -208,23 +217,22 @@ bool Monitor::wait_without_safepoint_check(int64_t timeout) {
208
217
209
218
bool Monitor::wait (int64_t timeout, bool as_suspend_equivalent) {
210
219
JavaThread* const self = JavaThread::current ();
220
+ // Safepoint checking logically implies an active JavaThread.
221
+ assert (self->is_active_Java_thread (), " invariant" );
211
222
212
223
// timeout is in milliseconds - with zero meaning never timeout
213
224
assert (timeout >= 0 , " negative timeout" );
214
-
215
225
assert_owner (self);
226
+ check_rank (self);
216
227
217
- // Safepoint checking logically implies an active JavaThread.
218
- guarantee (self->is_active_Java_thread (), " invariant" );
219
- assert_wait_lock_state (self);
220
-
221
- int wait_status;
222
228
// conceptually set the owner to NULL in anticipation of
223
229
// abdicating the lock in wait
224
230
set_owner (NULL );
231
+
225
232
// Check safepoint state after resetting owner and possible NSV.
226
233
check_safepoint_state (self);
227
234
235
+ int wait_status;
228
236
Mutex* in_flight_mutex = NULL ;
229
237
230
238
{
@@ -285,6 +293,7 @@ Mutex::Mutex(int Rank, const char * name, bool allow_vm_block,
285
293
_allow_vm_block = allow_vm_block;
286
294
_rank = Rank;
287
295
_safepoint_check_required = safepoint_check_required;
296
+ _skip_rank_check = false ;
288
297
289
298
assert (_safepoint_check_required != _safepoint_check_sometimes || is_sometimes_ok (name),
290
299
" Lock has _safepoint_check_sometimes %s" , name);
@@ -330,7 +339,7 @@ void Mutex::print_on(outputStream* st) const {
330
339
st->print (" %s" , print_safepoint_check (_safepoint_check_required));
331
340
st->cr ();
332
341
}
333
- #endif
342
+ #endif // PRODUCT
334
343
335
344
#ifdef ASSERT
336
345
void Mutex::assert_owner (Thread * expected) {
@@ -353,16 +362,6 @@ Mutex* Mutex::get_least_ranked_lock(Mutex* locks) {
353
362
res = tmp;
354
363
}
355
364
}
356
- if (!SafepointSynchronize::is_at_safepoint ()) {
357
- // In this case, we expect the held locks to be
358
- // in increasing rank order (modulo any native ranks)
359
- for (tmp = locks; tmp != NULL ; tmp = tmp->next ()) {
360
- if (tmp->next () != NULL ) {
361
- assert (tmp->rank () == Mutex::native ||
362
- tmp->rank () <= tmp->next ()->rank (), " mutex rank anomaly?" );
363
- }
364
- }
365
- }
366
365
return res;
367
366
}
368
367
@@ -373,17 +372,56 @@ Mutex* Mutex::get_least_ranked_lock_besides_this(Mutex* locks) {
373
372
res = tmp;
374
373
}
375
374
}
375
+ assert (res != this , " invariant" );
376
+ return res;
377
+ }
378
+
379
+ // Tests for rank violations that might indicate exposure to deadlock.
380
+ void Mutex::check_rank (Thread* thread) {
381
+ assert (this ->rank () >= 0 , " bad lock rank" );
382
+ Mutex* locks_owned = thread->owned_locks ();
383
+
376
384
if (!SafepointSynchronize::is_at_safepoint ()) {
377
- // In this case, we expect the held locks to be
378
- // in increasing rank order (modulo any native ranks )
379
- for (tmp = locks ; tmp != NULL ; tmp = tmp->next ()) {
385
+ // We expect the locks already acquired to be in increasing rank order,
386
+ // modulo locks of native rank or acquired in try_lock_without_rank_check( )
387
+ for (Mutex* tmp = locks_owned ; tmp != NULL ; tmp = tmp->next ()) {
380
388
if (tmp->next () != NULL ) {
381
- assert (tmp->rank () == Mutex::native ||
382
- tmp-> rank () <= tmp->next ()-> rank (), " mutex rank anomaly?" );
389
+ assert (tmp->rank () == Mutex::native || tmp-> rank () < tmp-> next ()-> rank ()
390
+ || tmp->skip_rank_check (), " mutex rank anomaly?" );
383
391
}
384
392
}
385
393
}
386
- return res;
394
+
395
+ // Locks with rank native or suspend_resume are an exception and are not
396
+ // subject to the verification rules.
397
+ bool check_can_be_skipped = this ->rank () == Mutex::native || this ->rank () == Mutex::suspend_resume
398
+ || SafepointSynchronize::is_at_safepoint ();
399
+ if (owned_by_self ()) {
400
+ // wait() case
401
+ Mutex* least = get_least_ranked_lock_besides_this (locks_owned);
402
+ // We enforce not holding locks of rank special or lower while waiting.
403
+ // Also "this" should be the monitor with lowest rank owned by this thread.
404
+ if (least != NULL && (least->rank () <= special ||
405
+ (least->rank () <= this ->rank () && !check_can_be_skipped))) {
406
+ assert (false , " Attempting to wait on monitor %s/%d while holding lock %s/%d -- "
407
+ " possible deadlock. %s" , name (), rank (), least->name (), least->rank (),
408
+ least->rank () <= this ->rank () ? " Should wait on the least ranked monitor from "
409
+ " all owned locks." : " Should not block(wait) while holding a lock of rank special." );
410
+ }
411
+ } else if (!check_can_be_skipped) {
412
+ // lock()/lock_without_safepoint_check()/try_lock() case
413
+ Mutex* least = get_least_ranked_lock (locks_owned);
414
+ // Deadlock prevention rules require us to acquire Mutexes only in
415
+ // a global total order. For example, if m1 is the lowest ranked mutex
416
+ // that the thread holds and m2 is the mutex the thread is trying
417
+ // to acquire, then deadlock prevention rules require that the rank
418
+ // of m2 be less than the rank of m1. This prevents circular waits.
419
+ if (least != NULL && least->rank () <= this ->rank ()) {
420
+ thread->print_owned_locks ();
421
+ assert (false , " Attempting to acquire lock %s/%d out of order with lock %s/%d -- "
422
+ " possible deadlock" , this ->name (), this ->rank (), least->name (), least->rank ());
423
+ }
424
+ }
387
425
}
388
426
389
427
bool Mutex::contains (Mutex* locks, Mutex* lock) {
@@ -413,8 +451,7 @@ void Mutex::no_safepoint_verifier(Thread* thread, bool enable) {
413
451
}
414
452
415
453
// Called immediately after lock acquisition or release as a diagnostic
416
- // to track the lock-set of the thread and test for rank violations that
417
- // might indicate exposure to deadlock.
454
+ // to track the lock-set of the thread.
418
455
// Rather like an EventListener for _owner (:>).
419
456
420
457
void Mutex::set_owner_implementation (Thread *new_owner) {
@@ -436,29 +473,6 @@ void Mutex::set_owner_implementation(Thread *new_owner) {
436
473
_owner = new_owner; // set the owner
437
474
438
475
// link "this" into the owned locks list
439
-
440
- Mutex* locks = get_least_ranked_lock (new_owner->owned_locks ());
441
- // Mutex::set_owner_implementation is a friend of Thread
442
-
443
- assert (this ->rank () >= 0 , " bad lock rank" );
444
-
445
- // Deadlock avoidance rules require us to acquire Mutexes only in
446
- // a global total order. For example m1 is the lowest ranked mutex
447
- // that the thread holds and m2 is the mutex the thread is trying
448
- // to acquire, then deadlock avoidance rules require that the rank
449
- // of m2 be less than the rank of m1.
450
- // The rank Mutex::native is an exception in that it is not subject
451
- // to the verification rules.
452
- if (this ->rank () != Mutex::native &&
453
- this ->rank () != Mutex::suspend_resume &&
454
- locks != NULL && locks->rank () <= this ->rank () &&
455
- !SafepointSynchronize::is_at_safepoint ()) {
456
- new_owner->print_owned_locks ();
457
- fatal (" acquiring lock %s/%d out of order with lock %s/%d -- "
458
- " possible deadlock" , this ->name (), this ->rank (),
459
- locks->name (), locks->rank ());
460
- }
461
-
462
476
this ->_next = new_owner->_owned_locks ;
463
477
new_owner->_owned_locks = this ;
464
478
@@ -470,6 +484,7 @@ void Mutex::set_owner_implementation(Thread *new_owner) {
470
484
471
485
Thread* old_owner = _owner;
472
486
_last_owner = old_owner;
487
+ _skip_rank_check = false ;
473
488
474
489
assert (old_owner != NULL , " removing the owner thread of an unowned mutex" );
475
490
assert (old_owner == Thread::current (), " removing the owner thread of an unowned mutex" );
0 commit comments