-
Notifications
You must be signed in to change notification settings - Fork 129
Expand file tree
/
Copy pathevent.ml
More file actions
147 lines (125 loc) · 3.91 KB
/
event.ml
File metadata and controls
147 lines (125 loc) · 3.91 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
open! Core
module Kind = struct
type t =
| Async
| Call
| Return
| Syscall
| Sysret
| Hardware_interrupt
| Interrupt
| Iret
| Jump
| Tx_abort
[@@deriving sexp, compare, bin_io]
end
module Thread = struct
type t =
{ pid : Pid.t option
; tid : Pid.t option
}
[@@deriving sexp, compare, hash, bin_io]
end
module Location = struct
type t =
{ instruction_pointer : Int64.Hex.t
; symbol : Symbol.t
; symbol_offset : Int.Hex.t
}
[@@deriving sexp, fields, bin_io]
module Ignore_symbol = struct
(* Ignoring symbol strings when serializing to save space. This reduces the size of events file
by ~50% based on small tests. The symbol information is still available implicitly by looking at the top
of the callstack that optionally is exported together with the events. Symbol offset will be missing.*)
type nonrec t = t
let to_sexpable { instruction_pointer; _ } = instruction_pointer
let of_sexpable instruction_pointer =
{ instruction_pointer; symbol = Symbol.Unknown; symbol_offset = 0 }
;;
let to_binable { instruction_pointer; _ } = instruction_pointer
let of_binable instruction_pointer =
{ instruction_pointer; symbol = Symbol.Unknown; symbol_offset = 0 }
;;
let caller_identity =
Bin_prot.Shape.Uuid.of_string "0d14b306-09e1-11ed-9c9e-a4bb6d9e5f20"
;;
end
include Binable.Of_binable_with_uuid (Int64.Hex) (Ignore_symbol)
include Sexpable.Of_sexpable (Int64.Hex) (Ignore_symbol)
(* magic-trace has some things that aren't functions but look like they are in the trace
(like "[untraced]" and "[syscall]") *)
let locationless symbol = { instruction_pointer = 0L; symbol; symbol_offset = 0 }
let unknown = locationless Unknown
let untraced = locationless Untraced
let returned = locationless Returned
let syscall = locationless Syscall
end
module Ok = struct
module Data = struct
type t =
| Trace of
{ trace_state_change : Trace_state_change.t option [@sexp.option]
; kind : Kind.t option [@sexp.option]
; src : Location.t
; dst : Location.t
}
| Power of { freq : int }
| Stacktrace_sample of { callstack : Location.t list }
| Event_sample of
{ location : Location.t
; count : int
; name : Collection_mode.Event.Name.t
}
| Ptwrite of
{ location : Location.t
; data : string
}
[@@deriving sexp, bin_io]
end
type t =
{ thread : Thread.t
; time : Time_ns.Span.t
; data : Data.t
; in_transaction : bool [@sexp.bool]
}
[@@deriving sexp, bin_io]
end
module Decode_error = struct
type t =
{ thread : Thread.t
(* The time is only present sometimes. I haven't figured out when, exactly, but my
Skylake test machine has it while my Tiger Lake test machine doesn't. It could
easily be a difference between different versions of perf... *)
; time : Time_ns_unix.Span.Option.t
; instruction_pointer : Int64.Hex.t option
; message : string
}
[@@deriving sexp, bin_io]
end
type t = (Ok.t, Decode_error.t) Result.t [@@deriving sexp, bin_io]
let thread (t : t) =
match t with
| Ok { thread; _ } | Error { thread; _ } -> thread
;;
let time (t : t) =
match t with
| Ok { time; _ } -> Time_ns_unix.Span.Option.some time
| Error { time; _ } -> time
;;
let change_time (t : t) ~f : t =
match t with
| Ok ({ time; _ } as t) -> Ok { t with time = f time }
| Error ({ time; _ } as u) ->
(match%optional.Time_ns_unix.Span.Option time with
| None -> t
| Some time -> Error { u with time = Time_ns_unix.Span.Option.some (f time) })
;;
module With_write_info = struct
type outer = t [@@deriving sexp_of]
type t =
{ event : outer
; should_write : bool
}
[@@deriving sexp_of, fields]
let create ?(should_write = true) event = { event; should_write }
end