#include "CpuProfiler.h"
#include "Mutator/MutatorManager.h"
namespace MapleRuntime {
CpuProfiler::~CpuProfiler()
{
TryStopSampling();
}
bool CpuProfiler::StartCpuProfilerForFile()
{
if (generator.GetIsStart()) {
LOG(RTLOG_ERROR, "Start CpuProfiler repeatedly.");
return false;
}
generator.SetIsStart(true);
tid = std::thread(CpuProfiler::SamplingThread, std::ref(generator));
if (!tid.joinable()) {
LOG(RTLOG_ERROR, "Failed to create sampling thread.");
return false;
}
return true;
}
bool CpuProfiler::StopCpuProfilerForFile(const int fd)
{
if (!generator.GetIsStart()) {
LOG(RTLOG_ERROR, "CpuProfiler is not in profiling");
return false;
}
bool ret = generator.OpenFile(fd);
if (!ret) {
LOG(RTLOG_ERROR, "Open file failed");
}
TryStopSampling();
return ret;
}
void CpuProfiler::TryStopSampling()
{
if (!generator.GetIsStart()) {
return;
}
generator.SetIsStart(false);
if (tid.joinable()) {
tid.join();
}
}
void CpuProfiler::SamplingThread(SamplesRecord& generator)
{
generator.InitProfileInfo();
uint32_t interval = generator.GetSamplingInterval();
uint64_t startTime = SamplesRecord::GetMicrosecondsTimeStamp();
generator.SetThreadStartTime(startTime);
uint64_t endTime = startTime;
while (generator.GetIsStart()) {
startTime = SamplesRecord::GetMicrosecondsTimeStamp();
int64_t ts = static_cast<int64_t>(interval) - static_cast<int64_t>(startTime - endTime);
endTime = startTime;
if (ts > 0) {
usleep(ts);
endTime = SamplesRecord::GetMicrosecondsTimeStamp();
}
DoSampleStack();
generator.ParseSampleData(endTime);
generator.DoSingleTask(endTime);
}
generator.RunTaskLoop();
generator.SetSampleStopTime(SamplesRecord::GetMicrosecondsTimeStamp());
generator.DumpProfileInfo();
generator.ReleaseProfileInfo();
}
void CpuProfiler::DoSampleStack()
{
MutatorManager::Instance().TransitionAllMutatorsToCpuProfile();
}
}