pcbnew: now PROGRESS_REPORTER should work in multi-threaded context under Windows...

This commit is contained in:
Tomasz Włostowski 2017-12-05 01:37:26 +01:00
parent 4bf90f9717
commit 7ad436c7aa
4 changed files with 91 additions and 47 deletions

View File

@ -28,15 +28,14 @@
PROGRESS_REPORTER::PROGRESS_REPORTER( int aNumPhases ) : PROGRESS_REPORTER::PROGRESS_REPORTER( int aNumPhases ) :
m_phase( 0 ), m_phase( 0 ),
m_progress( 0 ),
m_numPhases( aNumPhases ), m_numPhases( aNumPhases ),
m_progress( 0 ),
m_maxProgress( 1 ) m_maxProgress( 1 )
{ {
}; };
void PROGRESS_REPORTER::BeginPhase( int aPhase ) void PROGRESS_REPORTER::BeginPhase( int aPhase )
{ {
std::lock_guard<std::mutex> guard( m_lock );
m_phase = aPhase; m_phase = aPhase;
m_progress = 0; m_progress = 0;
updateUI(); updateUI();
@ -44,7 +43,6 @@ void PROGRESS_REPORTER::BeginPhase( int aPhase )
void PROGRESS_REPORTER::AdvancePhase( ) void PROGRESS_REPORTER::AdvancePhase( )
{ {
std::lock_guard<std::mutex> guard( m_lock );
m_phase++; m_phase++;
m_progress = 0; m_progress = 0;
updateUI(); updateUI();
@ -52,28 +50,24 @@ void PROGRESS_REPORTER::AdvancePhase( )
void PROGRESS_REPORTER::Report( const wxString& aMessage ) void PROGRESS_REPORTER::Report( const wxString& aMessage )
{ {
std::lock_guard<std::mutex> guard( m_lock );
m_rptMessage = aMessage; m_rptMessage = aMessage;
updateUI(); updateUI();
} }
void PROGRESS_REPORTER::SetMaxProgress ( int aMaxProgress ) void PROGRESS_REPORTER::SetMaxProgress ( int aMaxProgress )
{ {
std::lock_guard<std::mutex> guard( m_lock );
m_maxProgress = aMaxProgress; m_maxProgress = aMaxProgress;
updateUI(); updateUI();
} }
void PROGRESS_REPORTER::AdvanceProgress( ) void PROGRESS_REPORTER::AdvanceProgress( )
{ {
std::lock_guard<std::mutex> guard( m_lock );
m_progress++; m_progress++;
updateUI();
} }
int PROGRESS_REPORTER::currentProgress() const int PROGRESS_REPORTER::currentProgress() const
{ {
double current = (1.0 / (double)m_numPhases) * ( (double) m_phase + ( (double) m_progress / (double) m_maxProgress ) ); double current = (1.0 / (double)m_numPhases) * ( (double) m_phase + ( (double) m_progress.load() / (double) m_maxProgress ) );
return (int)(current * 1000); return (int)(current * 1000);
} }
@ -102,5 +96,16 @@ void WX_PROGRESS_REPORTER::updateUI()
cur = 0; cur = 0;
SetRange( 1000 ); SetRange( 1000 );
Update( cur, m_rptMessage ); wxProgressDialog::Update( cur, m_rptMessage );
}
void PROGRESS_REPORTER::KeepRefreshing()
{
while ( m_progress < m_maxProgress && m_maxProgress > 0)
{
updateUI();
#ifdef USE_OPENMP
wxMilliSleep(10);
#endif
}
} }

View File

@ -26,6 +26,7 @@
#define __PROGRESS_REPORTER #define __PROGRESS_REPORTER
#include <mutex> #include <mutex>
#include <atomic>
#include <wx/progdlg.h> #include <wx/progdlg.h>
@ -42,6 +43,8 @@ class PROGRESS_REPORTER
void SetMaxProgress ( int aMaxProgress ); void SetMaxProgress ( int aMaxProgress );
void AdvanceProgress( ); void AdvanceProgress( );
void KeepRefreshing();
protected: protected:
int currentProgress() const; int currentProgress() const;
@ -50,10 +53,8 @@ class PROGRESS_REPORTER
wxString m_rptMessage; wxString m_rptMessage;
int m_phase; int m_phase;
int m_numPhases; int m_numPhases;
int m_progress; std::atomic_int m_progress;
int m_maxProgress; int m_maxProgress;
std::mutex m_lock;
}; };
class WX_PROGRESS_REPORTER : public PROGRESS_REPORTER, public wxProgressDialog class WX_PROGRESS_REPORTER : public PROGRESS_REPORTER, public wxProgressDialog

View File

@ -521,30 +521,43 @@ void CN_CONNECTIVITY_ALGO::searchConnections( bool aIncludeZones )
} }
#ifdef USE_OPENMP #ifdef USE_OPENMP
#pragma omp parallel for schedule(dynamic) #pragma omp parallel
#endif #endif
for(int i = 0; i < m_zoneList.Size(); i++ )
{ {
auto item = m_zoneList[i]; #ifdef USE_OPENMP
auto zoneItem = static_cast<CN_ZONE *> (item); #pragma omp master
auto searchZones = std::bind( checkForConnection, _1, zoneItem ); #endif
if (m_progressReporter)
if( zoneItem->Dirty() || m_padList.IsDirty() || m_trackList.IsDirty() || m_viaList.IsDirty() )
{ {
totalDirtyCount++; m_progressReporter->KeepRefreshing();
m_viaList.FindNearby( zoneItem->BBox(), searchZones );
m_trackList.FindNearby( zoneItem->BBox(), searchZones );
m_padList.FindNearby( zoneItem->BBox(), searchZones );
m_zoneList.FindNearbyZones( zoneItem->BBox(), std::bind( checkInterZoneConnection, _1, zoneItem ) );
} }
#ifdef USE_OPENMP
#pragma omp for schedule(dynamic)
#endif
for(int i = 0; i < m_zoneList.Size(); i++ )
{ {
std::lock_guard<std::mutex> lock( cnListLock ); auto item = m_zoneList[i];
cnt++; auto zoneItem = static_cast<CN_ZONE *> (item);
auto searchZones = std::bind( checkForConnection, _1, zoneItem );
if (m_progressReporter) if( zoneItem->Dirty() || m_padList.IsDirty() || m_trackList.IsDirty() || m_viaList.IsDirty() )
{ {
m_progressReporter->AdvanceProgress(); totalDirtyCount++;
m_viaList.FindNearby( zoneItem->BBox(), searchZones );
m_trackList.FindNearby( zoneItem->BBox(), searchZones );
m_padList.FindNearby( zoneItem->BBox(), searchZones );
m_zoneList.FindNearbyZones( zoneItem->BBox(), std::bind( checkInterZoneConnection, _1, zoneItem ) );
}
{
std::lock_guard<std::mutex> lock( cnListLock );
cnt++;
if (m_progressReporter)
{
m_progressReporter->AdvanceProgress();
}
} }
} }
} }

View File

@ -126,24 +126,39 @@ void ZONE_FILLER::Fill( std::vector<ZONE_CONTAINER*> aZones )
m_progressReporter->SetMaxProgress( toFill.size() ); m_progressReporter->SetMaxProgress( toFill.size() );
} }
#ifdef USE_OPENMP #ifdef USE_OPENMP
#pragma omp parallel for schedule(dynamic) #pragma omp parallel
#endif #endif
for( int i = 0; i < toFill.size(); i++ )
{ {
SHAPE_POLY_SET rawPolys, finalPolys; #ifdef USE_OPENMP
ZONE_SEGMENT_FILL segFill; #pragma omp master
fillSingleZone ( toFill[i].m_zone, rawPolys, finalPolys, segFill ); #endif
toFill[i].m_zone->SetRawPolysList( rawPolys );
toFill[i].m_zone->SetFilledPolysList( finalPolys );
toFill[i].m_zone->SetFillSegments( segFill );
toFill[i].m_zone->SetIsFilled( true );
if( m_progressReporter ) if( m_progressReporter )
{ {
m_progressReporter->AdvanceProgress(); m_progressReporter->KeepRefreshing();
} }
#ifdef USE_OPENMP
#pragma omp for schedule(dynamic)
#endif
for( int i = 0; i < toFill.size(); i++ )
{
SHAPE_POLY_SET rawPolys, finalPolys;
ZONE_SEGMENT_FILL segFill;
fillSingleZone ( toFill[i].m_zone, rawPolys, finalPolys, segFill );
toFill[i].m_zone->SetRawPolysList( rawPolys );
toFill[i].m_zone->SetFilledPolysList( finalPolys );
toFill[i].m_zone->SetFillSegments( segFill );
toFill[i].m_zone->SetIsFilled( true );
if( m_progressReporter )
{
m_progressReporter->AdvanceProgress();
}
}
} }
if( m_progressReporter ) if( m_progressReporter )
@ -174,21 +189,31 @@ void ZONE_FILLER::Fill( std::vector<ZONE_CONTAINER*> aZones )
m_progressReporter->Report( _( "Caching polygon triangulations..." ) ); m_progressReporter->Report( _( "Caching polygon triangulations..." ) );
m_progressReporter->SetMaxProgress( toFill.size() ); m_progressReporter->SetMaxProgress( toFill.size() );
} }
#ifdef USE_OPENMP #ifdef USE_OPENMP
#pragma omp parallel for schedule(dynamic) #pragma omp parallel
#endif #endif
for( int i = 0; i < toFill.size(); i++ )
{ {
#ifdef USE_OPENMP
#pragma omp master
#endif
if( m_progressReporter ) if( m_progressReporter )
{ {
m_progressReporter->AdvanceProgress(); m_progressReporter->KeepRefreshing();
} }
toFill[i].m_zone->CacheTriangulation(); #ifdef USE_OPENMP
} #pragma omp for schedule(dynamic)
#endif
for( int i = 0; i < toFill.size(); i++ )
{
if( m_progressReporter )
{
m_progressReporter->AdvanceProgress();
}
toFill[i].m_zone->CacheTriangulation();
}
}
if( m_progressReporter ) if( m_progressReporter )
{ {
m_progressReporter->AdvancePhase(); m_progressReporter->AdvancePhase();