11use std:: convert:: TryInto ;
22use std:: time:: { Duration , SystemTime } ;
3+ use std:: ops:: Not ;
34
45use rustc_middle:: ty:: { layout:: TyAndLayout , TyKind , TypeAndMut } ;
56use rustc_target:: abi:: { LayoutOf , Size } ;
@@ -284,15 +285,16 @@ fn reacquire_cond_mutex<'mir, 'tcx: 'mir>(
284285 thread : ThreadId ,
285286 mutex : MutexId ,
286287) -> InterpResult < ' tcx > {
288+ ecx. unblock_thread ( thread) ;
287289 if ecx. mutex_is_locked ( mutex) {
288- ecx. mutex_enqueue ( mutex, thread) ;
290+ ecx. mutex_enqueue_and_block ( mutex, thread) ;
289291 } else {
290292 ecx. mutex_lock ( mutex, thread) ;
291- ecx. unblock_thread ( thread) ?;
292293 }
293294 Ok ( ( ) )
294295}
295296
297+ /// After a thread waiting on a condvar was signalled:
296298/// Reacquire the conditional variable and remove the timeout callback if any
297299/// was registered.
298300fn post_cond_signal < ' mir , ' tcx : ' mir > (
@@ -303,24 +305,25 @@ fn post_cond_signal<'mir, 'tcx: 'mir>(
303305 reacquire_cond_mutex ( ecx, thread, mutex) ?;
304306 // Waiting for the mutex is not included in the waiting time because we need
305307 // to acquire the mutex always even if we get a timeout.
306- ecx. unregister_timeout_callback_if_exists ( thread)
308+ ecx. unregister_timeout_callback_if_exists ( thread) ;
309+ Ok ( ( ) )
307310}
308311
309312/// Release the mutex associated with the condition variable because we are
310313/// entering the waiting state.
311- fn release_cond_mutex < ' mir , ' tcx : ' mir > (
314+ fn release_cond_mutex_and_block < ' mir , ' tcx : ' mir > (
312315 ecx : & mut MiriEvalContext < ' mir , ' tcx > ,
313316 active_thread : ThreadId ,
314317 mutex : MutexId ,
315318) -> InterpResult < ' tcx > {
316- if let Some ( old_locked_count) = ecx. mutex_unlock ( mutex, active_thread) ? {
319+ if let Some ( old_locked_count) = ecx. mutex_unlock ( mutex, active_thread) {
317320 if old_locked_count != 1 {
318321 throw_unsup_format ! ( "awaiting on a lock acquired multiple times is not supported" ) ;
319322 }
320323 } else {
321324 throw_ub_format ! ( "awaiting on unlocked or owned by a different thread mutex" ) ;
322325 }
323- ecx. block_thread ( active_thread) ? ;
326+ ecx. block_thread ( active_thread) ;
324327 Ok ( ( ) )
325328}
326329
@@ -411,14 +414,13 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
411414
412415 let kind = mutex_get_kind ( this, mutex_op) ?. not_undef ( ) ?;
413416 let id = mutex_get_or_create_id ( this, mutex_op) ?;
414- let active_thread = this. get_active_thread ( ) ? ;
417+ let active_thread = this. get_active_thread ( ) ;
415418
416419 if this. mutex_is_locked ( id) {
417420 let owner_thread = this. mutex_get_owner ( id) ;
418421 if owner_thread != active_thread {
419- // Block the active thread.
420- this. block_thread ( active_thread) ?;
421- this. mutex_enqueue ( id, active_thread) ;
422+ // Enqueue the active thread.
423+ this. mutex_enqueue_and_block ( id, active_thread) ;
422424 Ok ( 0 )
423425 } else {
424426 // Trying to acquire the same mutex again.
@@ -449,7 +451,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
449451
450452 let kind = mutex_get_kind ( this, mutex_op) ?. not_undef ( ) ?;
451453 let id = mutex_get_or_create_id ( this, mutex_op) ?;
452- let active_thread = this. get_active_thread ( ) ? ;
454+ let active_thread = this. get_active_thread ( ) ;
453455
454456 if this. mutex_is_locked ( id) {
455457 let owner_thread = this. mutex_get_owner ( id) ;
@@ -482,9 +484,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
482484
483485 let kind = mutex_get_kind ( this, mutex_op) ?. not_undef ( ) ?;
484486 let id = mutex_get_or_create_id ( this, mutex_op) ?;
485- let active_thread = this. get_active_thread ( ) ? ;
487+ let active_thread = this. get_active_thread ( ) ;
486488
487- if let Some ( _old_locked_count) = this. mutex_unlock ( id, active_thread) ? {
489+ if let Some ( _old_locked_count) = this. mutex_unlock ( id, active_thread) {
488490 // The mutex was locked by the current thread.
489491 Ok ( 0 )
490492 } else {
@@ -528,10 +530,10 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
528530 let this = self . eval_context_mut ( ) ;
529531
530532 let id = rwlock_get_or_create_id ( this, rwlock_op) ?;
531- let active_thread = this. get_active_thread ( ) ? ;
533+ let active_thread = this. get_active_thread ( ) ;
532534
533535 if this. rwlock_is_write_locked ( id) {
534- this. rwlock_enqueue_and_block_reader ( id, active_thread) ? ;
536+ this. rwlock_enqueue_and_block_reader ( id, active_thread) ;
535537 Ok ( 0 )
536538 } else {
537539 this. rwlock_reader_lock ( id, active_thread) ;
@@ -543,7 +545,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
543545 let this = self . eval_context_mut ( ) ;
544546
545547 let id = rwlock_get_or_create_id ( this, rwlock_op) ?;
546- let active_thread = this. get_active_thread ( ) ? ;
548+ let active_thread = this. get_active_thread ( ) ;
547549
548550 if this. rwlock_is_write_locked ( id) {
549551 this. eval_libc_i32 ( "EBUSY" )
@@ -557,22 +559,22 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
557559 let this = self . eval_context_mut ( ) ;
558560
559561 let id = rwlock_get_or_create_id ( this, rwlock_op) ?;
560- let active_thread = this. get_active_thread ( ) ? ;
562+ let active_thread = this. get_active_thread ( ) ;
561563
562564 if this. rwlock_is_locked ( id) {
563565 // Note: this will deadlock if the lock is already locked by this
564566 // thread in any way.
565567 //
566568 // Relevant documentation:
567569 // https://pubs.opengroup.org/onlinepubs/9699919799/functions/pthread_rwlock_wrlock.html
568- // An in depth discussion on this topic:
570+ // An in- depth discussion on this topic:
569571 // https://github.com/rust-lang/rust/issues/53127
570572 //
571573 // FIXME: Detect and report the deadlock proactively. (We currently
572574 // report the deadlock only when no thread can continue execution,
573575 // but we could detect that this lock is already locked and report
574576 // an error.)
575- this. rwlock_enqueue_and_block_writer ( id, active_thread) ? ;
577+ this. rwlock_enqueue_and_block_writer ( id, active_thread) ;
576578 } else {
577579 this. rwlock_writer_lock ( id, active_thread) ;
578580 }
@@ -584,7 +586,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
584586 let this = self . eval_context_mut ( ) ;
585587
586588 let id = rwlock_get_or_create_id ( this, rwlock_op) ?;
587- let active_thread = this. get_active_thread ( ) ? ;
589+ let active_thread = this. get_active_thread ( ) ;
588590
589591 if this. rwlock_is_locked ( id) {
590592 this. eval_libc_i32 ( "EBUSY" )
@@ -598,17 +600,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
598600 let this = self . eval_context_mut ( ) ;
599601
600602 let id = rwlock_get_or_create_id ( this, rwlock_op) ?;
601- let active_thread = this. get_active_thread ( ) ? ;
603+ let active_thread = this. get_active_thread ( ) ;
602604
603605 if this. rwlock_reader_unlock ( id, active_thread) {
604606 // The thread was a reader.
605- if this. rwlock_is_locked ( id) {
607+ if this. rwlock_is_locked ( id) . not ( ) {
606608 // No more readers owning the lock. Give it to a writer if there
607609 // is any.
608- if let Some ( writer) = this. rwlock_dequeue_writer ( id) {
609- this. unblock_thread ( writer) ?;
610- this. rwlock_writer_lock ( id, writer) ;
611- }
610+ this. rwlock_dequeue_and_lock_writer ( id) ;
612611 }
613612 Ok ( 0 )
614613 } else if Some ( active_thread) == this. rwlock_writer_unlock ( id) {
@@ -617,15 +616,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
617616 // We are prioritizing writers here against the readers. As a
618617 // result, not only readers can starve writers, but also writers can
619618 // starve readers.
620- if let Some ( writer) = this. rwlock_dequeue_writer ( id) {
621- // Give the lock to another writer.
622- this. unblock_thread ( writer) ?;
623- this. rwlock_writer_lock ( id, writer) ;
619+ if this. rwlock_dequeue_and_lock_writer ( id) {
620+ // Someone got the write lock, nice.
624621 } else {
625622 // Give the lock to all readers.
626- while let Some ( reader) = this. rwlock_dequeue_reader ( id) {
627- this. unblock_thread ( reader) ?;
628- this. rwlock_reader_lock ( id, reader) ;
623+ while this. rwlock_dequeue_and_lock_reader ( id) {
624+ // Rinse and repeat.
629625 }
630626 }
631627 Ok ( 0 )
@@ -753,9 +749,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
753749
754750 let id = cond_get_or_create_id ( this, cond_op) ?;
755751 let mutex_id = mutex_get_or_create_id ( this, mutex_op) ?;
756- let active_thread = this. get_active_thread ( ) ? ;
752+ let active_thread = this. get_active_thread ( ) ;
757753
758- release_cond_mutex ( this, active_thread, mutex_id) ?;
754+ release_cond_mutex_and_block ( this, active_thread, mutex_id) ?;
759755 this. condvar_wait ( id, active_thread, mutex_id) ;
760756
761757 Ok ( 0 )
@@ -774,9 +770,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
774770
775771 let id = cond_get_or_create_id ( this, cond_op) ?;
776772 let mutex_id = mutex_get_or_create_id ( this, mutex_op) ?;
777- let active_thread = this. get_active_thread ( ) ? ;
773+ let active_thread = this. get_active_thread ( ) ;
778774
779- release_cond_mutex ( this, active_thread, mutex_id) ?;
775+ release_cond_mutex_and_block ( this, active_thread, mutex_id) ?;
780776 this. condvar_wait ( id, active_thread, mutex_id) ;
781777
782778 // We return success for now and override it in the timeout callback.
@@ -823,7 +819,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
823819
824820 Ok ( ( ) )
825821 } ) ,
826- ) ? ;
822+ ) ;
827823
828824 Ok ( ( ) )
829825 }
@@ -833,7 +829,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
833829
834830 let id = cond_get_or_create_id ( this, cond_op) ?;
835831 if this. condvar_is_awaited ( id) {
836- throw_ub_format ! ( "destroyed an awaited conditional variable" ) ;
832+ throw_ub_format ! ( "destroying an awaited conditional variable" ) ;
837833 }
838834 cond_set_id ( this, cond_op, ScalarMaybeUninit :: Uninit ) ?;
839835 cond_set_clock_id ( this, cond_op, ScalarMaybeUninit :: Uninit ) ?;
0 commit comments