Thread the connectivity vector updates

Now that we are dealing with individual connection elements that do not
update their connected elements as well, we can thread the update, just
being careful to guard any remaining updates (bus_enty/busLine) that
need reciprocal updating

Fixes https://gitlab.com/kicad/code/kicad/issues/10974

(cherry picked from commit 6a53e318e5)
This commit is contained in:
Seth Hillbrand 2022-03-28 15:34:13 -07:00
parent 6a33bcdc78
commit 719874fe9c
1 changed files with 118 additions and 92 deletions

View File

@ -600,10 +600,19 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
// Pre-scan to see if we have a bus at this location
SCH_LINE* busLine = aSheet.LastScreen()->GetBus( it.first );
for( auto primary_it = connection_vec.begin(); primary_it != connection_vec.end(); primary_it++ )
{
SCH_ITEM* connected_item = *primary_it;
// We don't want to spin up a new thread for fewer than 4 items (overhead costs)
size_t parallelThreadCount = std::min<size_t>( std::thread::hardware_concurrency(),
( connection_vec.size() + 3 ) / 4 );
std::atomic<size_t> nextItem( 0 );
std::mutex update_mutex;
std::vector<std::future<size_t>> returns( parallelThreadCount );
auto update_lambda = [&]() -> size_t
{
for( size_t ii = nextItem++; ii < connection_vec.size(); ii = nextItem++ )
{
SCH_ITEM* connected_item = connection_vec[ii];
// Bus entries are special: they can have connection points in the
// middle of a wire segment, because the junction algo doesn't split
// the segment in two where you place a bus entry. This means that
@ -640,6 +649,7 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
else
bus_entry->m_connected_bus_items[1] = busLine;
std::lock_guard<std::mutex> lock( update_mutex );
bus_entry->AddConnectionTo( aSheet, busLine );
busLine->AddConnectionTo( aSheet, bus_entry );
}
@ -709,6 +719,22 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet,
}
}
}
return 1;
};
if( parallelThreadCount == 1 )
update_lambda();
else
{
for( size_t ii = 0; ii < parallelThreadCount; ++ii )
returns[ii] = std::async( std::launch::async, update_lambda );
// Finalize the threads
for( size_t ii = 0; ii < parallelThreadCount; ++ii )
returns[ii].wait();
}
}
}