diff --git a/example-slowFastRendering/example-slowFastRendering.qbs.user b/example-slowFastRendering/example-slowFastRendering.qbs.user index 79d9efd..cda4681 100644 --- a/example-slowFastRendering/example-slowFastRendering.qbs.user +++ b/example-slowFastRendering/example-slowFastRendering.qbs.user @@ -1,6 +1,6 @@ - + EnvironmentId @@ -75,7 +75,7 @@ Desktop Desktop {a59f5d47-09f7-45f4-8f6a-af2e6553b46c} - 0 + 1 0 0 @@ -137,10 +137,11 @@ release qtc_Desktop_842209c4 + false false true - 0 + 48 false false @@ -246,19 +247,19 @@ 2 - - ProjectExplorer.CustomExecutableRunConfiguration - + Qbs.RunConfiguration:example-slowFastRendering. + example-slowFastRendering. false false true + true false false true - + /home/pointer/of_v0.11.0_linux64gcc6_release/addons/ofxProfiler/example-slowFastRendering/bin 1 diff --git a/src/ofxProfiler.h b/src/ofxProfiler.h index 848da8f..23e2107 100644 --- a/src/ofxProfiler.h +++ b/src/ofxProfiler.h @@ -12,63 +12,61 @@ namespace ofxProfiler { - using FloatingPointMicroseconds = chrono::duration; +using FloatingPointMicroseconds = chrono::duration ; - struct ProfileResult - { - string Name; +struct ProfileResult { + string Name; - FloatingPointMicroseconds Start; - chrono::microseconds ElapsedTime; - thread::id ThreadID; - }; + FloatingPointMicroseconds Start; + chrono::microseconds ElapsedTime; + thread::id ThreadID; +}; - struct InstrumentationSession - { - string Name; - }; +struct InstrumentationSession { + string Name; +}; - class Instrumentor - { +class Instrumentor { private: mutex m_Mutex; - InstrumentationSession* m_CurrentSession; + InstrumentationSession * m_CurrentSession; ofstream m_OutputStream; public: Instrumentor() - : m_CurrentSession(nullptr) - { + : m_CurrentSession(nullptr){ + } + + void BeginSession(const string & name = "I do not want to name my profiling sessions.", + const string & filepath = "results.json", + const bool continueSession = false){ + lock_guard lock(m_Mutex); + if(!m_CurrentSession || !continueSession){ + // if there is no session, or it should not be continued + if(m_CurrentSession){ + // If there is already a current session, then close it before beginning new one. + // Subsequent profiling output meant for the original session will end up in the + // newly opened session instead. That's better than having badly formatted + // profiling output. + ofLog(OF_LOG_ERROR, "Instrumentor::BeginSession('%s') when session '%s' already open.", name.c_str(), m_CurrentSession->Name.c_str()); + InternalEndSession(); + } + m_OutputStream.open(filepath); + + if(m_OutputStream.is_open()){ + m_CurrentSession = new InstrumentationSession({name}); + WriteHeader(); + }else{ + ofLog(OF_LOG_ERROR, "Instrumentor could not open results file '%s'.", filepath.c_str()); + } + } } - void BeginSession(const string& name, const string& filepath = "results.json") - { - lock_guard lock(m_Mutex); - if (m_CurrentSession) { - // If there is already a current session, then close it before beginning new one. - // Subsequent profiling output meant for the original session will end up in the - // newly opened session instead. That's better than having badly formatted - // profiling output. - ofLog(OF_LOG_ERROR,"Instrumentor::BeginSession('%s') when session '%s' already open.", name.c_str(), m_CurrentSession->Name.c_str()); - InternalEndSession(); - } - m_OutputStream.open(filepath); - - if (m_OutputStream.is_open()) { - m_CurrentSession = new InstrumentationSession({name}); - WriteHeader(); - } else { - ofLog(OF_LOG_ERROR,"Instrumentor could not open results file '%s'.", filepath.c_str()); - } - } - - void EndSession() - { - lock_guard lock(m_Mutex); + void EndSession(){ + lock_guard lock(m_Mutex); InternalEndSession(); } - void WriteProfile(const ProfileResult& result) - { + void WriteProfile(const ProfileResult & result){ stringstream json; string name = result.Name; @@ -85,35 +83,33 @@ namespace ofxProfiler { json << "\"ts\":" << result.Start.count(); json << "}"; - lock_guard lock(m_Mutex); - if (m_CurrentSession) { + lock_guard lock(m_Mutex); + if(m_CurrentSession){ m_OutputStream << json.str(); m_OutputStream.flush(); } } - static Instrumentor& Get() { + static Instrumentor & Get(){ static Instrumentor instance; return instance; } private: - void WriteHeader() - { + void WriteHeader(){ m_OutputStream << "{\"otherData\": {},\"traceEvents\":[{}"; m_OutputStream.flush(); } - void WriteFooter() - { + void WriteFooter(){ m_OutputStream << "]}"; m_OutputStream.flush(); } // Note: you must already own lock on m_Mutex before // calling InternalEndSession() - void InternalEndSession() { - if (m_CurrentSession) { + void InternalEndSession(){ + if(m_CurrentSession){ WriteFooter(); m_OutputStream.close(); delete m_CurrentSession; @@ -121,69 +117,68 @@ namespace ofxProfiler { } } - }; +}; - class InstrumentationTimer - { +class InstrumentationTimer { public: - InstrumentationTimer(const char* name) - : m_Name(name), m_Stopped(false) - { + InstrumentationTimer(const char * name) + : m_Name(name), m_Stopped(false){ m_StartTimepoint = chrono::steady_clock::now(); } - ~InstrumentationTimer() - { - if (!m_Stopped) + ~InstrumentationTimer(){ + if(!m_Stopped){ Stop(); - } + } + } - void Stop() - { + void Stop(){ auto endTimepoint = chrono::steady_clock::now(); - auto highResStart = FloatingPointMicroseconds{ m_StartTimepoint.time_since_epoch() }; - auto elapsedTime = chrono::time_point_cast(endTimepoint).time_since_epoch() - chrono::time_point_cast(m_StartTimepoint).time_since_epoch(); + auto highResStart = FloatingPointMicroseconds{m_StartTimepoint.time_since_epoch()}; + auto elapsedTime = chrono::time_point_cast (endTimepoint).time_since_epoch() - chrono::time_point_cast (m_StartTimepoint).time_since_epoch(); - Instrumentor::Get().WriteProfile({ m_Name, highResStart, elapsedTime, this_thread::get_id() }); + Instrumentor::Get().WriteProfile({m_Name, highResStart, elapsedTime, this_thread::get_id()}); m_Stopped = true; } private: - const char* m_Name; - chrono::time_point m_StartTimepoint; + const char * m_Name; + chrono::time_point m_StartTimepoint; bool m_Stopped; - }; +}; } #define OFX_PROFILER 1 -#if OFX_PROFILER - // Resolve which function signature macro will HZ_PROFILE_BEGIN_SESSIONbe used. Note that this only - // is resolved when the (pre)compiler starts, so the syntax highlighting - // could mark the wrong one in your editor! - #if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__) - #define OFX_PROFILER_FUNC_SIG __PRETTY_FUNCTION__ - #elif defined(__DMC__) && (__DMC__ >= 0x810) - #define OFX_PROFILER_FUNC_SIG __PRETTY_FUNCTION__ - #elif defined(__FUNCSIG__) - #define OFX_PROFILER_FUNC_SIG __FUNCSIG__ - #elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500)) - #define OFX_PROFILER_FUNC_SIG __FUNCTION__ - #elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550) - #define OFX_PROFILER_FUNC_SIG __FUNC__ - #elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) - #define OFX_PROFILER_FUNC_SIG __func__ - #elif defined(__cplusplus) && (__cplusplus >= 201103) - #define OFX_PROFILER_FUNC_SIG __func__ - #else - #define OFX_PROFILER_FUNC_SIG "OFX_PROFILER_FUNC_SIG unknown!" - #endif +// Resolve which function signature macro will HZ_PROFILE_BEGIN_SESSIONbe used. Note that this only +// is resolved when the (pre)compiler starts, so the syntax highlighting +// could mark the wrong one in your editor! +#if defined(__GNUC__) || (defined(__MWERKS__) && (__MWERKS__ >= 0x3000)) || (defined(__ICC) && (__ICC >= 600)) || defined(__ghs__) + #define OFX_PROFILER_FUNC_SIG __PRETTY_FUNCTION__ +#elif defined(__DMC__) && (__DMC__ >= 0x810) + #define OFX_PROFILER_FUNC_SIG __PRETTY_FUNCTION__ +#elif defined(__FUNCSIG__) + #define OFX_PROFILER_FUNC_SIG __FUNCSIG__ +#elif (defined(__INTEL_COMPILER) && (__INTEL_COMPILER >= 600)) || (defined(__IBMCPP__) && (__IBMCPP__ >= 500)) + #define OFX_PROFILER_FUNC_SIG __FUNCTION__ +#elif defined(__BORLANDC__) && (__BORLANDC__ >= 0x550) + #define OFX_PROFILER_FUNC_SIG __FUNC__ +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) + #define OFX_PROFILER_FUNC_SIG __func__ +#elif defined(__cplusplus) && (__cplusplus >= 201103) + #define OFX_PROFILER_FUNC_SIG __func__ +#else + #define OFX_PROFILER_FUNC_SIG "OFX_PROFILER_FUNC_SIG unknown!" +#endif +#if OFX_PROFILER #define OFX_PROFILER_BEGIN_SESSION(name, filepath) ::ofxProfiler::Instrumentor::Get().BeginSession(name, filepath) + #define OFX_PROFILER_CONTINUE_SESSION(name, filepath) ::ofxProfiler::Instrumentor::Get().BeginSession(name, filepath, true) #define OFX_PROFILER_END_SESSION() ::ofxProfiler::Instrumentor::Get().EndSession() - #define OFX_PROFILER_SCOPE(name) ::ofxProfiler::InstrumentationTimer timer##__LINE__(name); + #define OFX_PROFILER_SCOPE(name) ::ofxProfiler::InstrumentationTimer timer ## __LINE__(name); #define OFX_PROFILER_FUNCTION() OFX_PROFILER_SCOPE(OFX_PROFILER_FUNC_SIG) #else #define OFX_PROFILER_BEGIN_SESSION(name, filepath) + #define OFX_PROFILER_CONTINUE_SESSION(name, filepath) #define OFX_PROFILER_END_SESSION() #define OFX_PROFILER_SCOPE(name) #define OFX_PROFILER_FUNCTION()