@@ -91,54 +91,43 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
91
91
// FIXME(genmc): improve error handling.
92
92
throw_ub_format ! ( "{}" , error. to_string_lossy( ) ) ;
93
93
}
94
- debug ! (
95
- "GenMC: Mutex::lock(): is_reset: {}, is_lock_acquired: {}" ,
96
- result. is_reset, result. is_lock_acquired
97
- ) ;
98
- if result. is_lock_acquired {
99
- // NOTE: We don't write anything back to Miri's memory, the Mutex state is handled only by GenMC.
100
- return interp_ok ( ( ) ) ;
101
- }
102
- // We either did not acquire the mutex, or GenMC informed us to reset and try the lock again later, so we block the current thread.
103
- if !result. is_reset {
104
- // GenMC expects us to block the thread if we did get a `reset`.
105
- genmc_ctx. handle_assume_block ( & this. machine , AssumeType :: Spinloop ) ?;
106
- }
107
- // Block the thread on the Miri side.
108
- this. block_thread (
94
+ if result. is_reset {
95
+ debug ! ( "GenMC: Mutex::lock: Reset" ) ;
96
+ // GenMC informed us to reset and try the lock again later.
97
+ // We block the current thread until GenMC schedules it again.
98
+ this. block_thread (
109
99
crate :: BlockReason :: Genmc ,
110
100
None ,
111
101
crate :: callback!(
112
102
@capture<' tcx> {
113
103
mutex: MPlaceTy <' tcx>,
114
104
}
115
105
|this, unblock: crate :: UnblockKind | {
116
- debug!( "GenMC: handling Mutex::lock: unblocking callback called." ) ;
106
+ debug!( "GenMC: Mutex::lock: unblocking callback called, attempting to lock the Mutex again ." ) ;
117
107
assert_eq!( unblock, crate :: UnblockKind :: Ready ) ;
118
- let genmc_ctx = this. machine. data_race. as_genmc_ref( ) . unwrap( ) ;
119
- let result = genmc_ctx. handle
120
- . borrow_mut( )
121
- . pin_mut( )
122
- . handle_mutex_lock(
123
- genmc_ctx. active_thread_genmc_tid( & this. machine) ,
124
- mutex. ptr( ) . addr( ) . bytes( ) ,
125
- mutex. layout. size. bytes( ) ,
126
- ) ;
127
- if let Some ( error) = result. error. as_ref( ) {
128
- // FIXME(genmc): improve error handling.
129
- throw_ub_format!( "{}" , error. to_string_lossy( ) ) ;
130
- }
131
- assert!( !result. is_reset, "We should not get a reset on the second lock attempt." ) ;
132
- // If we did not acquire the mutex and GenMC did not tell us to reset and try again, we block this thread for the remainder of the current execution.
133
- if !result. is_lock_acquired {
134
- debug!( "GenMC: Mutex::lock failed to acquire the Mutex twice, permanently blocking thread." ) ;
135
- // This is equivalent to a user inserted `assume(false)`.
136
- this. handle_user_assume_block( ) ?;
137
- }
108
+ this. intercept_mutex_lock( mutex) ?;
138
109
interp_ok( ( ) )
139
110
}
140
111
) ,
141
112
) ;
113
+ } else if result. is_lock_acquired {
114
+ debug ! ( "GenMC: Mutex::lock successfully acquired the Mutex." ) ;
115
+ } else {
116
+ debug ! ( "GenMC: Mutex::lock failed to acquire the Mutex, permanently blocking thread." ) ;
117
+ // NOTE: `handle_mutex_lock` already blocked the current thread on the GenMC side.
118
+ this. block_thread (
119
+ crate :: BlockReason :: Genmc ,
120
+ None ,
121
+ crate :: callback!(
122
+ @capture<' tcx> {
123
+ mutex: MPlaceTy <' tcx>,
124
+ }
125
+ |this, _unblock: crate :: UnblockKind | {
126
+ unreachable!( "A thread blocked on `Mutex::lock` should not be unblocked again." ) ;
127
+ }
128
+ ) ,
129
+ ) ;
130
+ }
142
131
// NOTE: We don't write anything back to Miri's memory where the Mutex is located, that state is handled only by GenMC.
143
132
interp_ok ( ( ) )
144
133
}
0 commit comments