@@ -47,7 +47,7 @@ use std::{
4747} ; 
4848
4949use  rustc_ast:: Mutability ; 
50- use  rustc_data_structures:: fx:: { FxHashMap ,   FxHashSet } ; 
50+ use  rustc_data_structures:: fx:: FxHashSet ; 
5151use  rustc_index:: { Idx ,  IndexVec } ; 
5252use  rustc_middle:: { mir,  ty:: Ty } ; 
5353use  rustc_span:: Span ; 
@@ -1432,13 +1432,6 @@ pub struct GlobalState {
14321432/// active vector-clocks catch up with the threads timestamp. 
14331433reuse_candidates :  RefCell < FxHashSet < VectorIdx > > , 
14341434
1435-     /// This contains threads that have terminated, but not yet joined 
1436- /// and so cannot become re-use candidates until a join operation 
1437- /// occurs. 
1438- /// The associated vector index will be moved into re-use candidates 
1439- /// after the join operation occurs. 
1440- terminated_threads :  RefCell < FxHashMap < ThreadId ,  VectorIdx > > , 
1441- 
14421435    /// The timestamp of last SC fence performed by each thread 
14431436last_sc_fence :  RefCell < VClock > , 
14441437
@@ -1466,7 +1459,6 @@ impl GlobalState {
14661459            vector_info :  RefCell :: new ( IndexVec :: new ( ) ) , 
14671460            thread_info :  RefCell :: new ( IndexVec :: new ( ) ) , 
14681461            reuse_candidates :  RefCell :: new ( FxHashSet :: default ( ) ) , 
1469-             terminated_threads :  RefCell :: new ( FxHashMap :: default ( ) ) , 
14701462            last_sc_fence :  RefCell :: new ( VClock :: default ( ) ) , 
14711463            last_sc_write :  RefCell :: new ( VClock :: default ( ) ) , 
14721464            track_outdated_loads :  config. track_outdated_loads , 
@@ -1500,8 +1492,6 @@ impl GlobalState {
15001492    fn  find_vector_index_reuse_candidate ( & self )  -> Option < VectorIdx >  { 
15011493        let  mut  reuse = self . reuse_candidates . borrow_mut ( ) ; 
15021494        let  vector_clocks = self . vector_clocks . borrow ( ) ; 
1503-         let  vector_info = self . vector_info . borrow ( ) ; 
1504-         let  terminated_threads = self . terminated_threads . borrow ( ) ; 
15051495        for  & candidate in  reuse. iter ( )  { 
15061496            let  target_timestamp = vector_clocks[ candidate] . clock [ candidate] ; 
15071497            if  vector_clocks. iter_enumerated ( ) . all ( |( clock_idx,  clock) | { 
@@ -1511,9 +1501,7 @@ impl GlobalState {
15111501
15121502                // The vector represents a thread that has terminated and hence cannot 
15131503                // report a data-race with the candidate index. 
1514-                 let  thread_id = vector_info[ clock_idx] ; 
1515-                 let  vector_terminated =
1516-                     reuse. contains ( & clock_idx)  || terminated_threads. contains_key ( & thread_id) ; 
1504+                 let  vector_terminated = reuse. contains ( & clock_idx) ; 
15171505
15181506                // The vector index cannot report a race with the candidate index 
15191507                // and hence allows the candidate index to be re-used. 
@@ -1603,55 +1591,38 @@ impl GlobalState {
16031591/// thread (the joinee, the thread that someone waited on) and the current thread (the joiner, 
16041592/// the thread who was waiting). 
16051593#[ inline]  
1606-     pub  fn  thread_joined ( 
1607-         & mut  self , 
1608-         thread_mgr :  & ThreadManager < ' _ ,  ' _ > , 
1609-         joiner :  ThreadId , 
1610-         joinee :  ThreadId , 
1611-     )  { 
1612-         let  clocks_vec = self . vector_clocks . get_mut ( ) ; 
1613-         let  thread_info = self . thread_info . get_mut ( ) ; 
1614- 
1615-         // Load the vector clock of the current thread. 
1616-         let  current_index = thread_info[ joiner] 
1617-             . vector_index 
1618-             . expect ( "Performed thread join on thread with no assigned vector" ) ; 
1619-         let  current = & mut  clocks_vec[ current_index] ; 
1594+     pub  fn  thread_joined ( & mut  self ,  threads :  & ThreadManager < ' _ ,  ' _ > ,  joinee :  ThreadId )  { 
1595+         let  thread_info = self . thread_info . borrow ( ) ; 
1596+         let  thread_info = & thread_info[ joinee] ; 
16201597
16211598        // Load the associated vector clock for the terminated thread. 
1622-         let  join_clock = thread_info[ joinee ] 
1599+         let  join_clock = thread_info
16231600            . termination_vector_clock 
16241601            . as_ref ( ) 
1625-             . expect ( "Joined with thread but thread has not terminated" ) ; 
1626- 
1627-         // The join thread happens-before the current thread 
1628-         // so update the current vector clock. 
1629-         // Is not a release operation so the clock is not incremented. 
1630-         current. clock . join ( join_clock) ; 
1602+             . expect ( "joined with thread but thread has not terminated" ) ; 
1603+         // Acquire that into the current thread. 
1604+         self . acquire_clock ( join_clock,  threads) ; 
16311605
16321606        // Check the number of live threads, if the value is 1 
16331607        // then test for potentially disabling multi-threaded execution. 
1634-         if  thread_mgr. get_live_thread_count ( )  == 1  { 
1635-             // May potentially be able to disable multi-threaded execution. 
1636-             let  current_clock = & clocks_vec[ current_index] ; 
1637-             if  clocks_vec
1638-                 . iter_enumerated ( ) 
1639-                 . all ( |( idx,  clocks) | clocks. clock [ idx]  <= current_clock. clock [ idx] ) 
1640-             { 
1641-                 // All thread terminations happen-before the current clock 
1642-                 // therefore no data-races can be reported until a new thread 
1643-                 // is created, so disable multi-threaded execution. 
1644-                 self . multi_threaded . set ( false ) ; 
1608+         // This has to happen after `acquire_clock`, otherwise there'll always 
1609+         // be some thread that has not synchronized yet. 
1610+         if  let  Some ( current_index)  = thread_info. vector_index  { 
1611+             if  threads. get_live_thread_count ( )  == 1  { 
1612+                 let  vector_clocks = self . vector_clocks . get_mut ( ) ; 
1613+                 // May potentially be able to disable multi-threaded execution. 
1614+                 let  current_clock = & vector_clocks[ current_index] ; 
1615+                 if  vector_clocks
1616+                     . iter_enumerated ( ) 
1617+                     . all ( |( idx,  clocks) | clocks. clock [ idx]  <= current_clock. clock [ idx] ) 
1618+                 { 
1619+                     // All thread terminations happen-before the current clock 
1620+                     // therefore no data-races can be reported until a new thread 
1621+                     // is created, so disable multi-threaded execution. 
1622+                     self . multi_threaded . set ( false ) ; 
1623+                 } 
16451624            } 
16461625        } 
1647- 
1648-         // If the thread is marked as terminated but not joined 
1649-         // then move the thread to the re-use set. 
1650-         let  termination = self . terminated_threads . get_mut ( ) ; 
1651-         if  let  Some ( index)  = termination. remove ( & joinee)  { 
1652-             let  reuse = self . reuse_candidates . get_mut ( ) ; 
1653-             reuse. insert ( index) ; 
1654-         } 
16551626    } 
16561627
16571628    /// On thread termination, the vector-clock may re-used 
@@ -1663,29 +1634,17 @@ impl GlobalState {
16631634/// `thread_joined`. 
16641635#[ inline]  
16651636    pub  fn  thread_terminated ( & mut  self ,  thread_mgr :  & ThreadManager < ' _ ,  ' _ > )  { 
1637+         let  current_thread = thread_mgr. active_thread ( ) ; 
16661638        let  current_index = self . active_thread_index ( thread_mgr) ; 
16671639
1668-         // Increment the clock to a unique termination timestamp. 
1669-         let  vector_clocks = self . vector_clocks . get_mut ( ) ; 
1670-         let  current_clocks = & mut  vector_clocks[ current_index] ; 
1671-         current_clocks
1672-             . increment_clock ( current_index,  thread_mgr. active_thread_ref ( ) . current_span ( ) ) ; 
1673- 
1674-         // Load the current thread id for the executing vector. 
1675-         let  vector_info = self . vector_info . get_mut ( ) ; 
1676-         let  current_thread = vector_info[ current_index] ; 
1677- 
1678-         // Load the current thread metadata, and move to a terminated 
1679-         // vector state. Setting up the vector clock all join operations 
1680-         // will use. 
1681-         let  thread_info = self . thread_info . get_mut ( ) ; 
1682-         let  current = & mut  thread_info[ current_thread] ; 
1683-         current. termination_vector_clock  = Some ( current_clocks. clock . clone ( ) ) ; 
1684- 
1685-         // Add this thread as a candidate for re-use after a thread join 
1686-         // occurs. 
1687-         let  termination = self . terminated_threads . get_mut ( ) ; 
1688-         termination. insert ( current_thread,  current_index) ; 
1640+         // Store the terminaion clock. 
1641+         let  terminaion_clock = self . release_clock ( thread_mgr) . clone ( ) ; 
1642+         self . thread_info . get_mut ( ) [ current_thread] . termination_vector_clock  =
1643+             Some ( terminaion_clock) ; 
1644+ 
1645+         // Add this thread's clock index as a candidate for re-use. 
1646+         let  reuse = self . reuse_candidates . get_mut ( ) ; 
1647+         reuse. insert ( current_index) ; 
16891648    } 
16901649
16911650    /// Attempt to perform a synchronized operation, this 
0 commit comments