From 2491eec38b451da5bf60120d3f16ac1187c24423 Mon Sep 17 00:00:00 2001 From: kgv Date: Wed, 30 Mar 2022 21:38:14 +0300 Subject: [PATCH] 0032897: Tests - include elapsed time into test log Added "ELAPSED TIME" to test case log. Improved syntax of chrono/dchrono command: added -elapsed, -userCPU, -sysCPU options printing individual values in seconds. OSD_Chronometer::IsThisThreadOnly() - added missing accessors to the property. --- src/Draw/Draw_BasicCommands.cxx | 295 ++++++++++++++++------------- src/Draw/Draw_Chronometer.cxx | 47 ++--- src/Draw/Draw_Chronometer.hxx | 41 +--- src/DrawResources/TestCommands.tcl | 8 +- src/OSD/OSD_Chronometer.cxx | 16 +- src/OSD/OSD_Chronometer.hxx | 8 + tests/perf/mesh/bug27626 | 16 +- tests/perf/modalg/bug25742_2 | 8 +- 8 files changed, 218 insertions(+), 221 deletions(-) diff --git a/src/Draw/Draw_BasicCommands.cxx b/src/Draw/Draw_BasicCommands.cxx index 9160a871e0..f115d05982 100644 --- a/src/Draw/Draw_BasicCommands.cxx +++ b/src/Draw/Draw_BasicCommands.cxx @@ -75,146 +75,150 @@ static OSD_Timer aTimer; extern Standard_Boolean Draw_Chrono; -static Standard_Integer chronom(Draw_Interpretor& di, - Standard_Integer n,const char** a) +static Standard_Integer dchronom (Draw_Interpretor& theDI, + Standard_Integer theNbArgs, + const char** theArgVec) { - if ((n == 1) || (*a[1] == '0') || (*a[1] == '1')) { - if (n == 1) + if (theNbArgs == 1 + || (theNbArgs == 2 + && (*theArgVec[1] == '0' + || *theArgVec[1] == '1'))) + { + if (theNbArgs == 1) + { Draw_Chrono = !Draw_Chrono; + } else - Draw_Chrono = (*a[1] == '1'); + { + Draw_Chrono = (*theArgVec[1] == '1'); + } - if (Draw_Chrono) di << "Chronometers activated.\n"; - else di << "Chronometers deactivated.\n"; + theDI << (Draw_Chrono + ? "Chronometers activated.\n" + : "Chronometers deactivated.\n"); + return 0; } - else { - Handle(Draw_Drawable3D) D = Draw::Get(a[1]); - Handle(Draw_Chronometer) C; - if (!D.IsNull()) { - C = Handle(Draw_Chronometer)::DownCast(D); - } - if (C.IsNull()) { - C = new Draw_Chronometer(); - Draw::Set(a[1],C,Standard_False); - } - if (n <= 2) { - C->Timer().Reset(); - } - else { - for (Standard_Integer anIter = 2; anIter < n; ++anIter) - { - TCollection_AsciiString anArg (a[anIter]); - anArg.LowerCase(); - if (anArg == "reset") - { - C->Timer().Reset(); - } - else if (anArg == "restart") - { - C->Timer().Restart(); - } - else if (anArg == "start") - { - C->Timer().Start(); - } - else if (anArg == "stop") - { - C->Timer().Stop(); - } - else if (anArg == "show") - { - C->Timer().Show(); - } - else if (anArg == "counter") - { - Standard_Real aSeconds,aCPUtime; - Standard_Integer aMinutes, aHours; - C->Timer().Show(aSeconds,aMinutes,aHours,aCPUtime); - std::cout << "COUNTER " << a[++anIter] << ": " << aCPUtime << "\n"; - } - else - { - std::cerr << "Unknown argument '" << a[anIter] << "'!\n"; - } + const char* aTimerName = theArgVec[1]; + Handle(Draw_Chronometer) aChronom; + if (Handle(Draw_Drawable3D) aDrawable = Draw::Get (aTimerName)) + { + aChronom = Handle(Draw_Chronometer)::DownCast (aDrawable); + } + if (aChronom.IsNull()) + { + aChronom = new Draw_Chronometer(); + Draw::Set (aTimerName, aChronom, false); + } + + if (theNbArgs <= 2) + { + aChronom->Timer().Reset(); + return 0; + } + + const bool toShowCout = (TCollection_AsciiString (theArgVec[0]) == "chrono"); + int aNbPuts = false; + for (Standard_Integer anIter = 2; anIter < theNbArgs; ++anIter) + { + TCollection_AsciiString anArg (theArgVec[anIter]); + anArg.LowerCase(); + if (anArg == "-reset" + || anArg == "reset") + { + aChronom->Timer().Reset(); + } + else if (anArg == "-restart" + || anArg == "restart") + { + aChronom->Timer().Restart(); + } + else if (anArg == "-start" + || anArg == "-resume" + || anArg == "start") + { + aChronom->Timer().Start(); + } + else if (anArg == "-stop" + || anArg == "-pause" + || anArg == "stop") + { + aChronom->Timer().Stop(); + } + else if (anArg == "-show" + || anArg == "show") + { + if (toShowCout) + { + aChronom->Timer().Show (std::cout); } + else + { + Standard_SStream aStream; + aChronom->Timer().Show (aStream); + theDI << aStream; + } + } + else if (anIter + 1 < theNbArgs + && (anArg == "-counter" + || anArg == "counter")) + { + Standard_Real aSeconds = 0.0, aCPUtime = 0.0; + Standard_Integer aMinutes = 0, aHours = 0; + aChronom->Timer().Show (aSeconds, aMinutes, aHours, aCPUtime); + if (toShowCout) + { + std::cout << "COUNTER " << theArgVec[++anIter] << ": " << aCPUtime << "\n"; + } + else + { + theDI << "COUNTER " << theArgVec[++anIter] << ": " << aCPUtime << "\n"; + } + } + else if (anArg == "-elapsed") + { + if (++aNbPuts > 1) { theDI << " "; } + theDI << aChronom->Timer().ElapsedTime(); + } + else if (anArg == "-cpu" + || anArg == "-usercpu" + || anArg == "-cpuuser") + { + if (++aNbPuts > 1) { theDI << " "; } + theDI << aChronom->Timer().UserTimeCPU(); + } + else if (anArg == "-systemcpu" + || anArg == "-syscpu" + || anArg == "-cpusystem" + || anArg == "-cpusys") + { + if (++aNbPuts > 1) { theDI << " "; } + theDI << aChronom->Timer().SystemTimeCPU(); + } + else if (anArg == "-thread" + || anArg == "-threadonly") + { + bool isThreadOnly = Draw::ParseOnOffIterator (theNbArgs, theArgVec, anIter); + aChronom->Timer().Stop(); + aChronom->Timer().Reset(); + aChronom->Timer().SetThisThreadOnly (isThreadOnly); + } + else if (anArg == "-process") + { + bool isProcessTime = Draw::ParseOnOffIterator (theNbArgs, theArgVec, anIter); + aChronom->Timer().Stop(); + aChronom->Timer().Reset(); + aChronom->Timer().SetThisThreadOnly (!isProcessTime); + } + else + { + theDI << "Syntax error at '" << theArgVec[anIter] << "'\n"; + return 1; } } return 0; } -static Standard_Integer dchronom(Draw_Interpretor& theDI, - Standard_Integer n,const char** a) -{ - if ((n == 1) || (*a[1] == '0') || (*a[1] == '1')) { - if (n == 1) - Draw_Chrono = !Draw_Chrono; - else - Draw_Chrono = (*a[1] == '1'); - - if (Draw_Chrono) theDI << "Chronometers activated.\n"; - else theDI << "Chronometers deactivated.\n"; - } - else { - Handle(Draw_Drawable3D) D = Draw::Get(a[1]); - Handle(Draw_Chronometer) C; - if (!D.IsNull()) { - C = Handle(Draw_Chronometer)::DownCast(D); - } - if (C.IsNull()) { - C = new Draw_Chronometer(); - Draw::Set(a[1],C,Standard_False); - } - if (n <= 2) { - C->Timer().Reset(); - } - else { - for (Standard_Integer anIter = 2; anIter < n; ++anIter) - { - TCollection_AsciiString anArg (a[anIter]); - anArg.LowerCase(); - - if (anArg == "reset") - { - C->Timer().Reset(); - } - else if (anArg == "restart") - { - C->Timer().Restart(); - } - else if (anArg == "start") - { - C->Timer().Start(); - } - else if (anArg == "stop") - { - C->Timer().Stop(); - } - else if (anArg == "show") - { - Standard_SStream ss; - C->Timer().Show(ss); - theDI << ss; - } - else if (anArg == "counter") - { - Standard_Real aSeconds,aCPUtime; - Standard_Integer aMinutes, aHours; - C->Timer().Show(aSeconds,aMinutes,aHours,aCPUtime); - theDI << "COUNTER " << a[++anIter] << ": " << aCPUtime << "\n"; - } - else - { - theDI << "Unknown argument '" << a[anIter] << "'!\n"; - } - } - } - } - return 0; -} - - - //======================================================================= //function : ifbatch //purpose : @@ -878,7 +882,8 @@ static int dmeminfo (Draw_Interpretor& theDI, } else { - std::cerr << "Unknown argument '" << theArgVec[anIter] << "'!\n"; + theDI << "Syntax error at '" << theArgVec[anIter] << "'!\n"; + return 1; } } @@ -1304,11 +1309,33 @@ void Draw::BasicCommands(Draw_Interpretor& theCommands) __FILE__,Draw_wait,g); theCommands.Add("cpulimit","cpulimit [nbseconds], no args remove limits", __FILE__,cpulimit,g); - theCommands.Add("chrono","chrono [name action [action...]] \n Operates named timer.\n" - " Supported actions: reset, start, stop, restart, show, counter [text].\n" - " Without arguments enables / disables global timer for all DRAW commands.", - __FILE__,chronom,g); - theCommands.Add("dchrono","see help of chrono command", + + const char* aChronoHelp = + "chrono Name [-start] [-stop] [-reset] [-restart] [-counter Text]" + "\n\t\t: [-show] [-elapsed] [-userCPU] [-sysCPU]" + "\n\t\t: [-thread|-process {0|1}]" + "\n\t\t: Operates named timer:" + "\n\t\t: -start starts (resumes) timer" + "\n\t\t: -stop stops (pauses) timer" + "\n\t\t: -reset resets timer progress" + "\n\t\t: -restart resets and starts timer" + "\n\t\t: -show prints timer progress" + "\n\t\t: ('dchrono' puts into Tcl, 'chrono' puts into std::cout)" + "\n\t\t: -elapsed prints elapsed time in seconds" + "\n\t\t: -userCPU prints user CPU time in seconds" + "\n\t\t: -sysCPU prints system CPU time in seconds" + "\n\t\t: -counter prints 'COUNTER '" + "\n\t\t: -thread stops timer and sets measuring of CPU time for this thread only (FALSE by default)" + "\n\t\t: -process stops timer and sets measuring of CPU time for all threads (TRUE by default)" + "\n\t\t: Without arguments enables / disables global timer for all DRAW commands." + "\n\t\t: chrono {0|1}" + "\n\t\t: Typical usage:" + "\n\t\t: chrono t -restart" + "\n\t\t: " + "\n\t\t: chrono t -stop -show"; + theCommands.Add("chrono", aChronoHelp, + __FILE__,dchronom,g); + theCommands.Add("dchrono", aChronoHelp, __FILE__,dchronom,g); theCommands.Add("mallochook", "debug memory allocation/deallocation, w/o args for help", diff --git a/src/Draw/Draw_Chronometer.cxx b/src/Draw/Draw_Chronometer.cxx index 4792f22d40..95360b27ce 100644 --- a/src/Draw/Draw_Chronometer.cxx +++ b/src/Draw/Draw_Chronometer.cxx @@ -14,69 +14,50 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. - #include -#include -#include -#include -#include -IMPLEMENT_STANDARD_RTTIEXT(Draw_Chronometer,Draw_Drawable3D) +#include + +IMPLEMENT_STANDARD_RTTIEXT(Draw_Chronometer, Draw_Drawable3D) //======================================================================= //function : Draw_Chronometer -//purpose : +//purpose : //======================================================================= Draw_Chronometer::Draw_Chronometer() { + // } - -//======================================================================= -//function : Timer -//purpose : -//======================================================================= - -OSD_Timer& Draw_Chronometer::Timer() -{ - return myTimer; -} - - - //======================================================================= //function : DrawOn -//purpose : +//purpose : //======================================================================= - -void Draw_Chronometer::DrawOn(Draw_Display&)const +void Draw_Chronometer::DrawOn (Draw_Display& ) const { + // } - //======================================================================= //function : Copy -//purpose : +//purpose : //======================================================================= - -Handle(Draw_Drawable3D) Draw_Chronometer::Copy()const +Handle(Draw_Drawable3D) Draw_Chronometer::Copy() const { Handle(Draw_Chronometer) C = new Draw_Chronometer(); return C; } - //======================================================================= //function : Dump -//purpose : +//purpose : //======================================================================= - -void Draw_Chronometer::Dump(Standard_OStream& S)const +void Draw_Chronometer::Dump (Standard_OStream& S) const { - S << "Chronometer : "; + S << "Chronometer, "; + myTimer.Show (S); } - //======================================================================= //function : Whatis //purpose : diff --git a/src/Draw/Draw_Chronometer.hxx b/src/Draw/Draw_Chronometer.hxx index 25b7275ebe..3ab1b51cbf 100644 --- a/src/Draw/Draw_Chronometer.hxx +++ b/src/Draw/Draw_Chronometer.hxx @@ -17,32 +17,25 @@ #ifndef _Draw_Chronometer_HeaderFile #define _Draw_Chronometer_HeaderFile -#include - -#include #include -#include -#include -class Draw_Display; +#include - -class Draw_Chronometer; DEFINE_STANDARD_HANDLE(Draw_Chronometer, Draw_Drawable3D) //! Class to store chronometer variables. class Draw_Chronometer : public Draw_Drawable3D { - + DEFINE_STANDARD_RTTIEXT(Draw_Chronometer, Draw_Drawable3D) public: - Standard_EXPORT Draw_Chronometer(); - - Standard_EXPORT OSD_Timer& Timer(); - - //! Does nothhing, + + //! Return timer. + OSD_Timer& Timer() { return myTimer; } + + //! Does nothing, Standard_EXPORT void DrawOn (Draw_Display& dis) const Standard_OVERRIDE; - + //! For variable copy. Standard_EXPORT virtual Handle(Draw_Drawable3D) Copy() const Standard_OVERRIDE; @@ -52,28 +45,10 @@ public: //! For variable whatis command. Standard_EXPORT virtual void Whatis (Draw_Interpretor& I) const Standard_OVERRIDE; - - - - DEFINE_STANDARD_RTTIEXT(Draw_Chronometer,Draw_Drawable3D) - -protected: - - - - private: - OSD_Timer myTimer; - }; - - - - - - #endif // _Draw_Chronometer_HeaderFile diff --git a/src/DrawResources/TestCommands.tcl b/src/DrawResources/TestCommands.tcl index 1a28ba29c2..f120af32bf 100644 --- a/src/DrawResources/TestCommands.tcl +++ b/src/DrawResources/TestCommands.tcl @@ -1402,10 +1402,10 @@ proc _run_test {scriptsdir group gridname casefile echo} { append stats "MEMORY DELTA: [expr ($memuse - $membase) / 1024] KiB\n" } uplevel dchrono _timer stop - set time [uplevel dchrono _timer show] - if { [regexp -nocase {CPU user time:[ \t]*([0-9.e-]+)} $time res cpu_usr] } { - append stats "TOTAL CPU TIME: $cpu_usr sec\n" - } + set cpu_usr [uplevel dchrono _timer -userCPU] + set elps [uplevel dchrono _timer -elapsed] + append stats "TOTAL CPU TIME: $cpu_usr sec\n" + append stats "ELAPSED TIME: $elps sec\n" if { $dlog_exists && ! $echo } { dlog add $stats } else { diff --git a/src/OSD/OSD_Chronometer.cxx b/src/OSD/OSD_Chronometer.cxx index 24b1cad3ed..9a95197797 100644 --- a/src/OSD/OSD_Chronometer.cxx +++ b/src/OSD/OSD_Chronometer.cxx @@ -14,8 +14,9 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. - #include + +#include #include #ifndef _WIN32 @@ -182,6 +183,19 @@ OSD_Chronometer::~OSD_Chronometer() { } +//======================================================================= +//function : SetThisThreadOnly +//purpose : +//======================================================================= +void OSD_Chronometer::SetThisThreadOnly (Standard_Boolean theIsThreadOnly) +{ + if (!myIsStopped) + { + throw Standard_ProgramError ("OSD_Chronometer::SetThreadOnly() called for started Timer"); + } + myIsThreadOnly = theIsThreadOnly; +} + //======================================================================= //function : Reset //purpose : diff --git a/src/OSD/OSD_Chronometer.hxx b/src/OSD/OSD_Chronometer.hxx index 9753497f0d..98b8793ba0 100644 --- a/src/OSD/OSD_Chronometer.hxx +++ b/src/OSD/OSD_Chronometer.hxx @@ -91,6 +91,14 @@ public: return aSysTime; } + //! Return TRUE if current thread CPU time should be measured, + //! and FALSE to measure all threads CPU time; FALSE by default, + Standard_Boolean IsThisThreadOnly() const { return myIsThreadOnly; } + + //! Set if current thread (TRUE) or all threads (FALSE) CPU time should be measured. + //! Will raise exception if Timer is in started state. + Standard_EXPORT void SetThisThreadOnly (Standard_Boolean theIsThreadOnly); + //! Returns the current CPU user time in a variable. //! The chronometer can be running (laps Time) or stopped. void Show (Standard_Real& theUserSeconds) const { theUserSeconds = UserTimeCPU(); } diff --git a/tests/perf/mesh/bug27626 b/tests/perf/mesh/bug27626 index 4d90dbf925..7eec1325ea 100644 --- a/tests/perf/mesh/bug27626 +++ b/tests/perf/mesh/bug27626 @@ -1,10 +1,8 @@ puts "==========" -puts "OCC27626" +puts "OCC27626: Attempt to display shape in 3d leads to very long calculation loop" puts "==========" puts "" -####################################################################### -# Attempt to display shape in 3d leads to very long calculation loop -####################################################################### + pload XDE igesread [locate_data_file bug27626_badfil.igs] a * @@ -12,15 +10,9 @@ tclean a vinit vsetdispmode 1 -dchrono h restart -# -# DISPLAY OPERATION ----- START -# +dchrono h -restart vdisplay a -# -# DISPLAY OPERATION ----- FINISH -# -dchrono h stop counterv display +dchrono h -stop -counter display vfit checkview -screenshot -3d -path ${imagedir}/${test_image}.png diff --git a/tests/perf/modalg/bug25742_2 b/tests/perf/modalg/bug25742_2 index f636f2683c..f9b3384fbd 100755 --- a/tests/perf/modalg/bug25742_2 +++ b/tests/perf/modalg/bug25742_2 @@ -35,18 +35,18 @@ donly b1_4 fit display b2_1 -dchrono h restart +dchrono h -restart bopcurves b1_4 b2_1 -2d -dchrono h stop bopcurves counter bopcurves +dchrono h -stop -counter bopcurves checkview -screenshot -2d -path ${imagedir}/${test_image}_1.png mksurface s1 b1_4 mksurface s2 b2_1 -dchrono h2 restart +dchrono h2 -restart set CurveNumb [intersect resi s1 s2] -dchrono h2 stop counter CurveNumb +dchrono h2 -stop -counter CurveNumb if { [llength ${CurveNumb}] < 1 } { puts "Error : Bad intersection"