@@ -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.
14331433 reuse_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
14431436 last_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