Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(539)

Unified Diff: base/debug/trace_event_android.cc

Issue 11345019: Make Chrome Trace work with Android ATrace. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Don't append arguments to name Created 8 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: base/debug/trace_event_android.cc
diff --git a/base/debug/trace_event_android.cc b/base/debug/trace_event_android.cc
new file mode 100644
index 0000000000000000000000000000000000000000..0cfa622bd283c323f72370b829281e0f5e250cd6
--- /dev/null
+++ b/base/debug/trace_event_android.cc
@@ -0,0 +1,140 @@
+// Copyright (c) 2012 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 "base/debug/trace_event_impl.h"
+
+#include <fcntl.h>
+
+#include "base/debug/trace_event.h"
+#include "base/file_util.h"
+#include "base/format_macros.h"
+#include "base/logging.h"
+#include "base/stringprintf.h"
+
+namespace {
+
+int g_atrace_fd = -1;
+const char* kATraceMarkerFile = "/sys/kernel/debug/tracing/trace_marker";
+
+} // namespace
+
+namespace base {
+namespace debug {
+
+// static
+void TraceLog::InitATrace() {
+ DCHECK(g_atrace_fd == -1);
+ g_atrace_fd = open(kATraceMarkerFile, O_WRONLY | O_APPEND);
+ if (g_atrace_fd == -1)
+ LOG(WARNING) << "Couldn't open " << kATraceMarkerFile;
+}
+
+// static
+bool TraceLog::IsATraceEnabled() {
+ return g_atrace_fd != -1;
+}
+
+void TraceLog::SendToATrace(char phase,
+ const char* category,
+ const char* name,
+ int num_args,
+ const char** arg_names,
+ const unsigned char* arg_types,
+ const unsigned long long* arg_values) {
+ if (!IsATraceEnabled())
+ return;
+
+ switch (phase) {
+ case TRACE_EVENT_PHASE_BEGIN:
+ case TRACE_EVENT_PHASE_INSTANT: {
+ std::string out = StringPrintf("B|%d|%s-%s", getpid(), category, name);
jbates 2012/10/30 20:22:14 There's plenty of room for performance improvement
Xianzhu 2012/10/30 21:45:01 Could you be more specific? Do you mean the "+=",
jbates 2012/10/31 22:26:01 Yep, StringPrintf and std::string temporaries are
+ for (int i = 0; i < num_args; ++i) {
+ out += '|';
+ out += arg_names[i];
+ out += '=';
+ TraceEvent::TraceValue value;
+ value.as_uint = arg_values[i];
+ std::string::size_type value_start = out.length();
+ TraceEvent::AppendValueAsJSON(arg_types[i], value, &out);
+ // Remove the quotes which may confuse the atrace script.
+ ReplaceSubstringsAfterOffset(&out, value_start, "\\\"", "'");
+ ReplaceSubstringsAfterOffset(&out, value_start, "\"", "");
+ }
+ write(g_atrace_fd, out.c_str(), out.size());
+
+ if (phase != TRACE_EVENT_PHASE_INSTANT)
+ break;
+ // Fall through. Simulate an instance event with a pair of begin/end.
+ }
+ case TRACE_EVENT_PHASE_END: {
+ // Though a single 'E' is enough, here append pid and name so that
+ // unpaired events can be found easily.
+ std::string out = StringPrintf("E|%d|%s-%s", getpid(), category, name);
+ write(g_atrace_fd, out.c_str(), out.size());
+ break;
+ }
+ case TRACE_EVENT_PHASE_COUNTER:
+ for (int i = 0; i < num_args; ++i) {
+ DCHECK(arg_types[i] == TRACE_VALUE_TYPE_INT);
+ std::string out = StringPrintf(
+ "C|%d|%s-%s-%s|%d",
+ getpid(), category, name,
+ arg_names[i], static_cast<int>(arg_values[i]));
+ write(g_atrace_fd, out.c_str(), out.size());
+ }
+ break;
+
+ default:
+ // Do nothing.
+ break;
+ }
+}
+
+void TraceLog::AddClockSyncMetadataEvents() {
+ // Since Android does not support sched_setaffinity, we cannot establish clock
+ // sync unless the scheduler clock is set to global. If the trace_clock file
+ // can't be read, we will assume the kernel doesn't support tracing and do
+ // nothing.
+ std::string clock_mode;
+ if (!file_util::ReadFileToString(
+ FilePath("/sys/kernel/debug/tracing/trace_clock"), &clock_mode))
+ return;
+
+ if (clock_mode != "local [global]\n") {
+ DLOG(WARNING) <<
+ "The kernel's tracing clock must be set to global in order for " <<
+ "trace_event to be synchronized with . Do this by\n" <<
+ " echo global > /sys/kerel/debug/tracing/trace_clock";
+ return;
+ }
+
+ int atrace_fd = g_atrace_fd;
+ if (atrace_fd == -1) {
+ // This function may be called when atrace is not enabled.
+ atrace_fd = open(kATraceMarkerFile, O_WRONLY | O_APPEND);
+ if (atrace_fd == -1) {
+ LOG(WARNING) << "Couldn't open " << kATraceMarkerFile;
+ return;
+ }
+ }
+
+ // Android's kernel trace system has a trace_marker feature: this is a file on
+ // debugfs that takes the written data and pushes it onto the trace
+ // buffer. So, to establish clock sync, we write our monotonic clock into that
+ // trace buffer.
+ TimeTicks now = TimeTicks::NowFromSystemTraceTime();
+ double now_in_seconds = now.ToInternalValue() / 1000000.0;
+ std::string marker = StringPrintf(
+ "trace_event_clock_sync: parent_ts=%f\n", now_in_seconds);
+ if (write(atrace_fd, marker.c_str(), marker.size()) != 0) {
+ DLOG(WARNING) << "Couldn't write to " << kATraceMarkerFile << ": "
+ << strerror(errno);
+ }
+
+ if (g_atrace_fd == -1)
+ close(atrace_fd);
+}
+
+} // namespace debug
+} // namespace base

Powered by Google App Engine
This is Rietveld 408576698