#!/usr/bin/env python
-import json, sys
+import json, sys, time
def is_inside(range1, range2):
a = range1["ts"]; b = a + range1["dur"]
b = range1["ts"] + range1["dur"]; c = range2["ts"]
return b <= c
-events = json.loads(sys.stdin.read())["traceEvents"]
+log_contents = json.loads(sys.stdin.read())
+events = log_contents["traceEvents"]
codegens = [event for event in events if event["name"] == "CodeGen Function"]
frontends = [event for event in events if event["name"] == "Frontend"]
backends = [event for event in events if event["name"] == "Backend"]
+beginning_of_time = log_contents["beginningOfTime"] / 1000000
+seconds_since_epoch = time.time()
+
+# Make sure that the 'beginningOfTime' is not earlier than 10 seconds ago
+# and not later than now.
+if beginning_of_time > seconds_since_epoch or \
+ seconds_since_epoch - beginning_of_time > 10:
+ sys.exit("'beginningOfTime' should represent the absolute time when the "
+ "process has started")
+
if not all([any([is_inside(codegen, frontend) for frontend in frontends])
for codegen in codegens]):
sys.exit("Not all CodeGen sections are inside any Frontend section!")
// RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \
// RUN: | FileCheck %s
-// CHECK: "traceEvents": [
-// CHECK: "args":
-// CHECK: "detail":
-// CHECK: "dur":
-// CHECK: "name":
+// CHECK: "beginningOfTime": {{[0-9]{16},}}
+// CHECK-NEXT: "traceEvents": [
+// CHECK: "args":
+// CHECK: "detail":
+// CHECK: "dur":
+// CHECK: "name":
// CHECK-NEXT: "ph":
// CHECK-NEXT: "pid":
// CHECK-NEXT: "tid":
// CHECK-NEXT: "ts":
-// CHECK: "name": "clang{{.*}}"
-// CHECK: "name": "process_name"
-// CHECK: "name": "thread_name"
+// CHECK: "name": "clang{{.*}}"
+// CHECK: "name": "process_name"
+// CHECK: "name": "thread_name"
template <typename T>
struct Struct {
# RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \
# RUN: | FileCheck %s
-# CHECK: "traceEvents": [
+# CHECK: "beginningOfTime": {{[0-9]{16},}}
+# CHECK-NEXT: "traceEvents": [
# Check one event has correct fields
# CHECK: "dur":
struct llvm::TimeTraceProfiler {
TimeTraceProfiler(unsigned TimeTraceGranularity = 0, StringRef ProcName = "")
- : StartTime(steady_clock::now()), ProcName(ProcName),
- Pid(sys::Process::getProcessId()), Tid(llvm::get_threadid()),
- TimeTraceGranularity(TimeTraceGranularity) {
+ : BeginningOfTime(system_clock::now()), StartTime(steady_clock::now()),
+ ProcName(ProcName), Pid(sys::Process::getProcessId()),
+ Tid(llvm::get_threadid()), TimeTraceGranularity(TimeTraceGranularity) {
llvm::get_thread_name(ThreadName);
}
J.arrayEnd();
J.attributeEnd();
+
+ // Emit the absolute time when this TimeProfiler started.
+ // This can be used to combine the profiling data from
+ // multiple processes and preserve actual time intervals.
+ J.attribute("beginningOfTime",
+ time_point_cast<microseconds>(BeginningOfTime)
+ .time_since_epoch()
+ .count());
+
J.objectEnd();
}
SmallVector<Entry, 16> Stack;
SmallVector<Entry, 128> Entries;
StringMap<CountAndDurationType> CountAndTotalPerName;
+ const time_point<system_clock> BeginningOfTime;
const TimePointType StartTime;
const std::string ProcName;
const sys::Process::Pid Pid;