@@ -445,14 +445,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriEvalContextExt<'mir, 'tcx> {
445445 #[ inline]
446446 fn allow_data_races_ref < R > ( & self , op : impl FnOnce ( & MiriEvalContext < ' mir , ' tcx > ) -> R ) -> R {
447447 let this = self . eval_context_ref ( ) ;
448- let old = if let Some ( data_race) = & this. machine . data_race {
449- data_race. multi_threaded . replace ( false )
450- } else {
451- false
452- } ;
448+ if let Some ( data_race) = & this. machine . data_race {
449+ data_race. ongoing_atomic_access . set ( true ) ;
450+ }
453451 let result = op ( this) ;
454452 if let Some ( data_race) = & this. machine . data_race {
455- data_race. multi_threaded . set ( old ) ;
453+ data_race. ongoing_atomic_access . set ( false ) ;
456454 }
457455 result
458456 }
@@ -466,14 +464,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: MiriEvalContextExt<'mir, 'tcx> {
466464 op : impl FnOnce ( & mut MiriEvalContext < ' mir , ' tcx > ) -> R ,
467465 ) -> R {
468466 let this = self . eval_context_mut ( ) ;
469- let old = if let Some ( data_race) = & this. machine . data_race {
470- data_race. multi_threaded . replace ( false )
471- } else {
472- false
473- } ;
467+ if let Some ( data_race) = & this. machine . data_race {
468+ data_race. ongoing_atomic_access . set ( true ) ;
469+ }
474470 let result = op ( this) ;
475471 if let Some ( data_race) = & this. machine . data_race {
476- data_race. multi_threaded . set ( old ) ;
472+ data_race. ongoing_atomic_access . set ( false ) ;
477473 }
478474 result
479475 }
@@ -923,7 +919,7 @@ impl VClockAlloc {
923919 }
924920
925921 /// Detect data-races for an unsynchronized read operation, will not perform
926- /// data-race detection if `multi-threaded ` is false, either due to no threads
922+ /// data-race detection if `race_detecting() ` is false, either due to no threads
927923 /// being created or if it is temporarily disabled during a racy read or write
928924 /// operation for which data-race detection is handled separately, for example
929925 /// atomic read operations.
@@ -933,7 +929,7 @@ impl VClockAlloc {
933929 range : AllocRange ,
934930 global : & GlobalState ,
935931 ) -> InterpResult < ' tcx > {
936- if global. multi_threaded . get ( ) {
932+ if global. race_detecting ( ) {
937933 let ( index, clocks) = global. current_thread_state ( ) ;
938934 let mut alloc_ranges = self . alloc_ranges . borrow_mut ( ) ;
939935 for ( offset, range) in alloc_ranges. iter_mut ( range. start , range. size ) {
@@ -962,7 +958,7 @@ impl VClockAlloc {
962958 write_type : WriteType ,
963959 global : & mut GlobalState ,
964960 ) -> InterpResult < ' tcx > {
965- if global. multi_threaded . get ( ) {
961+ if global. race_detecting ( ) {
966962 let ( index, clocks) = global. current_thread_state ( ) ;
967963 for ( offset, range) in self . alloc_ranges . get_mut ( ) . iter_mut ( range. start , range. size ) {
968964 if let Err ( DataRace ) = range. write_race_detect ( & * clocks, index, write_type) {
@@ -983,7 +979,7 @@ impl VClockAlloc {
983979 }
984980
985981 /// Detect data-races for an unsynchronized write operation, will not perform
986- /// data-race threads if `multi-threaded ` is false, either due to no threads
982+ /// data-race threads if `race_detecting() ` is false, either due to no threads
987983 /// being created or if it is temporarily disabled during a racy read or write
988984 /// operation
989985 pub fn write < ' tcx > (
@@ -996,7 +992,7 @@ impl VClockAlloc {
996992 }
997993
998994 /// Detect data-races for an unsynchronized deallocate operation, will not perform
999- /// data-race threads if `multi-threaded ` is false, either due to no threads
995+ /// data-race threads if `race_detecting() ` is false, either due to no threads
1000996 /// being created or if it is temporarily disabled during a racy read or write
1001997 /// operation
1002998 pub fn deallocate < ' tcx > (
@@ -1026,7 +1022,7 @@ trait EvalContextPrivExt<'mir, 'tcx: 'mir>: MiriEvalContextExt<'mir, 'tcx> {
10261022 ) -> InterpResult < ' tcx > {
10271023 let this = self . eval_context_ref ( ) ;
10281024 if let Some ( data_race) = & this. machine . data_race {
1029- if data_race. multi_threaded . get ( ) {
1025+ if data_race. race_detecting ( ) {
10301026 let size = place. layout . size ;
10311027 let ( alloc_id, base_offset, _tag) = this. ptr_get_alloc_id ( place. ptr ) ?;
10321028 // Load and log the atomic operation.
@@ -1116,6 +1112,10 @@ pub struct GlobalState {
11161112 /// any data-races.
11171113 multi_threaded : Cell < bool > ,
11181114
1115+ /// A flag to mark we are currently performing
1116+ /// an atomic access to supress data race detection
1117+ ongoing_atomic_access : Cell < bool > ,
1118+
11191119 /// Mapping of a vector index to a known set of thread
11201120 /// clocks, this is not directly mapping from a thread id
11211121 /// since it may refer to multiple threads.
@@ -1167,6 +1167,7 @@ impl GlobalState {
11671167 pub fn new ( ) -> Self {
11681168 let mut global_state = GlobalState {
11691169 multi_threaded : Cell :: new ( false ) ,
1170+ ongoing_atomic_access : Cell :: new ( false ) ,
11701171 vector_clocks : RefCell :: new ( IndexVec :: new ( ) ) ,
11711172 vector_info : RefCell :: new ( IndexVec :: new ( ) ) ,
11721173 thread_info : RefCell :: new ( IndexVec :: new ( ) ) ,
@@ -1192,6 +1193,13 @@ impl GlobalState {
11921193 global_state
11931194 }
11941195
1196+ // We perform data race detection when there are more than 1 active thread
1197+ // and we are not currently in the middle of an atomic acces where data race
1198+ // is impossible
1199+ fn race_detecting ( & self ) -> bool {
1200+ self . multi_threaded . get ( ) && !self . ongoing_atomic_access . get ( )
1201+ }
1202+
11951203 // Try to find vector index values that can potentially be re-used
11961204 // by a new thread instead of a new vector index being created.
11971205 fn find_vector_index_reuse_candidate ( & self ) -> Option < VectorIdx > {
0 commit comments