@@ -229,9 +229,9 @@ fn mutex_kind_from_static_initializer<'tcx>(
229229// We store some data directly inside the type, ignoring the platform layout:
230230// - init: u32
231231
232- #[ derive( Debug , Copy , Clone ) ]
232+ #[ derive( Debug , Clone ) ]
233233struct PthreadRwLock {
234- id : RwLockId ,
234+ rwlock_ref : RwLockRef ,
235235}
236236
237237fn rwlock_init_offset < ' tcx > ( ecx : & MiriInterpCx < ' tcx > ) -> InterpResult < ' tcx , Size > {
@@ -278,8 +278,8 @@ where
278278 ) ? {
279279 throw_unsup_format ! ( "unsupported static initializer used for `pthread_rwlock_t`" ) ;
280280 }
281- let id = ecx. machine . sync . rwlock_create ( ) ;
282- interp_ok ( PthreadRwLock { id } )
281+ let rwlock_ref = ecx. machine . sync . rwlock_create ( ) ;
282+ interp_ok ( PthreadRwLock { rwlock_ref } )
283283 } ,
284284 )
285285}
@@ -504,11 +504,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
504504
505505 let mutex = mutex_get_data ( this, mutex_op) ?. clone ( ) ;
506506
507- let ret = if this. mutex_is_locked ( & mutex. mutex_ref ) {
508- let owner_thread = this. mutex_get_owner ( & mutex. mutex_ref ) ;
507+ let ret = if let Some ( owner_thread) = mutex. mutex_ref . owner ( ) {
509508 if owner_thread != this. active_thread ( ) {
510509 this. mutex_enqueue_and_block (
511- & mutex. mutex_ref ,
510+ mutex. mutex_ref ,
512511 Some ( ( Scalar :: from_i32 ( 0 ) , dest. clone ( ) ) ) ,
513512 ) ;
514513 return interp_ok ( ( ) ) ;
@@ -541,8 +540,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
541540
542541 let mutex = mutex_get_data ( this, mutex_op) ?. clone ( ) ;
543542
544- interp_ok ( Scalar :: from_i32 ( if this. mutex_is_locked ( & mutex. mutex_ref ) {
545- let owner_thread = this. mutex_get_owner ( & mutex. mutex_ref ) ;
543+ interp_ok ( Scalar :: from_i32 ( if let Some ( owner_thread) = mutex. mutex_ref . owner ( ) {
546544 if owner_thread != this. active_thread ( ) {
547545 this. eval_libc_i32 ( "EBUSY" )
548546 } else {
@@ -596,7 +594,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
596594 // since we make the field uninit below.
597595 let mutex = mutex_get_data ( this, mutex_op) ?. clone ( ) ;
598596
599- if this . mutex_is_locked ( & mutex. mutex_ref ) {
597+ if mutex. mutex_ref . owner ( ) . is_some ( ) {
600598 throw_ub_format ! ( "destroyed a locked mutex" ) ;
601599 }
602600
@@ -616,12 +614,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
616614 ) -> InterpResult < ' tcx > {
617615 let this = self . eval_context_mut ( ) ;
618616
619- let id = rwlock_get_data ( this, rwlock_op) ?. id ;
617+ let rwlock = rwlock_get_data ( this, rwlock_op) ?. clone ( ) ;
620618
621- if this. rwlock_is_write_locked ( id) {
622- this. rwlock_enqueue_and_block_reader ( id, Scalar :: from_i32 ( 0 ) , dest. clone ( ) ) ;
619+ if rwlock. rwlock_ref . is_write_locked ( ) {
620+ this. rwlock_enqueue_and_block_reader (
621+ rwlock. rwlock_ref ,
622+ Scalar :: from_i32 ( 0 ) ,
623+ dest. clone ( ) ,
624+ ) ;
623625 } else {
624- this. rwlock_reader_lock ( id ) ;
626+ this. rwlock_reader_lock ( & rwlock . rwlock_ref ) ;
625627 this. write_null ( dest) ?;
626628 }
627629
@@ -631,12 +633,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
631633 fn pthread_rwlock_tryrdlock ( & mut self , rwlock_op : & OpTy < ' tcx > ) -> InterpResult < ' tcx , Scalar > {
632634 let this = self . eval_context_mut ( ) ;
633635
634- let id = rwlock_get_data ( this, rwlock_op) ?. id ;
636+ let rwlock = rwlock_get_data ( this, rwlock_op) ?. clone ( ) ;
635637
636- if this . rwlock_is_write_locked ( id ) {
638+ if rwlock . rwlock_ref . is_write_locked ( ) {
637639 interp_ok ( Scalar :: from_i32 ( this. eval_libc_i32 ( "EBUSY" ) ) )
638640 } else {
639- this. rwlock_reader_lock ( id ) ;
641+ this. rwlock_reader_lock ( & rwlock . rwlock_ref ) ;
640642 interp_ok ( Scalar :: from_i32 ( 0 ) )
641643 }
642644 }
@@ -648,9 +650,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
648650 ) -> InterpResult < ' tcx > {
649651 let this = self . eval_context_mut ( ) ;
650652
651- let id = rwlock_get_data ( this, rwlock_op) ?. id ;
653+ let rwlock = rwlock_get_data ( this, rwlock_op) ?. clone ( ) ;
652654
653- if this . rwlock_is_locked ( id ) {
655+ if rwlock . rwlock_ref . is_locked ( ) {
654656 // Note: this will deadlock if the lock is already locked by this
655657 // thread in any way.
656658 //
@@ -663,9 +665,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
663665 // report the deadlock only when no thread can continue execution,
664666 // but we could detect that this lock is already locked and report
665667 // an error.)
666- this. rwlock_enqueue_and_block_writer ( id, Scalar :: from_i32 ( 0 ) , dest. clone ( ) ) ;
668+ this. rwlock_enqueue_and_block_writer (
669+ rwlock. rwlock_ref ,
670+ Scalar :: from_i32 ( 0 ) ,
671+ dest. clone ( ) ,
672+ ) ;
667673 } else {
668- this. rwlock_writer_lock ( id ) ;
674+ this. rwlock_writer_lock ( & rwlock . rwlock_ref ) ;
669675 this. write_null ( dest) ?;
670676 }
671677
@@ -675,22 +681,24 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
675681 fn pthread_rwlock_trywrlock ( & mut self , rwlock_op : & OpTy < ' tcx > ) -> InterpResult < ' tcx , Scalar > {
676682 let this = self . eval_context_mut ( ) ;
677683
678- let id = rwlock_get_data ( this, rwlock_op) ?. id ;
684+ let rwlock = rwlock_get_data ( this, rwlock_op) ?. clone ( ) ;
679685
680- if this . rwlock_is_locked ( id ) {
686+ if rwlock . rwlock_ref . is_locked ( ) {
681687 interp_ok ( Scalar :: from_i32 ( this. eval_libc_i32 ( "EBUSY" ) ) )
682688 } else {
683- this. rwlock_writer_lock ( id ) ;
689+ this. rwlock_writer_lock ( & rwlock . rwlock_ref ) ;
684690 interp_ok ( Scalar :: from_i32 ( 0 ) )
685691 }
686692 }
687693
688694 fn pthread_rwlock_unlock ( & mut self , rwlock_op : & OpTy < ' tcx > ) -> InterpResult < ' tcx , ( ) > {
689695 let this = self . eval_context_mut ( ) ;
690696
691- let id = rwlock_get_data ( this, rwlock_op) ?. id ;
697+ let rwlock = rwlock_get_data ( this, rwlock_op) ?. clone ( ) ;
692698
693- if this. rwlock_reader_unlock ( id) ? || this. rwlock_writer_unlock ( id) ? {
699+ if this. rwlock_reader_unlock ( & rwlock. rwlock_ref ) ?
700+ || this. rwlock_writer_unlock ( & rwlock. rwlock_ref ) ?
701+ {
694702 interp_ok ( ( ) )
695703 } else {
696704 throw_ub_format ! ( "unlocked an rwlock that was not locked by the active thread" ) ;
@@ -702,9 +710,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
702710
703711 // Reading the field also has the side-effect that we detect double-`destroy`
704712 // since we make the field uninit below.
705- let id = rwlock_get_data ( this, rwlock_op) ?. id ;
713+ let rwlock = rwlock_get_data ( this, rwlock_op) ?. clone ( ) ;
706714
707- if this . rwlock_is_locked ( id ) {
715+ if rwlock . rwlock_ref . is_locked ( ) {
708716 throw_ub_format ! ( "destroyed a locked rwlock" ) ;
709717 }
710718
0 commit comments