mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-08-09 13:22:24 +03:00
0025748: Parallel version of progress indicator
Progress indication mechanism is refactored to support incrementing progress within multithreaded algorithms. The class Message_ProgressIndicator is only an interface to the user application. It accumulates the progress provided by progress scopes. The counter is protected by mutex for thread-safety. The new class Message_ProgressScope replacing Message_ProgressSentry should be used to advance the progress. The scopes are nested to each other to reflect the nested nature of operations. The new class Message_ProgressRange should be used to pass the progress to sub-scopes. All OCCT algorithms involving progress indication have been updated to new API. Improvements in Draw_ProgressIndicator: - Separate console mode has been added in order to make possible to put the progress into std::cout instead or in addition to the draw interpreter, instead of trigger option "-tclOutput". - Treatment of Ctrl-Break signal has been added. Now any operation can be aborted by Ctrl-C or Ctrl-Break keystroke. Added new test case 'perf fclasses progr_par' for testing of parallel work of the progress.
This commit is contained in:
@@ -74,7 +74,7 @@ std::filebuf Draw_Spyfile;
|
||||
|
||||
static std::ostream spystream(&Draw_Spyfile);
|
||||
|
||||
static Handle(Draw_ProgressIndicator) PInd = NULL;
|
||||
static Handle(Draw_ProgressIndicator) global_Progress = NULL;
|
||||
|
||||
Standard_EXPORT Standard_Boolean Draw_Interprete(const char* command);
|
||||
// true if complete command
|
||||
@@ -240,14 +240,14 @@ Draw_Interpretor& Draw::GetInterpretor()
|
||||
//function :
|
||||
//purpose : Set/Get Progress Indicator
|
||||
//=======================================================================
|
||||
void Draw::SetProgressBar(const Handle(Draw_ProgressIndicator)& thePI)
|
||||
void Draw::SetProgressBar(const Handle(Draw_ProgressIndicator)& theProgress)
|
||||
{
|
||||
PInd = thePI;
|
||||
global_Progress = theProgress;
|
||||
}
|
||||
|
||||
Handle(Draw_ProgressIndicator) Draw::GetProgressBar()
|
||||
{
|
||||
return PInd;
|
||||
return global_Progress;
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
|
@@ -188,7 +188,7 @@ public:
|
||||
Standard_EXPORT static void Repaint();
|
||||
|
||||
//! sets progress indicator
|
||||
Standard_EXPORT static void SetProgressBar (const Handle(Draw_ProgressIndicator)& thePI);
|
||||
Standard_EXPORT static void SetProgressBar (const Handle(Draw_ProgressIndicator)& theProgress);
|
||||
|
||||
//! gets progress indicator
|
||||
Standard_EXPORT static Handle(Draw_ProgressIndicator) GetProgressBar();
|
||||
|
@@ -17,8 +17,12 @@
|
||||
#include <Draw_ProgressIndicator.hxx>
|
||||
#include <Message.hxx>
|
||||
#include <Message_Messenger.hxx>
|
||||
#include <Message_ProgressScale.hxx>
|
||||
#include <Message_ProgressScope.hxx>
|
||||
#include <NCollection_List.hxx>
|
||||
#include <Precision.hxx>
|
||||
#include <OSD.hxx>
|
||||
#include <OSD_Exception_CTRL_BREAK.hxx>
|
||||
#include <OSD_Thread.hxx>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
@@ -29,15 +33,16 @@ IMPLEMENT_STANDARD_RTTIEXT(Draw_ProgressIndicator,Message_ProgressIndicator)
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
Draw_ProgressIndicator::Draw_ProgressIndicator (const Draw_Interpretor &di, Standard_Real theUpdateThreshold)
|
||||
: myTextMode ( DefaultTextMode() ),
|
||||
: myTclMode ( DefaultTclMode() ),
|
||||
myConsoleMode ( DefaultConsoleMode() ),
|
||||
myGraphMode ( DefaultGraphMode() ),
|
||||
myTclOutput ( DefaultTclOutput() ),
|
||||
myDraw ( (Draw_Interpretor*)&di ),
|
||||
myShown ( Standard_False ),
|
||||
myBreak ( Standard_False ),
|
||||
myUpdateThreshold ( 0.01 * theUpdateThreshold ),
|
||||
myLastPosition ( -1. ),
|
||||
myStartTime ( 0 )
|
||||
myStartTime ( 0 ),
|
||||
myGuiThreadId (OSD_Thread::Current())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -73,23 +78,27 @@ void Draw_ProgressIndicator::Reset()
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean Draw_ProgressIndicator::Show(const Standard_Boolean force)
|
||||
void Draw_ProgressIndicator::Show (const Message_ProgressScope& theScope, const Standard_Boolean force)
|
||||
{
|
||||
if ( ! myGraphMode && ! myTextMode )
|
||||
return Standard_False;
|
||||
if (!myGraphMode && !myTclMode && !myConsoleMode)
|
||||
return;
|
||||
|
||||
// remember time of the first call to Show as process start time
|
||||
if ( ! myStartTime )
|
||||
{
|
||||
time_t aTimeT;
|
||||
time ( &aTimeT );
|
||||
myStartTime = (Standard_Size)aTimeT;
|
||||
if (!myStartTime)
|
||||
{
|
||||
time_t aTimeT;
|
||||
time(&aTimeT);
|
||||
myStartTime = (Standard_Size)aTimeT;
|
||||
}
|
||||
}
|
||||
|
||||
// unless show is forced, show updated state only if at least 1% progress has been reached since the last update
|
||||
Standard_Real aPosition = GetPosition();
|
||||
if ( ! force && aPosition < 1. && Abs (aPosition - myLastPosition) < myUpdateThreshold)
|
||||
return Standard_False; // return if update interval has not elapsed
|
||||
return; // return if update interval has not elapsed
|
||||
|
||||
myLastPosition = aPosition;
|
||||
|
||||
// Prepare textual progress info
|
||||
@@ -97,17 +106,19 @@ Standard_Boolean Draw_ProgressIndicator::Show(const Standard_Boolean force)
|
||||
aText.setf (std::ios::fixed, std:: ios::floatfield);
|
||||
aText.precision(0);
|
||||
aText << "Progress: " << 100. * GetPosition() << "%";
|
||||
for ( Standard_Integer i=GetNbScopes(); i >=1; i-- ) {
|
||||
const Message_ProgressScale &scale = GetScope ( i );
|
||||
if ( scale.GetName().IsNull() ) continue; // skip unnamed scopes
|
||||
aText << " " << scale.GetName()->ToCString() << ": ";
|
||||
NCollection_List<const Message_ProgressScope*> aScopes;
|
||||
for (const Message_ProgressScope* aPS = &theScope; aPS; aPS = aPS->Parent())
|
||||
aScopes.Prepend(aPS);
|
||||
for (NCollection_List<const Message_ProgressScope*>::Iterator it(aScopes); it.More(); it.Next())
|
||||
{
|
||||
const Message_ProgressScope* aPS = it.Value();
|
||||
if (!aPS->Name()) continue; // skip unnamed scopes
|
||||
aText << " " << aPS->Name() << ": ";
|
||||
|
||||
// if scope has subscopes, print end of subscope as it s current position
|
||||
Standard_Real locPos = ( (i >1 && GetPosition()!=0) ? GetScope ( i-1 ).GetLast() : GetPosition() );
|
||||
// print progress info differently for finite and infinite scopes
|
||||
if ( scale.GetInfinite() )
|
||||
Standard_Real aVal = aPS->Value();
|
||||
if (aPS->IsInfinite())
|
||||
{
|
||||
Standard_Real aVal = scale.BaseToLocal(locPos);
|
||||
if (Precision::IsInfinite(aVal))
|
||||
{
|
||||
aText << "finished";
|
||||
@@ -119,13 +130,14 @@ Standard_Boolean Draw_ProgressIndicator::Show(const Standard_Boolean force)
|
||||
}
|
||||
else
|
||||
{
|
||||
aText << scale.BaseToLocal ( locPos ) << " / " << scale.GetMax();
|
||||
aText << aVal << " / " << aPS->MaxValue();
|
||||
}
|
||||
}
|
||||
|
||||
// Show graphic progress bar
|
||||
if ( myGraphMode ) {
|
||||
|
||||
// Show graphic progress bar.
|
||||
// It will be updated only within GUI thread.
|
||||
if (myGraphMode && myGuiThreadId == OSD_Thread::Current())
|
||||
{
|
||||
// In addition, write elapsed/estimated/remaining time
|
||||
if ( GetPosition() > 0.01 ) {
|
||||
time_t aTimeT;
|
||||
@@ -153,25 +165,21 @@ Standard_Boolean Draw_ProgressIndicator::Show(const Standard_Boolean force)
|
||||
aCommand.setf(std::ios::fixed, std::ios::floatfield);
|
||||
aCommand.precision(0);
|
||||
aCommand << ".xprogress.bar coords progress 2 2 " << (1 + 400 * GetPosition()) << " 21;";
|
||||
aCommand << ".xprogress.bar coords progress_next 2 2 " << (1 + 400 * GetScope(1).GetLast()) << " 21;";
|
||||
aCommand << ".xprogress.bar coords progress_next 2 2 " << (1 + 400 * theScope.GetPortion()) << " 21;";
|
||||
aCommand << ".xprogress.text configure -text \"" << aText.str() << "\";";
|
||||
aCommand << "update";
|
||||
myDraw->Eval (aCommand.str().c_str());
|
||||
}
|
||||
|
||||
// Print textual progress info
|
||||
if (myTextMode)
|
||||
if (myTclMode && myDraw)
|
||||
{
|
||||
if (myTclOutput && myDraw)
|
||||
{
|
||||
*myDraw << aText.str().c_str() << "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cout << aText.str().c_str() << "\n";
|
||||
}
|
||||
*myDraw << aText.str().c_str() << "\n";
|
||||
}
|
||||
if (myConsoleMode)
|
||||
{
|
||||
std::cout << aText.str().c_str() << "\n";
|
||||
}
|
||||
return Standard_True;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -181,32 +189,65 @@ Standard_Boolean Draw_ProgressIndicator::Show(const Standard_Boolean force)
|
||||
|
||||
Standard_Boolean Draw_ProgressIndicator::UserBreak()
|
||||
{
|
||||
if ( StopIndicator() == this ) {
|
||||
if ( StopIndicator() == this )
|
||||
{
|
||||
// std::cout << "Progress Indicator - User Break: " << StopIndicator() << ", " << (void*)this << std::endl;
|
||||
myBreak = Standard_True;
|
||||
myDraw->Eval ( "XProgress -stop 0" );
|
||||
}
|
||||
else
|
||||
{
|
||||
// treatment of Ctrl-Break signal
|
||||
try
|
||||
{
|
||||
OSD::ControlBreak();
|
||||
}
|
||||
catch (OSD_Exception_CTRL_BREAK)
|
||||
{
|
||||
myBreak = Standard_True;
|
||||
}
|
||||
}
|
||||
return myBreak;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetTextMode
|
||||
//purpose : Sets text output mode (on/off)
|
||||
//function : SetTclMode
|
||||
//purpose : Sets Tcl output mode (on/off)
|
||||
//=======================================================================
|
||||
|
||||
void Draw_ProgressIndicator::SetTextMode(const Standard_Boolean theTextMode)
|
||||
void Draw_ProgressIndicator::SetTclMode(const Standard_Boolean theTclMode)
|
||||
{
|
||||
myTextMode = theTextMode;
|
||||
myTclMode = theTclMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetTextMode
|
||||
//purpose : Returns text output mode (on/off)
|
||||
//function : GetTclMode
|
||||
//purpose : Returns Tcl output mode (on/off)
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean Draw_ProgressIndicator::GetTextMode() const
|
||||
Standard_Boolean Draw_ProgressIndicator::GetTclMode() const
|
||||
{
|
||||
return myTextMode;
|
||||
return myTclMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : SetConsoleMode
|
||||
//purpose : Sets Console output mode (on/off)
|
||||
//=======================================================================
|
||||
|
||||
void Draw_ProgressIndicator::SetConsoleMode(const Standard_Boolean theMode)
|
||||
{
|
||||
myConsoleMode = theMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : GetConsoleMode
|
||||
//purpose : Returns Console output mode (on/off)
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean Draw_ProgressIndicator::GetConsoleMode() const
|
||||
{
|
||||
return myConsoleMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -230,14 +271,25 @@ Standard_Boolean Draw_ProgressIndicator::GetGraphMode() const
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : DefaultTextMode
|
||||
//function : DefaultTclMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean &Draw_ProgressIndicator::DefaultTextMode()
|
||||
Standard_Boolean &Draw_ProgressIndicator::DefaultTclMode()
|
||||
{
|
||||
static Standard_Boolean defTextMode = Standard_False;
|
||||
return defTextMode;
|
||||
static Standard_Boolean defTclMode = Standard_False;
|
||||
return defTclMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : DefaultConsoleMode
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean &Draw_ProgressIndicator::DefaultConsoleMode()
|
||||
{
|
||||
static Standard_Boolean defConsoleMode = Standard_False;
|
||||
return defConsoleMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
@@ -251,17 +303,6 @@ Standard_Boolean &Draw_ProgressIndicator::DefaultGraphMode()
|
||||
return defGraphMode;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : DefaultTclOutput
|
||||
//purpose :
|
||||
//=======================================================================
|
||||
|
||||
Standard_Boolean &Draw_ProgressIndicator::DefaultTclOutput()
|
||||
{
|
||||
static Standard_Boolean defTclOutput = Standard_False;
|
||||
return defTclOutput;
|
||||
}
|
||||
|
||||
//=======================================================================
|
||||
//function : StopIndicator
|
||||
//purpose :
|
||||
|
@@ -43,41 +43,44 @@ public:
|
||||
//! Destructor; calls Reset()
|
||||
Standard_EXPORT ~Draw_ProgressIndicator();
|
||||
|
||||
//! Sets text output mode (on/off)
|
||||
Standard_EXPORT void SetTextMode (const Standard_Boolean theTextMode);
|
||||
|
||||
//! Gets text output mode (on/off)
|
||||
Standard_EXPORT Standard_Boolean GetTextMode() const;
|
||||
//! Sets tcl output mode (on/off).
|
||||
Standard_EXPORT void SetTclMode (const Standard_Boolean theTclMode);
|
||||
|
||||
//! Gets tcl output mode (on/off).
|
||||
Standard_EXPORT Standard_Boolean GetTclMode() const;
|
||||
|
||||
//! Sets console output mode (on/off).
|
||||
//! If it is on then progress is shown in the standard output.
|
||||
Standard_EXPORT void SetConsoleMode(const Standard_Boolean theMode);
|
||||
|
||||
//! Gets console output mode (on/off)
|
||||
Standard_EXPORT Standard_Boolean GetConsoleMode() const;
|
||||
|
||||
//! Sets graphical output mode (on/off)
|
||||
Standard_EXPORT void SetGraphMode (const Standard_Boolean theGraphMode);
|
||||
|
||||
//! Gets graphical output mode (on/off)
|
||||
Standard_EXPORT Standard_Boolean GetGraphMode() const;
|
||||
|
||||
//! Sets tcl output mode (on/off)
|
||||
void SetTclOutput (const Standard_Boolean theTclOutput) { myTclOutput = theTclOutput; }
|
||||
|
||||
//! Gets tcl output mode (on/off)
|
||||
Standard_Boolean GetTclOutput() const { return myTclOutput; }
|
||||
|
||||
//! Clears/erases opened TCL windows if any
|
||||
//! and sets myBreak to False
|
||||
Standard_EXPORT virtual void Reset() Standard_OVERRIDE;
|
||||
|
||||
//! Defines method Show of Progress Indicator
|
||||
Standard_EXPORT virtual Standard_Boolean Show (const Standard_Boolean force = Standard_True) Standard_OVERRIDE;
|
||||
Standard_EXPORT virtual void Show (const Message_ProgressScope& theScope,
|
||||
const Standard_Boolean force = Standard_True) Standard_OVERRIDE;
|
||||
|
||||
//! Redefines method UserBreak of Progress Indicator
|
||||
Standard_EXPORT virtual Standard_Boolean UserBreak() Standard_OVERRIDE;
|
||||
|
||||
Standard_EXPORT static Standard_Boolean& DefaultTextMode();
|
||||
|
||||
//! Get/Set default values for output modes
|
||||
Standard_EXPORT static Standard_Boolean& DefaultGraphMode();
|
||||
//! Get/Set default value for tcl mode
|
||||
Standard_EXPORT static Standard_Boolean& DefaultTclMode();
|
||||
|
||||
//! Get/Set default values for tcl output mode
|
||||
Standard_EXPORT static Standard_Boolean& DefaultTclOutput();
|
||||
//! Get/Set default value for console mode
|
||||
Standard_EXPORT static Standard_Boolean& DefaultConsoleMode();
|
||||
|
||||
//! Get/Set default value for graph mode
|
||||
Standard_EXPORT static Standard_Boolean& DefaultGraphMode();
|
||||
|
||||
//! Internal method for implementation of UserBreak mechanism;
|
||||
//! note that it uses static variable and thus not thread-safe!
|
||||
@@ -86,15 +89,16 @@ public:
|
||||
DEFINE_STANDARD_RTTIEXT(Draw_ProgressIndicator,Message_ProgressIndicator)
|
||||
|
||||
private:
|
||||
Standard_Boolean myTextMode;
|
||||
Standard_Boolean myTclMode;
|
||||
Standard_Boolean myConsoleMode;
|
||||
Standard_Boolean myGraphMode;
|
||||
Standard_Boolean myTclOutput;
|
||||
Draw_Interpretor* myDraw;
|
||||
Standard_Boolean myShown;
|
||||
Standard_Boolean myBreak;
|
||||
Standard_Real myUpdateThreshold;
|
||||
Standard_Real myLastPosition;
|
||||
Standard_Size myStartTime;
|
||||
Standard_ThreadId myGuiThreadId;
|
||||
};
|
||||
|
||||
#endif // _Draw_ProgressIndicator_HeaderFile
|
||||
|
@@ -157,9 +157,6 @@ static Standard_Integer save(Draw_Interpretor& di, Standard_Integer n, const cha
|
||||
// find a tool
|
||||
Draw_SaveAndRestore* tool = Draw_First;
|
||||
Handle(Draw_ProgressIndicator) progress = new Draw_ProgressIndicator ( di, 1 );
|
||||
progress->SetScale ( 0, 100, 1 );
|
||||
progress->NewScope(100,"Writing");
|
||||
progress->Show();
|
||||
|
||||
while (tool) {
|
||||
if (tool->Test(D)) break;
|
||||
@@ -176,8 +173,6 @@ static Standard_Integer save(Draw_Interpretor& di, Standard_Integer n, const cha
|
||||
return 1;
|
||||
}
|
||||
Draw::SetProgressBar( 0 );
|
||||
progress->EndScope();
|
||||
progress->Show();
|
||||
}
|
||||
|
||||
os << "0\n\n";
|
||||
@@ -222,8 +217,7 @@ static Standard_Integer restore(Draw_Interpretor& di, Standard_Integer n, const
|
||||
if (!in.fail()) {
|
||||
// search a tool
|
||||
Handle(Draw_ProgressIndicator) progress = new Draw_ProgressIndicator ( di, 1 );
|
||||
progress->NewScope(100,"Reading");
|
||||
progress->Show();
|
||||
Draw::SetProgressBar(progress);
|
||||
|
||||
Draw_SaveAndRestore* tool = Draw_First;
|
||||
Draw_SaveAndRestore* aDBRepTool = NULL;
|
||||
@@ -232,7 +226,6 @@ static Standard_Integer restore(Draw_Interpretor& di, Standard_Integer n, const
|
||||
if (!strcmp(typ,toolName)) break;
|
||||
if (!strcmp("DBRep_DrawableShape",toolName))
|
||||
aDBRepTool = tool;
|
||||
Draw::SetProgressBar(progress);
|
||||
tool = tool->Next();
|
||||
}
|
||||
|
||||
@@ -254,8 +247,6 @@ static Standard_Integer restore(Draw_Interpretor& di, Standard_Integer n, const
|
||||
return 1;
|
||||
}
|
||||
Draw::SetProgressBar( 0 );
|
||||
progress->EndScope();
|
||||
progress->Show();
|
||||
}
|
||||
|
||||
di << name;
|
||||
|
Reference in New Issue
Block a user