@@ -229,9 +229,9 @@ fn mutex_kind_from_static_initializer<'tcx>(
229
229
// We store some data directly inside the type, ignoring the platform layout:
230
230
// - init: u32
231
231
232
- #[ derive( Debug , Copy , Clone ) ]
232
+ #[ derive( Debug , Clone ) ]
233
233
struct PthreadRwLock {
234
- id : RwLockId ,
234
+ rwlock_ref : RwLockRef ,
235
235
}
236
236
237
237
fn rwlock_init_offset < ' tcx > ( ecx : & MiriInterpCx < ' tcx > ) -> InterpResult < ' tcx , Size > {
@@ -278,8 +278,8 @@ where
278
278
) ? {
279
279
throw_unsup_format ! ( "unsupported static initializer used for `pthread_rwlock_t`" ) ;
280
280
}
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 } )
283
283
} ,
284
284
)
285
285
}
@@ -504,11 +504,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
504
504
505
505
let mutex = mutex_get_data ( this, mutex_op) ?. clone ( ) ;
506
506
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 ( ) {
509
508
if owner_thread != this. active_thread ( ) {
510
509
this. mutex_enqueue_and_block (
511
- & mutex. mutex_ref ,
510
+ mutex. mutex_ref ,
512
511
Some ( ( Scalar :: from_i32 ( 0 ) , dest. clone ( ) ) ) ,
513
512
) ;
514
513
return interp_ok ( ( ) ) ;
@@ -541,8 +540,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
541
540
542
541
let mutex = mutex_get_data ( this, mutex_op) ?. clone ( ) ;
543
542
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 ( ) {
546
544
if owner_thread != this. active_thread ( ) {
547
545
this. eval_libc_i32 ( "EBUSY" )
548
546
} else {
@@ -596,7 +594,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
596
594
// since we make the field uninit below.
597
595
let mutex = mutex_get_data ( this, mutex_op) ?. clone ( ) ;
598
596
599
- if this . mutex_is_locked ( & mutex. mutex_ref ) {
597
+ if mutex. mutex_ref . owner ( ) . is_some ( ) {
600
598
throw_ub_format ! ( "destroyed a locked mutex" ) ;
601
599
}
602
600
@@ -616,12 +614,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
616
614
) -> InterpResult < ' tcx > {
617
615
let this = self . eval_context_mut ( ) ;
618
616
619
- let id = rwlock_get_data ( this, rwlock_op) ?. id ;
617
+ let rwlock = rwlock_get_data ( this, rwlock_op) ?. clone ( ) ;
620
618
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
+ ) ;
623
625
} else {
624
- this. rwlock_reader_lock ( id ) ;
626
+ this. rwlock_reader_lock ( & rwlock . rwlock_ref ) ;
625
627
this. write_null ( dest) ?;
626
628
}
627
629
@@ -631,12 +633,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
631
633
fn pthread_rwlock_tryrdlock ( & mut self , rwlock_op : & OpTy < ' tcx > ) -> InterpResult < ' tcx , Scalar > {
632
634
let this = self . eval_context_mut ( ) ;
633
635
634
- let id = rwlock_get_data ( this, rwlock_op) ?. id ;
636
+ let rwlock = rwlock_get_data ( this, rwlock_op) ?. clone ( ) ;
635
637
636
- if this . rwlock_is_write_locked ( id ) {
638
+ if rwlock . rwlock_ref . is_write_locked ( ) {
637
639
interp_ok ( Scalar :: from_i32 ( this. eval_libc_i32 ( "EBUSY" ) ) )
638
640
} else {
639
- this. rwlock_reader_lock ( id ) ;
641
+ this. rwlock_reader_lock ( & rwlock . rwlock_ref ) ;
640
642
interp_ok ( Scalar :: from_i32 ( 0 ) )
641
643
}
642
644
}
@@ -648,9 +650,9 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
648
650
) -> InterpResult < ' tcx > {
649
651
let this = self . eval_context_mut ( ) ;
650
652
651
- let id = rwlock_get_data ( this, rwlock_op) ?. id ;
653
+ let rwlock = rwlock_get_data ( this, rwlock_op) ?. clone ( ) ;
652
654
653
- if this . rwlock_is_locked ( id ) {
655
+ if rwlock . rwlock_ref . is_locked ( ) {
654
656
// Note: this will deadlock if the lock is already locked by this
655
657
// thread in any way.
656
658
//
@@ -663,9 +665,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
663
665
// report the deadlock only when no thread can continue execution,
664
666
// but we could detect that this lock is already locked and report
665
667
// 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
+ ) ;
667
673
} else {
668
- this. rwlock_writer_lock ( id ) ;
674
+ this. rwlock_writer_lock ( & rwlock . rwlock_ref ) ;
669
675
this. write_null ( dest) ?;
670
676
}
671
677
@@ -675,22 +681,24 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
675
681
fn pthread_rwlock_trywrlock ( & mut self , rwlock_op : & OpTy < ' tcx > ) -> InterpResult < ' tcx , Scalar > {
676
682
let this = self . eval_context_mut ( ) ;
677
683
678
- let id = rwlock_get_data ( this, rwlock_op) ?. id ;
684
+ let rwlock = rwlock_get_data ( this, rwlock_op) ?. clone ( ) ;
679
685
680
- if this . rwlock_is_locked ( id ) {
686
+ if rwlock . rwlock_ref . is_locked ( ) {
681
687
interp_ok ( Scalar :: from_i32 ( this. eval_libc_i32 ( "EBUSY" ) ) )
682
688
} else {
683
- this. rwlock_writer_lock ( id ) ;
689
+ this. rwlock_writer_lock ( & rwlock . rwlock_ref ) ;
684
690
interp_ok ( Scalar :: from_i32 ( 0 ) )
685
691
}
686
692
}
687
693
688
694
fn pthread_rwlock_unlock ( & mut self , rwlock_op : & OpTy < ' tcx > ) -> InterpResult < ' tcx , ( ) > {
689
695
let this = self . eval_context_mut ( ) ;
690
696
691
- let id = rwlock_get_data ( this, rwlock_op) ?. id ;
697
+ let rwlock = rwlock_get_data ( this, rwlock_op) ?. clone ( ) ;
692
698
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
+ {
694
702
interp_ok ( ( ) )
695
703
} else {
696
704
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> {
702
710
703
711
// Reading the field also has the side-effect that we detect double-`destroy`
704
712
// 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 ( ) ;
706
714
707
- if this . rwlock_is_locked ( id ) {
715
+ if rwlock . rwlock_ref . is_locked ( ) {
708
716
throw_ub_format ! ( "destroyed a locked rwlock" ) ;
709
717
}
710
718
0 commit comments