diff --git a/pcbnew/connectivity/connectivity_items.h b/pcbnew/connectivity/connectivity_items.h index 3e6ca7e9a..e41f84c54 100644 --- a/pcbnew/connectivity/connectivity_items.h +++ b/pcbnew/connectivity/connectivity_items.h @@ -109,7 +109,7 @@ public: m_cluster = aCluster; } - inline std::shared_ptr GetCluster() const + inline const std::shared_ptr& GetCluster() const { return m_cluster; } @@ -159,7 +159,7 @@ typedef std::vector CN_ANCHORS; class CN_ITEM : public INTRUSIVE_LIST { public: - using CONNECTED_ITEMS = std::set; + using CONNECTED_ITEMS = std::vector; private: BOARD_CONNECTED_ITEM* m_parent; @@ -178,8 +178,8 @@ private: ///> valid flag, used to identify garbage items (we use lazy removal) bool m_valid; - ///> mutex protecting this item's connected_items set to allow parallel connection threads - std::mutex m_listLock; + ///> atomic var protecting this item's connected_items set to allow parallel connection threads + std::atomic_flag m_listLock = ATOMIC_FLAG_INIT; protected: ///> dirty flag, used to identify recently added item not yet scanned into the connectivity search @@ -201,15 +201,16 @@ public: m_visited = false; m_valid = true; m_dirty = true; - m_anchors.reserve( 2 ); + m_anchors.reserve( std::max (6, aAnchorCount) ); m_layers = LAYER_RANGE( 0, PCB_LAYER_ID_COUNT ); + m_connected.reserve (8); } virtual ~CN_ITEM() {}; void AddAnchor( const VECTOR2I& aPos ) { - m_anchors.emplace_back( std::make_unique( aPos, this ) ); + m_anchors.emplace_back( std::make_shared( aPos, this ) ); } CN_ANCHORS& Anchors() @@ -319,8 +320,14 @@ public: void Connect( CN_ITEM* b ) { - std::lock_guard lock( m_listLock ); - m_connected.insert( b ); + while (m_listLock.test_and_set ()) { } + + auto i = std::lower_bound (m_connected.begin (), m_connected.end (), b); + if (i != m_connected.end () && *i == b) + return; + + m_connected.insert (i, b); + m_listLock.clear (); } void RemoveInvalidRefs();