@@ -828,15 +828,14 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> {
828
828
}
829
829
}
830
830
831
- /// Returns the ` release` clock of the current thread.
831
+ /// Calls the callback with the " release" clock of the current thread.
832
832
/// Other threads can acquire this clock in the future to establish synchronization
833
833
/// with this program point.
834
- fn release_clock < ' a > ( & ' a self ) -> Option < Ref < ' a , VClock > >
835
- where
836
- ' tcx : ' a ,
837
- {
834
+ ///
835
+ /// The closure will only be invoked if data race handling is on.
836
+ fn release_clock < R > ( & self , callback : impl FnOnce ( & VClock ) -> R ) -> Option < R > {
838
837
let this = self . eval_context_ref ( ) ;
839
- Some ( this. machine . data_race . as_ref ( ) ?. release_clock ( & this. machine . threads ) )
838
+ Some ( this. machine . data_race . as_ref ( ) ?. release_clock ( & this. machine . threads , callback ) )
840
839
}
841
840
842
841
/// Acquire the given clock into the current thread, establishing synchronization with
@@ -1728,7 +1727,7 @@ impl GlobalState {
1728
1727
let current_index = self . active_thread_index ( thread_mgr) ;
1729
1728
1730
1729
// Store the terminaion clock.
1731
- let terminaion_clock = self . release_clock ( thread_mgr) . clone ( ) ;
1730
+ let terminaion_clock = self . release_clock ( thread_mgr, |clock| clock . clone ( ) ) ;
1732
1731
self . thread_info . get_mut ( ) [ current_thread] . termination_vector_clock =
1733
1732
Some ( terminaion_clock) ;
1734
1733
@@ -1778,21 +1777,23 @@ impl GlobalState {
1778
1777
clocks. clock . join ( clock) ;
1779
1778
}
1780
1779
1781
- /// Returns the ` release` clock of the current thread.
1780
+ /// Calls the given closure with the " release" clock of the current thread.
1782
1781
/// Other threads can acquire this clock in the future to establish synchronization
1783
1782
/// with this program point.
1784
- pub fn release_clock < ' tcx > ( & self , threads : & ThreadManager < ' tcx > ) -> Ref < ' _ , VClock > {
1783
+ pub fn release_clock < ' tcx , R > (
1784
+ & self ,
1785
+ threads : & ThreadManager < ' tcx > ,
1786
+ callback : impl FnOnce ( & VClock ) -> R ,
1787
+ ) -> R {
1785
1788
let thread = threads. active_thread ( ) ;
1786
1789
let span = threads. active_thread_ref ( ) . current_span ( ) ;
1787
- // We increment the clock each time this happens, to ensure no two releases
1788
- // can be confused with each other.
1789
1790
let ( index, mut clocks) = self . thread_state_mut ( thread) ;
1791
+ let r = callback ( & clocks. clock ) ;
1792
+ // Increment the clock, so that all following events cannot be confused with anything that
1793
+ // occurred before the release. Crucially, the callback is invoked on the *old* clock!
1790
1794
clocks. increment_clock ( index, span) ;
1791
- drop ( clocks) ;
1792
- // To return a read-only view, we need to release the RefCell
1793
- // and borrow it again.
1794
- let ( _index, clocks) = self . thread_state ( thread) ;
1795
- Ref :: map ( clocks, |c| & c. clock )
1795
+
1796
+ r
1796
1797
}
1797
1798
1798
1799
fn thread_index ( & self , thread : ThreadId ) -> VectorIdx {
0 commit comments