summaryrefslogtreecommitdiffstats
path: root/cmds/atrace
diff options
context:
space:
mode:
authorColin Cross <ccross@android.com>2014-08-20 14:28:47 -0700
committerColin Cross <ccross@android.com>2014-08-20 14:28:47 -0700
commitb1ce49b2ed9ea953a7f534b4f36b6acb56fc0749 (patch)
tree6f3063776259b327310d3dbf95a11b4499578590 /cmds/atrace
parentb1f0f288e30c0448cabd46d19c60b3bd0d272f74 (diff)
downloadframeworks_native-b1ce49b2ed9ea953a7f534b4f36b6acb56fc0749.zip
frameworks_native-b1ce49b2ed9ea953a7f534b4f36b6acb56fc0749.tar.gz
frameworks_native-b1ce49b2ed9ea953a7f534b4f36b6acb56fc0749.tar.bz2
atrace: avoid unnecessary writes to trace_clock
Writing to trace_clock erases the trace buffer, even if the value hasn't changed. This prevents use of --async_start and --async_dump to leave background tracing running and dump after an even that needs debugging, because --async_dump writes to trace_clock and resets the buffer before it can read it. Read and parse the current value from trace_clock before writing, and skip the write if the value isn't changing. Change-Id: Ia2ec5bb654fb0bd179771b511ff261731ba47dca
Diffstat (limited to 'cmds/atrace')
-rw-r--r--cmds/atrace/atrace.cpp47
1 files changed, 46 insertions, 1 deletions
diff --git a/cmds/atrace/atrace.cpp b/cmds/atrace/atrace.cpp
index fb40193..9e5c910 100644
--- a/cmds/atrace/atrace.cpp
+++ b/cmds/atrace/atrace.cpp
@@ -341,11 +341,56 @@ static bool setTraceBufferSizeKB(int size)
return writeStr(k_traceBufferSizePath, str);
}
+// Read the trace_clock sysfs file and return true if it matches the requested
+// value. The trace_clock file format is:
+// local [global] counter uptime perf
+static bool isTraceClock(const char *mode)
+{
+ int fd = open(k_traceClockPath, O_RDONLY);
+ if (fd == -1) {
+ fprintf(stderr, "error opening %s: %s (%d)\n", k_traceClockPath,
+ strerror(errno), errno);
+ return false;
+ }
+
+ char buf[4097];
+ ssize_t n = read(fd, buf, 4096);
+ close(fd);
+ if (n == -1) {
+ fprintf(stderr, "error reading %s: %s (%d)\n", k_traceClockPath,
+ strerror(errno), errno);
+ return false;
+ }
+ buf[n] = '\0';
+
+ char *start = strchr(buf, '[');
+ if (start == NULL) {
+ return false;
+ }
+ start++;
+
+ char *end = strchr(start, ']');
+ if (end == NULL) {
+ return false;
+ }
+ *end = '\0';
+
+ return strcmp(mode, start) == 0;
+}
+
// Enable or disable the kernel's use of the global clock. Disabling the global
// clock will result in the kernel using a per-CPU local clock.
+// Any write to the trace_clock sysfs file will reset the buffer, so only
+// update it if the requested value is not the current value.
static bool setGlobalClockEnable(bool enable)
{
- return writeStr(k_traceClockPath, enable ? "global" : "local");
+ const char *clock = enable ? "global" : "local";
+
+ if (isTraceClock(clock)) {
+ return true;
+ }
+
+ return writeStr(k_traceClockPath, clock);
}
static bool setPrintTgidEnableIfPresent(bool enable)