Fix the TODOs in the traceview support.

Change-Id: Iefd57761231820afec7278345dcefd1c7eae4a77
diff --git a/src/runtime.cc b/src/runtime.cc
index c452771..e033059 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -465,6 +465,12 @@
       parsed->method_trace_file_ = option.substr(strlen("-Xmethod-trace-file:"));
     } else if (StartsWith(option, "-Xmethod-trace-file-size:")) {
       parsed->method_trace_file_size_ = ParseIntegerOrDie(option);
+    } else if (option == "-Xprofile:threadcpuclock") {
+      Trace::SetDefaultClockSource(kProfilerClockSourceThreadCpu);
+    } else if (option == "-Xprofile:wallclock") {
+      Trace::SetDefaultClockSource(kProfilerClockSourceWall);
+    } else if (option == "-Xprofile:dualclock") {
+      Trace::SetDefaultClockSource(kProfilerClockSourceDual);
     } else {
       if (!ignore_unrecognized) {
         // TODO: print usage via vfprintf
diff --git a/src/trace.cc b/src/trace.cc
index 7b7a767..aa6c523 100644
--- a/src/trace.cc
+++ b/src/trace.cc
@@ -32,6 +32,40 @@
 
 namespace art {
 
+// File format:
+//     header
+//     record 0
+//     record 1
+//     ...
+//
+// Header format:
+//     u4  magic ('SLOW')
+//     u2  version
+//     u2  offset to data
+//     u8  start date/time in usec
+//     u2  record size in bytes (version >= 2 only)
+//     ... padding to 32 bytes
+//
+// Record format v1:
+//     u1  thread ID
+//     u4  method ID | method action
+//     u4  time delta since start, in usec
+//
+// Record format v2:
+//     u2  thread ID
+//     u4  method ID | method action
+//     u4  time delta since start, in usec
+//
+// Record format v3:
+//     u2  thread ID
+//     u4  method ID | method action
+//     u4  time delta since start, in usec
+//     u4  wall time since start, in usec (when clock == "dual" only)
+//
+// 32 bits of microseconds is 70 minutes.
+//
+// All values are stored in little-endian order.
+
 static const uint32_t kTraceMethodActionMask      = 0x03; // two bits
 static const char     kTraceTokenChar             = '*';
 static const uint16_t kTraceHeaderLength          = 32;
@@ -41,44 +75,57 @@
 static const uint16_t kTraceRecordSizeSingleClock = 10; // using v2
 static const uint16_t kTraceRecordSizeDualClock   = 14; // using v3 with two timestamps
 
+static ProfilerClockSource gDefaultTraceClockSource = kProfilerClockSourceDual;
+
 static inline uint32_t TraceMethodId(uint32_t methodValue) {
   return (methodValue & ~kTraceMethodActionMask);
 }
+
 static inline uint32_t TraceMethodCombine(uint32_t method, uint8_t traceEvent) {
   return (method | traceEvent);
 }
 
-static bool UseThreadCpuClock() {
-  // TODO: Allow control over which clock is used
-  return true;
+void Trace::SetDefaultClockSource(ProfilerClockSource clock_source) {
+  gDefaultTraceClockSource = clock_source;
 }
 
-static bool UseWallClock() {
-  // TODO: Allow control over which clock is used
-  return true;
+bool Trace::UseThreadCpuClock() {
+#if defined(HAVE_POSIX_CLOCKS)
+  return clock_source_ != kProfilerClockSourceWall;
+#else
+  return false;
+#endif
 }
 
-static void MeasureClockOverhead() {
-  if (UseThreadCpuClock()) {
+bool Trace::UseWallClock() {
+#if defined(HAVE_POSIX_CLOCKS)
+  return clock_source_ != kProfilerClockSourceThreadCpu;
+#else
+  return true;
+#endif
+}
+
+static void MeasureClockOverhead(Trace* trace) {
+  if (trace->UseThreadCpuClock()) {
     ThreadCpuMicroTime();
   }
-  if (UseWallClock()) {
+  if (trace->UseWallClock()) {
     MicroTime();
   }
 }
 
-static uint32_t GetClockOverhead() {
+static uint32_t GetClockOverhead(Trace* trace) {
   uint64_t start = ThreadCpuMicroTime();
 
   for (int i = 4000; i > 0; i--) {
-    MeasureClockOverhead();
-    MeasureClockOverhead();
-    MeasureClockOverhead();
-    MeasureClockOverhead();
-    MeasureClockOverhead();
-    MeasureClockOverhead();
-    MeasureClockOverhead();
-    MeasureClockOverhead();
+    MeasureClockOverhead(trace);
+    MeasureClockOverhead(trace);
+    MeasureClockOverhead(trace);
+    MeasureClockOverhead(trace);
+    MeasureClockOverhead(trace);
+    MeasureClockOverhead(trace);
+    MeasureClockOverhead(trace);
+    MeasureClockOverhead(trace);
   }
 
   uint64_t elapsed = ThreadCpuMicroTime() - start;
@@ -204,6 +251,12 @@
   RemoveSavedCodeFromMap(method);
 }
 
+Trace::Trace(File* trace_file, int buffer_size, int flags)
+    : trace_file_(trace_file), buf_(new uint8_t[buffer_size]()), flags_(flags),
+      clock_source_(gDefaultTraceClockSource), overflow_(false),
+      buffer_size_(buffer_size), start_time_(0), trace_version_(0), record_size_(0), cur_offset_(0) {
+}
+
 void Trace::Start(const char* trace_filename, int trace_fd, int buffer_size, int flags, bool direct_to_ddms) {
   if (Runtime::Current()->IsMethodTracingActive()) {
     LOG(INFO) << "Trace already in progress, ignoring this request";
@@ -306,7 +359,7 @@
   uint64_t elapsed = MicroTime() - start_time_;
 
   size_t final_offset = cur_offset_;
-  uint32_t clock_overhead = GetClockOverhead();
+  uint32_t clock_overhead = GetClockOverhead(this);
 
   if ((flags_ & kTraceCountAllocs) != 0) {
     Runtime::Current()->SetStatsEnabled(false);
diff --git a/src/trace.h b/src/trace.h
index bcf7f0a..0042fc2 100644
--- a/src/trace.h
+++ b/src/trace.h
@@ -43,9 +43,14 @@
   uintptr_t return_pc_;
 };
 
+enum ProfilerClockSource {
+  kProfilerClockSourceThreadCpu,
+  kProfilerClockSourceWall,
+  kProfilerClockSourceDual,
+};
+
 class Trace {
  public:
-
   enum TraceEvent {
     kMethodTraceEnter = 0,
     kMethodTraceExit = 1,
@@ -56,10 +61,15 @@
     kTraceCountAllocs = 1,
   };
 
+  static void SetDefaultClockSource(ProfilerClockSource clock_source);
+
   static void Start(const char* trace_filename, int trace_fd, int buffer_size, int flags, bool direct_to_ddms);
   static void Stop();
   static void Shutdown();
 
+  bool UseWallClock();
+  bool UseThreadCpuClock();
+
   void LogMethodTraceEvent(Thread* self, const Method* method, TraceEvent event);
 
   void AddSavedCodeToMap(const Method* method, const void* code);
@@ -70,10 +80,7 @@
   void ResetSavedCode(Method* method);
 
  private:
-  explicit Trace(File* trace_file, int buffer_size, int flags)
-      : trace_file_(trace_file), buf_(new uint8_t[buffer_size]()), flags_(flags), overflow_(false),
-        buffer_size_(buffer_size), start_time_(0), trace_version_(0), record_size_(0), cur_offset_(0) {
-  }
+  explicit Trace(File* trace_file, int buffer_size, int flags);
 
   void BeginTracing();
   void FinishTracing();
@@ -107,6 +114,8 @@
   // Flags enabling extra tracing of things such as alloc counts.
   int flags_;
 
+  ProfilerClockSource clock_source_;
+
   bool overflow_;
   int buffer_size_;
   uint64_t start_time_;