mirror of
https://git.dev.opencascade.org/repos/occt.git
synced 2025-06-30 12:14:08 +03:00
Foundation Classes - Return value is overridden by OCCT #528
- Removed OSD_PerfMeter.h and integrated its functionality directly into OSD_PerfMeter.hxx. - Updated OSD_PerfMeter to manage stopwatches through a singleton StopwatchStorage class. - Enhanced meter initialization and management to support shared meters by name. - Implemented methods for starting, stopping, and printing elapsed time for performance meters. - Added OSD_PerfMeter_Test.cxx to implement unit tests for OSD_PerfMeter functionality. - Test bug23237 is delete as it refers to removed code.
This commit is contained in:
parent
e82126db69
commit
66d2a06b5a
@ -28,6 +28,7 @@
|
||||
#include <OSD_MAllocHook.hxx>
|
||||
#include <OSD_MemInfo.hxx>
|
||||
#include <OSD_Parallel.hxx>
|
||||
#include <OSD_PerfMeter.hxx>
|
||||
#include <OSD_ThreadPool.hxx>
|
||||
#include <Standard_Macro.hxx>
|
||||
#include <Standard_SStream.hxx>
|
||||
@ -35,7 +36,6 @@
|
||||
#include <Standard_Version.hxx>
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
|
||||
#include <OSD_PerfMeter.h>
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
@ -970,9 +970,13 @@ static int dperf(Draw_Interpretor& theDI, Standard_Integer theArgNb, const char*
|
||||
{
|
||||
// reset if argument is provided and it is not '0'
|
||||
int reset = (theArgNb > 1 ? theArgVec[1][0] != '0' && theArgVec[1][0] != '\0' : 0);
|
||||
char buffer[25600];
|
||||
perf_sprint_all_meters(buffer, 25600 - 1, reset);
|
||||
theDI << buffer;
|
||||
const TCollection_AsciiString anOutput = OSD_PerfMeter::PrintALL();
|
||||
theDI << anOutput;
|
||||
if (reset)
|
||||
{
|
||||
OSD_PerfMeter::ResetALL();
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -130,58 +130,6 @@ static Standard_Integer OCC23361(Draw_Interpretor& di,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static Standard_Integer OCC23237(Draw_Interpretor& di,
|
||||
Standard_Integer /*argc*/,
|
||||
const char** /*argv*/)
|
||||
{
|
||||
OSD_PerfMeter aPM("TestMeter", 0);
|
||||
OSD_Timer aTM;
|
||||
|
||||
// run some operation in cycle for about 2 seconds to have good values of times to compare
|
||||
int count = 0;
|
||||
printf("OSD_PerfMeter test.\nRunning Boolean operation on solids in loop.\n");
|
||||
for (; aTM.ElapsedTime() < 2.; count++)
|
||||
{
|
||||
aPM.Start();
|
||||
aTM.Start();
|
||||
|
||||
// do some operation that will take considerable time compared with time of starting / stopping
|
||||
// timers
|
||||
BRepPrimAPI_MakeBox aBox(10., 10., 10.);
|
||||
BRepPrimAPI_MakeSphere aSphere(10.);
|
||||
BRepAlgoAPI_Cut aCutter(aBox.Shape(), aSphere.Shape());
|
||||
|
||||
aTM.Stop();
|
||||
aPM.Stop();
|
||||
}
|
||||
|
||||
int aNbEnters = 0;
|
||||
Standard_Real aPerfMeter_CPUtime = 0., aTimer_CPUTime = 0., aS;
|
||||
Standard_Integer aM, aH;
|
||||
aTM.Show(aS, aM, aH, aTimer_CPUTime);
|
||||
|
||||
perf_get_meter("TestMeter", &aNbEnters, &aPerfMeter_CPUtime);
|
||||
perf_init_meter("TestMeter");
|
||||
|
||||
Standard_Real aTimeDiff = (fabs(aTimer_CPUTime - aPerfMeter_CPUtime) / aTimer_CPUTime);
|
||||
|
||||
printf("\nMeasurement results (%d cycles):\n", count);
|
||||
printf("\nOSD_PerfMeter CPU time: %lf\nOSD_Timer CPU time: %lf\n",
|
||||
aPerfMeter_CPUtime,
|
||||
aTimer_CPUTime);
|
||||
printf("Time delta is: %.3lf %%\n", aTimeDiff * 100);
|
||||
|
||||
if (aTimeDiff > 0.2)
|
||||
di << "OCC23237: Error: too much difference between CPU and elapsed times";
|
||||
else if (aNbEnters != count)
|
||||
di << "OCC23237: Error: counter reported by PerfMeter (" << aNbEnters
|
||||
<< ") does not correspond to actual number of cycles";
|
||||
else
|
||||
di << "OCC23237: OK";
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
class IncrementerDecrementer
|
||||
{
|
||||
public:
|
||||
@ -5462,7 +5410,6 @@ void QABugs::Commands_19(Draw_Interpretor& theCommands)
|
||||
|
||||
theCommands.Add("OCC230", "OCC230 TrimmedCurve Pnt2d Pnt2d", __FILE__, OCC230, group);
|
||||
theCommands.Add("OCC23361", "OCC23361", __FILE__, OCC23361, group);
|
||||
theCommands.Add("OCC23237", "OCC23237", __FILE__, OCC23237, group);
|
||||
theCommands.Add("OCC22980", "OCC22980", __FILE__, OCC22980, group);
|
||||
theCommands.Add("OCC23595", "OCC23595", __FILE__, OCC23595, group);
|
||||
theCommands.Add("OCC22611", "OCC22611 string nb", __FILE__, OCC22611, group);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -14,6 +14,7 @@ set(OCCT_TKernel_GTests_FILES
|
||||
NCollection_Sequence_Test.cxx
|
||||
NCollection_SparseArray_Test.cxx
|
||||
NCollection_Vector_Test.cxx
|
||||
OSD_PerfMeter_Test.cxx
|
||||
TCollection_AsciiString_Test.cxx
|
||||
TCollection_ExtendedString_Test.cxx
|
||||
)
|
||||
|
357
src/FoundationClasses/TKernel/GTests/OSD_PerfMeter_Test.cxx
Normal file
357
src/FoundationClasses/TKernel/GTests/OSD_PerfMeter_Test.cxx
Normal file
@ -0,0 +1,357 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include <OSD_PerfMeter.hxx>
|
||||
|
||||
#include <BRepPrimAPI_MakeBox.hxx>
|
||||
#include <BRepPrimAPI_MakeSphere.hxx>
|
||||
#include <BRepAlgoAPI_Cut.hxx>
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
// Test fixture for OSD_PerfMeter tests
|
||||
class OSD_PerfMeterTest : public ::testing::Test
|
||||
{
|
||||
protected:
|
||||
void SetUp() override
|
||||
{
|
||||
// Reset all meters before each test
|
||||
OSD_PerfMeter::ResetALL();
|
||||
}
|
||||
|
||||
void TearDown() override
|
||||
{
|
||||
// Reset all meters after each test
|
||||
OSD_PerfMeter::ResetALL();
|
||||
}
|
||||
|
||||
// Helper function to perform some measurable work
|
||||
static void DoSomeWork(const double theTimeInSec = 0.1)
|
||||
{
|
||||
OSD_PerfMeter meter("WorkMeter", true);
|
||||
while (meter.Elapsed() < theTimeInSec)
|
||||
{
|
||||
// do some operation that will take considerable time compared with time of starting /
|
||||
// stopping timers
|
||||
BRepPrimAPI_MakeBox aBox(10., 10., 10.);
|
||||
BRepPrimAPI_MakeSphere aSphere(10.);
|
||||
BRepAlgoAPI_Cut aCutter(aBox.Shape(), aSphere.Shape());
|
||||
}
|
||||
meter.Kill();
|
||||
}
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
// Test basic creation and auto-start functionality
|
||||
TEST_F(OSD_PerfMeterTest, BasicCreationWithAutoStart)
|
||||
{
|
||||
// Create an auto-started meter
|
||||
OSD_PerfMeter meter("TestMeter", true);
|
||||
|
||||
// Do some work
|
||||
DoSomeWork();
|
||||
|
||||
// Stop the meter
|
||||
meter.Stop();
|
||||
|
||||
// Check elapsed time is positive
|
||||
double elapsed = meter.Elapsed();
|
||||
EXPECT_GT(elapsed, 0.0) << "Elapsed time should be positive";
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
// Test manual start/stop functionality
|
||||
TEST_F(OSD_PerfMeterTest, ManualStartStop)
|
||||
{
|
||||
// Create a meter without auto-start
|
||||
OSD_PerfMeter meter("ManualMeter", false);
|
||||
|
||||
// Start the meter
|
||||
meter.Start();
|
||||
|
||||
// Do some work
|
||||
DoSomeWork();
|
||||
|
||||
// Stop the meter
|
||||
meter.Stop();
|
||||
|
||||
// Check elapsed time is positive
|
||||
double elapsed = meter.Elapsed();
|
||||
EXPECT_GT(elapsed, 0.0) << "Elapsed time should be positive";
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
// Test default constructor and Init
|
||||
TEST_F(OSD_PerfMeterTest, DefaultConstructorAndInit)
|
||||
{
|
||||
// Create meter with default constructor
|
||||
OSD_PerfMeter meter;
|
||||
|
||||
// Initialize it
|
||||
meter.Init("InitializedMeter");
|
||||
|
||||
// Start it manually
|
||||
meter.Start();
|
||||
|
||||
// Do some work
|
||||
DoSomeWork();
|
||||
|
||||
// Stop and check elapsed time
|
||||
meter.Stop();
|
||||
EXPECT_GT(meter.Elapsed(), 0.0) << "Initialized meter should have positive elapsed time";
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
// Test that two meters with the same name refer to the same internal meter
|
||||
TEST_F(OSD_PerfMeterTest, SharedMetersByName)
|
||||
{
|
||||
const char* meterName = "SharedMeter";
|
||||
|
||||
// Create and start first meter
|
||||
OSD_PerfMeter meter1(meterName);
|
||||
|
||||
// Do some work
|
||||
DoSomeWork();
|
||||
|
||||
// Create second meter with the same name, but don't auto-start
|
||||
OSD_PerfMeter meter2;
|
||||
meter2.Init(meterName);
|
||||
|
||||
// Do more work
|
||||
DoSomeWork();
|
||||
|
||||
// Stop both meters
|
||||
meter1.Stop();
|
||||
|
||||
// The elapsed time should account for both work segments
|
||||
double elapsed = meter1.Elapsed();
|
||||
EXPECT_GT(elapsed, 0.0) << "Elapsed time should be positive";
|
||||
|
||||
// Stopping meter2 should have no effect since they share the same meter
|
||||
// and meter1 already stopped it
|
||||
meter2.Stop();
|
||||
double elapsed2 = meter2.Elapsed();
|
||||
EXPECT_DOUBLE_EQ(elapsed, elapsed2) << "Both meter instances should show same elapsed time";
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
// Test restarting a meter
|
||||
TEST_F(OSD_PerfMeterTest, RestartMeter)
|
||||
{
|
||||
// Create and start meter
|
||||
OSD_PerfMeter meter("RestartMeter");
|
||||
|
||||
// Do some work
|
||||
DoSomeWork(0.1);
|
||||
|
||||
// Stop and get elapsed time
|
||||
meter.Stop();
|
||||
double elapsed1 = meter.Elapsed();
|
||||
EXPECT_GT(elapsed1, 0.0) << "First elapsed time should be positive";
|
||||
|
||||
// Restart the meter
|
||||
meter.Start();
|
||||
|
||||
// Do more work
|
||||
DoSomeWork(0.2);
|
||||
|
||||
// Stop and get elapsed time again
|
||||
meter.Stop();
|
||||
double elapsed2 = meter.Elapsed();
|
||||
EXPECT_GT(elapsed2, 0.0) << "Second elapsed time should be positive";
|
||||
|
||||
// Second elapsed time should be different from first
|
||||
EXPECT_NE(elapsed1, elapsed2) << "After restart, elapsed time should be different";
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
// Test relative timing accuracy
|
||||
TEST_F(OSD_PerfMeterTest, RelativeTimingAccuracy)
|
||||
{
|
||||
// Create two meters
|
||||
OSD_PerfMeter meter1("ShortMeter");
|
||||
OSD_PerfMeter meter2("LongMeter");
|
||||
|
||||
// Short work for meter1
|
||||
DoSomeWork(0.1);
|
||||
meter1.Stop();
|
||||
|
||||
// Long work for meter2
|
||||
DoSomeWork(0.5);
|
||||
meter2.Stop();
|
||||
|
||||
// Long work should take more time than short work
|
||||
double shortElapsed = meter1.Elapsed();
|
||||
double longElapsed = meter2.Elapsed();
|
||||
|
||||
EXPECT_GT(shortElapsed, 0.0) << "Short elapsed time should be positive";
|
||||
EXPECT_GT(longElapsed, 0.0) << "Long elapsed time should be positive";
|
||||
EXPECT_GT(longElapsed, shortElapsed) << "Long work should take more time than short work";
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
// Test the static PrintALL method
|
||||
TEST_F(OSD_PerfMeterTest, PrintALL)
|
||||
{
|
||||
// Create and use several meters
|
||||
OSD_PerfMeter meter1("Meter1");
|
||||
DoSomeWork(0.1);
|
||||
meter1.Stop();
|
||||
|
||||
OSD_PerfMeter meter2("Meter2");
|
||||
DoSomeWork(0.2);
|
||||
meter2.Stop();
|
||||
|
||||
OSD_PerfMeter meter3("Meter3");
|
||||
DoSomeWork(0.3);
|
||||
meter3.Stop();
|
||||
|
||||
// Get the printed output
|
||||
std::string output = OSD_PerfMeter::PrintALL().ToCString();
|
||||
|
||||
// Check that the output contains all meter names
|
||||
EXPECT_TRUE(output.find("Meter1") != std::string::npos)
|
||||
<< "PrintALL output should contain Meter1";
|
||||
EXPECT_TRUE(output.find("Meter2") != std::string::npos)
|
||||
<< "PrintALL output should contain Meter2";
|
||||
EXPECT_TRUE(output.find("Meter3") != std::string::npos)
|
||||
<< "PrintALL output should contain Meter3";
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
// Test the static ResetALL method
|
||||
TEST_F(OSD_PerfMeterTest, ResetALL)
|
||||
{
|
||||
// Create and use several meters
|
||||
OSD_PerfMeter meter1("ResetMeter1");
|
||||
DoSomeWork(0.1);
|
||||
meter1.Stop();
|
||||
|
||||
OSD_PerfMeter meter2("ResetMeter2");
|
||||
DoSomeWork(0.2);
|
||||
meter2.Stop();
|
||||
|
||||
// Both meters should have positive elapsed times
|
||||
EXPECT_GT(meter1.Elapsed(), 0.0);
|
||||
EXPECT_GT(meter2.Elapsed(), 0.0);
|
||||
|
||||
// Reset all meters
|
||||
OSD_PerfMeter::ResetALL();
|
||||
|
||||
// After reset, all meters should have zero elapsed time
|
||||
EXPECT_EQ(meter1.Elapsed(), 0.0) << "Elapsed time should be zero after ResetALL";
|
||||
EXPECT_EQ(meter2.Elapsed(), 0.0) << "Elapsed time should be zero after ResetALL";
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
// Test unused meter behavior
|
||||
TEST_F(OSD_PerfMeterTest, UnusedMeter)
|
||||
{
|
||||
// Create a meter but don't start it
|
||||
OSD_PerfMeter meter("UnusedMeter", false);
|
||||
|
||||
// Elapsed time should be zero
|
||||
EXPECT_EQ(meter.Elapsed(), 0.0) << "Unused meter should have zero elapsed time, actual";
|
||||
|
||||
// Stopping not started meter should have no effect
|
||||
meter.Stop();
|
||||
EXPECT_EQ(meter.Elapsed(), 0.0) << "Stopping an unused meter should leave elapsed time at zero";
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
// Test the Print() method
|
||||
TEST_F(OSD_PerfMeterTest, PrintMethod)
|
||||
{
|
||||
// Create and start the meter
|
||||
const TCollection_AsciiString meterName = "PrintTestMeter";
|
||||
OSD_PerfMeter meter(meterName);
|
||||
|
||||
// Do some work
|
||||
DoSomeWork();
|
||||
|
||||
// Stop the meter
|
||||
meter.Stop();
|
||||
|
||||
// Get the printed output
|
||||
std::string output = meter.Print().ToCString();
|
||||
|
||||
// Verify output contains necessary information
|
||||
EXPECT_TRUE(output.find(meterName.ToCString()) != std::string::npos)
|
||||
<< "Print output should contain meter name";
|
||||
|
||||
// Verify output contains elapsed time info (we can't check exact time,
|
||||
// but there should be numbers)
|
||||
EXPECT_TRUE(output.find_first_of("0123456789") != std::string::npos)
|
||||
<< "Print output should contain elapsed time values";
|
||||
|
||||
EXPECT_TRUE(output.find("sec") != std::string::npos)
|
||||
<< "Print output should contain millisecond units";
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
// Test the Kill() method
|
||||
TEST_F(OSD_PerfMeterTest, KillMethod)
|
||||
{
|
||||
// Create and start the meter
|
||||
OSD_PerfMeter meter("KillTestMeter");
|
||||
|
||||
// Do some work
|
||||
DoSomeWork();
|
||||
|
||||
// Stop the meter
|
||||
meter.Stop();
|
||||
|
||||
// Verify we have non-zero elapsed time
|
||||
double elapsed = meter.Elapsed();
|
||||
EXPECT_GT(elapsed, 0.0) << "Meter should have recorded time before Kill";
|
||||
|
||||
// Kill the meter
|
||||
meter.Kill();
|
||||
|
||||
// Verify elapsed time is reset
|
||||
double elapsedAfterKill = meter.Elapsed();
|
||||
EXPECT_EQ(elapsedAfterKill, 0.0) << "Elapsed time should be reset after Kill";
|
||||
|
||||
// Verify killing a meter makes it disappear from the global list
|
||||
std::string allMeters = OSD_PerfMeter::PrintALL().ToCString();
|
||||
EXPECT_TRUE(allMeters.find("KillTestMeter") == std::string::npos)
|
||||
<< "Killed meter should not appear in PrintALL output";
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
// Test Kill method on a running meter
|
||||
TEST_F(OSD_PerfMeterTest, KillRunningMeter)
|
||||
{
|
||||
// Create and start the meter
|
||||
OSD_PerfMeter meter("KillRunningMeter");
|
||||
|
||||
// Don't stop the meter, kill it while running
|
||||
meter.Kill();
|
||||
|
||||
// Verify elapsed time is reset
|
||||
double elapsedAfterKill = meter.Elapsed();
|
||||
EXPECT_EQ(elapsedAfterKill, 0.0) << "Elapsed time should be reset after Kill";
|
||||
|
||||
// Start the meter again to verify it's usable after being killed
|
||||
meter.Init("KillRunningMeter");
|
||||
meter.Start();
|
||||
DoSomeWork();
|
||||
meter.Stop();
|
||||
|
||||
// Verify it records time correctly after being killed and restarted
|
||||
EXPECT_GT(meter.Elapsed(), 0.0) << "Meter should record time after Kill and restart";
|
||||
}
|
@ -66,7 +66,6 @@ set(OCCT_OSD_FILES
|
||||
OSD_Path.cxx
|
||||
OSD_Path.hxx
|
||||
OSD_PerfMeter.cxx
|
||||
OSD_PerfMeter.h
|
||||
OSD_PerfMeter.hxx
|
||||
OSD_Process.cxx
|
||||
OSD_Process.hxx
|
||||
|
@ -15,389 +15,379 @@
|
||||
commercial license or contractual agreement.
|
||||
*/
|
||||
|
||||
/*======================================================================
|
||||
*/
|
||||
/*Purpose : Set of functions to measure the CPU user time
|
||||
*/
|
||||
/*25/09/2001 : AGV : (const char *) in prototypes;
|
||||
*/
|
||||
/*09/11/2001 : AGV : Add functions perf_*_imeter for performance
|
||||
*/
|
||||
/*Add function perf_tick_meter
|
||||
*/
|
||||
/*14/05/2002 : AGV : Portability UNIX/Windows
|
||||
*/
|
||||
/*======================================================================*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <OSD_PerfMeter.hxx>
|
||||
|
||||
#include <OSD_Chronometer.hxx>
|
||||
#include <OSD_PerfMeter.h>
|
||||
|
||||
/*======================================================================
|
||||
DEFINITIONS
|
||||
======================================================================*/
|
||||
#include <unordered_map>
|
||||
|
||||
typedef Standard_Real PERF_TIME;
|
||||
// Simple stopwatch class to measure elapsed time
|
||||
// and provides methods to start, stop, and get the elapsed time in seconds.
|
||||
class Stopwatch
|
||||
{
|
||||
public:
|
||||
// Constructor initializes the stopwatch.
|
||||
// It does not start the stopwatch.
|
||||
Stopwatch();
|
||||
|
||||
#define PICK_TIME(_utime) \
|
||||
{ \
|
||||
Standard_Real ktime; \
|
||||
OSD_Chronometer::GetThreadCPU(_utime, ktime); \
|
||||
// Starts the stopwatch. If it is already running, it resets the start time.
|
||||
void Start();
|
||||
|
||||
// Stops the stopwatch. If it is already stopped, it does nothing.
|
||||
void Stop();
|
||||
|
||||
// Returns the elapsed time in seconds since the stopwatch was started.
|
||||
// If the stopwatch is still running, it returns the time since the last start.
|
||||
// If the stopwatch was stopped, it returns the time between the last start and stop.
|
||||
// If the stopwatch was never started, it returns 0.
|
||||
double Elapsed() const;
|
||||
|
||||
// Returns true if the stopwatch is currently running.
|
||||
// Returns false if the stopwatch is stopped or was never started.
|
||||
inline bool IsRunning() const;
|
||||
|
||||
// Returns true if the stopwatch has been started at least once and has a non-zero elapsed time.
|
||||
// Returns false if the stopwatch was never started or has zero elapsed time.
|
||||
inline bool IsActive() const;
|
||||
|
||||
private:
|
||||
// Returns the current time in seconds.
|
||||
static double getTime();
|
||||
|
||||
private:
|
||||
double myStartTime; //< The time when the stopwatch was started.
|
||||
double myEndTime; //< The time when the stopwatch was stopped.
|
||||
// Equal to myStartTime if the stopwatch is
|
||||
// running or was never started.
|
||||
bool myIsTicking; //< Indicates whether the stopwatch is
|
||||
// currently running.
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
Stopwatch::Stopwatch()
|
||||
: myStartTime(getTime()),
|
||||
myEndTime(myStartTime),
|
||||
myIsTicking(false)
|
||||
{
|
||||
}
|
||||
|
||||
typedef struct
|
||||
//==================================================================================================
|
||||
|
||||
void Stopwatch::Start()
|
||||
{
|
||||
char* name; /* identifier */
|
||||
PERF_TIME cumul_time; /* cumulative time */
|
||||
PERF_TIME start_time; /* to store start time */
|
||||
int nb_enter; /* number of enters */
|
||||
} t_TimeCounter;
|
||||
|
||||
#define MAX_METERS 100
|
||||
|
||||
static t_TimeCounter MeterTable[MAX_METERS];
|
||||
static int nb_meters = 0;
|
||||
|
||||
static int find_meter(const char* const MeterName);
|
||||
static int _perf_init_meter(const char* const MeterName, const int doFind);
|
||||
|
||||
/*======================================================================
|
||||
Function : perf_init_meter
|
||||
Purpose : Creates new counter (if it is absent) identified by
|
||||
MeterName and resets its cumulative value
|
||||
Returns : iMeter if OK, -1 if alloc problem
|
||||
======================================================================*/
|
||||
int perf_init_meter(const char* const MeterName)
|
||||
{
|
||||
return _perf_init_meter(MeterName, ~0);
|
||||
myStartTime = getTime();
|
||||
myIsTicking = true;
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
Function : perf_tick_meter
|
||||
Purpose : Increments the counter of meter MeterName without changing
|
||||
its state with respect to measurement of time.
|
||||
creates new meter if there is no such meter
|
||||
Returns : iMeter if OK, -1 if no such meter and cannot create a new one
|
||||
======================================================================*/
|
||||
int perf_tick_meter(const char* const MeterName)
|
||||
{
|
||||
int ic = find_meter(MeterName);
|
||||
//==================================================================================================
|
||||
|
||||
if (ic == -1)
|
||||
void Stopwatch::Stop()
|
||||
{
|
||||
/* create new meter */
|
||||
ic = _perf_init_meter(MeterName, 0);
|
||||
if (!myIsTicking)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (ic >= 0)
|
||||
MeterTable[ic].nb_enter++;
|
||||
|
||||
return ic;
|
||||
myEndTime = getTime();
|
||||
myIsTicking = false;
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
Function : perf_tick_imeter
|
||||
Purpose : Increments the counter of meter iMeter without changing
|
||||
its state with respect to measurement of time.
|
||||
Returns : iMeter if OK, -1 if no such meter
|
||||
======================================================================*/
|
||||
int perf_tick_imeter(const int iMeter)
|
||||
//==================================================================================================
|
||||
|
||||
double Stopwatch::Elapsed() const
|
||||
{
|
||||
if (iMeter >= 0 && iMeter < nb_meters)
|
||||
{
|
||||
MeterTable[iMeter].nb_enter++;
|
||||
return iMeter;
|
||||
}
|
||||
return -1;
|
||||
const double anEndTime = myIsTicking ? getTime() : myEndTime;
|
||||
return anEndTime - myStartTime;
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
Function : perf_start_meter
|
||||
Purpose : Forces meter MeterName to begin to count by remembering
|
||||
the current data of timer;
|
||||
creates new meter if there is no such meter
|
||||
Returns : iMeter if OK, -1 if no such meter and cannot create a new one
|
||||
======================================================================*/
|
||||
int perf_start_meter(const char* const MeterName)
|
||||
{
|
||||
int ic = find_meter(MeterName);
|
||||
//==================================================================================================
|
||||
|
||||
if (ic == -1)
|
||||
bool Stopwatch::IsRunning() const
|
||||
{
|
||||
/* create new meter */
|
||||
ic = _perf_init_meter(MeterName, 0);
|
||||
return myIsTicking;
|
||||
}
|
||||
|
||||
if (ic >= 0)
|
||||
PICK_TIME(MeterTable[ic].start_time)
|
||||
//==================================================================================================
|
||||
|
||||
return ic;
|
||||
bool Stopwatch::IsActive() const
|
||||
{
|
||||
return myIsTicking || (myEndTime - myStartTime) > 0.0;
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
Function : perf_start_imeter
|
||||
Purpose : Forces meter with number iMeter to begin count by remembering
|
||||
the current data of timer;
|
||||
the meter must be previously created
|
||||
Returns : iMeter if OK, -1 if no such meter
|
||||
======================================================================*/
|
||||
int perf_start_imeter(const int iMeter)
|
||||
//==================================================================================================
|
||||
|
||||
double Stopwatch::getTime()
|
||||
{
|
||||
if (iMeter >= 0 && iMeter < nb_meters)
|
||||
{
|
||||
PICK_TIME(MeterTable[iMeter].start_time)
|
||||
return iMeter;
|
||||
}
|
||||
return -1;
|
||||
Standard_Real aUserSeconds = 0.0;
|
||||
Standard_Real aSystemSeconds = 0.0;
|
||||
OSD_Chronometer::GetThreadCPU(aUserSeconds, aSystemSeconds);
|
||||
(void)(aSystemSeconds); // Unused variable
|
||||
return aUserSeconds;
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
Function : perf_stop_meter
|
||||
Purpose : Forces meter MeterName to stop and cumulate time elapsed
|
||||
since start
|
||||
Returns : iMeter if OK, -1 if no such meter or it is has not been started
|
||||
======================================================================*/
|
||||
int perf_stop_meter(const char* const MeterName)
|
||||
{
|
||||
const int ic = find_meter(MeterName);
|
||||
//==================================================================================================
|
||||
|
||||
if (ic >= 0 && MeterTable[ic].start_time)
|
||||
// Singleton class to manage multiple stopwatches.
|
||||
// It provides methods to create, retrieve, and print stopwatches by name.
|
||||
// It also handles the lifetime of the stopwatches and prints their results when the program ends.
|
||||
// The class is designed to be used as a singleton, ensuring that there is only one instance of the
|
||||
// stopwatch manager throughout the program.
|
||||
class StopwatchStorage
|
||||
{
|
||||
t_TimeCounter* const ptc = &MeterTable[ic];
|
||||
PERF_TIME utime;
|
||||
PICK_TIME(utime)
|
||||
ptc->cumul_time += utime - ptc->start_time;
|
||||
ptc->start_time = 0;
|
||||
ptc->nb_enter++;
|
||||
private:
|
||||
StopwatchStorage() = default;
|
||||
StopwatchStorage(const StopwatchStorage&) = delete;
|
||||
StopwatchStorage& operator=(const StopwatchStorage&) = delete;
|
||||
StopwatchStorage(StopwatchStorage&&) = delete;
|
||||
StopwatchStorage& operator=(StopwatchStorage&&) = delete;
|
||||
|
||||
~StopwatchStorage() { PrintAll(); }
|
||||
|
||||
public:
|
||||
// Returns the singleton instance of the StopwatchStorage class.
|
||||
static StopwatchStorage& Instance();
|
||||
|
||||
// Retrieves a stopwatch by name. If the stopwatch does not exist, it returns nullptr.
|
||||
// If the stopwatch exists, it returns a pointer to the stopwatch.
|
||||
// This allows the user to access and manipulate the stopwatch directly.
|
||||
// @param theName The name of the stopwatch to retrieve.
|
||||
// @return A pointer to the stopwatch if it exists, nullptr otherwise.
|
||||
Stopwatch* GetStopwatch(const std::string& theName);
|
||||
|
||||
// Creates a new stopwatch with the specified name.
|
||||
// If a stopwatch with the same name already exists, it will be replaced.
|
||||
// @param theName The name of the stopwatch to create.
|
||||
// @return A reference to the created stopwatch.
|
||||
Stopwatch& CreateStopwatch(const std::string& theName);
|
||||
|
||||
// Checks if a stopwatch with the specified name exists.
|
||||
// This method allows the user to check if a stopwatch is already created before attempting to
|
||||
// create or retrieve it.
|
||||
// @param theName The name of the stopwatch to check.
|
||||
// @return True if the stopwatch exists, false otherwise.
|
||||
bool HasStopwatch(const std::string& theName) const;
|
||||
|
||||
// Deletes a stopwatch with the specified name.
|
||||
// If the stopwatch does not exist, it does nothing.
|
||||
// This method allows the user to remove a stopwatch from the storage.
|
||||
// @param theName The name of the stopwatch to delete.
|
||||
// @return True if the stopwatch was successfully deleted, false otherwise.
|
||||
void KillStopwatch(const std::string& theName);
|
||||
|
||||
// Clears all stopwatches from the storage.
|
||||
// This method removes all stopwatches and resets the storage to its initial state.
|
||||
// It is useful for cleaning up the storage when it is no longer needed.
|
||||
void Clear();
|
||||
|
||||
// Prints the results of a specific stopwatch by name.
|
||||
// If the stopwatch does not exist, it does nothing.
|
||||
// If the stopwatch is still running, it prints a warning message.
|
||||
// If the stopwatch was never started, it prints a message indicating that.
|
||||
// @param theName The name of the stopwatch to print.
|
||||
// @return A string containing the results of the stopwatch.
|
||||
std::string Print(const std::string& theName) const;
|
||||
|
||||
// Prints the results of all stopwatches in the storage.
|
||||
// It iterates through all stopwatches and prints their results.
|
||||
// If a stopwatch is still running, it prints a warning message.
|
||||
// If a stopwatch was never started, it prints a message indicating that.
|
||||
// @return A string containing the results of all stopwatches.
|
||||
std::string PrintAll() const;
|
||||
|
||||
private:
|
||||
// Helper method to print the results of a specific stopwatch.
|
||||
// It formats the output and appends it to the provided output string.
|
||||
// @param theName The name of the stopwatch to print.
|
||||
// @param theOutput The output string to append the results to.
|
||||
void print(const std::string& theName, std::string& theOutput) const;
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, Stopwatch> myStopwatches; //< Map to store stopwatches by name.
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
StopwatchStorage& StopwatchStorage::Instance()
|
||||
{
|
||||
static StopwatchStorage instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
return ic;
|
||||
//===================================================================================================
|
||||
|
||||
Stopwatch* StopwatchStorage::GetStopwatch(const std::string& theName)
|
||||
{
|
||||
auto it = myStopwatches.find(theName);
|
||||
return (it != myStopwatches.end()) ? &it->second : nullptr;
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
Function : perf_stop_imeter
|
||||
Purpose : Forces meter with number iMeter to stop and cumulate the time
|
||||
elapsed since the start
|
||||
Returns : iMeter if OK, -1 if no such meter or it is has not been started
|
||||
======================================================================*/
|
||||
int perf_stop_imeter(const int iMeter)
|
||||
//===================================================================================================
|
||||
|
||||
Stopwatch& StopwatchStorage::CreateStopwatch(const std::string& theName)
|
||||
{
|
||||
if (iMeter >= 0 && iMeter < nb_meters)
|
||||
{
|
||||
t_TimeCounter* const ptc = &MeterTable[iMeter];
|
||||
if (ptc->start_time)
|
||||
{
|
||||
PERF_TIME utime;
|
||||
PICK_TIME(utime)
|
||||
ptc->cumul_time += utime - ptc->start_time;
|
||||
ptc->start_time = 0;
|
||||
ptc->nb_enter++;
|
||||
return iMeter;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
myStopwatches[theName] = Stopwatch();
|
||||
return myStopwatches[theName];
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
Function : perf_get_meter
|
||||
Purpose : Tells the time cumulated by meter MeterName and the number
|
||||
of enters to this meter
|
||||
Output : *nb_enter, *seconds if the pointers != NULL
|
||||
Returns : iMeter if OK, -1 if no such meter
|
||||
======================================================================*/
|
||||
int perf_get_meter(const char* const MeterName, int* nb_enter, double* seconds)
|
||||
{
|
||||
const int ic = find_meter(MeterName);
|
||||
//===================================================================================================
|
||||
|
||||
if (ic >= 0)
|
||||
bool StopwatchStorage::HasStopwatch(const std::string& theName) const
|
||||
{
|
||||
if (nb_enter)
|
||||
*nb_enter = MeterTable[ic].nb_enter;
|
||||
if (seconds)
|
||||
*seconds = MeterTable[ic].cumul_time;
|
||||
}
|
||||
return ic;
|
||||
return myStopwatches.find(theName) != myStopwatches.end();
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
Function : perf_print_all_meters
|
||||
Purpose : Prints on stdout the cumulated time and the number of
|
||||
enters for each meter in MeterTable;
|
||||
resets all meters if reset is non-null
|
||||
======================================================================*/
|
||||
void perf_print_all_meters(int reset)
|
||||
//===================================================================================================
|
||||
|
||||
void StopwatchStorage::KillStopwatch(const std::string& theName)
|
||||
{
|
||||
char buffer[MAX_METERS * 256];
|
||||
perf_sprint_all_meters(buffer, MAX_METERS * 256, reset);
|
||||
printf("%s", buffer);
|
||||
myStopwatches.erase(theName);
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
Function : perf_print_all_meters
|
||||
Purpose : Prints to string buffer the cumulated time and the number of
|
||||
enters for each meter in MeterTable;
|
||||
resets all meters if reset is non-null
|
||||
======================================================================*/
|
||||
void perf_sprint_all_meters(char* buffer, int length, int reset)
|
||||
{
|
||||
char string[256];
|
||||
//===================================================================================================
|
||||
|
||||
int i;
|
||||
for (i = 0; i < nb_meters; i++)
|
||||
void StopwatchStorage::Clear()
|
||||
{
|
||||
const t_TimeCounter* const ptc = &MeterTable[i];
|
||||
if (ptc && ptc->nb_enter)
|
||||
{
|
||||
int n =
|
||||
sprintf(string,
|
||||
" Perf meter results : enters seconds microsec/enter\n");
|
||||
if (n < length)
|
||||
{
|
||||
memcpy(buffer, string, n);
|
||||
buffer += n;
|
||||
length -= n;
|
||||
myStopwatches.clear();
|
||||
}
|
||||
break;
|
||||
|
||||
//===================================================================================================
|
||||
|
||||
std::string StopwatchStorage::Print(const std::string& theName) const
|
||||
{
|
||||
std::string anOutput;
|
||||
auto it = myStopwatches.find(theName);
|
||||
if (it != myStopwatches.end())
|
||||
{
|
||||
print(theName, anOutput);
|
||||
}
|
||||
return anOutput;
|
||||
}
|
||||
|
||||
//===================================================================================================
|
||||
|
||||
std::string StopwatchStorage::PrintAll() const
|
||||
{
|
||||
std::string anOutput;
|
||||
for (const auto& aStopwatch : myStopwatches)
|
||||
{
|
||||
print(aStopwatch.first, anOutput);
|
||||
}
|
||||
return anOutput;
|
||||
}
|
||||
|
||||
//===================================================================================================
|
||||
|
||||
void StopwatchStorage::print(const std::string& theName, std::string& theOutput) const
|
||||
{
|
||||
auto it = myStopwatches.find(theName);
|
||||
if (it == myStopwatches.end())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!it->second.IsActive())
|
||||
{
|
||||
theOutput += "Stopwatch " + theName + " have never been started.\n";
|
||||
return;
|
||||
}
|
||||
|
||||
if (it->second.IsRunning())
|
||||
{
|
||||
theOutput += "Warning: Stopwatch " + theName + " is still running.\n";
|
||||
return;
|
||||
}
|
||||
theOutput += "Stopwatch " + theName + ": " + std::to_string(it->second.Elapsed()) + " sec\n";
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
OSD_PerfMeter::OSD_PerfMeter(const TCollection_AsciiString& theMeterName, const bool theToAutoStart)
|
||||
{
|
||||
Init(theMeterName);
|
||||
|
||||
if (theToAutoStart)
|
||||
{
|
||||
Start();
|
||||
}
|
||||
}
|
||||
|
||||
while (i < nb_meters)
|
||||
//==================================================================================================
|
||||
|
||||
OSD_PerfMeter::~OSD_PerfMeter() {}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
void OSD_PerfMeter::Init(const TCollection_AsciiString& theMeterName)
|
||||
{
|
||||
t_TimeCounter* const ptc = &MeterTable[i++];
|
||||
|
||||
if (ptc && ptc->nb_enter)
|
||||
myMeterName = theMeterName;
|
||||
if (!StopwatchStorage::Instance().HasStopwatch(myMeterName.ToCString()))
|
||||
{
|
||||
const double secs = ptc->cumul_time;
|
||||
StopwatchStorage::Instance().CreateStopwatch(myMeterName.ToCString());
|
||||
}
|
||||
}
|
||||
|
||||
int n = 0;
|
||||
if (ptc->start_time)
|
||||
n = sprintf(string, "Warning : meter %42s has not been stopped\n", ptc->name);
|
||||
//==================================================================================================
|
||||
|
||||
n += sprintf(string + n,
|
||||
"%-42s : %7d %8.2f %10.2f\n",
|
||||
ptc->name,
|
||||
ptc->nb_enter,
|
||||
secs,
|
||||
(secs > 0. ? 1000000 * secs / ptc->nb_enter : 0.));
|
||||
if (n < length)
|
||||
void OSD_PerfMeter::Start() const
|
||||
{
|
||||
memcpy(buffer, string, n);
|
||||
buffer += n;
|
||||
length -= n;
|
||||
}
|
||||
|
||||
if (reset)
|
||||
Stopwatch* aStopwatch = StopwatchStorage::Instance().GetStopwatch(myMeterName.ToCString());
|
||||
if (aStopwatch != nullptr)
|
||||
{
|
||||
ptc->cumul_time = 0;
|
||||
ptc->start_time = 0;
|
||||
ptc->nb_enter = 0;
|
||||
aStopwatch->Start();
|
||||
}
|
||||
}
|
||||
}
|
||||
*buffer = '\0';
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
Function : perf_close_meter
|
||||
Purpose : Prints out a meter and resets it
|
||||
Returns : none
|
||||
======================================================================*/
|
||||
void perf_close_meter(const char* const MeterName)
|
||||
//==================================================================================================
|
||||
|
||||
void OSD_PerfMeter::Stop() const
|
||||
{
|
||||
perf_close_imeter(find_meter(MeterName));
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
Function : perf_close_imeter
|
||||
Purpose : Prints out a meter and resets it
|
||||
Returns : none
|
||||
======================================================================*/
|
||||
void perf_close_imeter(const int iMeter)
|
||||
Stopwatch* aStopwatch = StopwatchStorage::Instance().GetStopwatch(myMeterName.ToCString());
|
||||
if (aStopwatch != nullptr)
|
||||
{
|
||||
if (iMeter >= 0 && iMeter < nb_meters && MeterTable[iMeter].nb_enter)
|
||||
aStopwatch->Stop();
|
||||
}
|
||||
}
|
||||
|
||||
//==================================================================================================
|
||||
|
||||
double OSD_PerfMeter::Elapsed() const
|
||||
{
|
||||
t_TimeCounter* const ptc = &MeterTable[iMeter];
|
||||
if (ptc->start_time)
|
||||
printf(" ===> Warning : meter %s has not been stopped\n", ptc->name);
|
||||
printf(" ===> [%s] : %d enters, %9.3f seconds\n", ptc->name, ptc->nb_enter, ptc->cumul_time);
|
||||
ptc->cumul_time = 0;
|
||||
ptc->start_time = 0;
|
||||
ptc->nb_enter = 0;
|
||||
}
|
||||
Stopwatch* aStopwatch = StopwatchStorage::Instance().GetStopwatch(myMeterName.ToCString());
|
||||
return aStopwatch ? aStopwatch->Elapsed() : 0.0;
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
Function : perf_destroy_all_meters
|
||||
Purpose : Deletes all meters and frees memory
|
||||
Returns : none
|
||||
======================================================================*/
|
||||
void perf_destroy_all_meters(void)
|
||||
//==================================================================================================
|
||||
|
||||
void OSD_PerfMeter::Kill() const
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < nb_meters; i++)
|
||||
free(MeterTable[i].name);
|
||||
nb_meters = 0;
|
||||
StopwatchStorage::Instance().KillStopwatch(myMeterName.ToCString());
|
||||
}
|
||||
|
||||
/* agv - non portable: #pragma fini (perf_print_and_destroy)
|
||||
using atexit instead (see _perf_init_meter below) */
|
||||
//==================================================================================================
|
||||
|
||||
void perf_print_and_destroy(void)
|
||||
TCollection_AsciiString OSD_PerfMeter::Print() const
|
||||
{
|
||||
perf_print_all_meters(0);
|
||||
perf_destroy_all_meters();
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
Function : _perf_init_meter
|
||||
Purpose : Creates new counter (if it is absent) identified by
|
||||
MeterName and resets its cumulative value
|
||||
Returns : index of meter if OK, -1 if alloc problem
|
||||
Remarks : For internal use in this module
|
||||
======================================================================*/
|
||||
static int _perf_init_meter(const char* const MeterName, const int doFind)
|
||||
Stopwatch* aStopwatch = StopwatchStorage::Instance().GetStopwatch(myMeterName.ToCString());
|
||||
if (aStopwatch != nullptr)
|
||||
{
|
||||
static int hasbeencalled = 0;
|
||||
int ic = -1;
|
||||
if (doFind)
|
||||
ic = find_meter(MeterName);
|
||||
const std::string anOutput = StopwatchStorage::Instance().Print(myMeterName.ToCString());
|
||||
return anOutput.c_str();
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
if (ic == -1)
|
||||
//==================================================================================================
|
||||
|
||||
TCollection_AsciiString OSD_PerfMeter::PrintALL()
|
||||
{
|
||||
if (nb_meters >= MAX_METERS)
|
||||
return 0;
|
||||
ic = nb_meters;
|
||||
|
||||
MeterTable[ic].name = strdup(MeterName);
|
||||
if (!MeterTable[ic].name)
|
||||
return -1;
|
||||
|
||||
nb_meters++;
|
||||
const std::string anOutput = StopwatchStorage::Instance().PrintAll();
|
||||
return anOutput.c_str();
|
||||
}
|
||||
|
||||
MeterTable[ic].cumul_time = 0;
|
||||
MeterTable[ic].start_time = 0;
|
||||
MeterTable[ic].nb_enter = 0;
|
||||
if (hasbeencalled == 0)
|
||||
//==================================================================================================
|
||||
|
||||
void OSD_PerfMeter::ResetALL()
|
||||
{
|
||||
atexit(perf_print_and_destroy);
|
||||
hasbeencalled = ~0;
|
||||
}
|
||||
return ic;
|
||||
}
|
||||
|
||||
/*======================================================================
|
||||
Function : find_meter
|
||||
Purpose : Finds the meter MeterName in the MeterTable
|
||||
Returns : Index of meter object, -1 if not found
|
||||
Remarks : For internal use in this module
|
||||
======================================================================*/
|
||||
static int find_meter(const char* const MeterName)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < nb_meters; i++)
|
||||
if (!strcmp(MeterTable[i].name, MeterName))
|
||||
return i;
|
||||
return -1;
|
||||
StopwatchStorage::Instance().Clear();
|
||||
}
|
||||
|
@ -1,182 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 1999-2014 OPEN CASCADE SAS
|
||||
|
||||
This file is part of Open CASCADE Technology software library.
|
||||
|
||||
This library is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU Lesser General Public License version 2.1 as published
|
||||
by the Free Software Foundation, with special exception defined in the file
|
||||
OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
|
||||
distribution for complete text of the license and disclaimer of any warranty.
|
||||
|
||||
Alternatively, this file may be used under the terms of Open CASCADE
|
||||
commercial license or contractual agreement.
|
||||
*/
|
||||
|
||||
#ifndef _OSD_PERFMETER_H
|
||||
#define _OSD_PERFMETER_H
|
||||
|
||||
/**
|
||||
* Macros for convenient and fast usage of meters.
|
||||
* Define PERF_ENABLE_METERS to make them available.
|
||||
*/
|
||||
#ifdef PERF_ENABLE_METERS
|
||||
|
||||
/**
|
||||
* @def PERF_START_METER(theMeterName)
|
||||
* Forces meter MeterName to begin to count by remembering the current data of timer.
|
||||
* Creates new meter if there is no such meter.
|
||||
*/
|
||||
#define PERF_START_METER(_m_name) \
|
||||
{ \
|
||||
static int __iMeter = -1; \
|
||||
if (__iMeter >= 0) \
|
||||
perf_start_imeter(__iMeter); \
|
||||
else \
|
||||
__iMeter = perf_start_meter(_m_name); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @def PERF_STOP_METER(theMeterName)
|
||||
* Forces meter MeterName to stop and cumulate the time elapsed since the start.
|
||||
*/
|
||||
#define PERF_STOP_METER(_m_name) \
|
||||
{ \
|
||||
static int __iMeter = -1; \
|
||||
if (__iMeter >= 0) \
|
||||
perf_stop_imeter(__iMeter); \
|
||||
else \
|
||||
__iMeter = perf_stop_meter(_m_name); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @def PERF_TICK_METER(theMeterName)
|
||||
* Increments the counter of meter MeterName without changing its state with respect to
|
||||
* measurement of time. Creates new meter if there is no such meter. It is useful to count the
|
||||
* number of enters to a part of code without wasting a time to measure CPU time.
|
||||
*/
|
||||
#define PERF_TICK_METER(_m_name) \
|
||||
{ \
|
||||
static int __iMeter = -1; \
|
||||
if (__iMeter >= 0) \
|
||||
perf_tick_imeter(__iMeter); \
|
||||
else \
|
||||
__iMeter = perf_tick_meter(_m_name); \
|
||||
}
|
||||
|
||||
/**
|
||||
* @def PERF_CLOSE_METER(theMeterName)
|
||||
* Prints out and resets the given meter.
|
||||
*/
|
||||
#define PERF_CLOSE_METER(_m_name) perf_close_meter(_m_name);
|
||||
|
||||
/**
|
||||
* @def PERF_PRINT_ALL
|
||||
* Prints all existing meters which have been entered at least once and resets them.
|
||||
*/
|
||||
#define PERF_PRINT_ALL() \
|
||||
{ \
|
||||
perf_print_all_meters(1); \
|
||||
}
|
||||
|
||||
#else
|
||||
#define PERF_TICK_METER(_m_name)
|
||||
#define PERF_START_METER(_m_name)
|
||||
#define PERF_STOP_METER(_m_name)
|
||||
#define PERF_CLOSE_METER(_m_name)
|
||||
#define PERF_PRINT_ALL()
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Creates new counter (if it is absent) identified by theMeterName and resets its cumulative value
|
||||
* @return meter global identifier if OK, -1 if alloc problem
|
||||
*/
|
||||
Standard_EXPORTEXTERNC int perf_init_meter(const char* const theMeterName);
|
||||
|
||||
/**
|
||||
* Forces meter theMeterName to begin to count by remembering the current data of timer.
|
||||
* Creates new meter if there is no such meter.
|
||||
* @return meter global identifier if OK, -1 if no such meter and cannot create a new one
|
||||
*/
|
||||
Standard_EXPORTEXTERNC int perf_start_meter(const char* const theMeterName);
|
||||
|
||||
/**
|
||||
* Forces meter with number theMeterId to begin count by remembering the current data of timer.
|
||||
* @return meter global identifier if OK, -1 if no such meter
|
||||
*/
|
||||
Standard_EXPORTEXTERNC int perf_start_imeter(const int theMeterId);
|
||||
|
||||
/**
|
||||
* Forces meter theMeterName to stop and cumulate the time elapsed since the start.
|
||||
* @return meter global identifier if OK, -1 if no such meter or it is has not been started
|
||||
*/
|
||||
Standard_EXPORTEXTERNC int perf_stop_meter(const char* const theMeterName);
|
||||
|
||||
/**
|
||||
* Forces meter with number theMeterId to stop and cumulate the time elapsed since the start.
|
||||
* @return meter global identifier if OK, -1 if no such meter or it is has not been started
|
||||
*/
|
||||
Standard_EXPORTEXTERNC int perf_stop_imeter(const int theMeterId);
|
||||
|
||||
/**
|
||||
* Increments the counter of meter theMeterName without changing its state with respect to
|
||||
* measurement of time. Creates new meter if there is no such meter.
|
||||
* @return meter global identifier if OK, -1 if no such meter and cannot create a new one
|
||||
*/
|
||||
Standard_EXPORTEXTERNC int perf_tick_meter(const char* const theMeterName);
|
||||
|
||||
/**
|
||||
* Increments the counter of meter theMeterId without changing its state with respect to measurement
|
||||
* of time.
|
||||
* @return meter global identifier if OK, -1 if no such meter
|
||||
*/
|
||||
Standard_EXPORTEXTERNC int perf_tick_imeter(const int theMeterId);
|
||||
|
||||
/**
|
||||
* Tells the time cumulated by meter theMeterName and the number of enters to this meter.
|
||||
* @param theNbEnter [OUT] number of enters if the pointer != NULL
|
||||
* @param theSeconds [OUT] seconds if the pointer != NULL
|
||||
* @return meter global identifier if OK, -1 if no such meter
|
||||
*/
|
||||
Standard_EXPORTEXTERNC int perf_get_meter(const char* const theMeterName,
|
||||
int* theNbEnter,
|
||||
double* theSeconds);
|
||||
|
||||
/**
|
||||
* Prints on stdout the cumulated time and the number of enters for the specified meter.
|
||||
*/
|
||||
Standard_EXPORTEXTERNC void perf_close_meter(const char* const theMeterName);
|
||||
|
||||
/**
|
||||
* Prints on stdout the cumulated time and the number of enters for the specified meter.
|
||||
*/
|
||||
Standard_EXPORTEXTERNC void perf_close_imeter(const int theMeterId);
|
||||
|
||||
/**
|
||||
* Prints on stdout the cumulated time and the number of enters for each alive meter which have the
|
||||
* number of enters > 0. Resets all meters if reset is non-null.
|
||||
*/
|
||||
Standard_EXPORTEXTERNC void perf_print_all_meters(int reset);
|
||||
|
||||
/**
|
||||
* Prints to supplied string buffer the cumulated time and the number of enters
|
||||
* for each alive meter with the number of enters > 0.
|
||||
* If buffer length is not sufficient, data of some meters may be lost.
|
||||
* It is recommended to reserve 256 bytes per meter, 25600 bytes should fit all.
|
||||
* Resets all meters.
|
||||
*/
|
||||
Standard_EXPORTEXTERNC void perf_sprint_all_meters(char* buffer, int length, int reset);
|
||||
|
||||
/**
|
||||
* Deletes all meters and frees memory.
|
||||
*/
|
||||
Standard_EXPORTEXTERNC void perf_destroy_all_meters(void);
|
||||
|
||||
/**
|
||||
* ATTENTION!!!
|
||||
* This func calls perf_print_all_meters() and perf_destroy_all_meters()
|
||||
* and is called automatically at the end of a program via system call atexit().
|
||||
*/
|
||||
Standard_EXPORTEXTERNC void perf_print_and_destroy(void);
|
||||
|
||||
#endif
|
@ -16,7 +16,8 @@
|
||||
#ifndef OSD_PerfMeter_HeaderFile
|
||||
#define OSD_PerfMeter_HeaderFile
|
||||
|
||||
#include <OSD_PerfMeter.h>
|
||||
#include <Standard_Macro.hxx>
|
||||
#include <TCollection_AsciiString.hxx>
|
||||
|
||||
//! This class enables measuring the CPU time between two points of code execution, regardless of
|
||||
//! the scope of these points of code. A meter is identified by its name (string). So multiple
|
||||
@ -24,57 +25,53 @@
|
||||
//! on stdout upon finish of the program. For details see OSD_PerfMeter.h
|
||||
class OSD_PerfMeter
|
||||
{
|
||||
|
||||
public:
|
||||
//! Constructs a void meter (to further call Init and Start)
|
||||
OSD_PerfMeter()
|
||||
: myIMeter(-1)
|
||||
{
|
||||
}
|
||||
//! Constructs a void meter (to further call Init and Start).
|
||||
Standard_EXPORT OSD_PerfMeter() = default;
|
||||
|
||||
//! Constructs and starts (if autoStart is true) the named meter
|
||||
OSD_PerfMeter(const char* theMeter, const bool theToAutoStart = true)
|
||||
: myIMeter(perf_get_meter(theMeter, 0, 0))
|
||||
{
|
||||
if (myIMeter < 0)
|
||||
myIMeter = perf_init_meter(theMeter);
|
||||
if (theToAutoStart)
|
||||
Start();
|
||||
}
|
||||
//! Constructs and starts (if autoStart is true) the named meter.
|
||||
//! @param theMeterName Name of the meter. If the meter with such name was already created,
|
||||
//! and hasn't been killed, it will be used.
|
||||
//! @param theToAutoStart If true, the meter will be started immediately after creation.
|
||||
//! Otherwise, the user should call Start() method to start the meter.
|
||||
//! Note that if meter already exists, theToAutoStart == true will reset it.
|
||||
Standard_EXPORT OSD_PerfMeter(const TCollection_AsciiString& theMeterName,
|
||||
const bool theToAutoStart = true);
|
||||
|
||||
//! Prepares the named meter
|
||||
void Init(const char* theMeter)
|
||||
{
|
||||
myIMeter = perf_get_meter(theMeter, 0, 0);
|
||||
if (myIMeter < 0)
|
||||
myIMeter = perf_init_meter(theMeter);
|
||||
}
|
||||
//! Destructs this meter handler. Note that the meter itself is not destructed
|
||||
//! and will be printed on stdout upon finish of the program. The meter with the name
|
||||
//! Specified in the constructor can still be used in other places of the code.
|
||||
Standard_EXPORT ~OSD_PerfMeter();
|
||||
|
||||
//! Starts the meter
|
||||
void Start() const { perf_start_imeter(myIMeter); }
|
||||
//! Prepares the named meter. If the meter with such name was already created,
|
||||
//! it will be used. Otherwise, a new meter will be created.
|
||||
Standard_EXPORT void Init(const TCollection_AsciiString& theMeterName);
|
||||
|
||||
//! Stops the meter
|
||||
void Stop() const { perf_stop_imeter(myIMeter); }
|
||||
//! Starts the meter. If the meter was already started, it will be reset.
|
||||
//! Note that the meter with the name specified in the constructor can still be used
|
||||
//! in other places of the code.
|
||||
Standard_EXPORT void Start() const;
|
||||
|
||||
//! Increments the counter w/o time measurement
|
||||
void Tick() const { perf_tick_imeter(myIMeter); }
|
||||
//! Stops the meter.
|
||||
Standard_EXPORT void Stop() const;
|
||||
|
||||
//! Outputs the meter data and resets it to initial state
|
||||
void Flush() const { perf_close_imeter(myIMeter); }
|
||||
//! Returns the elapsed time in seconds since the meter was started.
|
||||
Standard_EXPORT double Elapsed() const;
|
||||
|
||||
//! Assures stopping upon destruction
|
||||
~OSD_PerfMeter()
|
||||
{
|
||||
if (myIMeter >= 0)
|
||||
Stop();
|
||||
}
|
||||
//! Outputs the meter data and resets it to initial state.
|
||||
Standard_EXPORT void Kill() const;
|
||||
|
||||
//! Prints the data of this meter.
|
||||
Standard_EXPORT TCollection_AsciiString Print() const;
|
||||
|
||||
//! Prints the data of all meters with non-zero elapsed time.
|
||||
Standard_EXPORT static TCollection_AsciiString PrintALL();
|
||||
|
||||
//! Resets all meters.
|
||||
Standard_EXPORT static void ResetALL();
|
||||
|
||||
private:
|
||||
OSD_PerfMeter(const OSD_PerfMeter&);
|
||||
OSD_PerfMeter& operator=(const OSD_PerfMeter&);
|
||||
|
||||
protected:
|
||||
int myIMeter;
|
||||
TCollection_AsciiString myMeterName;
|
||||
};
|
||||
|
||||
#endif // OSD_PerfMeter_HeaderFile
|
||||
|
@ -1,11 +0,0 @@
|
||||
puts "============"
|
||||
puts "CR23237"
|
||||
puts "==========="
|
||||
puts ""
|
||||
################################################
|
||||
# Bug in OSD_PerfMeter
|
||||
################################################
|
||||
|
||||
pload QAcommands
|
||||
|
||||
OCC23237
|
Loading…
x
Reference in New Issue
Block a user