Bug 1961012 - Put platform-specific start time values into the profile JSON. r=profiler-reviewers,canaltinova

This allows lining up the data from the profile with data that was captured
from other sources, for example from ETW, perf, simpleperf, or samply.

Differential Revision: https://phabricator.services.mozilla.com/D245805
This commit is contained in:
Markus Stange
2025-05-16 15:20:33 +00:00
committed by mstange@themasta.com
parent aa771d331b
commit 0656895cdb
2 changed files with 78 additions and 18 deletions

View File

@@ -1603,6 +1603,28 @@ static void StreamMarkerSchema(SpliceableJSONWriter& aWriter) {
static int64_t MicrosecondsSince1970();
static void MaybeWriteRawStartTimeValue(SpliceableJSONWriter& aWriter,
const TimeStamp& aStartTime) {
#ifdef XP_LINUX
aWriter.DoubleProperty(
"startTimeAsClockMonotonicNanosecondsSinceBoot",
static_cast<double>(aStartTime.RawClockMonotonicNanosecondsSinceBoot()));
#endif
#ifdef XP_DARWIN
aWriter.DoubleProperty(
"startTimeAsMachAbsoluteTimeNanoseconds",
static_cast<double>(aStartTime.RawMachAbsoluteTimeNanoseconds()));
#endif
#ifdef XP_WIN
Maybe<uint64_t> startTimeQPC = aStartTime.RawQueryPerformanceCounterValue();
if (startTimeQPC)
aWriter.DoubleProperty("startTimeAsQueryPerformanceCounterValue",
static_cast<double>(*startTimeQPC));
#endif
}
static void StreamMetaJSCustomObject(PSLockRef aLock,
SpliceableJSONWriter& aWriter,
bool aIsShuttingDown) {
@@ -1611,13 +1633,21 @@ static void StreamMetaJSCustomObject(PSLockRef aLock,
aWriter.IntProperty("version", GECKO_PROFILER_FORMAT_VERSION);
// The "startTime" field holds the number of milliseconds since midnight
// January 1, 1970 GMT. This grotty code computes (Now - (Now -
// ProcessStartTime)) to convert CorePS::ProcessStartTime() into that form.
// Note: This is the only absolute time in the profile! All other timestamps
// are relative to this startTime.
TimeDuration delta = TimeStamp::Now() - CorePS::ProcessStartTime();
aWriter.DoubleProperty(
"startTime", MicrosecondsSince1970() / 1000.0 - delta.ToMilliseconds());
// January 1, 1970 GMT (the "Unix epoch"). This grotty code computes (Now -
// (Now - ProcessStartTime)) to convert CorePS::ProcessStartTime() into that
// form. Note: This start time, and the platform-specific "raw start time",
// are the only absolute time values in the profile! All other timestamps are
// relative to this startTime.
TimeStamp startTime = CorePS::ProcessStartTime();
TimeStamp now = TimeStamp::Now();
double millisecondsSinceUnixEpoch =
static_cast<double>(MicrosecondsSince1970()) / 1000.0;
double millisecondsSinceStartTime = (now - startTime).ToMilliseconds();
double millisecondsBetweenUnixEpochAndStartTime =
millisecondsSinceUnixEpoch - millisecondsSinceStartTime;
aWriter.DoubleProperty("startTime", millisecondsBetweenUnixEpochAndStartTime);
MaybeWriteRawStartTimeValue(aWriter, startTime);
aWriter.DoubleProperty("profilingStartTime", (ActivePS::ProfilingStartTime() -
CorePS::ProcessStartTime())

View File

@@ -3282,6 +3282,28 @@ static PreRecordedMetaInformation PreRecordMetaInformation(
static void StreamMetaPlatformSampleUnits(PSLockRef aLock,
SpliceableJSONWriter& aWriter);
static void MaybeWriteRawStartTimeValue(SpliceableJSONWriter& aWriter,
const TimeStamp& aStartTime) {
#ifdef XP_LINUX
aWriter.DoubleProperty(
"startTimeAsClockMonotonicNanosecondsSinceBoot",
static_cast<double>(aStartTime.RawClockMonotonicNanosecondsSinceBoot()));
#endif
#ifdef XP_DARWIN
aWriter.DoubleProperty(
"startTimeAsMachAbsoluteTimeNanoseconds",
static_cast<double>(aStartTime.RawMachAbsoluteTimeNanoseconds()));
#endif
#ifdef XP_WIN
Maybe<uint64_t> startTimeQPC = aStartTime.RawQueryPerformanceCounterValue();
if (startTimeQPC)
aWriter.DoubleProperty("startTimeAsQueryPerformanceCounterValue",
static_cast<double>(*startTimeQPC));
#endif
}
static void StreamMetaJSCustomObject(
PSLockRef aLock, SpliceableJSONWriter& aWriter, bool aIsShuttingDown,
const PreRecordedMetaInformation& aPreRecordedMetaInformation) {
@@ -3290,14 +3312,20 @@ static void StreamMetaJSCustomObject(
aWriter.IntProperty("version", GECKO_PROFILER_FORMAT_VERSION);
// The "startTime" field holds the number of milliseconds since midnight
// January 1, 1970 GMT. This grotty code computes (Now - (Now -
// ProcessStartTime)) to convert CorePS::ProcessStartTime() into that form.
// Note: This is the only absolute time in the profile! All other timestamps
// are relative to this startTime.
TimeDuration delta = TimeStamp::Now() - CorePS::ProcessStartTime();
aWriter.DoubleProperty(
"startTime",
static_cast<double>(PR_Now() / 1000.0 - delta.ToMilliseconds()));
// January 1, 1970 GMT (the "Unix epoch"). This grotty code computes (Now -
// (Now - ProcessStartTime)) to convert CorePS::ProcessStartTime() into that
// form. Note: This start time, and the platform-specific "raw start time",
// are the only absolute time values in the profile! All other timestamps are
// relative to this startTime.
TimeStamp startTime = CorePS::ProcessStartTime();
TimeStamp now = TimeStamp::Now();
double millisecondsSinceUnixEpoch = static_cast<double>(PR_Now()) / 1000.0;
double millisecondsSinceStartTime = (now - startTime).ToMilliseconds();
double millisecondsBetweenUnixEpochAndStartTime =
millisecondsSinceUnixEpoch - millisecondsSinceStartTime;
aWriter.DoubleProperty("startTime", millisecondsBetweenUnixEpochAndStartTime);
MaybeWriteRawStartTimeValue(aWriter, startTime);
aWriter.DoubleProperty("profilingStartTime", (ActivePS::ProfilingStartTime() -
CorePS::ProcessStartTime())
@@ -3757,7 +3785,9 @@ locked_profiler_stream_json_for_this_process(
// Put page data
aWriter.StartArrayProperty("pages");
{ StreamPages(aLock, aWriter); }
{
StreamPages(aLock, aWriter);
}
aWriter.EndArray();
aProgressLogger.SetLocalProgress(6_pc, "Wrote pages");
@@ -5847,7 +5877,7 @@ void profiler_dump_and_stop() {
#if defined(GECKO_PROFILER_ASYNC_POSIX_SIGNAL_CONTROL)
void profiler_init_signal_handlers() {
// Set a handler to start the profiler
struct sigaction prof_start_sa {};
struct sigaction prof_start_sa{};
memset(&prof_start_sa, 0, sizeof(struct sigaction));
prof_start_sa.sa_sigaction = profiler_start_signal_handler;
prof_start_sa.sa_flags = SA_RESTART | SA_SIGINFO;
@@ -5856,7 +5886,7 @@ void profiler_init_signal_handlers() {
MOZ_ASSERT(rstart == 0, "Failed to install Profiler SIGUSR1 handler");
// Set a handler to stop the profiler
struct sigaction prof_stop_sa {};
struct sigaction prof_stop_sa{};
memset(&prof_stop_sa, 0, sizeof(struct sigaction));
prof_stop_sa.sa_sigaction = profiler_stop_signal_handler;
prof_stop_sa.sa_flags = SA_RESTART | SA_SIGINFO;