diff options
author | Colin Cross <ccross@android.com> | 2014-08-20 14:28:47 -0700 |
---|---|---|
committer | Colin Cross <ccross@android.com> | 2014-08-20 14:28:47 -0700 |
commit | b1ce49b2ed9ea953a7f534b4f36b6acb56fc0749 (patch) | |
tree | 6f3063776259b327310d3dbf95a11b4499578590 /cmds/atrace | |
parent | b1f0f288e30c0448cabd46d19c60b3bd0d272f74 (diff) | |
download | frameworks_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.cpp | 47 |
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) |