POSIX clock_gettime is only available on OS X >= 10.12, only log the monotonic clock for now
Bug: 76169489
Change-Id: I52bd416f7ebaa46aedd8cfd6a85391ed113f6432
diff --git a/include/perfetto/base/time.h b/include/perfetto/base/time.h
index bd2498c..46e0293 100644
--- a/include/perfetto/base/time.h
+++ b/include/perfetto/base/time.h
@@ -21,20 +21,28 @@
#include <chrono>
+#include "perfetto/base/build_config.h"
#include "perfetto/base/logging.h"
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
+#include <mach/mach_time.h>
+#endif
+
namespace perfetto {
namespace base {
using TimeSeconds = std::chrono::seconds;
using TimeMillis = std::chrono::milliseconds;
using TimeNanos = std::chrono::nanoseconds;
-constexpr clockid_t kWallTimeClockSource = CLOCK_MONOTONIC;
inline TimeNanos FromPosixTimespec(const struct timespec& ts) {
return TimeNanos(ts.tv_sec * 1000000000LL + ts.tv_nsec);
}
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
+
+constexpr clockid_t kWallTimeClockSource = CLOCK_MONOTONIC;
+
inline TimeNanos GetTimeInternalNs(clockid_t clk_id) {
struct timespec ts = {};
PERFETTO_CHECK(clock_gettime(clk_id, &ts) == 0);
@@ -45,6 +53,25 @@
return GetTimeInternalNs(kWallTimeClockSource);
}
+inline TimeNanos GetThreadCPUTimeNs() {
+ return GetTimeInternalNs(CLOCK_THREAD_CPUTIME_ID);
+}
+
+#else // !PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
+
+inline TimeNanos GetWallTimeNs() {
+ auto init_time_factor = []() -> uint64_t {
+ mach_timebase_info_data_t timebase_info;
+ mach_timebase_info(&timebase_info);
+ return timebase_info.numer / timebase_info.denom;
+ }
+
+ static uint64_t monotonic_timebase_factor = init_time_factor();
+ return TimeNanos(mach_absolute_time() * monotonic_timebase_factor);
+}
+
+#endif // !PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
+
inline TimeMillis GetWallTimeMs() {
return std::chrono::duration_cast<TimeMillis>(GetWallTimeNs());
}
@@ -53,10 +80,6 @@
return std::chrono::duration_cast<TimeSeconds>(GetWallTimeNs());
}
-inline TimeNanos GetThreadCPUTimeNs() {
- return GetTimeInternalNs(CLOCK_THREAD_CPUTIME_ID);
-}
-
inline struct timespec ToPosixTimespec(TimeMillis time) {
struct timespec ts {};
const long time_s = static_cast<long>(time.count() / 1000);
diff --git a/src/tracing/core/service_impl.cc b/src/tracing/core/service_impl.cc
index cb22c4f..be8a970 100644
--- a/src/tracing/core/service_impl.cc
+++ b/src/tracing/core/service_impl.cc
@@ -884,14 +884,16 @@
if (now < tracing_session->last_clock_snapshot + kClockSnapshotInterval)
return;
tracing_session->last_clock_snapshot = now;
+
+ protos::TracePacket packet;
+ protos::ClockSnapshot* clock_snapshot = packet.mutable_clock_snapshot();
+
+#if !PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
struct {
clockid_t id;
protos::ClockSnapshot::Clock::Type type;
struct timespec ts;
} clocks[] = {
-#if PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
- {CLOCK_UPTIME_RAW, protos::ClockSnapshot::Clock::BOOTTIME, {0, 0}},
-#else
{CLOCK_BOOTTIME, protos::ClockSnapshot::Clock::BOOTTIME, {0, 0}},
{CLOCK_REALTIME_COARSE,
protos::ClockSnapshot::Clock::REALTIME_COARSE,
@@ -899,7 +901,6 @@
{CLOCK_MONOTONIC_COARSE,
protos::ClockSnapshot::Clock::MONOTONIC_COARSE,
{0, 0}},
-#endif
{CLOCK_REALTIME, protos::ClockSnapshot::Clock::REALTIME, {0, 0}},
{CLOCK_MONOTONIC, protos::ClockSnapshot::Clock::MONOTONIC, {0, 0}},
{CLOCK_MONOTONIC_RAW, protos::ClockSnapshot::Clock::MONOTONIC_RAW, {0, 0}},
@@ -910,8 +911,6 @@
protos::ClockSnapshot::Clock::THREAD_CPUTIME,
{0, 0}},
};
- protos::TracePacket packet;
- protos::ClockSnapshot* clock_snapshot = packet.mutable_clock_snapshot();
// First snapshot all the clocks as atomically as we can.
for (auto& clock : clocks) {
if (clock_gettime(clock.id, &clock.ts) == -1)
@@ -922,6 +921,12 @@
c->set_type(clock.type);
c->set_timestamp(base::FromPosixTimespec(clock.ts).count());
}
+#else // !PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
+ protos::ClockSnapshot::Clock* c = clock_snapshot->add_clocks();
+ c->set_type(protos::ClockSnapshot::Clock::MONOTONIC);
+ c->set_timestamp(base::GetWallTimeNs().count());
+#endif // !PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
+
packet.set_trusted_uid(getuid());
Slice slice = Slice::Allocate(packet.ByteSize());
PERFETTO_CHECK(packet.SerializeWithCachedSizesToArray(slice.own_data()));
diff --git a/src/tracing/test/tracing_integration_test.cc b/src/tracing/test/tracing_integration_test.cc
index 426f469..79f4db4 100644
--- a/src/tracing/test/tracing_integration_test.cc
+++ b/src/tracing/test/tracing_integration_test.cc
@@ -218,6 +218,12 @@
Invoke([&num_pack_rx, all_packets_rx, &trace_config,
&saw_clock_snapshot, &saw_trace_config](
std::vector<TracePacket>* packets, bool has_more) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_MACOSX)
+ const int kExpectedMinNumberOfClocks = 1;
+#else
+ const int kExpectedMinNumberOfClocks = 6;
+#endif
+
for (auto& packet : *packets) {
ASSERT_TRUE(packet.Decode());
if (packet->has_for_testing()) {
@@ -225,7 +231,8 @@
sprintf(buf, "evt_%zu", num_pack_rx++);
EXPECT_EQ(std::string(buf), packet->for_testing().str());
} else if (packet->has_clock_snapshot()) {
- EXPECT_GE(packet->clock_snapshot().clocks_size(), 6);
+ EXPECT_GE(packet->clock_snapshot().clocks_size(),
+ kExpectedMinNumberOfClocks);
saw_clock_snapshot = true;
} else if (packet->has_trace_config()) {
protos::TraceConfig config_proto;