From a5a56c46c35329eaaabc22f946e8fece2965c634 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Mon, 27 Jul 2020 09:33:01 -0700 Subject: [PATCH] Remove INTRUSIVE_LIST from CN_ITEM Intrusive lists made the connectivity search not thread-safe. Using iterators for item deletion provides the same order performance while keeping the container thread-localized --- pcbnew/connectivity/connectivity_algo.cpp | 28 ++++++++++++----------- pcbnew/connectivity/connectivity_items.h | 2 +- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/pcbnew/connectivity/connectivity_algo.cpp b/pcbnew/connectivity/connectivity_algo.cpp index d75d8796ad..00c17521e8 100644 --- a/pcbnew/connectivity/connectivity_algo.cpp +++ b/pcbnew/connectivity/connectivity_algo.cpp @@ -310,13 +310,14 @@ const CN_CONNECTIVITY_ALGO::CLUSTERS CN_CONNECTIVITY_ALGO::SearchClusters( CLUST bool withinAnyNet = ( aMode != CSM_PROPAGATE ); std::deque Q; - CN_ITEM* head = nullptr; + std::set item_set; + CLUSTERS clusters; if( m_itemList.IsDirty() ) searchConnections(); - auto addToSearchList = [&head, withinAnyNet, aSingleNet, aTypes] ( CN_ITEM *aItem ) + auto addToSearchList = [&item_set, withinAnyNet, aSingleNet, aTypes] ( CN_ITEM *aItem ) { if( withinAnyNet && aItem->Net() <= 0 ) return; @@ -341,27 +342,29 @@ const CN_CONNECTIVITY_ALGO::CLUSTERS CN_CONNECTIVITY_ALGO::SearchClusters( CLUST if( !found ) return; - aItem->ListClear(); aItem->SetVisited( false ); - if( !head ) - head = aItem; - else - head->ListInsert( aItem ); + item_set.insert( aItem ); }; std::for_each( m_itemList.begin(), m_itemList.end(), addToSearchList ); - while( head ) + while( !item_set.empty() ) { CN_CLUSTER_PTR cluster ( new CN_CLUSTER() ); + CN_ITEM* root; + auto it = item_set.begin(); - Q.clear(); - CN_ITEM* root = head; + while( it != item_set.end() && (*it)->Visited() ) + it = item_set.erase( item_set.begin() ); + + if( it == item_set.end() ) + break; + + root = *it; root->SetVisited ( true ); - head = root->ListRemove(); - + Q.clear(); Q.push_back( root ); while( Q.size() ) @@ -380,7 +383,6 @@ const CN_CONNECTIVITY_ALGO::CLUSTERS CN_CONNECTIVITY_ALGO::SearchClusters( CLUST { n->SetVisited( true ); Q.push_back( n ); - head = n->ListRemove(); } } } diff --git a/pcbnew/connectivity/connectivity_items.h b/pcbnew/connectivity/connectivity_items.h index 4d4e0defed..b9157da4da 100644 --- a/pcbnew/connectivity/connectivity_items.h +++ b/pcbnew/connectivity/connectivity_items.h @@ -162,7 +162,7 @@ typedef std::vector CN_ANCHORS; // basic connectivity item -class CN_ITEM : public INTRUSIVE_LIST +class CN_ITEM { public: using CONNECTED_ITEMS = std::vector;