Commit 9e0365a7 authored by Eric Seckler's avatar Eric Seckler Committed by Commit Bot

tracing: Always tie sequence-local clocks to boottime

Previously, we were relating the microsecond-granularity sequence-local
clocks to CLOCK_MONOTONIC, which meant that trace processor has to find
a 2-step path via CLOCK_MONOTONIC to CLOCK_BOOTTIME, which is rather
slow. Instead, tie the sequence-local monotonic clocks directly to
CLOCK_BOOTTIME in their ClockSnapshots.

Bug: 928738, b/148506711
Change-Id: I8247d0ca1acb76e661675cd9a732942b4d2401f0
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2027369
Commit-Queue: Eric Seckler <eseckler@chromium.org>
Reviewed-by: default avatarSami Kyöstilä <skyostil@chromium.org>
Cr-Commit-Position: refs/heads/master@{#736370}
parent b2c90ffa
......@@ -84,6 +84,7 @@ target(tracing_lib_type, "cpp") {
"perfetto/task_runner.h",
"perfetto/trace_event_data_source.cc",
"perfetto/trace_event_data_source.h",
"perfetto/trace_time.cc",
"perfetto/trace_time.h",
"perfetto/traced_value_proto_writer.cc",
"perfetto/traced_value_proto_writer.h",
......
......@@ -301,9 +301,8 @@ class TraceEventDataSourceTest : public testing::Test {
ASSERT_EQ(packet->clock_snapshot().clocks().size(), 3);
EXPECT_EQ(packet->clock_snapshot().clocks()[0].clock_id(),
static_cast<uint32_t>(kTraceClockId));
EXPECT_GE(packet->clock_snapshot().clocks()[0].timestamp(),
min_timestamp * 1000);
static_cast<uint32_t>(
perfetto::protos::pbzero::ClockSnapshot::Clock::BOOTTIME));
EXPECT_FALSE(packet->clock_snapshot().clocks()[0].has_unit_multiplier_ns());
EXPECT_FALSE(packet->clock_snapshot().clocks()[0].has_is_incremental());
......@@ -319,8 +318,6 @@ class TraceEventDataSourceTest : public testing::Test {
EXPECT_EQ(packet->clock_snapshot().clocks()[2].unit_multiplier_ns(), 1000u);
EXPECT_TRUE(packet->clock_snapshot().clocks()[2].is_incremental());
EXPECT_EQ(packet->clock_snapshot().clocks()[0].timestamp(),
packet->clock_snapshot().clocks()[1].timestamp() * 1000);
EXPECT_EQ(packet->clock_snapshot().clocks()[1].timestamp(),
packet->clock_snapshot().clocks()[2].timestamp());
......
// Copyright 2020 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "services/tracing/public/cpp/perfetto/trace_time.h"
#include "base/logging.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "third_party/perfetto/include/perfetto/base/time.h"
namespace tracing {
int64_t TraceBootTicksNow() {
// On Windows and Mac, TRACE_TIME_TICKS_NOW() behaves like boottime already.
#if defined(OS_LINUX) || defined(OS_ANDROID) || defined(OS_FUCHSIA)
struct timespec ts;
int res = clock_gettime(CLOCK_BOOTTIME, &ts);
if (res != -1)
return static_cast<int64_t>(perfetto::base::FromPosixTimespec(ts).count());
#endif
return TRACE_TIME_TICKS_NOW().since_origin().InNanoseconds();
}
} // namespace tracing
\ No newline at end of file
......@@ -23,6 +23,10 @@ constexpr perfetto::protos::pbzero::ClockSnapshot::Clock::BuiltinClocks
kTraceClockId = perfetto::protos::pbzero::ClockSnapshot::Clock::BOOTTIME;
#endif
// Returns CLOCK_BOOTTIME on systems that support it, otherwise falls back to
// TRACE_TIME_TICKS_NOW().
int64_t TraceBootTicksNow();
} // namespace tracing
#endif // SERVICES_TRACING_PUBLIC_CPP_PERFETTO_TRACE_TIME_H_
......@@ -802,10 +802,20 @@ void TrackEventThreadLocalEventSink::DoResetIncrementalState(
perfetto::ThreadTrack::ForThread(thread_id_).uuid);
ClockSnapshot* clocks = packet->set_clock_snapshot();
// Reference clock (CLOCK_MONOTONIC or CLOCK_BOOTTIME) is in nanos.
// Always reference the boottime timestamps to help trace processor
// translate the clocks to boottime more efficiently.
ClockSnapshot::Clock* clock_reference = clocks->add_clocks();
clock_reference->set_clock_id(kTraceClockId);
clock_reference->set_timestamp(timestamp.since_origin().InNanoseconds());
clock_reference->set_clock_id(ClockSnapshot::Clock::BOOTTIME);
if (kTraceClockId == ClockSnapshot::Clock::BOOTTIME) {
clock_reference->set_timestamp(timestamp.since_origin().InNanoseconds());
} else {
int64_t current_boot_nanos = TraceBootTicksNow();
int64_t current_monotonic_nanos =
TRACE_TIME_TICKS_NOW().since_origin().InNanoseconds();
int64_t diff = current_boot_nanos - current_monotonic_nanos;
clock_reference->set_timestamp(timestamp.since_origin().InNanoseconds() +
diff);
}
// Absolute clock in micros.
ClockSnapshot::Clock* clock_absolute = clocks->add_clocks();
clock_absolute->set_clock_id(kClockIdAbsolute);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment