diff --git a/src/fuchsia/write/trace_fuchsia_write.ml b/src/fuchsia/write/trace_fuchsia_write.ml index 65a69a0..4bed4cb 100644 --- a/src/fuchsia/write/trace_fuchsia_write.ml +++ b/src/fuchsia/write/trace_fuchsia_write.ml @@ -90,10 +90,10 @@ module Thread_ref = struct invalid_arg "fuchsia: thread inline ref must be >0 < 256"; Ref x - let size_B (self : t) : int = + let size_word (self : t) : int = match self with | Ref _ -> 0 - | Inline _ -> 16 + | Inline _ -> 2 (** 8-bit int for the reference *) let as_i8 (self : t) : int = @@ -107,10 +107,39 @@ module Metadata = struct (** First record in the trace *) module Magic_record = struct let value = 0x0016547846040010L - let size_B = 8 + let size_word = 1 let encode (buf : Buf.t) = Buf.add_i64 buf value end + module Initialization_record = struct + let size_word = 2 + + (** Default: 1 tick = 1 ns *) + let default_ticks_per_sec = 1_000_000_000L + + let encode (buf : Buf.t) ~ticks_per_secs () : unit = + let hd = I64.(1L lor (of_int size_word lsl 4)) in + Buf.add_i64 buf hd; + Buf.add_i64 buf ticks_per_secs + end + + module Provider_info = struct + let size_word ~name () = 1 + (round_to_word (String.length name) lsr 3) + + let encode buf ~(id : int) ~name () : unit = + let size = size_word ~name () in + let hd = + I64.( + (of_int size lsl 4) + lor (1L lsl 16) + lor (of_int id lsl 20) + lor (of_int (Str_ref.inline (String.length name)) lsl 52)) + in + Buf.add_i64 buf hd; + Buf.add_string buf name + end + + module Provider_section = struct end module Trace_info = struct end end @@ -122,16 +151,17 @@ module Argument = struct let[@inline] is_i32_ (i : int) : bool = Int32.(to_int (of_int i) = i) - (** Size in bytes *) - let size_B (self : t) = + let size_word (self : t) = let name, data = self in match data with - | `None | `Bool _ -> 8 + round_to_word (String.length name) - | `Int i when is_i32_ i -> 8 + round_to_word (String.length name) - | `Int _ -> (* int64 *) 16 + round_to_word (String.length name) - | `Float _ -> 16 + round_to_word (String.length name) + | `None | `Bool _ -> 1 + (round_to_word (String.length name) lsr 3) + | `Int i when is_i32_ i -> 1 + (round_to_word (String.length name) lsr 3) + | `Int _ -> (* int64 *) 2 + (round_to_word (String.length name) lsr 3) + | `Float _ -> 2 + (round_to_word (String.length name) lsr 3) | `String s -> - 8 + round_to_word (String.length s) + round_to_word (String.length name) + 1 + + (round_to_word (String.length s) lsr 3) + + (round_to_word (String.length name) lsr 3) open struct external int_of_bool : bool -> int = "%identity" @@ -139,7 +169,7 @@ module Argument = struct let encode (buf : Buf.t) (self : t) : unit = let name, data = self in - let size = size_B self in + let size = size_word self in (* part of header with argument name + size *) let hd_arg_size = @@ -193,8 +223,8 @@ module Arguments = struct List.iter Argument.check_valid self; () - let[@inline] size_B (self : t) = - List.fold_left (fun n arg -> n + Argument.size_B arg) 0 self + let[@inline] size_word (self : t) = + List.fold_left (fun n arg -> n + Argument.size_word arg) 0 self let encode (buf : Buf.t) (self : t) = let rec aux buf l = @@ -209,11 +239,13 @@ end (** record type = 3 *) module Thread_record = struct - let size_B : int = 24 + let size_word : int = 3 (** Record that [Thread_ref.ref as_ref] represents the pair [pid, tid] *) let encode (buf : Buf.t) ~as_ref ~pid ~tid () : unit = - let hd = I64.(3L lor (of_int size_B lsl 4) lor (of_int as_ref lsl 16)) in + if as_ref <= 0 || as_ref > 255 then + invalid_arg "fuchsia: thread_record: invalid ref"; + let hd = I64.(3L lor (of_int size_word lsl 4) lor (of_int as_ref lsl 16)) in Buf.add_i64 buf hd; Buf.add_i64 buf (I64.of_int pid); Buf.add_i64 buf (I64.of_int tid) @@ -222,19 +254,14 @@ end (** record type = 4 *) module Event = struct module Instant = struct - (* TODO: find out how to encode tid/pid (are they both in64?) - - then compute size; then add encoder - *) - - let size_B ~name ~t_ref ~args () : int = - 8 + Thread_ref.size_B t_ref + 8 - (* timestamp *) + round_to_word (String.length name) - + Arguments.size_B args + let size_word ~name ~t_ref ~args () : int = + 1 + Thread_ref.size_word t_ref + 1 + (* timestamp *) + (round_to_word (String.length name) / 8) + + Arguments.size_word args let encode (buf : Buf.t) ~name ~(t_ref : Thread_ref.t) ~time_ns ~args () : unit = - let size = size_B ~name ~t_ref ~args () in + let size = size_word ~name ~t_ref ~args () in (* set category = 0 *) let hd = I64.( @@ -257,4 +284,38 @@ module Event = struct Arguments.encode buf args; () end + + module Duration_complete = struct + let size_word ~name ~t_ref ~args () : int = + 1 + Thread_ref.size_word t_ref + 1 + (* timestamp *) + (round_to_word (String.length name) lsr 3) + + Arguments.size_word args + 1 (* end timestamp *) + + let encode (buf : Buf.t) ~name ~(t_ref : Thread_ref.t) ~time_ns ~end_time_ns + ~args () : unit = + let size = size_word ~name ~t_ref ~args () in + (* set category = 0 *) + let hd = + I64.( + 4L + lor (of_int size lsl 4) + lor (4L lsl 16) + lor (of_int (List.length args) lsl 20) + lor (of_int (Thread_ref.as_i8 t_ref) lsl 24) + lor (of_int (Str_ref.inline (String.length name)) lsl 48)) + in + Buf.add_i64 buf hd; + Buf.add_i64 buf time_ns; + + (match t_ref with + | Thread_ref.Inline { pid; tid } -> + Buf.add_i64 buf (I64.of_int pid); + Buf.add_i64 buf (I64.of_int tid) + | Thread_ref.Ref _ -> ()); + + Buf.add_string buf name; + Arguments.encode buf args; + Buf.add_i64 buf end_time_ns; + () + end end