mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-13 17:53:11 +02:00
Update BS Threadpool to 5.0
This commit is contained in:
parent
2f1a91279f
commit
6e2b20ed0e
@ -277,7 +277,7 @@ void RENDER_3D_RAYTRACE_BASE::renderTracing( uint8_t* ptrPBO, REPORTER* aStatusR
|
||||
BS::multi_future<void> futures;
|
||||
|
||||
for( size_t i = 0; i < tp.get_thread_count(); ++i )
|
||||
futures.push_back( tp.submit( processBlocks ) );
|
||||
futures.push_back( tp.submit_task( processBlocks ) );
|
||||
|
||||
futures.wait();
|
||||
|
||||
|
@ -190,7 +190,7 @@ void DESIGN_BLOCK_LIST_IMPL::loadDesignBlocks()
|
||||
};
|
||||
|
||||
for( size_t ii = 0; ii < num_elements; ++ii )
|
||||
returns[ii] = tp.submit( db_thread );
|
||||
returns[ii] = tp.submit_task( db_thread );
|
||||
|
||||
for( const std::future<size_t>& ret : returns )
|
||||
{
|
||||
|
@ -1614,11 +1614,10 @@ void CONNECTION_GRAPH::resolveAllDrivers()
|
||||
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
|
||||
auto results = tp.parallelize_loop( dirty_graphs.size(),
|
||||
[&]( const int a, const int b)
|
||||
auto results = tp.submit_loop( 0, dirty_graphs.size(),
|
||||
[&]( const int ii )
|
||||
{
|
||||
for( int ii = a; ii < b; ++ii )
|
||||
update_lambda( dirty_graphs[ii] );
|
||||
update_lambda( dirty_graphs[ii] );
|
||||
});
|
||||
results.wait();
|
||||
|
||||
@ -2257,11 +2256,10 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
|
||||
auto results = tp.parallelize_loop( m_driver_subgraphs.size(),
|
||||
[&]( const int a, const int b)
|
||||
auto results = tp.submit_loop( 0, m_driver_subgraphs.size(),
|
||||
[&]( const int ii )
|
||||
{
|
||||
for( int ii = a; ii < b; ++ii )
|
||||
m_driver_subgraphs[ii]->UpdateItemConnections();
|
||||
m_driver_subgraphs[ii]->UpdateItemConnections();
|
||||
});
|
||||
|
||||
results.wait();
|
||||
@ -2464,12 +2462,11 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function<void( SCH_ITEM* )>* a
|
||||
return 1;
|
||||
};
|
||||
|
||||
auto results2 = tp.parallelize_loop( m_driver_subgraphs.size(),
|
||||
[&]( const int a, const int b)
|
||||
auto results2 = tp.submit_loop( 0, m_driver_subgraphs.size(),
|
||||
[&]( const int ii )
|
||||
{
|
||||
for( int ii = a; ii < b; ++ii )
|
||||
updateItemConnectionsTask( m_driver_subgraphs[ii] );
|
||||
});
|
||||
updateItemConnectionsTask( m_driver_subgraphs[ii] );
|
||||
} );
|
||||
results2.wait();
|
||||
|
||||
m_net_code_to_subgraphs_map.clear();
|
||||
|
@ -140,11 +140,10 @@ void SPICE_LIBRARY_PARSER::ReadFile( const wxString& aFilePath, REPORTER& aRepor
|
||||
// Read all self-contained models in parallel
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
|
||||
auto results = tp.parallelize_loop( modelQueue.size(),
|
||||
[&]( const int a, const int b )
|
||||
auto results = tp.submit_loop( 0, modelQueue.size(),
|
||||
[&]( const int ii )
|
||||
{
|
||||
for( int ii = a; ii < b; ++ii )
|
||||
createModel( ii, true );
|
||||
createModel( ii, true );
|
||||
} );
|
||||
results.wait();
|
||||
|
||||
|
@ -110,7 +110,7 @@ public:
|
||||
*/
|
||||
void BuildArgvUtf8();
|
||||
|
||||
BS::thread_pool& GetThreadPool() { return *m_singleton.m_ThreadPool; }
|
||||
BS::thread_pool<0>& GetThreadPool() { return *m_singleton.m_ThreadPool; }
|
||||
|
||||
GL_CONTEXT_MANAGER* GetGLContextManager() { return m_singleton.m_GLContextManager; }
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
class GL_CONTEXT_MANAGER;
|
||||
namespace BS
|
||||
{
|
||||
template <std::uint8_t>
|
||||
class thread_pool;
|
||||
}
|
||||
|
||||
@ -42,7 +43,7 @@ public:
|
||||
void Init();
|
||||
|
||||
public:
|
||||
BS::thread_pool* m_ThreadPool;
|
||||
BS::thread_pool<0>* m_ThreadPool;
|
||||
GL_CONTEXT_MANAGER* m_GLContextManager;
|
||||
};
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
#include <bs_thread_pool.hpp>
|
||||
#include <import_export.h>
|
||||
|
||||
using thread_pool = BS::thread_pool;
|
||||
using thread_pool = BS::thread_pool<0>;
|
||||
|
||||
/**
|
||||
* Get a reference to the current thread pool. N.B., you cannot copy the thread pool
|
||||
|
@ -636,7 +636,11 @@ void PROJECT_TREE_PANE::ReCreateTreePrj()
|
||||
std::lock_guard<std::mutex> lock2( m_gitTreeCacheMutex );
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
|
||||
tp.wait_for_tasks();
|
||||
while( tp.get_tasks_running() )
|
||||
{
|
||||
tp.wait_for( std::chrono::milliseconds( 250 ) );
|
||||
}
|
||||
|
||||
m_gitStatusTimer.Stop();
|
||||
m_gitSyncTimer.Stop();
|
||||
m_gitTreeCache.clear();
|
||||
@ -2293,25 +2297,21 @@ void PROJECT_TREE_PANE::onGitSyncTimer( wxTimerEvent& aEvent )
|
||||
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
|
||||
tp.push_task(
|
||||
[this]()
|
||||
{
|
||||
KIGIT_COMMON* gitCommon = m_TreeProject->GitCommon();
|
||||
tp.submit_task( [this]()
|
||||
{
|
||||
KIGIT_COMMON* gitCommon = m_TreeProject->GitCommon();
|
||||
|
||||
if( !gitCommon )
|
||||
{
|
||||
wxLogTrace( traceGit, "onGitSyncTimer: No git repository found" );
|
||||
return;
|
||||
}
|
||||
if( !gitCommon )
|
||||
{
|
||||
wxLogTrace( traceGit, "onGitSyncTimer: No git repository found" );
|
||||
return;
|
||||
}
|
||||
|
||||
GIT_PULL_HANDLER handler( gitCommon );
|
||||
handler.PerformFetch();
|
||||
GIT_PULL_HANDLER handler( gitCommon );
|
||||
handler.PerformFetch();
|
||||
|
||||
CallAfter( [this]()
|
||||
{
|
||||
gitStatusTimerHandler();
|
||||
} );
|
||||
} );
|
||||
CallAfter( [this]() { gitStatusTimerHandler(); } );
|
||||
} );
|
||||
|
||||
if( gitSettings.updatInterval > 0 )
|
||||
{
|
||||
@ -2327,11 +2327,7 @@ void PROJECT_TREE_PANE::gitStatusTimerHandler()
|
||||
updateTreeCache();
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
|
||||
tp.push_task(
|
||||
[this]()
|
||||
{
|
||||
updateGitStatusIconMap();
|
||||
} );
|
||||
tp.submit_task( [this]() { updateGitStatusIconMap(); } );
|
||||
}
|
||||
|
||||
void PROJECT_TREE_PANE::onGitStatusTimer( wxTimerEvent& aEvent )
|
||||
|
@ -274,5 +274,5 @@ void UPDATE_MANAGER::CheckForUpdate( wxWindow* aNoticeParent )
|
||||
};
|
||||
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
m_updateTask = tp.submit( update_check );
|
||||
m_updateTask = tp.submit_task( update_check );
|
||||
}
|
||||
|
@ -1114,7 +1114,7 @@ void BOARD::CacheTriangulation( PROGRESS_REPORTER* aReporter, const std::vector<
|
||||
};
|
||||
|
||||
for( ZONE* zone : zones )
|
||||
returns.emplace_back( tp.submit( cache_zones, zone ) );
|
||||
returns.emplace_back( tp.submit_task( [cache_zones, zone] { return cache_zones( zone ); } ) );
|
||||
|
||||
// Finalize the triangulation threads
|
||||
for( const std::future<size_t>& ret : returns )
|
||||
|
@ -270,24 +270,21 @@ void CN_CONNECTIVITY_ALGO::searchConnections()
|
||||
{
|
||||
std::vector<std::future<size_t>> returns( dirtyItems.size() );
|
||||
|
||||
auto conn_lambda =
|
||||
[&dirtyItems]( size_t aItem, CN_LIST* aItemList,
|
||||
PROGRESS_REPORTER* aReporter) -> size_t
|
||||
{
|
||||
if( aReporter && aReporter->IsCancelled() )
|
||||
for( size_t ii = 0; ii < dirtyItems.size(); ++ii )
|
||||
{
|
||||
returns[ii] = tp.submit_task(
|
||||
[&dirtyItems, ii, this] () ->size_t {
|
||||
if( m_progressReporter && m_progressReporter->IsCancelled() )
|
||||
return 0;
|
||||
|
||||
CN_VISITOR visitor( dirtyItems[aItem] );
|
||||
aItemList->FindNearby( dirtyItems[aItem], visitor );
|
||||
CN_VISITOR visitor( dirtyItems[ii] );
|
||||
m_itemList.FindNearby( dirtyItems[ii], visitor );
|
||||
|
||||
if( aReporter )
|
||||
aReporter->AdvanceProgress();
|
||||
if( m_progressReporter )
|
||||
m_progressReporter->AdvanceProgress();
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
for( size_t ii = 0; ii < dirtyItems.size(); ++ii )
|
||||
returns[ii] = tp.submit( conn_lambda, ii, &m_itemList, m_progressReporter );
|
||||
return 1; } );
|
||||
}
|
||||
|
||||
for( const std::future<size_t>& ret : returns )
|
||||
{
|
||||
@ -490,7 +487,11 @@ void CN_CONNECTIVITY_ALGO::Build( BOARD* aBoard, PROGRESS_REPORTER* aReporter )
|
||||
};
|
||||
|
||||
for( size_t ii = 0; ii < zitems.size(); ++ii )
|
||||
returns[ii] = tp.submit( cache_zones, zitems[ii] );
|
||||
{
|
||||
CN_ZONE_LAYER* ptr = zitems[ii];
|
||||
returns[ii] = tp.submit_task(
|
||||
[cache_zones, ptr] { return cache_zones( ptr ); } );
|
||||
}
|
||||
|
||||
for( const std::future<size_t>& ret : returns )
|
||||
{
|
||||
|
@ -191,19 +191,17 @@ void CONNECTIVITY_DATA::updateRatsnest()
|
||||
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
|
||||
auto results = tp.parallelize_loop( dirty_nets.size(),
|
||||
[&]( const int a, const int b )
|
||||
auto results = tp.submit_loop( 0, dirty_nets.size(),
|
||||
[&]( const int ii )
|
||||
{
|
||||
for( int ii = a; ii < b; ++ii )
|
||||
dirty_nets[ii]->UpdateNet();
|
||||
dirty_nets[ii]->UpdateNet();
|
||||
} );
|
||||
results.wait();
|
||||
|
||||
auto results2 = tp.parallelize_loop( dirty_nets.size(),
|
||||
[&]( const int a, const int b )
|
||||
auto results2 = tp.submit_loop( 0, dirty_nets.size(),
|
||||
[&]( const int ii )
|
||||
{
|
||||
for( int ii = a; ii < b; ++ii )
|
||||
dirty_nets[ii]->OptimizeRNEdges();
|
||||
dirty_nets[ii]->OptimizeRNEdges();
|
||||
} );
|
||||
results2.wait();
|
||||
|
||||
@ -370,11 +368,10 @@ void CONNECTIVITY_DATA::ComputeLocalRatsnest( const std::vector<BOARD_ITEM*>& aI
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
size_t num_nets = std::min( m_nets.size(), aDynamicData->m_nets.size() );
|
||||
|
||||
auto results = tp.parallelize_loop( 1, num_nets,
|
||||
[&]( const int a, const int b)
|
||||
auto results = tp.submit_loop( 1, num_nets,
|
||||
[&]( const int ii )
|
||||
{
|
||||
for( int ii = a; ii < b; ++ii )
|
||||
update_lambda( ii );
|
||||
update_lambda( ii );
|
||||
});
|
||||
results.wait();
|
||||
|
||||
|
@ -425,7 +425,7 @@ void DIALOG_EXPORT_ODBPP::GenerateODBPPFiles( const JOB_EXPORT_PCB_ODB& aJob, BO
|
||||
};
|
||||
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
auto ret = tp.submit( saveFile );
|
||||
auto ret = tp.submit_task( saveFile );
|
||||
|
||||
std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
|
||||
|
||||
|
@ -158,7 +158,7 @@ bool DRC_CACHE_GENERATOR::Run()
|
||||
|
||||
forEachGeometryItem( itemTypes, boardCopperLayers, countItems );
|
||||
|
||||
std::future<void> retn = tp.submit(
|
||||
std::future<void> retn = tp.submit_task(
|
||||
[&]()
|
||||
{
|
||||
std::unique_lock<std::shared_mutex> writeLock( m_board->m_CachesMutex );
|
||||
@ -225,7 +225,7 @@ bool DRC_CACHE_GENERATOR::Run()
|
||||
};
|
||||
|
||||
for( ZONE* zone : allZones )
|
||||
returns.emplace_back( tp.submit( cache_zones, zone ) );
|
||||
returns.emplace_back( tp.submit_task( [cache_zones, zone] { return cache_zones( zone ); } ) );
|
||||
|
||||
done.store( 1 );
|
||||
|
||||
|
@ -2317,56 +2317,54 @@ void CREEPAGE_GRAPH::GeneratePaths( double aMaxWeight, PCB_LAYER_ID aLayer )
|
||||
}
|
||||
}
|
||||
|
||||
auto processWorkItems = [&]( size_t start_idx, size_t end_idx ) -> bool
|
||||
auto processWorkItems = [&]( size_t idx ) -> bool
|
||||
{
|
||||
for( size_t idx = start_idx; idx < end_idx; ++idx )
|
||||
auto [gn1, gn2] = work_items[idx];
|
||||
|
||||
for( PATH_CONNECTION pc : GetPaths( gn1->m_parent, gn2->m_parent, aMaxWeight ) )
|
||||
{
|
||||
auto [gn1, gn2] = work_items[idx];
|
||||
std::vector<const BOARD_ITEM*> IgnoreForTest = {
|
||||
gn1->m_parent->GetParent(), gn2->m_parent->GetParent()
|
||||
};
|
||||
|
||||
for( PATH_CONNECTION pc : GetPaths( gn1->m_parent, gn2->m_parent, aMaxWeight ) )
|
||||
if( !pc.isValid( m_board, aLayer, m_boardEdge, IgnoreForTest, m_boardOutline,
|
||||
{ false, true }, m_minGrooveWidth ) )
|
||||
continue;
|
||||
|
||||
std::shared_ptr<GRAPH_NODE> connect1 = gn1, connect2 = gn2;
|
||||
std::lock_guard<std::mutex> lock( nodes_lock );
|
||||
|
||||
// Handle non-point node1
|
||||
if( gn1->m_parent->GetType() != CREEP_SHAPE::TYPE::POINT )
|
||||
{
|
||||
std::vector<const BOARD_ITEM*> IgnoreForTest = {
|
||||
gn1->m_parent->GetParent(), gn2->m_parent->GetParent()
|
||||
};
|
||||
auto gnt1 = AddNode( GRAPH_NODE::POINT, gn1->m_parent, pc.a1 );
|
||||
gnt1->m_connectDirectly = false;
|
||||
connect1 = gnt1;
|
||||
|
||||
if( !pc.isValid( m_board, aLayer, m_boardEdge, IgnoreForTest, m_boardOutline,
|
||||
{ false, true }, m_minGrooveWidth ) )
|
||||
continue;
|
||||
|
||||
std::shared_ptr<GRAPH_NODE> connect1 = gn1, connect2 = gn2;
|
||||
std::lock_guard<std::mutex> lock( nodes_lock );
|
||||
|
||||
// Handle non-point node1
|
||||
if( gn1->m_parent->GetType() != CREEP_SHAPE::TYPE::POINT )
|
||||
if( gn1->m_parent->IsConductive() )
|
||||
{
|
||||
auto gnt1 = AddNode( GRAPH_NODE::POINT, gn1->m_parent, pc.a1 );
|
||||
gnt1->m_connectDirectly = false;
|
||||
connect1 = gnt1;
|
||||
|
||||
if( gn1->m_parent->IsConductive() )
|
||||
{
|
||||
if( auto gc = AddConnection( gn1, gnt1 ) )
|
||||
gc->m_path.m_show = false;
|
||||
}
|
||||
if( auto gc = AddConnection( gn1, gnt1 ) )
|
||||
gc->m_path.m_show = false;
|
||||
}
|
||||
|
||||
// Handle non-point node2
|
||||
if( gn2->m_parent->GetType() != CREEP_SHAPE::TYPE::POINT )
|
||||
{
|
||||
auto gnt2 = AddNode( GRAPH_NODE::POINT, gn2->m_parent, pc.a2 );
|
||||
gnt2->m_connectDirectly = false;
|
||||
connect2 = gnt2;
|
||||
|
||||
if( gn2->m_parent->IsConductive() )
|
||||
{
|
||||
if( auto gc = AddConnection( gn2, gnt2 ) )
|
||||
gc->m_path.m_show = false;
|
||||
}
|
||||
}
|
||||
|
||||
AddConnection( connect1, connect2, pc );
|
||||
}
|
||||
|
||||
// Handle non-point node2
|
||||
if( gn2->m_parent->GetType() != CREEP_SHAPE::TYPE::POINT )
|
||||
{
|
||||
auto gnt2 = AddNode( GRAPH_NODE::POINT, gn2->m_parent, pc.a2 );
|
||||
gnt2->m_connectDirectly = false;
|
||||
connect2 = gnt2;
|
||||
|
||||
if( gn2->m_parent->IsConductive() )
|
||||
{
|
||||
if( auto gc = AddConnection( gn2, gnt2 ) )
|
||||
gc->m_path.m_show = false;
|
||||
}
|
||||
}
|
||||
|
||||
AddConnection( connect1, connect2, pc );
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
@ -2374,15 +2372,16 @@ void CREEPAGE_GRAPH::GeneratePaths( double aMaxWeight, PCB_LAYER_ID aLayer )
|
||||
// has already parallelized the work, so we can process all items in one go.
|
||||
if( tp.get_tasks_total() >= tp.get_thread_count() - 4 )
|
||||
{
|
||||
processWorkItems( 0, work_items.size() );
|
||||
for( size_t ii = 0; ii < work_items.size(); ii++ )
|
||||
processWorkItems( ii );
|
||||
}
|
||||
else
|
||||
{
|
||||
auto ret = tp.parallelize_loop( work_items.size(), processWorkItems );
|
||||
auto ret = tp.submit_loop( 0, work_items.size(), processWorkItems );
|
||||
|
||||
for( size_t ii = 0; ii < ret.size(); ii++ )
|
||||
{
|
||||
std::future<bool>& r = ret[ii];
|
||||
auto& r = ret[ii];
|
||||
|
||||
if( !r.valid() )
|
||||
continue;
|
||||
|
@ -505,7 +505,6 @@ bool DRC_TEST_PROVIDER_CONNECTION_WIDTH::Run()
|
||||
}
|
||||
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
std::vector<std::future<size_t>> returns;
|
||||
size_t total_effort = 0;
|
||||
|
||||
for( const auto& [ netLayer, itemsPoly ] : dataset )
|
||||
@ -513,14 +512,16 @@ bool DRC_TEST_PROVIDER_CONNECTION_WIDTH::Run()
|
||||
|
||||
total_effort += std::max( (size_t) 1, total_effort ) * distinctMinWidths.size();
|
||||
|
||||
std::vector<std::future<size_t>> returns;
|
||||
returns.reserve( dataset.size() );
|
||||
|
||||
for( const auto& [ netLayer, itemsPoly ] : dataset )
|
||||
{
|
||||
returns.emplace_back( tp.submit( build_netlayer_polys, netLayer.Netcode, netLayer.Layer ) );
|
||||
int netcode = netLayer.Netcode;
|
||||
PCB_LAYER_ID layer = netLayer.Layer;
|
||||
returns.emplace_back( tp.submit_task( [&, netcode, layer]() { return build_netlayer_polys( netcode, layer ); } ) );
|
||||
}
|
||||
|
||||
for( std::future<size_t>& ret : returns )
|
||||
for( auto& ret : returns )
|
||||
{
|
||||
std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
|
||||
|
||||
@ -541,11 +542,13 @@ bool DRC_TEST_PROVIDER_CONNECTION_WIDTH::Run()
|
||||
if( minWidth - epsilon <= 0 )
|
||||
continue;
|
||||
|
||||
returns.emplace_back( tp.submit( min_checker, itemsPoly, netLayer.Layer, minWidth ) );
|
||||
returns.emplace_back( tp.submit_task( [min_checker, &itemsPoly, &netLayer, minWidth]() {
|
||||
return min_checker( itemsPoly, netLayer.Layer, minWidth );
|
||||
} ) );
|
||||
}
|
||||
}
|
||||
|
||||
for( std::future<size_t>& ret : returns )
|
||||
for( auto& ret : returns )
|
||||
{
|
||||
std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
|
||||
|
||||
|
@ -594,115 +594,112 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances()
|
||||
|
||||
LSET boardCopperLayers = LSET::AllCuMask( m_board->GetCopperLayerCount() );
|
||||
|
||||
auto testTrack = [&]( const int start_idx, const int end_idx )
|
||||
auto testTrack = [&]( const int trackIdx )
|
||||
{
|
||||
for( int trackIdx = start_idx; trackIdx < end_idx; ++trackIdx )
|
||||
PCB_TRACK* track = m_board->Tracks()[trackIdx];
|
||||
|
||||
for( PCB_LAYER_ID layer : LSET( track->GetLayerSet() & boardCopperLayers ) )
|
||||
{
|
||||
PCB_TRACK* track = m_board->Tracks()[trackIdx];
|
||||
std::shared_ptr<SHAPE> trackShape = track->GetEffectiveShape( layer );
|
||||
|
||||
for( PCB_LAYER_ID layer : LSET( track->GetLayerSet() & boardCopperLayers ) )
|
||||
m_board->m_CopperItemRTreeCache->QueryColliding( track, layer, layer,
|
||||
// Filter:
|
||||
[&]( BOARD_ITEM* other ) -> bool
|
||||
{
|
||||
BOARD_CONNECTED_ITEM* otherCItem = dynamic_cast<BOARD_CONNECTED_ITEM*>( other );
|
||||
|
||||
if( otherCItem && otherCItem->GetNetCode() == track->GetNetCode() )
|
||||
return false;
|
||||
|
||||
BOARD_ITEM* a = track;
|
||||
BOARD_ITEM* b = other;
|
||||
|
||||
// store canonical order so we don't collide in both directions
|
||||
// (a:b and b:a)
|
||||
if( static_cast<void*>( a ) > static_cast<void*>( b ) )
|
||||
std::swap( a, b );
|
||||
|
||||
std::lock_guard<std::mutex> lock( checkedPairsMutex );
|
||||
auto it = checkedPairs.find( { a, b } );
|
||||
|
||||
if( it != checkedPairs.end()
|
||||
&& ( it->second.layers.test( layer ) || ( it->second.has_error ) ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
checkedPairs[ { a, b } ].layers.set( layer );
|
||||
return true;
|
||||
}
|
||||
},
|
||||
// Visitor:
|
||||
[&]( BOARD_ITEM* other ) -> bool
|
||||
{
|
||||
if( m_drcEngine->IsCancelled() )
|
||||
return false;
|
||||
|
||||
if( other->Type() == PCB_PAD_T && static_cast<PAD*>( other )->IsFreePad() )
|
||||
{
|
||||
if( other->GetEffectiveShape( layer )->Collide( trackShape.get() ) )
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( freePadsUsageMapMutex );
|
||||
auto it = freePadsUsageMap.find( other );
|
||||
|
||||
if( it == freePadsUsageMap.end() )
|
||||
{
|
||||
freePadsUsageMap[ other ] = track->GetNetCode();
|
||||
return true; // Continue colliding tests
|
||||
}
|
||||
else if( it->second == track->GetNetCode() )
|
||||
{
|
||||
return true; // Continue colliding tests
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we get an error, mark the pair as having a clearance error already
|
||||
if( !testSingleLayerItemAgainstItem( track, trackShape.get(), layer, other ) )
|
||||
{
|
||||
if( !m_drcEngine->GetReportAllTrackErrors() )
|
||||
{
|
||||
BOARD_ITEM* a = track;
|
||||
BOARD_ITEM* b = other;
|
||||
|
||||
// store canonical order so we don't collide in both directions
|
||||
// (a:b and b:a)
|
||||
if( static_cast<void*>( a ) > static_cast<void*>( b ) )
|
||||
std::swap( a, b );
|
||||
|
||||
std::lock_guard<std::mutex> lock( checkedPairsMutex );
|
||||
auto it = checkedPairs.find( { a, b } );
|
||||
|
||||
if( it != checkedPairs.end() )
|
||||
it->second.has_error = true;
|
||||
|
||||
return false; // We're done with this track
|
||||
}
|
||||
}
|
||||
|
||||
return !m_drcEngine->IsCancelled();
|
||||
},
|
||||
m_board->m_DRCMaxClearance );
|
||||
|
||||
for( ZONE* zone : m_board->m_DRCCopperZones )
|
||||
{
|
||||
std::shared_ptr<SHAPE> trackShape = track->GetEffectiveShape( layer );
|
||||
testItemAgainstZone( track, zone, layer );
|
||||
|
||||
m_board->m_CopperItemRTreeCache->QueryColliding( track, layer, layer,
|
||||
// Filter:
|
||||
[&]( BOARD_ITEM* other ) -> bool
|
||||
{
|
||||
BOARD_CONNECTED_ITEM* otherCItem = dynamic_cast<BOARD_CONNECTED_ITEM*>( other );
|
||||
|
||||
if( otherCItem && otherCItem->GetNetCode() == track->GetNetCode() )
|
||||
return false;
|
||||
|
||||
BOARD_ITEM* a = track;
|
||||
BOARD_ITEM* b = other;
|
||||
|
||||
// store canonical order so we don't collide in both directions
|
||||
// (a:b and b:a)
|
||||
if( static_cast<void*>( a ) > static_cast<void*>( b ) )
|
||||
std::swap( a, b );
|
||||
|
||||
std::lock_guard<std::mutex> lock( checkedPairsMutex );
|
||||
auto it = checkedPairs.find( { a, b } );
|
||||
|
||||
if( it != checkedPairs.end()
|
||||
&& ( it->second.layers.test( layer ) || ( it->second.has_error ) ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
checkedPairs[ { a, b } ].layers.set( layer );
|
||||
return true;
|
||||
}
|
||||
},
|
||||
// Visitor:
|
||||
[&]( BOARD_ITEM* other ) -> bool
|
||||
{
|
||||
if( m_drcEngine->IsCancelled() )
|
||||
return false;
|
||||
|
||||
if( other->Type() == PCB_PAD_T && static_cast<PAD*>( other )->IsFreePad() )
|
||||
{
|
||||
if( other->GetEffectiveShape( layer )->Collide( trackShape.get() ) )
|
||||
{
|
||||
std::lock_guard<std::mutex> lock( freePadsUsageMapMutex );
|
||||
auto it = freePadsUsageMap.find( other );
|
||||
|
||||
if( it == freePadsUsageMap.end() )
|
||||
{
|
||||
freePadsUsageMap[ other ] = track->GetNetCode();
|
||||
return true; // Continue colliding tests
|
||||
}
|
||||
else if( it->second == track->GetNetCode() )
|
||||
{
|
||||
return true; // Continue colliding tests
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we get an error, mark the pair as having a clearance error already
|
||||
if( !testSingleLayerItemAgainstItem( track, trackShape.get(), layer, other ) )
|
||||
{
|
||||
if( !m_drcEngine->GetReportAllTrackErrors() )
|
||||
{
|
||||
BOARD_ITEM* a = track;
|
||||
BOARD_ITEM* b = other;
|
||||
|
||||
// store canonical order so we don't collide in both directions
|
||||
// (a:b and b:a)
|
||||
if( static_cast<void*>( a ) > static_cast<void*>( b ) )
|
||||
std::swap( a, b );
|
||||
|
||||
std::lock_guard<std::mutex> lock( checkedPairsMutex );
|
||||
auto it = checkedPairs.find( { a, b } );
|
||||
|
||||
if( it != checkedPairs.end() )
|
||||
it->second.has_error = true;
|
||||
|
||||
return false; // We're done with this track
|
||||
}
|
||||
}
|
||||
|
||||
return !m_drcEngine->IsCancelled();
|
||||
},
|
||||
m_board->m_DRCMaxClearance );
|
||||
|
||||
for( ZONE* zone : m_board->m_DRCCopperZones )
|
||||
{
|
||||
testItemAgainstZone( track, zone, layer );
|
||||
|
||||
if( m_drcEngine->IsCancelled() )
|
||||
break;
|
||||
}
|
||||
if( m_drcEngine->IsCancelled() )
|
||||
break;
|
||||
}
|
||||
|
||||
done.fetch_add( 1 );
|
||||
}
|
||||
|
||||
done.fetch_add( 1 );
|
||||
};
|
||||
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
|
||||
tp.push_loop( m_board->Tracks().size(), testTrack );
|
||||
auto track_futures = tp.submit_loop( 0, m_board->Tracks().size(), testTrack );
|
||||
|
||||
while( done < count )
|
||||
{
|
||||
@ -710,7 +707,8 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testTrackClearances()
|
||||
|
||||
if( m_drcEngine->IsCancelled() )
|
||||
{
|
||||
tp.wait_for_tasks();
|
||||
// Wait for the submitted loop tasks to finish
|
||||
track_futures.wait();
|
||||
break;
|
||||
}
|
||||
|
||||
@ -967,82 +965,79 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testPadClearances( )
|
||||
|
||||
LSET boardCopperLayers = LSET::AllCuMask( m_board->GetCopperLayerCount() );
|
||||
|
||||
const auto fp_check = [&]( size_t aFromIdx, size_t aToIdx )
|
||||
const auto fp_check = [&]( size_t ii )
|
||||
{
|
||||
for( size_t ii = aFromIdx; ii < aToIdx; ++ii )
|
||||
FOOTPRINT* footprint = m_board->Footprints()[ ii ];
|
||||
|
||||
for( PAD* pad : footprint->Pads() )
|
||||
{
|
||||
FOOTPRINT* footprint = m_board->Footprints()[ ii ];
|
||||
|
||||
for( PAD* pad : footprint->Pads() )
|
||||
for( PCB_LAYER_ID layer : LSET( pad->GetLayerSet() & boardCopperLayers ) )
|
||||
{
|
||||
for( PCB_LAYER_ID layer : LSET( pad->GetLayerSet() & boardCopperLayers ) )
|
||||
{
|
||||
if( m_drcEngine->IsCancelled() )
|
||||
return;
|
||||
if( m_drcEngine->IsCancelled() )
|
||||
return;
|
||||
|
||||
std::shared_ptr<SHAPE> padShape = pad->GetEffectiveShape( layer );
|
||||
std::shared_ptr<SHAPE> padShape = pad->GetEffectiveShape( layer );
|
||||
|
||||
m_board->m_CopperItemRTreeCache->QueryColliding( pad, layer, layer,
|
||||
// Filter:
|
||||
[&]( BOARD_ITEM* other ) -> bool
|
||||
m_board->m_CopperItemRTreeCache->QueryColliding( pad, layer, layer,
|
||||
// Filter:
|
||||
[&]( BOARD_ITEM* other ) -> bool
|
||||
{
|
||||
BOARD_ITEM* a = pad;
|
||||
BOARD_ITEM* b = other;
|
||||
|
||||
// store canonical order so we don't collide in both
|
||||
// directions (a:b and b:a)
|
||||
if( static_cast<void*>( a ) > static_cast<void*>( b ) )
|
||||
std::swap( a, b );
|
||||
|
||||
std::lock_guard<std::mutex> lock( checkedPairsMutex );
|
||||
auto it = checkedPairs.find( { a, b } );
|
||||
|
||||
if( it != checkedPairs.end()
|
||||
&& ( it->second.layers.test( layer ) || it->second.has_error ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
checkedPairs[ { a, b } ].layers.set( layer );
|
||||
return true;
|
||||
}
|
||||
},
|
||||
// Visitor
|
||||
[&]( BOARD_ITEM* other ) -> bool
|
||||
{
|
||||
if( !testPadAgainstItem( pad, padShape.get(), layer, other ) )
|
||||
{
|
||||
BOARD_ITEM* a = pad;
|
||||
BOARD_ITEM* b = other;
|
||||
|
||||
// store canonical order so we don't collide in both
|
||||
// directions (a:b and b:a)
|
||||
if( static_cast<void*>( a ) > static_cast<void*>( b ) )
|
||||
std::swap( a, b );
|
||||
|
||||
std::lock_guard<std::mutex> lock( checkedPairsMutex );
|
||||
auto it = checkedPairs.find( { a, b } );
|
||||
|
||||
if( it != checkedPairs.end()
|
||||
&& ( it->second.layers.test( layer ) || it->second.has_error ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
checkedPairs[ { a, b } ].layers.set( layer );
|
||||
return true;
|
||||
}
|
||||
},
|
||||
// Visitor
|
||||
[&]( BOARD_ITEM* other ) -> bool
|
||||
{
|
||||
if( !testPadAgainstItem( pad, padShape.get(), layer, other ) )
|
||||
{
|
||||
BOARD_ITEM* a = pad;
|
||||
BOARD_ITEM* b = other;
|
||||
if( it != checkedPairs.end() )
|
||||
it->second.has_error = true;
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock( checkedPairsMutex );
|
||||
auto it = checkedPairs.find( { a, b } );
|
||||
return !m_drcEngine->IsCancelled();
|
||||
},
|
||||
m_board->m_DRCMaxClearance );
|
||||
|
||||
if( it != checkedPairs.end() )
|
||||
it->second.has_error = true;
|
||||
}
|
||||
for( ZONE* zone : m_board->m_DRCCopperZones )
|
||||
{
|
||||
testItemAgainstZone( pad, zone, layer );
|
||||
|
||||
return !m_drcEngine->IsCancelled();
|
||||
},
|
||||
m_board->m_DRCMaxClearance );
|
||||
|
||||
for( ZONE* zone : m_board->m_DRCCopperZones )
|
||||
{
|
||||
testItemAgainstZone( pad, zone, layer );
|
||||
|
||||
if( m_drcEngine->IsCancelled() )
|
||||
return;
|
||||
}
|
||||
if( m_drcEngine->IsCancelled() )
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
done.fetch_add( 1 );
|
||||
}
|
||||
|
||||
done.fetch_add( 1 );
|
||||
};
|
||||
|
||||
size_t numFootprints = m_board->Footprints().size();
|
||||
auto returns = tp.parallelize_loop( numFootprints, fp_check );
|
||||
auto returns = tp.submit_loop( 0, numFootprints, fp_check );
|
||||
|
||||
// Wait for all threads to finish
|
||||
for( size_t ii = 0; ii < returns.size(); ++ii )
|
||||
@ -1152,7 +1147,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testGraphicClearances()
|
||||
m_board->m_DRCMaxClearance );
|
||||
};
|
||||
|
||||
std::future<void> retn = tp.submit(
|
||||
std::future<void> retn = tp.submit_task(
|
||||
[&]()
|
||||
{
|
||||
for( BOARD_ITEM* item : m_board->Drawings() )
|
||||
@ -1370,7 +1365,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
|
||||
continue;
|
||||
|
||||
count++;
|
||||
tp.push_task( checkZones, ia, ia2, sameNet, layer );
|
||||
tp.submit_task( [checkZones, ia, ia2, sameNet, layer]() { checkZones(ia, ia2, sameNet, layer); } );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1382,7 +1377,7 @@ void DRC_TEST_PROVIDER_COPPER_CLEARANCE::testZonesToZones()
|
||||
if( m_drcEngine->IsCancelled() )
|
||||
break;
|
||||
|
||||
if( tp.wait_for_tasks_duration( std::chrono::milliseconds( 250 ) ) )
|
||||
if( tp.wait_for( std::chrono::milliseconds( 250 ) ) )
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -110,11 +110,11 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
|
||||
}
|
||||
|
||||
auto query_areas =
|
||||
[&]( std::pair<ZONE* /* rule area */, ZONE* /* copper zone */> areaZonePair ) -> size_t
|
||||
[&]( const int idx ) -> size_t
|
||||
{
|
||||
if( m_drcEngine->IsCancelled() )
|
||||
return 0;
|
||||
|
||||
const auto& areaZonePair = toCache[idx];
|
||||
ZONE* ruleArea = areaZonePair.first;
|
||||
ZONE* copperZone = areaZonePair.second;
|
||||
BOX2I areaBBox = ruleArea->GetBoundingBox();
|
||||
@ -169,14 +169,9 @@ bool DRC_TEST_PROVIDER_DISALLOW::Run()
|
||||
};
|
||||
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
std::vector<std::future<size_t>> returns;
|
||||
auto futures = tp.submit_loop( 0, toCache.size(), query_areas );
|
||||
|
||||
returns.reserve( toCache.size() );
|
||||
|
||||
for( const std::pair<ZONE*, ZONE*>& areaZonePair : toCache )
|
||||
returns.emplace_back( tp.submit( query_areas, areaZonePair ) );
|
||||
|
||||
for( const std::future<size_t>& ret : returns )
|
||||
for( auto& ret : futures )
|
||||
{
|
||||
std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
|
||||
|
||||
|
@ -149,14 +149,10 @@ bool DRC_TEST_PROVIDER_SLIVER_CHECKER::Run()
|
||||
};
|
||||
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
std::vector<std::future<size_t>> returns;
|
||||
|
||||
returns.reserve( copperLayers.size() );
|
||||
auto returns = tp.submit_loop( 0, copperLayers.size(), build_layer_polys );
|
||||
|
||||
for( size_t ii = 0; ii < copperLayers.size(); ++ii )
|
||||
returns.emplace_back( tp.submit( build_layer_polys, ii ) );
|
||||
|
||||
for( const std::future<size_t>& ret : returns )
|
||||
for( auto& ret : returns )
|
||||
{
|
||||
std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
|
||||
|
||||
|
@ -737,50 +737,47 @@ void DRC_TEST_PROVIDER_SOLDER_MASK::testMaskBridges()
|
||||
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
|
||||
auto returns = tp.parallelize_loop( test_items.size(), [&]( size_t a, size_t b ) -> bool
|
||||
auto returns = tp.submit_loop( 0, test_items.size(), [&]( size_t i ) -> bool
|
||||
{
|
||||
BOARD_ITEM* item = test_items[ i ];
|
||||
|
||||
if( m_drcEngine->IsErrorLimitExceeded( DRCE_SOLDERMASK_BRIDGE ) )
|
||||
return false;
|
||||
|
||||
BOX2I itemBBox = item->GetBoundingBox();
|
||||
|
||||
if( item->IsOnLayer( F_Mask ) && !isNullAperture( item ) )
|
||||
{
|
||||
for( size_t i = a; i < b; ++i )
|
||||
{
|
||||
BOARD_ITEM* item = test_items[ i ];
|
||||
// Test for aperture-to-aperture collisions
|
||||
testItemAgainstItems( item, itemBBox, F_Mask, F_Mask );
|
||||
|
||||
if( m_drcEngine->IsErrorLimitExceeded( DRCE_SOLDERMASK_BRIDGE ) )
|
||||
return false;
|
||||
// Test for aperture-to-zone collisions
|
||||
testMaskItemAgainstZones( item, itemBBox, F_Mask, F_Cu );
|
||||
}
|
||||
else if( item->IsOnLayer( PADSTACK::ALL_LAYERS ) )
|
||||
{
|
||||
// Test for copper-item-to-aperture collisions
|
||||
testItemAgainstItems( item, itemBBox, F_Cu, F_Mask );
|
||||
}
|
||||
|
||||
BOX2I itemBBox = item->GetBoundingBox();
|
||||
if( item->IsOnLayer( B_Mask ) && !isNullAperture( item ) )
|
||||
{
|
||||
// Test for aperture-to-aperture collisions
|
||||
testItemAgainstItems( item, itemBBox, B_Mask, B_Mask );
|
||||
|
||||
if( item->IsOnLayer( F_Mask ) && !isNullAperture( item ) )
|
||||
{
|
||||
// Test for aperture-to-aperture collisions
|
||||
testItemAgainstItems( item, itemBBox, F_Mask, F_Mask );
|
||||
// Test for aperture-to-zone collisions
|
||||
testMaskItemAgainstZones( item, itemBBox, B_Mask, B_Cu );
|
||||
}
|
||||
else if( item->IsOnLayer( B_Cu ) )
|
||||
{
|
||||
// Test for copper-item-to-aperture collisions
|
||||
testItemAgainstItems( item, itemBBox, B_Cu, B_Mask );
|
||||
}
|
||||
|
||||
// Test for aperture-to-zone collisions
|
||||
testMaskItemAgainstZones( item, itemBBox, F_Mask, F_Cu );
|
||||
}
|
||||
else if( item->IsOnLayer( PADSTACK::ALL_LAYERS ) )
|
||||
{
|
||||
// Test for copper-item-to-aperture collisions
|
||||
testItemAgainstItems( item, itemBBox, F_Cu, F_Mask );
|
||||
}
|
||||
++count;
|
||||
|
||||
if( item->IsOnLayer( B_Mask ) && !isNullAperture( item ) )
|
||||
{
|
||||
// Test for aperture-to-aperture collisions
|
||||
testItemAgainstItems( item, itemBBox, B_Mask, B_Mask );
|
||||
|
||||
// Test for aperture-to-zone collisions
|
||||
testMaskItemAgainstZones( item, itemBBox, B_Mask, B_Cu );
|
||||
}
|
||||
else if( item->IsOnLayer( B_Cu ) )
|
||||
{
|
||||
// Test for copper-item-to-aperture collisions
|
||||
testItemAgainstItems( item, itemBBox, B_Cu, B_Mask );
|
||||
}
|
||||
|
||||
++count;
|
||||
}
|
||||
|
||||
return true;
|
||||
} );
|
||||
return true;
|
||||
} );
|
||||
|
||||
for( size_t i = 0; i < returns.size(); ++i )
|
||||
{
|
||||
|
@ -70,13 +70,15 @@ bool DRC_TEST_PROVIDER_TRACK_ANGLE::Run()
|
||||
return false; // DRC cancelled
|
||||
|
||||
auto checkTrackAngle =
|
||||
[&]( PCB_TRACK* item ) -> bool
|
||||
[&]( const int ind ) -> bool
|
||||
{
|
||||
if( m_drcEngine->IsErrorLimitExceeded( DRCE_TRACK_ANGLE ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
PCB_TRACK* item = m_drcEngine->GetBoard()->Tracks()[ind];
|
||||
|
||||
if( item->Type() != PCB_TRACE_T )
|
||||
{
|
||||
return true;
|
||||
@ -195,17 +197,10 @@ bool DRC_TEST_PROVIDER_TRACK_ANGLE::Run()
|
||||
const int progressDelta = 250;
|
||||
int ii = 0;
|
||||
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
std::vector<std::future<bool>> returns;
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
auto futures = tp.submit_loop( 0, m_drcEngine->GetBoard()->Tracks().size(), checkTrackAngle );
|
||||
|
||||
returns.reserve( m_drcEngine->GetBoard()->Tracks().size() );
|
||||
|
||||
for( PCB_TRACK* item : m_drcEngine->GetBoard()->Tracks() )
|
||||
{
|
||||
returns.emplace_back( tp.submit( checkTrackAngle, item ) );
|
||||
}
|
||||
|
||||
for( std::future<bool>& ret : returns )
|
||||
for( auto& ret : futures )
|
||||
{
|
||||
std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
|
||||
|
||||
|
@ -67,8 +67,9 @@ bool DRC_TEST_PROVIDER_TRACK_SEGMENT_LENGTH::Run()
|
||||
return false; // DRC cancelled
|
||||
|
||||
auto checkTrackSegmentLength =
|
||||
[&]( BOARD_ITEM* item ) -> bool
|
||||
[&]( const int idx ) -> bool
|
||||
{
|
||||
BOARD_ITEM* item = m_drcEngine->GetBoard()->Tracks()[idx];
|
||||
if( m_drcEngine->IsErrorLimitExceeded( DRCE_TRACK_SEGMENT_LENGTH ) )
|
||||
return false;
|
||||
|
||||
@ -153,16 +154,9 @@ bool DRC_TEST_PROVIDER_TRACK_SEGMENT_LENGTH::Run()
|
||||
int ii = 0;
|
||||
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
std::vector<std::future<bool>> returns;
|
||||
auto futures = tp.submit_loop( 0, m_drcEngine->GetBoard()->Tracks().size(), checkTrackSegmentLength );
|
||||
|
||||
returns.reserve( m_drcEngine->GetBoard()->Tracks().size() );
|
||||
|
||||
for( PCB_TRACK* item : m_drcEngine->GetBoard()->Tracks() )
|
||||
{
|
||||
returns.emplace_back( tp.submit( checkTrackSegmentLength, item ) );
|
||||
}
|
||||
|
||||
for( std::future<bool>& ret : returns )
|
||||
for( auto& ret : futures )
|
||||
{
|
||||
std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
|
||||
|
||||
|
@ -319,27 +319,17 @@ bool DRC_TEST_PROVIDER_ZONE_CONNECTIONS::Run()
|
||||
total_effort = std::max( (size_t) 1, total_effort );
|
||||
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
std::vector<std::future<int>> returns;
|
||||
auto returns = tp.submit_loop( 0, zoneLayers.size(),
|
||||
[&]( const int ii )
|
||||
{
|
||||
if( !m_drcEngine->IsCancelled() )
|
||||
{
|
||||
testZoneLayer( zoneLayers[ii].first, zoneLayers[ii].second );
|
||||
done.fetch_add( zoneLayers[ii].first->GetFilledPolysList( zoneLayers[ii].second )->FullPointCount() );
|
||||
}
|
||||
} );
|
||||
|
||||
returns.reserve( zoneLayers.size() );
|
||||
|
||||
for( const std::pair<ZONE*, PCB_LAYER_ID>& zonelayer : zoneLayers )
|
||||
{
|
||||
returns.emplace_back( tp.submit(
|
||||
[&]( ZONE* aZone, PCB_LAYER_ID aLayer ) -> int
|
||||
{
|
||||
if( !m_drcEngine->IsCancelled() )
|
||||
{
|
||||
testZoneLayer( aZone, aLayer );
|
||||
done.fetch_add( aZone->GetFilledPolysList( aLayer )->FullPointCount() );
|
||||
}
|
||||
|
||||
return 0;
|
||||
},
|
||||
zonelayer.first, zonelayer.second ) );
|
||||
}
|
||||
|
||||
for( const std::future<int>& ret : returns )
|
||||
for( auto& ret : returns )
|
||||
{
|
||||
std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
|
||||
|
||||
|
@ -2026,76 +2026,73 @@ bool STEP_PCB_MODEL::CreatePCB( SHAPE_POLY_SET& aOutline, const VECTOR2D& aOrigi
|
||||
{
|
||||
std::mutex mutex;
|
||||
|
||||
auto subtractLoopFn = [&]( const int a, const int b )
|
||||
auto subtractLoopFn = [&]( const int shapeId )
|
||||
{
|
||||
for( int shapeId = a; shapeId < b; shapeId++ )
|
||||
TopoDS_Shape& shape = vec[shapeId];
|
||||
|
||||
Bnd_Box shapeBbox;
|
||||
BRepBndLib::Add( shape, shapeBbox );
|
||||
|
||||
TopTools_ListOfShape holelist;
|
||||
|
||||
{
|
||||
TopoDS_Shape& shape = vec[shapeId];
|
||||
std::unique_lock lock( mutex );
|
||||
|
||||
Bnd_Box shapeBbox;
|
||||
BRepBndLib::Add( shape, shapeBbox );
|
||||
const TColStd_ListOfInteger& indices = aBSBHoles.Compare( shapeBbox );
|
||||
|
||||
TopTools_ListOfShape holelist;
|
||||
|
||||
{
|
||||
std::unique_lock lock( mutex );
|
||||
|
||||
const TColStd_ListOfInteger& indices = aBSBHoles.Compare( shapeBbox );
|
||||
|
||||
for( const Standard_Integer& index : indices )
|
||||
holelist.Append( aHolesList[index] );
|
||||
}
|
||||
|
||||
if( holelist.IsEmpty() )
|
||||
continue;
|
||||
|
||||
TopTools_ListOfShape cutArgs;
|
||||
cutArgs.Append( shape );
|
||||
|
||||
BRepAlgoAPI_Cut cut;
|
||||
|
||||
cut.SetRunParallel( true );
|
||||
cut.SetToFillHistory( false );
|
||||
|
||||
cut.SetArguments( cutArgs );
|
||||
cut.SetTools( holelist );
|
||||
cut.Build();
|
||||
|
||||
if( cut.HasErrors() || cut.HasWarnings() )
|
||||
{
|
||||
m_reporter->Report( wxString::Format( _( "** Got problems while cutting "
|
||||
"%s net '%s' **" ),
|
||||
aWhat,
|
||||
UnescapeString( netname ) ),
|
||||
RPT_SEVERITY_ERROR );
|
||||
shapeBbox.Dump();
|
||||
|
||||
if( cut.HasErrors() )
|
||||
{
|
||||
wxString msg = _( "Errors:\n" );
|
||||
wxStringOutputStream os_stream( &msg );
|
||||
wxStdOutputStream out( os_stream );
|
||||
|
||||
cut.DumpErrors( out );
|
||||
m_reporter->Report( msg, RPT_SEVERITY_ERROR );
|
||||
}
|
||||
|
||||
if( cut.HasWarnings() )
|
||||
{
|
||||
wxString msg = _( "Warnings:\n" );
|
||||
wxStringOutputStream os_stream( &msg );
|
||||
wxStdOutputStream out( os_stream );
|
||||
|
||||
cut.DumpWarnings( out );
|
||||
m_reporter->Report( msg, RPT_SEVERITY_WARNING );
|
||||
}
|
||||
}
|
||||
|
||||
shape = cut.Shape();
|
||||
for( const Standard_Integer& index : indices )
|
||||
holelist.Append( aHolesList[index] );
|
||||
}
|
||||
|
||||
if( holelist.IsEmpty() )
|
||||
return; // nothing to cut for this shape
|
||||
|
||||
TopTools_ListOfShape cutArgs;
|
||||
cutArgs.Append( shape );
|
||||
|
||||
BRepAlgoAPI_Cut cut;
|
||||
|
||||
cut.SetRunParallel( true );
|
||||
cut.SetToFillHistory( false );
|
||||
|
||||
cut.SetArguments( cutArgs );
|
||||
cut.SetTools( holelist );
|
||||
cut.Build();
|
||||
|
||||
if( cut.HasErrors() || cut.HasWarnings() )
|
||||
{
|
||||
m_reporter->Report( wxString::Format( _( "** Got problems while cutting "
|
||||
"%s net '%s' **" ),
|
||||
aWhat,
|
||||
UnescapeString( netname ) ),
|
||||
RPT_SEVERITY_ERROR );
|
||||
shapeBbox.Dump();
|
||||
|
||||
if( cut.HasErrors() )
|
||||
{
|
||||
wxString msg = _( "Errors:\n" );
|
||||
wxStringOutputStream os_stream( &msg );
|
||||
wxStdOutputStream out( os_stream );
|
||||
|
||||
cut.DumpErrors( out );
|
||||
m_reporter->Report( msg, RPT_SEVERITY_ERROR );
|
||||
}
|
||||
|
||||
if( cut.HasWarnings() )
|
||||
{
|
||||
wxString msg = _( "Warnings:\n" );
|
||||
wxStringOutputStream os_stream( &msg );
|
||||
wxStdOutputStream out( os_stream );
|
||||
|
||||
cut.DumpWarnings( out );
|
||||
m_reporter->Report( msg, RPT_SEVERITY_WARNING );
|
||||
}
|
||||
}
|
||||
|
||||
shape = cut.Shape();
|
||||
};
|
||||
|
||||
tp.parallelize_loop( vec.size(), subtractLoopFn ).wait();
|
||||
tp.submit_loop( 0, vec.size(), subtractLoopFn ).wait();
|
||||
}
|
||||
};
|
||||
|
||||
@ -2172,7 +2169,7 @@ bool STEP_PCB_MODEL::CreatePCB( SHAPE_POLY_SET& aOutline, const VECTOR2D& aOrigi
|
||||
BS::multi_future<void> mf;
|
||||
|
||||
for( const auto& [netname, _] : shapesToFuseMap )
|
||||
mf.push_back( tp.submit( fuseLoopFn, netname ) );
|
||||
mf.push_back( tp.submit_task( [&, netname]() { fuseLoopFn( netname ); } ) );
|
||||
|
||||
mf.wait();
|
||||
}
|
||||
|
@ -207,7 +207,7 @@ void FOOTPRINT_LIST_IMPL::loadFootprints()
|
||||
};
|
||||
|
||||
for( size_t ii = 0; ii < num_elements; ++ii )
|
||||
returns[ii] = tp.submit( fp_thread );
|
||||
returns[ii] = tp.submit_task( fp_thread );
|
||||
|
||||
for( const std::future<size_t>& ret : returns )
|
||||
{
|
||||
|
@ -581,7 +581,7 @@ void TRACKS_CLEANER::cleanup( bool aDeleteDuplicateVias, bool aDeleteNullSegment
|
||||
// and extract all of the pairs of segments that might be merged. Then, perform
|
||||
// the actual merge in the main loop.
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
auto merge_returns = tp.parallelize_loop( 0, m_brd->Tracks().size(), track_loop );
|
||||
auto merge_returns = tp.submit_blocks( 0, m_brd->Tracks().size(), track_loop );
|
||||
bool retval = false;
|
||||
|
||||
for( size_t ii = 0; ii < merge_returns.size(); ++ii )
|
||||
|
@ -654,49 +654,46 @@ PCB_NET_INSPECTOR_PANEL::calculateNets( const std::vector<NETINFO_ITEM*>& aNetCo
|
||||
std::mutex resultsMutex;
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
|
||||
auto resultsFuture = tp.parallelize_loop(
|
||||
0, foundNets.size(),
|
||||
[&, this, calc]( const int start, const int end )
|
||||
auto resultsFuture = tp.submit_loop(
|
||||
0, foundNets.size(),
|
||||
[&, this, calc]( const int i )
|
||||
{
|
||||
int netCode = foundNets[i]->GetNetCode();
|
||||
|
||||
constexpr PATH_OPTIMISATIONS opts = { .OptimiseViaLayers = true,
|
||||
.MergeTracks = true,
|
||||
.OptimiseTracesInPads = true,
|
||||
.InferViaInPad = false };
|
||||
|
||||
LENGTH_DELAY_STATS lengthDetails = calc->CalculateLengthDetails(
|
||||
netItemsMap[netCode],
|
||||
opts,
|
||||
nullptr,
|
||||
nullptr,
|
||||
LENGTH_DELAY_LAYER_OPT::WITH_LAYER_DETAIL,
|
||||
m_showTimeDomainDetails ? LENGTH_DELAY_DOMAIN_OPT::WITH_DELAY_DETAIL
|
||||
: LENGTH_DELAY_DOMAIN_OPT::NO_DELAY_DETAIL );
|
||||
|
||||
if( aIncludeZeroPadNets || lengthDetails.NumPads > 0 )
|
||||
{
|
||||
for( int i = start; i < end; ++i )
|
||||
{
|
||||
int netCode = foundNets[i]->GetNetCode();
|
||||
std::unique_ptr<LIST_ITEM> new_item = std::make_unique<LIST_ITEM>( foundNets[i] );
|
||||
|
||||
constexpr PATH_OPTIMISATIONS opts = { .OptimiseViaLayers = true,
|
||||
.MergeTracks = true,
|
||||
.OptimiseTracesInPads = true,
|
||||
.InferViaInPad = false };
|
||||
new_item->SetPadCount( lengthDetails.NumPads );
|
||||
new_item->SetLayerCount( m_board->GetCopperLayerCount() );
|
||||
new_item->SetPadDieLength( lengthDetails.PadToDieLength );
|
||||
new_item->SetPadDieDelay( lengthDetails.PadToDieDelay );
|
||||
new_item->SetViaCount( lengthDetails.NumVias );
|
||||
new_item->SetViaLength( lengthDetails.ViaLength );
|
||||
new_item->SetViaDelay( lengthDetails.ViaDelay );
|
||||
new_item->SetLayerWireLengths( *lengthDetails.LayerLengths );
|
||||
|
||||
LENGTH_DELAY_STATS lengthDetails = calc->CalculateLengthDetails(
|
||||
netItemsMap[netCode],
|
||||
opts,
|
||||
nullptr,
|
||||
nullptr,
|
||||
LENGTH_DELAY_LAYER_OPT::WITH_LAYER_DETAIL,
|
||||
m_showTimeDomainDetails ? LENGTH_DELAY_DOMAIN_OPT::WITH_DELAY_DETAIL
|
||||
: LENGTH_DELAY_DOMAIN_OPT::NO_DELAY_DETAIL );
|
||||
if( m_showTimeDomainDetails )
|
||||
new_item->SetLayerWireDelays( *lengthDetails.LayerDelays );
|
||||
|
||||
if( aIncludeZeroPadNets || lengthDetails.NumPads > 0 )
|
||||
{
|
||||
std::unique_ptr<LIST_ITEM> new_item = std::make_unique<LIST_ITEM>( foundNets[i] );
|
||||
|
||||
new_item->SetPadCount( lengthDetails.NumPads );
|
||||
new_item->SetLayerCount( m_board->GetCopperLayerCount() );
|
||||
new_item->SetPadDieLength( lengthDetails.PadToDieLength );
|
||||
new_item->SetPadDieDelay( lengthDetails.PadToDieDelay );
|
||||
new_item->SetViaCount( lengthDetails.NumVias );
|
||||
new_item->SetViaLength( lengthDetails.ViaLength );
|
||||
new_item->SetViaDelay( lengthDetails.ViaDelay );
|
||||
new_item->SetLayerWireLengths( *lengthDetails.LayerLengths );
|
||||
|
||||
if( m_showTimeDomainDetails )
|
||||
new_item->SetLayerWireDelays( *lengthDetails.LayerDelays );
|
||||
|
||||
std::scoped_lock lock( resultsMutex );
|
||||
results.emplace_back( std::move( new_item ) );
|
||||
}
|
||||
}
|
||||
} );
|
||||
std::scoped_lock lock( resultsMutex );
|
||||
results.emplace_back( std::move( new_item ) );
|
||||
}
|
||||
} );
|
||||
|
||||
resultsFuture.get();
|
||||
|
||||
|
@ -611,7 +611,7 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE*>& aZones, bool aCheck, wxWindow*
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
|
||||
for( const std::pair<ZONE*, PCB_LAYER_ID>& fillItem : toFill )
|
||||
returns.emplace_back( std::make_pair( tp.submit( fill_lambda, fillItem ), 0 ) );
|
||||
returns.emplace_back( std::make_pair( tp.submit_task( [&, fillItem]() { return fill_lambda( fillItem ); } ), 0 ) );
|
||||
|
||||
while( !cancelled && finished != 2 * toFill.size() )
|
||||
{
|
||||
@ -636,9 +636,9 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE*>& aZones, bool aCheck, wxWindow*
|
||||
{
|
||||
// Queue the next step (will re-queue the existing step if it didn't complete)
|
||||
if( ret.second == 0 )
|
||||
returns[ii].first = tp.submit( fill_lambda, toFill[ii] );
|
||||
returns[ii].first = tp.submit_task( [&, idx = ii]() { return fill_lambda( toFill[idx] ); } );
|
||||
else if( ret.second == 1 )
|
||||
returns[ii].first = tp.submit( tesselate_lambda, toFill[ii] );
|
||||
returns[ii].first = tp.submit_task( [&, idx = ii]() { return tesselate_lambda( toFill[idx] ); } );
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -827,7 +827,7 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE*>& aZones, bool aCheck, wxWindow*
|
||||
return retval;
|
||||
};
|
||||
|
||||
auto island_returns = tp.parallelize_loop( 0, polys_to_check.size(), island_lambda );
|
||||
auto island_returns = tp.submit_blocks( 0, polys_to_check.size(), island_lambda );
|
||||
cancelled = false;
|
||||
|
||||
// Allow island removal threads to finish
|
||||
|
@ -97,7 +97,7 @@ long PYTHON_MANAGER::Execute( const std::vector<wxString>& aArgs,
|
||||
PYTHON_PROCESS* process = new PYTHON_PROCESS( aCallback );
|
||||
process->Redirect();
|
||||
|
||||
auto monitor =
|
||||
auto monitor =
|
||||
[]( PYTHON_PROCESS* aProcess )
|
||||
{
|
||||
wxInputStream* processOut = aProcess->GetInputStream();
|
||||
@ -147,7 +147,7 @@ long PYTHON_MANAGER::Execute( const std::vector<wxString>& aArgs,
|
||||
if( !aSaveOutput )
|
||||
{
|
||||
thread_pool& tp = GetKiCadThreadPool();
|
||||
auto ret = tp.submit( monitor, process );
|
||||
auto ret = tp.submit_task( [monitor, process] { monitor( process ); } );
|
||||
}
|
||||
}
|
||||
|
||||
@ -236,7 +236,7 @@ std::optional<wxString> PYTHON_MANAGER::GetVirtualPython( const wxString& aNames
|
||||
return std::nullopt;
|
||||
|
||||
wxFileName python( *envPath, wxEmptyString );
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
python.AppendDir( "Scripts" );
|
||||
python.SetFullName( "pythonw.exe" );
|
||||
|
2313
thirdparty/thread-pool/bs_thread_pool.hpp
vendored
2313
thirdparty/thread-pool/bs_thread_pool.hpp
vendored
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user