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 ) :
m_phase( 0 ),
m_progress( 0 ),
m_numPhases( aNumPhases ),
m_progress( 0 ),
m_maxProgress( 1 )
{
};
void PROGRESS_REPORTER::BeginPhase( int aPhase )
{
std::lock_guard<std::mutex> guard( m_lock );
m_phase = aPhase;
m_progress = 0;
updateUI();
@ -44,7 +43,6 @@ void PROGRESS_REPORTER::BeginPhase( int aPhase )
void PROGRESS_REPORTER::AdvancePhase( )
{
std::lock_guard<std::mutex> guard( m_lock );
m_phase++;
m_progress = 0;
updateUI();
@ -52,28 +50,24 @@ void PROGRESS_REPORTER::AdvancePhase( )
void PROGRESS_REPORTER::Report( const wxString& aMessage )
{
std::lock_guard<std::mutex> guard( m_lock );
m_rptMessage = aMessage;
updateUI();
}
void PROGRESS_REPORTER::SetMaxProgress ( int aMaxProgress )
{
std::lock_guard<std::mutex> guard( m_lock );
m_maxProgress = aMaxProgress;
updateUI();
}
void PROGRESS_REPORTER::AdvanceProgress( )
{
std::lock_guard<std::mutex> guard( m_lock );
m_progress++;
updateUI();
}
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);
}
@ -102,5 +96,16 @@ void WX_PROGRESS_REPORTER::updateUI()
cur = 0;
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
#include <mutex>
#include <atomic>
#include <wx/progdlg.h>
@ -42,6 +43,8 @@ class PROGRESS_REPORTER
void SetMaxProgress ( int aMaxProgress );
void AdvanceProgress( );
void KeepRefreshing();
protected:
int currentProgress() const;
@ -50,10 +53,8 @@ class PROGRESS_REPORTER
wxString m_rptMessage;
int m_phase;
int m_numPhases;
int m_progress;
std::atomic_int m_progress;
int m_maxProgress;
std::mutex m_lock;
};
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
#pragma omp parallel for schedule(dynamic)
#pragma omp parallel
#endif
for(int i = 0; i < m_zoneList.Size(); i++ )
{
auto item = m_zoneList[i];
auto zoneItem = static_cast<CN_ZONE *> (item);
auto searchZones = std::bind( checkForConnection, _1, zoneItem );
if( zoneItem->Dirty() || m_padList.IsDirty() || m_trackList.IsDirty() || m_viaList.IsDirty() )
#ifdef USE_OPENMP
#pragma omp master
#endif
if (m_progressReporter)
{
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 ) );
m_progressReporter->KeepRefreshing();
}
#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 );
cnt++;
auto item = m_zoneList[i];
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() );
}
#ifdef USE_OPENMP
#pragma omp parallel for schedule(dynamic)
#pragma omp parallel
#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 );
#ifdef USE_OPENMP
#pragma omp master
#endif
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 )
@ -174,21 +189,31 @@ void ZONE_FILLER::Fill( std::vector<ZONE_CONTAINER*> aZones )
m_progressReporter->Report( _( "Caching polygon triangulations..." ) );
m_progressReporter->SetMaxProgress( toFill.size() );
}
#ifdef USE_OPENMP
#pragma omp parallel for schedule(dynamic)
#pragma omp parallel
#endif
for( int i = 0; i < toFill.size(); i++ )
{
#ifdef USE_OPENMP
#pragma omp master
#endif
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 )
{
m_progressReporter->AdvancePhase();