Persist pack profile snapshots during timed captures
Some checks failed
build / Windows Build (push) Has been cancelled

This commit is contained in:
server
2026-04-15 17:06:11 +02:00
parent 2d9beb4793
commit db7ae1f841

View File

@@ -4,12 +4,14 @@
#include <array>
#include <cctype>
#include <chrono>
#include <condition_variable>
#include <filesystem>
#include <fstream>
#include <map>
#include <mutex>
#include <sstream>
#include <string>
#include <thread>
#include <vector>
#include <windows.h>
@@ -24,6 +26,7 @@ using Clock = std::chrono::steady_clock;
constexpr const char* kPackProfileEnv = "M2PACK_PROFILE";
constexpr const char* kPackProfileOutput = "log/pack_profile.txt";
constexpr std::size_t kTopListLimit = 12;
constexpr auto kSnapshotFlushInterval = std::chrono::seconds(1);
struct LoadStats
{
@@ -69,10 +72,15 @@ struct PackProfileState
std::map<std::string, MountStats> mount_by_format;
std::map<std::string, MountStats> mount_by_pack;
std::map<std::string, StageStats> stage_by_key;
bool snapshot_dirty = false;
bool stop_snapshot_thread = false;
std::condition_variable snapshot_cv;
std::thread snapshot_thread;
std::mutex mutex;
~PackProfileState()
{
StopSnapshotThread();
if (enabled)
{
std::lock_guard<std::mutex> lock(mutex);
@@ -80,6 +88,50 @@ struct PackProfileState
}
}
void StartSnapshotThread()
{
snapshot_thread = std::thread([this]() {
SnapshotLoop();
});
}
void StopSnapshotThread()
{
{
std::lock_guard<std::mutex> lock(mutex);
stop_snapshot_thread = true;
}
snapshot_cv.notify_all();
if (snapshot_thread.joinable())
{
snapshot_thread.join();
}
}
void SnapshotLoop()
{
std::unique_lock<std::mutex> lock(mutex);
for (;;)
{
const bool shouldStop = snapshot_cv.wait_for(
lock,
kSnapshotFlushInterval,
[this]() { return stop_snapshot_thread; });
if (shouldStop)
{
return;
}
if (!enabled || !snapshot_dirty)
{
continue;
}
WriteReportLocked("periodic");
snapshot_dirty = false;
}
}
void WriteReportLocked(std::string_view reason) const
{
std::error_code ec;
@@ -376,6 +428,9 @@ void InitializePackProfile(const char* commandLine)
.elapsed_us = 0,
});
g_pack_profile.WriteReportLocked("initialized");
g_pack_profile.snapshot_dirty = false;
g_pack_profile.stop_snapshot_thread = false;
g_pack_profile.StartSnapshotThread();
}
bool IsPackProfileEnabled()
@@ -402,6 +457,7 @@ void MarkPackProfilePhase(std::string_view phase)
.elapsed_us = CurrentElapsedUs(),
});
g_pack_profile.WriteReportLocked(PackProfileState::MakePhaseKey("phase", phase));
g_pack_profile.snapshot_dirty = false;
}
void RecordPackProfileMount(
@@ -429,6 +485,7 @@ void RecordPackProfileMount(
packStats.failures += ok ? 0 : 1;
packStats.entry_count += entryCount;
packStats.elapsed_us += elapsedUs;
g_pack_profile.snapshot_dirty = true;
}
void RecordPackProfileLoad(
@@ -459,6 +516,7 @@ void RecordPackProfileLoad(
update(g_pack_profile.load_by_phase_pack[
PackProfileState::MakePhaseKey(g_pack_profile.current_phase, PackProfileState::ParsePackLabel(packPath))]);
update(g_pack_profile.load_by_extension[PackProfileState::ParseExtension(requestPath)]);
g_pack_profile.snapshot_dirty = true;
}
void RecordPackProfileStage(
@@ -480,6 +538,7 @@ void RecordPackProfileStage(
stats.input_bytes += inputBytes;
stats.output_bytes += outputBytes;
stats.elapsed_us += elapsedUs;
g_pack_profile.snapshot_dirty = true;
}
void FlushPackProfileSnapshot(std::string_view reason)
@@ -491,4 +550,5 @@ void FlushPackProfileSnapshot(std::string_view reason)
std::lock_guard<std::mutex> lock(g_pack_profile.mutex);
g_pack_profile.WriteReportLocked(reason);
g_pack_profile.snapshot_dirty = false;
}