@@ -284,15 +284,16 @@ fn reacquire_cond_mutex<'mir, 'tcx: 'mir>(
284284 thread : ThreadId ,
285285 mutex : MutexId ,
286286) -> InterpResult < ' tcx > {
287+ ecx. unblock_thread ( thread) ;
287288 if ecx. mutex_is_locked ( mutex) {
288- ecx. mutex_enqueue ( mutex, thread) ;
289+ ecx. mutex_enqueue_and_block ( mutex, thread) ;
289290 } else {
290291 ecx. mutex_lock ( mutex, thread) ;
291- ecx. unblock_thread ( thread) ?;
292292 }
293293 Ok ( ( ) )
294294}
295295
296+ /// After a thread waiting on a condvar was signalled:
296297/// Reacquire the conditional variable and remove the timeout callback if any
297298/// was registered.
298299fn post_cond_signal < ' mir , ' tcx : ' mir > (
@@ -303,12 +304,13 @@ fn post_cond_signal<'mir, 'tcx: 'mir>(
303304 reacquire_cond_mutex ( ecx, thread, mutex) ?;
304305 // Waiting for the mutex is not included in the waiting time because we need
305306 // to acquire the mutex always even if we get a timeout.
306- ecx. unregister_timeout_callback_if_exists ( thread)
307+ ecx. unregister_timeout_callback_if_exists ( thread) ;
308+ Ok ( ( ) )
307309}
308310
309311/// Release the mutex associated with the condition variable because we are
310312/// entering the waiting state.
311- fn release_cond_mutex < ' mir , ' tcx : ' mir > (
313+ fn release_cond_mutex_and_block < ' mir , ' tcx : ' mir > (
312314 ecx : & mut MiriEvalContext < ' mir , ' tcx > ,
313315 active_thread : ThreadId ,
314316 mutex : MutexId ,
@@ -320,7 +322,7 @@ fn release_cond_mutex<'mir, 'tcx: 'mir>(
320322 } else {
321323 throw_ub_format ! ( "awaiting on unlocked or owned by a different thread mutex" ) ;
322324 }
323- ecx. block_thread ( active_thread) ? ;
325+ ecx. block_thread ( active_thread) ;
324326 Ok ( ( ) )
325327}
326328
@@ -411,14 +413,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
411413
412414 let kind = mutex_get_kind ( this, mutex_op) ?. not_undef ( ) ?;
413415 let id = mutex_get_or_create_id ( this, mutex_op) ?;
414- let active_thread = this. get_active_thread ( ) ? ;
416+ let active_thread = this. get_active_thread ( ) ;
415417
416418 if this. mutex_is_locked ( id) {
417419 let owner_thread = this. mutex_get_owner ( id) ;
418420 if owner_thread != active_thread {
419- // Block the active thread.
420- this. block_thread ( active_thread) ?;
421- this. mutex_enqueue ( id, active_thread) ;
421+ // Enqueue the active thread.
422+ this. mutex_enqueue_and_block ( id, active_thread) ;
422423 Ok ( 0 )
423424 } else {
424425 // Trying to acquire the same mutex again.
@@ -449,7 +450,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
449450
450451 let kind = mutex_get_kind ( this, mutex_op) ?. not_undef ( ) ?;
451452 let id = mutex_get_or_create_id ( this, mutex_op) ?;
452- let active_thread = this. get_active_thread ( ) ? ;
453+ let active_thread = this. get_active_thread ( ) ;
453454
454455 if this. mutex_is_locked ( id) {
455456 let owner_thread = this. mutex_get_owner ( id) ;
@@ -482,7 +483,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
482483
483484 let kind = mutex_get_kind ( this, mutex_op) ?. not_undef ( ) ?;
484485 let id = mutex_get_or_create_id ( this, mutex_op) ?;
485- let active_thread = this. get_active_thread ( ) ? ;
486+ let active_thread = this. get_active_thread ( ) ;
486487
487488 if let Some ( _old_locked_count) = this. mutex_unlock ( id, active_thread) ? {
488489 // The mutex was locked by the current thread.
@@ -528,10 +529,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
528529 let this = self . eval_context_mut ( ) ;
529530
530531 let id = rwlock_get_or_create_id ( this, rwlock_op) ?;
531- let active_thread = this. get_active_thread ( ) ? ;
532+ let active_thread = this. get_active_thread ( ) ;
532533
533534 if this. rwlock_is_write_locked ( id) {
534- this. rwlock_enqueue_and_block_reader ( id, active_thread) ? ;
535+ this. rwlock_enqueue_and_block_reader ( id, active_thread) ;
535536 Ok ( 0 )
536537 } else {
537538 this. rwlock_reader_lock ( id, active_thread) ;
@@ -543,7 +544,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
543544 let this = self . eval_context_mut ( ) ;
544545
545546 let id = rwlock_get_or_create_id ( this, rwlock_op) ?;
546- let active_thread = this. get_active_thread ( ) ? ;
547+ let active_thread = this. get_active_thread ( ) ;
547548
548549 if this. rwlock_is_write_locked ( id) {
549550 this. eval_libc_i32 ( "EBUSY" )
@@ -557,22 +558,22 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
557558 let this = self . eval_context_mut ( ) ;
558559
559560 let id = rwlock_get_or_create_id ( this, rwlock_op) ?;
560- let active_thread = this. get_active_thread ( ) ? ;
561+ let active_thread = this. get_active_thread ( ) ;
561562
562563 if this. rwlock_is_locked ( id) {
563564 // Note: this will deadlock if the lock is already locked by this
564565 // thread in any way.
565566 //
566567 // Relevant documentation:
567568 // https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_rwlock_wrlock.html
568- // An in depth discussion on this topic:
569+ // An in- depth discussion on this topic:
569570 // https://github.com/rust-lang/rust/issues/53127
570571 //
571572 // FIXME: Detect and report the deadlock proactively. (We currently
572573 // report the deadlock only when no thread can continue execution,
573574 // but we could detect that this lock is already locked and report
574575 // an error.)
575- this. rwlock_enqueue_and_block_writer ( id, active_thread) ? ;
576+ this. rwlock_enqueue_and_block_writer ( id, active_thread) ;
576577 } else {
577578 this. rwlock_writer_lock ( id, active_thread) ;
578579 }
@@ -584,7 +585,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
584585 let this = self . eval_context_mut ( ) ;
585586
586587 let id = rwlock_get_or_create_id ( this, rwlock_op) ?;
587- let active_thread = this. get_active_thread ( ) ? ;
588+ let active_thread = this. get_active_thread ( ) ;
588589
589590 if this. rwlock_is_locked ( id) {
590591 this. eval_libc_i32 ( "EBUSY" )
@@ -598,15 +599,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
598599 let this = self . eval_context_mut ( ) ;
599600
600601 let id = rwlock_get_or_create_id ( this, rwlock_op) ?;
601- let active_thread = this. get_active_thread ( ) ? ;
602+ let active_thread = this. get_active_thread ( ) ;
602603
603604 if this. rwlock_reader_unlock ( id, active_thread) {
604605 // The thread was a reader.
605606 if this. rwlock_is_locked ( id) {
606607 // No more readers owning the lock. Give it to a writer if there
607608 // is any.
608- if let Some ( writer) = this. rwlock_dequeue_writer ( id) {
609- this. unblock_thread ( writer) ?;
609+ if let Some ( writer) = this. rwlock_dequeue_and_unblock_writer ( id) {
610610 this. rwlock_writer_lock ( id, writer) ;
611611 }
612612 }
@@ -617,14 +617,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
617617 // We are prioritizing writers here against the readers. As a
618618 // result, not only readers can starve writers, but also writers can
619619 // starve readers.
620- if let Some ( writer) = this. rwlock_dequeue_writer ( id) {
620+ if let Some ( writer) = this. rwlock_dequeue_and_unblock_writer ( id) {
621621 // Give the lock to another writer.
622- this. unblock_thread ( writer) ?;
623622 this. rwlock_writer_lock ( id, writer) ;
624623 } else {
625624 // Give the lock to all readers.
626- while let Some ( reader) = this. rwlock_dequeue_reader ( id) {
627- this. unblock_thread ( reader) ?;
625+ while let Some ( reader) = this. rwlock_dequeue_and_unblock_reader ( id) {
628626 this. rwlock_reader_lock ( id, reader) ;
629627 }
630628 }
@@ -753,9 +751,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
753751
754752 let id = cond_get_or_create_id ( this, cond_op) ?;
755753 let mutex_id = mutex_get_or_create_id ( this, mutex_op) ?;
756- let active_thread = this. get_active_thread ( ) ? ;
754+ let active_thread = this. get_active_thread ( ) ;
757755
758- release_cond_mutex ( this, active_thread, mutex_id) ?;
756+ release_cond_mutex_and_block ( this, active_thread, mutex_id) ?;
759757 this. condvar_wait ( id, active_thread, mutex_id) ;
760758
761759 Ok ( 0 )
@@ -774,9 +772,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
774772
775773 let id = cond_get_or_create_id ( this, cond_op) ?;
776774 let mutex_id = mutex_get_or_create_id ( this, mutex_op) ?;
777- let active_thread = this. get_active_thread ( ) ? ;
775+ let active_thread = this. get_active_thread ( ) ;
778776
779- release_cond_mutex ( this, active_thread, mutex_id) ?;
777+ release_cond_mutex_and_block ( this, active_thread, mutex_id) ?;
780778 this. condvar_wait ( id, active_thread, mutex_id) ;
781779
782780 // We return success for now and override it in the timeout callback.
@@ -823,7 +821,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
823821
824822 Ok ( ( ) )
825823 } ) ,
826- ) ? ;
824+ ) ;
827825
828826 Ok ( ( ) )
829827 }
@@ -833,7 +831,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
833831
834832 let id = cond_get_or_create_id ( this, cond_op) ?;
835833 if this. condvar_is_awaited ( id) {
836- throw_ub_format ! ( "destroyed an awaited conditional variable" ) ;
834+ throw_ub_format ! ( "destroying an awaited conditional variable" ) ;
837835 }
838836 cond_set_id ( this, cond_op, ScalarMaybeUninit :: Uninit ) ?;
839837 cond_set_clock_id ( this, cond_op, ScalarMaybeUninit :: Uninit ) ?;
0 commit comments