am 83fdbb05: Add disk I/O tracing.

* commit '83fdbb05c39b030ef1e5b3a7db79c617114c20f4':
  Add disk I/O tracing.
diff --git a/atrace/Android.mk b/atrace/Android.mk
index df79e82..1de8e95 100644
--- a/atrace/Android.mk
+++ b/atrace/Android.mk
@@ -6,6 +6,7 @@
 LOCAL_SRC_FILES:= atrace.c
 
 LOCAL_C_INCLUDES += external/zlib
+LOCAL_CFLAGS += -std=c99
 
 LOCAL_MODULE:= atrace
 
diff --git a/atrace/atrace.c b/atrace/atrace.c
index a674295..a0d4250 100644
--- a/atrace/atrace.c
+++ b/atrace/atrace.c
@@ -25,11 +25,14 @@
 #include <time.h>
 #include <zlib.h>
 
+#define NELEM(x) ((int) (sizeof(x) / sizeof((x)[0])))
+
 /* Command line options */
 static int g_traceDurationSeconds = 5;
 static bool g_traceSchedSwitch = false;
 static bool g_traceCpuFrequency = false;
 static bool g_traceCpuIdle = false;
+static bool g_traceDisk = false;
 static bool g_traceGovernorLoad = false;
 static bool g_traceWorkqueue = false;
 static bool g_traceOverwrite = false;
@@ -64,6 +67,13 @@
 static const char* k_workqueueEnablePath =
     "/sys/kernel/debug/tracing/events/workqueue/enable";
 
+static const char* k_diskEnablePaths[] = {
+        "/sys/kernel/debug/tracing/events/ext4/ext4_sync_file_enter/enable",
+        "/sys/kernel/debug/tracing/events/ext4/ext4_sync_file_exit/enable",
+        "/sys/kernel/debug/tracing/events/block/block_rq_issue/enable",
+        "/sys/kernel/debug/tracing/events/block/block_rq_complete/enable",
+};
+
 static const char* k_tracingOnPath =
     "/sys/kernel/debug/tracing/tracing_on";
 
@@ -102,6 +112,16 @@
     return writeStr(filename, enable ? "1" : "0");
 }
 
+// Enable or disable a collection of kernel options by writing a "1" or a "0" into each /sys file.
+static bool setMultipleKernelOptionsEnable(const char** filenames, size_t count, bool enable)
+{
+    bool result = true;
+    for (size_t i = 0; i < count; i++) {
+        result &= setKernelOptionEnable(filenames[i], enable);
+    }
+    return result;
+}
+
 // Enable or disable overwriting of the kernel trace buffers.  Disabling this
 // will cause tracing to stop once the trace buffers have filled up.
 static bool setTraceOverwriteEnable(bool enable)
@@ -140,6 +160,12 @@
     return setKernelOptionEnable(k_workqueueEnablePath, enable);
 }
 
+// Enable or disable tracing of disk I/O.
+static bool setDiskTracingEnabled(bool enable)
+{
+    return setMultipleKernelOptionsEnable(k_diskEnablePaths, NELEM(k_diskEnablePaths), enable);
+}
+
 // Enable or disable kernel tracing.
 static bool setTracingEnabled(bool enable)
 {
@@ -199,6 +225,7 @@
         ok &= setGovernorLoadTracingEnable(g_traceGovernorLoad);
     }
     ok &= setWorkqueueTracingEnabled(g_traceWorkqueue);
+    ok &= setDiskTracingEnabled(g_traceDisk);
     ok &= setTraceBufferSizeKB(g_traceBufferSizeKB);
     ok &= setGlobalClockEnable(true);
 
@@ -336,6 +363,7 @@
     fprintf(stderr, "options include:\n"
                     "  -b N            use a trace buffer size of N KB\n"
                     "  -c              trace into a circular buffer\n"
+                    "  -d              trace disk I/O\n"
                     "  -f              trace CPU frequency changes\n"
                     "  -l              trace CPU frequency governor load\n"
                     "  -s              trace the kernel scheduler switches\n"
@@ -374,7 +402,7 @@
     for (;;) {
         int ret;
 
-        ret = getopt(argc, argv, "b:ciflst:wz");
+        ret = getopt(argc, argv, "b:cidflst:wz");
 
         if (ret < 0) {
             break;
@@ -397,6 +425,10 @@
                 g_traceGovernorLoad = true;
             break;
 
+            case 'd':
+                g_traceDisk = true;
+            break;
+
             case 'f':
                 g_traceCpuFrequency = true;
             break;