@@ -7,6 +7,33 @@ use std::time::{Duration, Instant};
77impl < ' mir , ' tcx : ' mir > EvalContextExtPriv < ' mir , ' tcx > for crate :: MiriEvalContext < ' mir , ' tcx > { }
88
99trait EvalContextExtPriv < ' mir , ' tcx : ' mir > : crate :: MiriEvalContextExt < ' mir , ' tcx > {
10+ fn get_or_create_id (
11+ & mut self ,
12+ next_id : Scalar < Tag > ,
13+ value_place : & MPlaceTy < ' tcx , Tag > ,
14+ ) -> InterpResult < ' tcx , Option < u32 > > {
15+ let this = self . eval_context_mut ( ) ;
16+
17+ let ( old, success) = this
18+ . atomic_compare_exchange_scalar (
19+ value_place,
20+ & ImmTy :: from_uint ( 0u32 , this. machine . layouts . u32 ) ,
21+ next_id. into ( ) ,
22+ AtomicRwOp :: Relaxed ,
23+ AtomicReadOp :: Relaxed ,
24+ false ,
25+ ) ?
26+ . to_scalar_pair ( )
27+ . expect ( "compare_exchange returns a scalar pair" ) ;
28+
29+ Ok ( if success. to_bool ( ) . expect ( "compare_exchange's second return value is a bool" ) {
30+ // Caller of the closure needs to allocate next_id
31+ None
32+ } else {
33+ Some ( old. to_u32 ( ) . expect ( "layout is u32" ) )
34+ } )
35+ }
36+
1037 // Locks are pointer-sized pieces of data, initialized to 0.
1138 // We use the first 4 bytes to store the RwLockId.
1239 fn srwlock_get_or_create_id (
@@ -17,24 +44,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
1744 let value_place = this. deref_operand_and_offset ( lock_op, 0 , this. machine . layouts . u32 ) ?;
1845
1946 this. rwlock_get_or_create ( |ecx, next_id| {
20- let ( old, success) = ecx
21- . atomic_compare_exchange_scalar (
22- & value_place,
23- & ImmTy :: from_uint ( 0u32 , ecx. machine . layouts . u32 ) ,
24- next_id. to_u32_scalar ( ) . into ( ) ,
25- AtomicRwOp :: Relaxed ,
26- AtomicReadOp :: Relaxed ,
27- false ,
28- ) ?
29- . to_scalar_pair ( )
30- . expect ( "compare_exchange returns a scalar pair" ) ;
31-
32- Ok ( if success. to_bool ( ) . expect ( "compare_exchange's second return value is a bool" ) {
33- // Caller of the closure needs to allocate next_id
34- None
35- } else {
36- Some ( RwLockId :: from_u32 ( old. to_u32 ( ) . expect ( "layout is u32" ) ) )
37- } )
47+ Ok ( ecx. get_or_create_id ( next_id. to_u32_scalar ( ) , & value_place) ?. map ( RwLockId :: from_u32) )
3848 } )
3949 }
4050
@@ -47,24 +57,9 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
4757 let value_place = this. deref_operand_and_offset ( condvar_op, 0 , this. machine . layouts . u32 ) ?;
4858
4959 this. condvar_get_or_create ( |ecx, next_id| {
50- let ( old, success) = ecx
51- . atomic_compare_exchange_scalar (
52- & value_place,
53- & ImmTy :: from_uint ( 0u32 , ecx. machine . layouts . u32 ) ,
54- next_id. to_u32_scalar ( ) . into ( ) ,
55- AtomicRwOp :: Relaxed ,
56- AtomicReadOp :: Relaxed ,
57- false ,
58- ) ?
59- . to_scalar_pair ( )
60- . expect ( "compare_exchange returns a scalar pair" ) ;
61-
62- Ok ( if success. to_bool ( ) . expect ( "compare_exchange's second return value is a bool" ) {
63- // Caller of the closure needs to allocate next_id
64- None
65- } else {
66- Some ( CondvarId :: from_u32 ( old. to_u32 ( ) . expect ( "layout is u32" ) ) )
67- } )
60+ Ok ( ecx
61+ . get_or_create_id ( next_id. to_u32_scalar ( ) , & value_place) ?
62+ . map ( CondvarId :: from_u32) )
6863 } )
6964 }
7065
0 commit comments