@@ -828,15 +828,14 @@ pub trait EvalContextExt<'tcx>: MiriInterpCxExt<'tcx> {
828828 }
829829 }
830830
831- /// Returns the ` release` clock of the current thread.
831+ /// Calls the callback with the " release" clock of the current thread.
832832 /// Other threads can acquire this clock in the future to establish synchronization
833833 /// 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 > {
838837 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 ) )
840839 }
841840
842841 /// Acquire the given clock into the current thread, establishing synchronization with
@@ -1728,7 +1727,7 @@ impl GlobalState {
17281727 let current_index = self . active_thread_index ( thread_mgr) ;
17291728
17301729 // 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 ( ) ) ;
17321731 self . thread_info . get_mut ( ) [ current_thread] . termination_vector_clock =
17331732 Some ( terminaion_clock) ;
17341733
@@ -1778,21 +1777,23 @@ impl GlobalState {
17781777 clocks. clock . join ( clock) ;
17791778 }
17801779
1781- /// Returns the ` release` clock of the current thread.
1780+ /// Calls the given closure with the " release" clock of the current thread.
17821781 /// Other threads can acquire this clock in the future to establish synchronization
17831782 /// 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 {
17851788 let thread = threads. active_thread ( ) ;
17861789 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.
17891790 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!
17901794 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
17961797 }
17971798
17981799 fn thread_index ( & self , thread : ThreadId ) -> VectorIdx {
0 commit comments