@@ -7,6 +7,33 @@ use std::time::{Duration, Instant};
7
7
impl < ' mir , ' tcx : ' mir > EvalContextExtPriv < ' mir , ' tcx > for crate :: MiriEvalContext < ' mir , ' tcx > { }
8
8
9
9
trait 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
+
10
37
// Locks are pointer-sized pieces of data, initialized to 0.
11
38
// We use the first 4 bytes to store the RwLockId.
12
39
fn srwlock_get_or_create_id (
@@ -17,24 +44,7 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
17
44
let value_place = this. deref_operand_and_offset ( lock_op, 0 , this. machine . layouts . u32 ) ?;
18
45
19
46
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) )
38
48
} )
39
49
}
40
50
@@ -47,24 +57,9 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
47
57
let value_place = this. deref_operand_and_offset ( condvar_op, 0 , this. machine . layouts . u32 ) ?;
48
58
49
59
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) )
68
63
} )
69
64
}
70
65
0 commit comments