libreoffice-online/common/ProfileZone.cpp
Tor Lillqvist e7ed4e11cf Add a ProfileZone implementation here, too
Compiled but not yet used.

Signed-off-by: Tor Lillqvist <tml@collabora.com>
Change-Id: I3b85696ca6076e42d16e710b49bfd37bac342ec8
Signed-off-by: Tor Lillqvist <tml@collabora.com>
2021-05-03 16:09:35 +03:00

159 lines
3.5 KiB
C++

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <cassert>
#include <mutex>
#include <sys/syscall.h>
#include "ProfileZone.hpp"
std::atomic<bool> ProfileZone::s_bRecording(false);
int ProfileZone::s_nNesting = 0; // level of overlapped zones
namespace
{
std::vector<std::string> g_aRecording; // recorded data
std::mutex g_aMutex;
}
void ProfileZone::startRecording()
{
std::lock_guard<std::mutex> aGuard(g_aMutex);
s_nNesting = 0;
s_bRecording = true;
}
void ProfileZone::stopRecording() { s_bRecording = false; }
void ProfileZone::addRecording()
{
assert(s_bRecording);
auto nNow = std::chrono::system_clock::now();
// Generate a single "Complete Event" (type X)
auto nDuration = nNow - m_nCreateTime;
std::string sRecordingData(
"{"
"\"name\":\""
+ std::string(m_sProfileId)
+ "\","
"\"ph\":\"X\","
"\"ts\":"
+ std::to_string(std::chrono::duration_cast<std::chrono::microseconds>(
m_nCreateTime.time_since_epoch())
.count())
+ ","
"\"dur\":"
+ std::to_string(std::chrono::duration_cast<std::chrono::microseconds>(nDuration).count())
+ ","
"\"pid\":"
+ std::to_string(m_nPid)
+ ","
"\"tid\":"
+ std::to_string(syscall(SYS_gettid)) + "},");
std::lock_guard<std::mutex> aGuard(g_aMutex);
g_aRecording.emplace_back(sRecordingData);
}
std::vector<std::string> ProfileZone::getRecordingAndClear()
{
bool bRecording;
std::vector<std::string> aRecording;
{
std::lock_guard<std::mutex> aGuard(g_aMutex);
bRecording = s_bRecording;
stopRecording();
aRecording.swap(g_aRecording);
}
// reset start time and nesting level
if (bRecording)
startRecording();
return aRecording;
}
#if 0 // Test main() used during development of this
#include <iostream>
#include <thread>
int main(int argc, char** argv)
{
ProfileZone::startRecording();
ProfileZone a("main");
{
ProfileZone b("first block");
for (auto n = 0; n < 100000000; n++)
{
volatile auto x = n * 42;
(void)x;
}
}
std::thread t1([]() {
ProfileZone b("thread t1");
for (auto n = 0; n < 400000000; n++)
{
volatile auto x = n * 42;
(void)x;
}
});
std::thread t2([]() {
ProfileZone b("thread t2");
for (auto n = 0; n < 400000000; n++)
{
volatile auto x = n * 42;
(void)x;
}
});
std::thread t3([]() {
ProfileZone b("thread t3");
for (auto n = 0; n < 400000000; n++)
{
volatile auto x = n * 42;
(void)x;
}
});
{
ProfileZone b("second block");
for (auto n = 0; n < 300000000; n++)
{
volatile auto x = n * 42;
(void)x;
}
}
t1.join();
t2.join();
t3.join();
auto v = ProfileZone::getRecordingAndClear();
std::cout << "[\n";
for (auto e : v)
std::cout << " " << e << "\n";
std::cout << "]\n";
return 0;
}
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */