@@ -3,7 +3,7 @@ use std::sync::Arc;
3
3
4
4
use genmc_sys:: {
5
5
ActionKind , GENMC_GLOBAL_ADDRESSES_MASK , GenmcScalar , GenmcThreadId , MemOrdering ,
6
- MiriGenMCShim , RMWBinOp , StoreEventType , UniquePtr , createGenmcHandle,
6
+ MiriGenMCShim , StoreEventType , UniquePtr , createGenmcHandle,
7
7
} ;
8
8
use rustc_abi:: { Align , Size } ;
9
9
use rustc_const_eval:: interpret:: { AllocId , InterpCx , InterpResult , interp_ok} ;
@@ -12,10 +12,9 @@ use tracing::info;
12
12
13
13
use self :: global_allocations:: { EvalContextExtPriv as _, GlobalAllocationHandler } ;
14
14
use self :: helper:: {
15
- genmc_scalar_to_scalar, option_scalar_to_genmc_scalar, rhs_scalar_to_genmc_scalar ,
15
+ genmc_scalar_to_scalar, option_scalar_to_genmc_scalar,
16
16
scalar_to_genmc_scalar,
17
17
} ;
18
- use self :: mapping:: { min_max_to_genmc_rmw_op, to_genmc_rmw_op} ;
19
18
use self :: thread_info_manager:: ThreadInfoManager ;
20
19
use crate :: concurrency:: genmc:: helper:: split_access;
21
20
use crate :: {
@@ -205,101 +204,51 @@ impl GenmcCtx {
205
204
/// Returns `(old_val, Option<new_val>)`. `new_val` might not be the latest write in coherence order, which is indicated by `None`.
206
205
pub ( crate ) fn atomic_rmw_op < ' tcx > (
207
206
& self ,
208
- ecx : & InterpCx < ' tcx , MiriMachine < ' tcx > > ,
209
- address : Size ,
210
- size : Size ,
211
- ordering : AtomicRwOrd ,
212
- ( rmw_op , not ) : ( mir:: BinOp , bool ) ,
213
- rhs_scalar : Scalar ,
207
+ _ecx : & InterpCx < ' tcx , MiriMachine < ' tcx > > ,
208
+ _address : Size ,
209
+ _size : Size ,
210
+ _ordering : AtomicRwOrd ,
211
+ ( _rmw_op , _not ) : ( mir:: BinOp , bool ) ,
212
+ _rhs_scalar : Scalar ,
214
213
// The value that we would get, if we were to do a non-atomic load here.
215
- old_value : Scalar ,
214
+ _old_value : Scalar ,
216
215
) -> InterpResult < ' tcx , ( Scalar , Option < Scalar > ) > {
217
- assert ! ( !self . allow_data_races. get( ) ) ; // TODO GENMC: handle this properly
218
- let ( load_ordering, store_ordering) = ordering. to_genmc_memory_orderings ( ) ;
219
- let genmc_rmw_op = to_genmc_rmw_op ( rmw_op, not) ;
220
- tracing:: info!(
221
- "GenMC: atomic_rmw_op (op: {rmw_op:?}, not: {not}, genmc_rmw_op: {genmc_rmw_op:?}): rhs value: {rhs_scalar:?}, orderings ({load_ordering:?}, {store_ordering:?})"
222
- ) ;
223
- let genmc_rhs_scalar = rhs_scalar_to_genmc_scalar ( ecx, rhs_scalar) ?;
224
- let genmc_old_value = scalar_to_genmc_scalar ( ecx, old_value) ?;
225
- self . atomic_rmw_op_impl (
226
- ecx,
227
- address,
228
- size,
229
- load_ordering,
230
- store_ordering,
231
- genmc_rmw_op,
232
- genmc_rhs_scalar,
233
- genmc_old_value,
234
- )
216
+ assert ! ( !self . allow_data_races. get( ) ) ;
217
+ throw_unsup_format ! ( "FIXME(genmc): Add support for atomic min/max." )
235
218
}
236
219
237
220
/// Inform GenMC about an atomic `min` or `max` operation.
238
221
///
239
222
/// Returns `(old_val, Option<new_val>)`. `new_val` might not be the latest write in coherence order, which is indicated by `None`.
240
223
pub ( crate ) fn atomic_min_max_op < ' tcx > (
241
224
& self ,
242
- ecx : & InterpCx < ' tcx , MiriMachine < ' tcx > > ,
243
- address : Size ,
244
- size : Size ,
245
- ordering : AtomicRwOrd ,
246
- min : bool ,
247
- is_signed : bool ,
248
- rhs_scalar : Scalar ,
225
+ _ecx : & InterpCx < ' tcx , MiriMachine < ' tcx > > ,
226
+ _address : Size ,
227
+ _size : Size ,
228
+ _ordering : AtomicRwOrd ,
229
+ _min : bool ,
230
+ _is_signed : bool ,
231
+ _rhs_scalar : Scalar ,
249
232
// The value that we would get, if we were to do a non-atomic load here.
250
- old_value : Scalar ,
233
+ _old_value : Scalar ,
251
234
) -> InterpResult < ' tcx , ( Scalar , Option < Scalar > ) > {
252
- assert ! ( !self . allow_data_races. get( ) ) ; // TODO GENMC: handle this properly
253
- let ( load_ordering, store_ordering) = ordering. to_genmc_memory_orderings ( ) ;
254
- let genmc_rmw_op = min_max_to_genmc_rmw_op ( min, is_signed) ;
255
- tracing:: info!(
256
- "GenMC: atomic_min_max_op (min: {min}, signed: {is_signed}, genmc_rmw_op: {genmc_rmw_op:?}): rhs value: {rhs_scalar:?}, orderings ({load_ordering:?}, {store_ordering:?})"
257
- ) ;
258
- let genmc_rhs_scalar = rhs_scalar_to_genmc_scalar ( ecx, rhs_scalar) ?;
259
- let genmc_old_value = scalar_to_genmc_scalar ( ecx, old_value) ?;
260
- self . atomic_rmw_op_impl (
261
- ecx,
262
- address,
263
- size,
264
- load_ordering,
265
- store_ordering,
266
- genmc_rmw_op,
267
- genmc_rhs_scalar,
268
- genmc_old_value,
269
- )
235
+ assert ! ( !self . allow_data_races. get( ) ) ;
236
+ throw_unsup_format ! ( "FIXME(genmc): Add support for atomic min/max." )
270
237
}
271
238
272
239
/// Returns `(old_val, Option<new_val>)`. `new_val` might not be the latest write in coherence order, which is indicated by `None`.
273
240
pub ( crate ) fn atomic_exchange < ' tcx > (
274
241
& self ,
275
- ecx : & InterpCx < ' tcx , MiriMachine < ' tcx > > ,
276
- address : Size ,
277
- size : Size ,
278
- rhs_scalar : Scalar ,
279
- ordering : AtomicRwOrd ,
242
+ _ecx : & InterpCx < ' tcx , MiriMachine < ' tcx > > ,
243
+ _address : Size ,
244
+ _size : Size ,
245
+ _rhs_scalar : Scalar ,
246
+ _ordering : AtomicRwOrd ,
280
247
// The value that we would get, if we were to do a non-atomic load here.
281
- old_value : Scalar ,
248
+ _old_value : Scalar ,
282
249
) -> InterpResult < ' tcx , ( Scalar , Option < Scalar > ) > {
283
- assert ! ( !self . allow_data_races. get( ) ) ; // TODO GENMC: handle this properly
284
- // TODO GENMC: could maybe merge this with atomic_rmw?
285
-
286
- let ( load_ordering, store_ordering) = ordering. to_genmc_memory_orderings ( ) ;
287
- let genmc_rmw_op = RMWBinOp :: Xchg ;
288
- tracing:: info!(
289
- "GenMC: atomic_exchange (op: {genmc_rmw_op:?}): new value: {rhs_scalar:?}, orderings ({load_ordering:?}, {store_ordering:?})"
290
- ) ;
291
- let genmc_rhs_scalar = scalar_to_genmc_scalar ( ecx, rhs_scalar) ?;
292
- let genmc_old_value = scalar_to_genmc_scalar ( ecx, old_value) ?;
293
- self . atomic_rmw_op_impl (
294
- ecx,
295
- address,
296
- size,
297
- load_ordering,
298
- store_ordering,
299
- genmc_rmw_op,
300
- genmc_rhs_scalar,
301
- genmc_old_value,
302
- )
250
+ assert ! ( !self . allow_data_races. get( ) ) ;
251
+ throw_unsup_format ! ( "FIXME(genmc): Add support for atomic swap." )
303
252
}
304
253
305
254
pub ( crate ) fn atomic_compare_exchange < ' tcx > (
@@ -734,64 +683,6 @@ impl GenmcCtx {
734
683
interp_ok ( store_result. isCoMaxWrite )
735
684
}
736
685
737
- fn atomic_rmw_op_impl < ' tcx > (
738
- & self ,
739
- ecx : & InterpCx < ' tcx , MiriMachine < ' tcx > > ,
740
- address : Size ,
741
- size : Size ,
742
- load_ordering : MemOrdering ,
743
- store_ordering : MemOrdering ,
744
- genmc_rmw_op : RMWBinOp ,
745
- genmc_rhs_scalar : GenmcScalar ,
746
- genmc_old_value : GenmcScalar ,
747
- ) -> InterpResult < ' tcx , ( Scalar , Option < Scalar > ) > {
748
- assert ! (
749
- size. bytes( ) <= 8 ,
750
- "TODO GENMC: no support for accesses larger than 8 bytes (got {} bytes)" ,
751
- size. bytes( )
752
- ) ;
753
- let machine = & ecx. machine ;
754
- assert_ne ! ( 0 , size. bytes( ) ) ;
755
- let thread_infos = self . thread_infos . borrow ( ) ;
756
- let curr_thread_id = machine. threads . active_thread ( ) ;
757
- let genmc_tid = thread_infos. get_info ( curr_thread_id) . genmc_tid ;
758
-
759
- let genmc_address = address. bytes ( ) ;
760
- let genmc_size = size. bytes ( ) ;
761
-
762
- info ! (
763
- "GenMC: atomic_rmw_op, thread: {curr_thread_id:?} ({genmc_tid:?}) (op: {genmc_rmw_op:?}, rhs value: {genmc_rhs_scalar:?}), address: {address:?}, size: {size:?}, orderings: ({load_ordering:?}, {store_ordering:?})" ,
764
- ) ;
765
-
766
- let mut mc = self . handle . borrow_mut ( ) ;
767
- let pinned_mc = mc. as_mut ( ) ;
768
- let rmw_result = pinned_mc. handleReadModifyWrite (
769
- genmc_tid. 0 ,
770
- genmc_address,
771
- genmc_size,
772
- load_ordering,
773
- store_ordering,
774
- genmc_rmw_op,
775
- genmc_rhs_scalar,
776
- genmc_old_value,
777
- ) ;
778
-
779
- if let Some ( error) = rmw_result. error . as_ref ( ) {
780
- let msg = error. to_string_lossy ( ) . to_string ( ) ;
781
- info ! ( "GenMC: RMW operation returned an error: \" {msg}\" " ) ;
782
- throw_ub_format ! ( "{}" , msg) ; // TODO GENMC: proper error handling: find correct error here
783
- }
784
-
785
- let old_value_scalar = genmc_scalar_to_scalar ( ecx, rmw_result. old_value , size) ?;
786
-
787
- let new_value_scalar = if rmw_result. isCoMaxWrite {
788
- Some ( genmc_scalar_to_scalar ( ecx, rmw_result. new_value , size) ?)
789
- } else {
790
- None
791
- } ;
792
- interp_ok ( ( old_value_scalar, new_value_scalar) )
793
- }
794
-
795
686
/**** Scheduling functionality ****/
796
687
797
688
pub fn schedule_thread < ' tcx > (
0 commit comments