diff options
author | Tor Lillqvist <tml@collabora.com> | 2021-04-27 18:43:16 +0300 |
---|---|---|
committer | Tor Lillqvist <tml@collabora.com> | 2021-04-29 08:45:07 +0200 |
commit | 89c0d087c657c31a3198c481a63ca0549b8a4503 (patch) | |
tree | b578887c79856f9050eb879efdd5255bae8d4d51 /include/comphelper | |
parent | 896586e91a2b0b3437ff1c9ad1d72fbce04a7fed (diff) |
Introduce Async trace events and a unit test
Async events are ones that emit separate 'b' (begin) and 'e' (end)
traces. (Compare to the Complete event that emit a single 'X' trace
that contains both the start timstamp and the duration.)
There are two kinds of Async events: Freestanding ones that are not
related to other events at all, and nested ones that have to be nested
between the 'b' and 'e' events of a parent Async event.
Still needs some work, at least a way to end a nested AsyncEvent
(cause it to emit the 'e' event) before it gets destructed thanks to
the parent being destructed.
Change-Id: I3721fa701ad32639b1edc1cfa8db7acde5caf9b4
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/114756
Tested-by: Jenkins
Reviewed-by: Tor Lillqvist <tml@collabora.com>
Diffstat (limited to 'include/comphelper')
-rw-r--r-- | include/comphelper/profilezone.hxx | 6 | ||||
-rw-r--r-- | include/comphelper/traceevent.hxx | 115 |
2 files changed, 115 insertions, 6 deletions
diff --git a/include/comphelper/profilezone.hxx b/include/comphelper/profilezone.hxx index 8ef851cfaea1..40e2ee97e502 100644 --- a/include/comphelper/profilezone.hxx +++ b/include/comphelper/profilezone.hxx @@ -57,11 +57,7 @@ public: m_nCreateTime = static_cast<long long>(systemTime.Seconds) * 1000000 + systemTime.Nanosec / 1000; - oslProcessInfo aProcessInfo; - aProcessInfo.Size = sizeof(oslProcessInfo); - if (osl_getProcessInfo(nullptr, osl_Process_IDENTIFIER, &aProcessInfo) - == osl_Process_E_None) - m_nPid = aProcessInfo.Ident; + m_nPid = getPid(); m_nNesting = s_nNesting++; } diff --git a/include/comphelper/traceevent.hxx b/include/comphelper/traceevent.hxx index 7e988bd063f0..3d3c748ec278 100644 --- a/include/comphelper/traceevent.hxx +++ b/include/comphelper/traceevent.hxx @@ -14,9 +14,10 @@ #include <atomic> #include <memory> -#include <set> +#include <vector> #include <osl/process.h> +#include <osl/thread.h> #include <osl/time.h> #include <com/sun/star/uno/Sequence.h> #include <comphelper/comphelperdllapi.h> @@ -33,12 +34,31 @@ protected: static void addRecording(const OUString& sObject); + static long long getNow() + { + TimeValue systemTime; + osl_getSystemTime(&systemTime); + return static_cast<long long>(systemTime.Seconds) * 1000000 + systemTime.Nanosec / 1000; + } + + static int getPid() + { + oslProcessInfo aProcessInfo; + aProcessInfo.Size = sizeof(oslProcessInfo); + if (osl_getProcessInfo(nullptr, osl_Process_IDENTIFIER, &aProcessInfo) + == osl_Process_E_None) + return aProcessInfo.Ident; + return -1; + } + public: static void addInstantEvent(const char* sName); static void startRecording(); static void stopRecording(); + static std::vector<OUString> getEventVectorAndClear(); + static css::uno::Sequence<OUString> getRecordingAndClear(); }; @@ -53,6 +73,99 @@ protected: } }; +// An AsyncEvent generates a 'b' (begin) event when constructed and an 'e' (end) event when destructed + +class COMPHELPER_DLLPUBLIC AsyncEvent : public NamedEvent, + public std::enable_shared_from_this<AsyncEvent> +{ + static int s_nIdCounter; + int m_nId; + int m_nPid; + std::vector<std::shared_ptr<AsyncEvent>> m_aChildren; + bool m_bBeginRecorded; + + AsyncEvent(const char* sName, int nId) + : NamedEvent(sName) + , m_nId(nId) + , m_bBeginRecorded(false) + { + if (s_bRecording) + { + long long nNow = getNow(); + + m_nPid = getPid(); + + // Generate a "Begin " (type b) event + TraceEvent::addRecording("{" + "\"name\":\"" + + OUString(m_sName, strlen(m_sName), RTL_TEXTENCODING_UTF8) + + "\"," + "\"ph\":\"b\"" + "," + "\"id\":" + + OUString::number(m_nId) + + "\"," + "\"ts\":" + + OUString::number(nNow) + + "," + "\"pid\":" + + OUString::number(m_nPid) + + "," + "\"tid\":" + + OUString::number(osl_getThreadIdentifier(nullptr)) + "},"); + m_bBeginRecorded = true; + } + } + +public: + AsyncEvent(const char* sName) + : AsyncEvent(sName, s_nIdCounter++) + { + } + + ~AsyncEvent() + { + if (m_bBeginRecorded) + { + m_aChildren.clear(); + + long long nNow = getNow(); + // Generate a "Env " (type e) event + TraceEvent::addRecording("{" + "\"name\":\"" + + OUString(m_sName, strlen(m_sName), RTL_TEXTENCODING_UTF8) + + "\"," + "\"ph\":\"e\"" + "," + "\"id\":" + + OUString::number(m_nId) + + "\"," + "\"ts\":" + + OUString::number(nNow) + + "," + "\"pid\":" + + OUString::number(m_nPid) + + "," + "\"tid\":" + + OUString::number(osl_getThreadIdentifier(nullptr)) + "},"); + } + } + + static std::weak_ptr<AsyncEvent> createWithParent(const char* sName, + std::shared_ptr<AsyncEvent> pParent) + { + std::shared_ptr<AsyncEvent> pResult; + + if (s_bRecording && pParent->m_bBeginRecorded) + { + pResult.reset(new AsyncEvent(sName, pParent->m_nId)); + pParent->m_aChildren.push_back(pResult); + } + + return pResult; + } +}; + } // namespace comphelper #endif // INCLUDED_COMPHELPER_TRACEEVENT_HXX |