From bccf36538065a8c318dcdb2bc8b28bd855fb5e81 Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Mon, 7 Apr 2025 12:14:41 -0700 Subject: [PATCH] Isolate thread pool loops Now that we are threading things in different frames, we need to watch that we are not waiting for a process to complete in one frame while working in another. To accomplish this, we only wait for our own loop results Fixes https://gitlab.com/kicad/code/kicad/-/issues/20572 --- .../raytracing/render_3d_raytrace_base.cpp | 8 ++- eeschema/connection_graph.cpp | 56 +++++++++---------- eeschema/sim/spice_library_parser.cpp | 14 ++--- pcbnew/connectivity/connectivity_data.cpp | 42 +++++++------- 4 files changed, 61 insertions(+), 59 deletions(-) diff --git a/3d-viewer/3d_rendering/raytracing/render_3d_raytrace_base.cpp b/3d-viewer/3d_rendering/raytracing/render_3d_raytrace_base.cpp index c336d557d7..4ad55f6213 100644 --- a/3d-viewer/3d_rendering/raytracing/render_3d_raytrace_base.cpp +++ b/3d-viewer/3d_rendering/raytracing/render_3d_raytrace_base.cpp @@ -274,10 +274,12 @@ void RENDER_3D_RAYTRACE_BASE::renderTracing( uint8_t* ptrPBO, REPORTER* aStatusR } }; - for( size_t i = 0; i < tp.get_thread_count() + 1; ++i ) - tp.push_task( processBlocks ); + BS::multi_future futures; - tp.wait_for_tasks(); + for( size_t i = 0; i < tp.get_thread_count(); ++i ) + futures.push_back( tp.submit( processBlocks ) ); + + futures.wait(); m_blockRenderProgressCount += numBlocksRendered; diff --git a/eeschema/connection_graph.cpp b/eeschema/connection_graph.cpp index 2df8cbef61..9e28d88677 100644 --- a/eeschema/connection_graph.cpp +++ b/eeschema/connection_graph.cpp @@ -1398,13 +1398,13 @@ void CONNECTION_GRAPH::updateItemConnectivity( const SCH_SHEET_PATH& aSheet, thread_pool& tp = GetKiCadThreadPool(); - tp.push_loop( connection_vec.size(), - [&]( const int a, const int b) - { - for( int ii = a; ii < b; ++ii ) - update_lambda( connection_vec[ii] ); - }); - tp.wait_for_tasks(); + auto results = tp.parallelize_loop( connection_vec.size(), + [&]( const int a, const int b) + { + for( int ii = a; ii < b; ++ii ) + update_lambda( connection_vec[ii] ); + }); + results.wait(); } } @@ -1555,13 +1555,13 @@ void CONNECTION_GRAPH::resolveAllDrivers() thread_pool& tp = GetKiCadThreadPool(); - tp.push_loop( dirty_graphs.size(), - [&]( const int a, const int b) - { - for( int ii = a; ii < b; ++ii ) - update_lambda( dirty_graphs[ii] ); - }); - tp.wait_for_tasks(); + auto results = tp.parallelize_loop( dirty_graphs.size(), + [&]( const int a, const int b) + { + for( int ii = a; ii < b; ++ii ) + update_lambda( dirty_graphs[ii] ); + }); + results.wait(); // Now discard any non-driven subgraphs from further consideration @@ -2208,14 +2208,14 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function* a thread_pool& tp = GetKiCadThreadPool(); - tp.push_loop( m_driver_subgraphs.size(), - [&]( const int a, const int b) - { - for( int ii = a; ii < b; ++ii ) - m_driver_subgraphs[ii]->UpdateItemConnections(); - }); + auto results = tp.parallelize_loop( m_driver_subgraphs.size(), + [&]( const int a, const int b) + { + for( int ii = a; ii < b; ++ii ) + m_driver_subgraphs[ii]->UpdateItemConnections(); + }); - tp.wait_for_tasks(); + results.wait(); // Next time through the subgraphs, we do some post-processing to handle things like // connecting bus members to their neighboring subgraphs, and then propagate connections @@ -2414,13 +2414,13 @@ void CONNECTION_GRAPH::buildConnectionGraph( std::function* a return 1; }; - tp.push_loop( m_driver_subgraphs.size(), - [&]( const int a, const int b) - { - for( int ii = a; ii < b; ++ii ) - updateItemConnectionsTask( m_driver_subgraphs[ii] ); - }); - tp.wait_for_tasks(); + auto results2 = tp.parallelize_loop( m_driver_subgraphs.size(), + [&]( const int a, const int b) + { + for( int ii = a; ii < b; ++ii ) + updateItemConnectionsTask( m_driver_subgraphs[ii] ); + }); + results2.wait(); m_net_code_to_subgraphs_map.clear(); m_net_name_to_subgraphs_map.clear(); diff --git a/eeschema/sim/spice_library_parser.cpp b/eeschema/sim/spice_library_parser.cpp index dbb0f11920..54d7b60db1 100644 --- a/eeschema/sim/spice_library_parser.cpp +++ b/eeschema/sim/spice_library_parser.cpp @@ -140,13 +140,13 @@ void SPICE_LIBRARY_PARSER::ReadFile( const wxString& aFilePath, REPORTER& aRepor // Read all self-contained models in parallel thread_pool& tp = GetKiCadThreadPool(); - tp.push_loop( modelQueue.size(), - [&]( const int a, const int b ) - { - for( int ii = a; ii < b; ++ii ) - createModel( ii, true ); - } ); - tp.wait_for_tasks(); + auto results = tp.parallelize_loop( modelQueue.size(), + [&]( const int a, const int b ) + { + for( int ii = a; ii < b; ++ii ) + createModel( ii, true ); + } ); + results.wait(); // Now read all models that might refer to other models in order. for( int ii = 0; ii < (int) modelQueue.size(); ++ii ) diff --git a/pcbnew/connectivity/connectivity_data.cpp b/pcbnew/connectivity/connectivity_data.cpp index 844e4fda65..74e4826556 100644 --- a/pcbnew/connectivity/connectivity_data.cpp +++ b/pcbnew/connectivity/connectivity_data.cpp @@ -192,21 +192,21 @@ void CONNECTIVITY_DATA::updateRatsnest() thread_pool& tp = GetKiCadThreadPool(); - tp.push_loop( dirty_nets.size(), - [&]( const int a, const int b ) - { - for( int ii = a; ii < b; ++ii ) - dirty_nets[ii]->UpdateNet(); - } ); - tp.wait_for_tasks(); + auto results = tp.parallelize_loop( dirty_nets.size(), + [&]( const int a, const int b ) + { + for( int ii = a; ii < b; ++ii ) + dirty_nets[ii]->UpdateNet(); + } ); + results.wait(); - tp.push_loop( dirty_nets.size(), - [&]( const int a, const int b ) - { - for( int ii = a; ii < b; ++ii ) - dirty_nets[ii]->OptimizeRNEdges(); - } ); - tp.wait_for_tasks(); + auto results2 = tp.parallelize_loop( dirty_nets.size(), + [&]( const int a, const int b ) + { + for( int ii = a; ii < b; ++ii ) + dirty_nets[ii]->OptimizeRNEdges(); + } ); + results2.wait(); #ifdef PROFILE rnUpdate.Show(); @@ -374,13 +374,13 @@ void CONNECTIVITY_DATA::ComputeLocalRatsnest( const std::vector& aI thread_pool& tp = GetKiCadThreadPool(); size_t num_nets = std::min( m_nets.size(), aDynamicData->m_nets.size() ); - tp.push_loop( 1, num_nets, - [&]( const int a, const int b) - { - for( int ii = a; ii < b; ++ii ) - update_lambda( ii ); - }); - tp.wait_for_tasks(); + auto results = tp.parallelize_loop( 1, num_nets, + [&]( const int a, const int b) + { + for( int ii = a; ii < b; ++ii ) + update_lambda( ii ); + }); + results.wait(); // This gets the ratsnest for internal connections in the moving set const std::vector& edges = GetRatsnestForItems( aItems );