Extend flags passed to Trace::Start to also specify the clock source
We should enable users of method tracing to choose the clock source.
Earlier the clock source could only be chosen at the boot time and
wasn't very useful. This CL extends the flags that's already used by the
method profilers to specify the clock source. The clock source could be
wall clock, thread cpu or both. Thread cpu is an expensive operation and
hence we should enable it only when requested.
Drive-by fix: Also expose interval from Trace, so we can use it in the
post zygote hooks.
Bug: 259258187
Test: art/test.py
Change-Id: I6850fe2dc90d9d1e7f9408b5fd4bfbf390bc7ea3
diff --git a/runtime/native/dalvik_system_ZygoteHooks.cc b/runtime/native/dalvik_system_ZygoteHooks.cc
index f7d7d80..fb077e2 100644
--- a/runtime/native/dalvik_system_ZygoteHooks.cc
+++ b/runtime/native/dalvik_system_ZygoteHooks.cc
@@ -386,10 +386,10 @@
std::string trace_file = StringPrintf("%s/%s.trace.bin", path, proc_name.c_str());
Trace::Start(trace_file.c_str(),
buffer_size,
- 0, // TODO: Expose flags.
+ Trace::GetFlags(),
output_mode,
trace_mode,
- 0); // TODO: Expose interval.
+ Trace::GetIntervalInMillis());
if (thread->IsExceptionPending()) {
ScopedObjectAccess soa(env);
thread->ClearException();
diff --git a/runtime/parsed_options.cc b/runtime/parsed_options.cc
index 8e207b2..b682e60 100644
--- a/runtime/parsed_options.cc
+++ b/runtime/parsed_options.cc
@@ -356,6 +356,12 @@
.IntoKey(M::MethodTraceFileSize)
.Define("-Xmethod-trace-stream")
.IntoKey(M::MethodTraceStreaming)
+ .Define("-Xmethod-trace-clock:_")
+ .WithType<TraceClockSource>()
+ .WithValueMap({{"threadcpuclock", TraceClockSource::kThreadCpu},
+ {"wallclock", TraceClockSource::kWall},
+ {"dualclock", TraceClockSource::kDual}})
+ .IntoKey(M::MethodTraceClock)
.Define("-Xcompiler:_")
.WithType<std::string>()
.IntoKey(M::Compiler)
diff --git a/runtime/runtime.cc b/runtime/runtime.cc
index 27a1c58..3f337f4 100644
--- a/runtime/runtime.cc
+++ b/runtime/runtime.cc
@@ -212,6 +212,7 @@
Trace::TraceOutputMode trace_output_mode;
std::string trace_file;
size_t trace_file_size;
+ TraceClockSource clock_source;
};
namespace {
@@ -1060,9 +1061,20 @@
if (trace_config_.get() != nullptr && trace_config_->trace_file != "") {
ScopedThreadStateChange tsc(self, ThreadState::kWaitingForMethodTracingStart);
+ int flags = 0;
+ if (trace_config_->clock_source == TraceClockSource::kDual) {
+ flags = Trace::TraceFlag::kTraceClockSourceWallClock |
+ Trace::TraceFlag::kTraceClockSourceThreadCpu;
+ } else if (trace_config_->clock_source == TraceClockSource::kWall) {
+ flags = Trace::TraceFlag::kTraceClockSourceWallClock;
+ } else if (TraceClockSource::kThreadCpu == trace_config_->clock_source) {
+ flags = Trace::TraceFlag::kTraceClockSourceThreadCpu;
+ } else {
+ LOG(ERROR) << "Unexpected clock source";
+ }
Trace::Start(trace_config_->trace_file.c_str(),
static_cast<int>(trace_config_->trace_file_size),
- 0,
+ flags,
trace_config_->trace_output_mode,
trace_config_->trace_mode,
0);
@@ -1928,9 +1940,10 @@
trace_config_->trace_output_mode = runtime_options.Exists(Opt::MethodTraceStreaming) ?
Trace::TraceOutputMode::kStreaming :
Trace::TraceOutputMode::kFile;
+ trace_config_->clock_source = runtime_options.GetOrDefault(Opt::MethodTraceClock);
}
- // TODO: move this to just be an Trace::Start argument
+ // TODO: Remove this in a follow up CL. This isn't used anywhere.
Trace::SetDefaultClockSource(runtime_options.GetOrDefault(Opt::ProfileClock));
if (GetHeap()->HasBootImageSpace()) {
diff --git a/runtime/runtime_options.def b/runtime/runtime_options.def
index 769ed04..b2fcf7d 100644
--- a/runtime/runtime_options.def
+++ b/runtime/runtime_options.def
@@ -126,6 +126,7 @@
RUNTIME_OPTIONS_KEY (std::string, MethodTraceFile, "/data/misc/trace/method-trace-file.bin")
RUNTIME_OPTIONS_KEY (unsigned int, MethodTraceFileSize, 10 * MB)
RUNTIME_OPTIONS_KEY (Unit, MethodTraceStreaming)
+RUNTIME_OPTIONS_KEY (TraceClockSource, MethodTraceClock, kDefaultTraceClockSource)
RUNTIME_OPTIONS_KEY (TraceClockSource, ProfileClock, kDefaultTraceClockSource) // -Xprofile:
RUNTIME_OPTIONS_KEY (ProfileSaverOptions, ProfileSaverOpts) // -Xjitsaveprofilinginfo, -Xps-*
RUNTIME_OPTIONS_KEY (std::string, Compiler)
diff --git a/runtime/trace.cc b/runtime/trace.cc
index e73a28b..0de55fa 100644
--- a/runtime/trace.cc
+++ b/runtime/trace.cc
@@ -566,6 +566,24 @@
static constexpr size_t kPerThreadBufSize = 512 * 1024;
static_assert(kPerThreadBufSize > kMinBufSize);
+namespace {
+
+TraceClockSource GetClockSourceFromFlags(int flags) {
+ bool need_wall = flags & Trace::TraceFlag::kTraceClockSourceWallClock;
+ bool need_thread_cpu = flags & Trace::TraceFlag::kTraceClockSourceThreadCpu;
+ if (need_wall && need_thread_cpu) {
+ return TraceClockSource::kDual;
+ } else if (need_wall) {
+ return TraceClockSource::kWall;
+ } else if (need_thread_cpu) {
+ return TraceClockSource::kThreadCpu;
+ } else {
+ return kDefaultTraceClockSource;
+ }
+}
+
+} // namespace
+
Trace::Trace(File* trace_file,
size_t buffer_size,
int flags,
@@ -576,7 +594,7 @@
flags_(flags),
trace_output_mode_(output_mode),
trace_mode_(trace_mode),
- clock_source_(default_clock_source_),
+ clock_source_(GetClockSourceFromFlags(flags)),
buffer_size_(std::max(kMinBufSize, buffer_size)),
start_time_(MicroTime()),
clock_overhead_ns_(GetClockOverheadNanoSeconds()),
@@ -1174,6 +1192,18 @@
return the_trace_->trace_mode_;
}
+int Trace::GetFlags() {
+ MutexLock mu(Thread::Current(), *Locks::trace_lock_);
+ CHECK(the_trace_ != nullptr) << "Trace mode requested, but no trace currently running";
+ return the_trace_->flags_;
+}
+
+int Trace::GetIntervalInMillis() {
+ MutexLock mu(Thread::Current(), *Locks::trace_lock_);
+ CHECK(the_trace_ != nullptr) << "Trace mode requested, but no trace currently running";
+ return the_trace_->interval_us_;
+}
+
size_t Trace::GetBufferSize() {
MutexLock mu(Thread::Current(), *Locks::trace_lock_);
CHECK(the_trace_ != nullptr) << "Trace mode requested, but no trace currently running";
diff --git a/runtime/trace.h b/runtime/trace.h
index bce8efc..344c783 100644
--- a/runtime/trace.h
+++ b/runtime/trace.h
@@ -104,7 +104,9 @@
class Trace final : public instrumentation::InstrumentationListener {
public:
enum TraceFlag {
- kTraceCountAllocs = 1,
+ kTraceCountAllocs = 0x001,
+ kTraceClockSourceWallClock = 0x010,
+ kTraceClockSourceThreadCpu = 0x100,
};
enum class TraceOutputMode {
@@ -230,6 +232,8 @@
static TraceOutputMode GetOutputMode() REQUIRES(!Locks::trace_lock_);
static TraceMode GetMode() REQUIRES(!Locks::trace_lock_);
static size_t GetBufferSize() REQUIRES(!Locks::trace_lock_);
+ static int GetFlags() REQUIRES(!Locks::trace_lock_);
+ static int GetIntervalInMillis() REQUIRES(!Locks::trace_lock_);
// Used by class linker to prevent class unloading.
static bool IsTracingEnabled() REQUIRES(!Locks::trace_lock_);