change m_CachesMutex to shared_mutex and do shared locking for read access in zone BBox calculations
This commit is contained in:
parent
aff3064187
commit
1f1b97212b
|
@ -262,7 +262,7 @@ void BOARD::IncrementTimeStamp()
|
|||
|| !m_ZoneBBoxCache.empty()
|
||||
|| m_CopperItemRTreeCache )
|
||||
{
|
||||
std::unique_lock<std::mutex> cacheLock( m_CachesMutex );
|
||||
std::unique_lock<std::shared_mutex> cacheLock( m_CachesMutex );
|
||||
|
||||
m_IntersectsAreaCache.clear();
|
||||
m_EnclosedByAreaCache.clear();
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
#include <pcb_plot_params.h>
|
||||
#include <title_block.h>
|
||||
#include <tools/pcb_selection.h>
|
||||
#include <mutex>
|
||||
#include <shared_mutex>
|
||||
#include <list>
|
||||
|
||||
class BOARD_DESIGN_SETTINGS;
|
||||
|
@ -1227,7 +1227,7 @@ public:
|
|||
};
|
||||
|
||||
// ------------ Run-time caches -------------
|
||||
std::mutex m_CachesMutex;
|
||||
std::shared_mutex m_CachesMutex;
|
||||
std::unordered_map<PTR_PTR_CACHE_KEY, bool> m_IntersectsCourtyardCache;
|
||||
std::unordered_map<PTR_PTR_CACHE_KEY, bool> m_IntersectsFCourtyardCache;
|
||||
std::unordered_map<PTR_PTR_CACHE_KEY, bool> m_IntersectsBCourtyardCache;
|
||||
|
|
|
@ -136,7 +136,7 @@ bool DRC_CACHE_GENERATOR::Run()
|
|||
std::future<void> retn = tp.submit(
|
||||
[&]()
|
||||
{
|
||||
std::unique_lock<std::mutex> cacheLock( m_board->m_CachesMutex );
|
||||
std::unique_lock<std::shared_mutex> cacheLock( m_board->m_CachesMutex );
|
||||
|
||||
if( !m_board->m_CopperItemRTreeCache )
|
||||
m_board->m_CopperItemRTreeCache = std::make_shared<DRC_RTREE>();
|
||||
|
@ -184,7 +184,7 @@ bool DRC_CACHE_GENERATOR::Run()
|
|||
rtree->Insert( aZone, layer );
|
||||
}
|
||||
|
||||
std::unique_lock<std::mutex> cacheLock( m_board->m_CachesMutex );
|
||||
std::unique_lock<std::shared_mutex> cacheLock( m_board->m_CachesMutex );
|
||||
m_board->m_CopperZoneRTreeCache[ aZone ] = std::move( rtree );
|
||||
|
||||
done.fetch_add( 1 );
|
||||
|
|
|
@ -153,7 +153,7 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
|
|||
PTR_PTR_LAYER_CACHE_KEY key = { ruleArea, copperZone, UNDEFINED_LAYER };
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> cacheLock( board->m_CachesMutex );
|
||||
std::unique_lock<std::shared_mutex> cacheLock( board->m_CachesMutex );
|
||||
board->m_IntersectsAreaCache[ key ] = isInside;
|
||||
}
|
||||
|
||||
|
|
|
@ -57,12 +57,12 @@ public:
|
|||
// in the ENUM_MAP: one for the canonical layer name and one for the user layer name.
|
||||
// We need to check against both.
|
||||
|
||||
wxPGChoices& layerMap = ENUM_MAP<PCB_LAYER_ID>::Instance().Choices();
|
||||
const wxString& layerName = b->AsString();
|
||||
BOARD* board = static_cast<PCBEXPR_CONTEXT*>( aCtx )->GetBoard();
|
||||
std::unique_lock<std::mutex> cacheLock( board->m_CachesMutex );
|
||||
auto i = board->m_LayerExpressionCache.find( layerName );
|
||||
LSET mask;
|
||||
wxPGChoices& layerMap = ENUM_MAP<PCB_LAYER_ID>::Instance().Choices();
|
||||
const wxString& layerName = b->AsString();
|
||||
BOARD* board = static_cast<PCBEXPR_CONTEXT*>( aCtx )->GetBoard();
|
||||
std::unique_lock<std::shared_mutex> cacheLock( board->m_CachesMutex );
|
||||
auto i = board->m_LayerExpressionCache.find( layerName );
|
||||
LSET mask;
|
||||
|
||||
if( i == board->m_LayerExpressionCache.end() )
|
||||
{
|
||||
|
|
|
@ -135,7 +135,7 @@ static void existsOnLayerFunc( LIBEVAL::CONTEXT* aCtx, void *self )
|
|||
*/
|
||||
|
||||
BOARD* board = item->GetBoard();
|
||||
std::unique_lock<std::mutex> cacheLock( board->m_CachesMutex );
|
||||
std::unique_lock<std::shared_mutex> cacheLock( board->m_CachesMutex );
|
||||
auto i = board->m_LayerExpressionCache.find( layerName );
|
||||
LSET mask;
|
||||
|
||||
|
@ -271,8 +271,8 @@ static void intersectsCourtyardFunc( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
if( searchFootprints( board, arg->AsString(), context,
|
||||
[&]( FOOTPRINT* fp )
|
||||
{
|
||||
PTR_PTR_CACHE_KEY key = { fp, item };
|
||||
std::unique_lock<std::mutex> cacheLock( board->m_CachesMutex );
|
||||
PTR_PTR_CACHE_KEY key = { fp, item };
|
||||
std::unique_lock<std::shared_mutex> cacheLock( board->m_CachesMutex );
|
||||
|
||||
if( ( item->GetFlags() & ROUTER_TRANSIENT ) == 0 )
|
||||
{
|
||||
|
@ -331,8 +331,8 @@ static void intersectsFrontCourtyardFunc( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
if( searchFootprints( board, arg->AsString(), context,
|
||||
[&]( FOOTPRINT* fp )
|
||||
{
|
||||
PTR_PTR_CACHE_KEY key = { fp, item };
|
||||
std::unique_lock<std::mutex> cacheLock( board->m_CachesMutex );
|
||||
PTR_PTR_CACHE_KEY key = { fp, item };
|
||||
std::unique_lock<std::shared_mutex> cacheLock( board->m_CachesMutex );
|
||||
|
||||
if( ( item->GetFlags() & ROUTER_TRANSIENT ) == 0 )
|
||||
{
|
||||
|
@ -390,8 +390,8 @@ static void intersectsBackCourtyardFunc( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
if( searchFootprints( board, arg->AsString(), context,
|
||||
[&]( FOOTPRINT* fp )
|
||||
{
|
||||
PTR_PTR_CACHE_KEY key = { fp, item };
|
||||
std::unique_lock<std::mutex> cacheLock( board->m_CachesMutex );
|
||||
PTR_PTR_CACHE_KEY key = { fp, item };
|
||||
std::unique_lock<std::shared_mutex> cacheLock( board->m_CachesMutex );
|
||||
|
||||
if( ( item->GetFlags() & ROUTER_TRANSIENT ) == 0 )
|
||||
{
|
||||
|
@ -660,7 +660,7 @@ static void intersectsAreaFunc( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
{
|
||||
if( ( item->GetFlags() & ROUTER_TRANSIENT ) == 0 )
|
||||
{
|
||||
std::unique_lock<std::mutex> cacheLock( board->m_CachesMutex );
|
||||
std::shared_lock<std::shared_mutex> cacheLock( board->m_CachesMutex );
|
||||
key = { aArea, item, layer };
|
||||
|
||||
auto i = board->m_IntersectsAreaCache.find( key );
|
||||
|
@ -673,7 +673,7 @@ static void intersectsAreaFunc( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
|
||||
if( ( item->GetFlags() & ROUTER_TRANSIENT ) == 0 )
|
||||
{
|
||||
std::unique_lock<std::mutex> cacheLock( board->m_CachesMutex );
|
||||
std::unique_lock<std::shared_mutex> cacheLock( board->m_CachesMutex );
|
||||
board->m_IntersectsAreaCache[ key ] = collides;
|
||||
}
|
||||
|
||||
|
@ -735,8 +735,8 @@ static void enclosedByAreaFunc( LIBEVAL::CONTEXT* aCtx, void* self )
|
|||
if( !aArea->GetBoundingBox().Intersects( itemBBox ) )
|
||||
return false;
|
||||
|
||||
std::unique_lock<std::mutex> cacheLock( board->m_CachesMutex );
|
||||
PTR_PTR_LAYER_CACHE_KEY key = { aArea, item, layer };
|
||||
std::unique_lock<std::shared_mutex> cacheLock( board->m_CachesMutex );
|
||||
PTR_PTR_LAYER_CACHE_KEY key = { aArea, item, layer };
|
||||
|
||||
if( ( item->GetFlags() & ROUTER_TRANSIENT ) == 0 )
|
||||
{
|
||||
|
|
|
@ -344,13 +344,24 @@ const BOX2I ZONE::GetBoundingBox() const
|
|||
if( const BOARD* board = GetBoard() )
|
||||
{
|
||||
std::unordered_map<const ZONE*, BOX2I>& cache = board->m_ZoneBBoxCache;
|
||||
std::unique_lock<std::mutex> cacheLock( const_cast<BOARD*>( board )->m_CachesMutex );
|
||||
std::shared_lock<std::shared_mutex> readLock( const_cast<BOARD*>( board )->m_CachesMutex );
|
||||
auto cacheIter = cache.find( this );
|
||||
|
||||
if( cacheIter != cache.end() )
|
||||
return cacheIter->second;
|
||||
|
||||
readLock.unlock();
|
||||
|
||||
// if we get here we need an exclusive lock to cache the entry
|
||||
std::unique_lock<std::shared_mutex> writeLock( const_cast<BOARD*>( board )->m_CachesMutex );
|
||||
|
||||
// check again for the cached item; it might have been computed meanwhile by another thread
|
||||
cacheIter = cache.find( this );
|
||||
if( cacheIter != cache.end() )
|
||||
return cacheIter->second;
|
||||
|
||||
BOX2I bbox = m_Poly->BBox();
|
||||
|
||||
cache[ this ] = bbox;
|
||||
|
||||
return bbox;
|
||||
|
@ -364,11 +375,16 @@ void ZONE::CacheBoundingBox()
|
|||
{
|
||||
BOARD* board = GetBoard();
|
||||
std::unordered_map<const ZONE*, BOX2I>& cache = board->m_ZoneBBoxCache;
|
||||
std::unique_lock<std::mutex> cacheLock( board->m_CachesMutex );
|
||||
std::shared_lock<std::shared_mutex> readLock( board->m_CachesMutex );
|
||||
auto cacheIter = cache.find( this );
|
||||
|
||||
if( cacheIter == cache.end() )
|
||||
cache[ this ] = m_Poly->BBox();
|
||||
if( cacheIter == cache.end() ) {
|
||||
readLock.unlock();
|
||||
std::unique_lock<std::shared_mutex> writeLock(board->m_CachesMutex);
|
||||
// check again in case another thread has already calculated the entry while we were waiting for the exclusive lock
|
||||
if ( cache.count( this ) == 0 )
|
||||
cache[this] = m_Poly->BBox();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue