Improve logic for setting trace clock 49/229649/3
authorSeungha Son <seungha.son@samsung.com>
Thu, 2 Apr 2020 11:40:22 +0000 (20:40 +0900)
committerSeungha Son <seungha.son@samsung.com>
Fri, 3 Apr 2020 07:39:21 +0000 (16:39 +0900)
 Set the clock to the best available option while tracing. Use 'boot' if it's
 available; otherwise, use 'mono'. If neither are available use 'global'.
 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.

 Reference : https://www.kernel.org/doc/Documentation/trace/ftrace.txt

 trace_clock:
        Whenever an event is recorded into the ring buffer, a
"timestamp" is added. This stamp comes from a specified
clock. By default, ftrace uses the "local" clock. This
clock is very fast and strictly per cpu, but on some
systems it may not be monotonic with respect to other
CPUs. In other words, the local clocks may not be in sync
with local clocks on other CPUs.

Usual clocks for tracing:

  # cat trace_clock
  [local] global counter x86-tsc

  The clock with the square brackets around it is the one
  in effect.

  local: Default clock, but may not be in sync across CPUs

  global: This clock is in sync with all CPUs but may
     be a bit slower than the local clock.

          mono: This uses the fast monotonic clock (CLOCK_MONOTONIC)
which is monotonic and is subject to NTP rate adjustments.

  boot: This is the boot clock (CLOCK_BOOTTIME) and is based on the
fast monotonic clock, but also accounts for time spent in
suspend. Since the clock access is designed for use in
tracing in the suspend path, some side effects are possible
if clock is accessed after the suspend time is accounted before
the fast mono clock is updated. In this case, the clock update
appears to happen slightly sooner than it normally would have.
Also on 32-bit systems, it's possible that the 64-bit boot offset
sees a partial update. These effects are rare and post
processing should be able to handle them. See comments in the
ktime_get_boot_fast_ns() function for more information.

Change-Id: Iba2d4fcd4f6272fd8faa2e7d462c5b275547c73f
Signed-off-by: Seungha Son <seungha.son@samsung.com>
CMakeLists.txt
src/atrace/atrace.cpp

index 1a1abf683b3c01acf905e9235df8313a1c0efbf4..ca1c48ff8196099964004306a5a93b6b516585ac 100755 (executable)
@@ -94,7 +94,7 @@ pkg_check_modules(pkg_atrace REQUIRED zlib)
 FOREACH(flag ${pkg_atrace_CXXFLAGS})
        SET(EXTRA_CXXFLAGS_common "${EXTRA_CXXFLAGS_common} ${flag}")
 ENDFOREACH(flag)
-SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS} ${EXTRA_CXXFLAGS_common}")
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS} ${EXTRA_CXXFLAGS_common} -std=c++11")
 MESSAGE("CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
 
 ADD_EXECUTABLE(${ATRACE} ${SRCS_atrace})
index 8fcc67e2670f404ad2c97c05dabd47e89962509d..dea5d0a2b2c47824913279297924e62864df361d 100755 (executable)
@@ -24,7 +24,6 @@
 #include <sys/sendfile.h>
 #include <time.h>
 #include <zlib.h>
-
 #include <stdint.h>
 #include <strings.h>
 #include <string.h>
 #include <sys/file.h>
 #include <sys/stat.h>
 #include <sys/smack.h>
+#include <sys/types.h>
 #include <unistd.h>
+
+#include <fstream>
+
 #include "ttrace.h"
+
+using std::string;
+
 #define TTRACE_TAG_NONE     9999
 #define TAG_NONE_IDX        0
 
@@ -386,11 +392,33 @@ static bool setTraceBufferSizeKB(int size)
     return writeStr(k_traceBufferSizePath, str);
 }
 
-// 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.
-static bool setGlobalClockEnable(bool enable)
+// Set the clock to the best available option while tracing. Use 'boot' if it's
+// available; otherwise, use 'mono'. If neither are available use 'global'.
+// 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 setBestClock(bool enable)
 {
-    return writeStr(k_traceClockPath, enable ? "global" : "local");
+    std::ifstream clockFile(k_traceClockPath, std::ios::in);
+    std::string clockStr((std::istreambuf_iterator<char>(clockFile)),
+        std::istreambuf_iterator<char>());
+    std::string newClock;
+
+    if (enable == false)
+        return writeStr(k_traceClockPath, "local");
+
+    if (clockStr.find("boot") != std::string::npos)
+        newClock = "boot";
+    else if (clockStr.find("mono") != std::string::npos)
+        newClock = "mono";
+    else
+        newClock = "global";
+
+    size_t begin = clockStr.find('[') + 1;
+    size_t end = clockStr.find(']');
+    if (newClock.compare(0, std::string::npos, clockStr, begin, end-begin) == 0)
+        return true;
+
+    return writeStr(k_traceClockPath, newClock.c_str());
 }
 
 static bool setPrintTgidEnableIfPresent(bool enable)
@@ -571,7 +599,7 @@ static bool setUpTrace()
     ok &= setTraceOverwriteEnable(g_traceOverwrite);
     if(!g_append_trace) {
         ok &= setTraceBufferSizeKB(g_traceBufferSizeKB);
-        ok &= setGlobalClockEnable(true);
+        ok &= setBestClock(true);
         ok &= setKernelTraceFuncs(g_kernelTraceFuncs);
     }
     ok &= setPrintTgidEnableIfPresent(true);
@@ -643,7 +671,7 @@ static void cleanUpTrace()
     // Set the options back to their defaults.
     setTraceOverwriteEnable(true);
     setTraceBufferSizeKB(1);
-    setGlobalClockEnable(false);
+    setBestClock(false);
     setPrintTgidEnableIfPresent(false);
     setKernelTraceFuncs(nullptr);
 }