Split out Ctf_unix module

This helps avoid Eio getting a dependency on Unix.
Also, added `Ctf_unix.with_tracing` as a convenience function.
This commit is contained in:
Thomas Leonard 2021-12-02 14:36:28 +00:00
parent 0b364581d7
commit d8e91951e8
7 changed files with 45 additions and 30 deletions

View File

@ -180,12 +180,10 @@ The library can write traces in CTF format, showing when threads (fibres) are cr
We can run the previous code with tracing enabled (writing to a new `trace.ctf` file) like this:
```ocaml
# #require "ctf.unix";;
# let () =
let buffer = Ctf.Unix.mmap_buffer ~size:0x100000 "trace.ctf" in
let trace_config = Ctf.Control.make buffer in
Ctf.Control.start trace_config;
Eio_main.run main;
Ctf.Control.stop trace_config;;
Ctf_unix.with_tracing "trace.ctf" @@ fun () ->
Eio_main.run main;;
+x = 1
+y = 1
+x = 2

View File

@ -45,20 +45,6 @@ type event =
type log_buffer = (char, int8_unsigned_elt, c_layout) Array1.t
module Unix = struct
let timestamper log_buffer ofs =
let ns = Mtime.to_uint64_ns @@ Mtime_clock.now () in
EndianBigstring.LittleEndian.set_int64 log_buffer ofs ns
let mmap_buffer ~size path =
let fd = Unix.(openfile path [O_RDWR; O_CREAT; O_TRUNC] 0o644) in
Unix.set_close_on_exec fd;
Unix.ftruncate fd size;
let ba = array1_of_genarray (Unix.map_file fd char c_layout true [| size |]) in
Unix.close fd;
ba
end
let current_thread = ref (-1)
let int_of_thread_type t =
@ -150,6 +136,9 @@ module Control = struct
*)
type t = {
log : log_buffer;
timestamper : log_buffer -> int -> unit; (* Write a timestamp at the given offset. *)
mutable next_event : int; (* Index to write next event (always < packet_end) *)
mutable packet_end: int;
packets : Packet.t array;
@ -224,7 +213,7 @@ module Control = struct
(* Printf.printf "writing at %d\n%!" i; *)
log.next_event <- new_i;
Packet.set_content_end log.packets.(log.active_packet) new_i;
Unix.timestamper log.log i;
log.timestamper log.log i;
i + 8 |> write8 log.log op
)
@ -334,7 +323,7 @@ module Control = struct
|> end_event
*)
let make log =
let make ~timestamper log =
let size = Array1.dim log in
let n_packets = 4 in
let packet_size = size / n_packets in
@ -346,6 +335,7 @@ module Control = struct
let active_packet = 0 in
{
log;
timestamper;
packets;
active_packet;
packet_end = Packet.packet_end packets.(active_packet);

View File

@ -87,16 +87,12 @@ val note_signal : ?src:id -> id -> unit
type log_buffer = (char, Bigarray.int8_unsigned_elt, Bigarray.c_layout) Bigarray.Array1.t
module Unix : sig
val mmap_buffer : size:int -> string -> log_buffer
(** [mmap_buffer ~size path] initialises file [path] as an empty buffer for tracing. *)
end
module Control : sig
type t
val make : log_buffer -> t
(** [make b] is a trace buffer that record events in [b]. *)
val make : timestamper:(log_buffer -> int -> unit) -> log_buffer -> t
(** [make ~timestamper b] is a trace buffer that record events in [b].
In most cases, the {!Ctf_unix} module provides a simpler interface. *)
val start : t -> unit
(** [start t] begins recording events in [t]. *)
@ -104,4 +100,3 @@ module Control : sig
val stop : t -> unit
(** [stop t] stops recording to [t] (which must be the current trace buffer). *)
end

View File

@ -2,4 +2,4 @@
(name ctf)
(public_name ctf)
(preprocess (pps ppx_cstruct))
(libraries cstruct ocplib-endian.bigstring mtime mtime.clock.os))
(libraries cstruct ocplib-endian.bigstring mtime))

19
lib_ctf/unix/ctf_unix.ml Normal file
View File

@ -0,0 +1,19 @@
open Bigarray
let timestamper log_buffer ofs =
let ns = Mtime.to_uint64_ns @@ Mtime_clock.now () in
EndianBigstring.LittleEndian.set_int64 log_buffer ofs ns
let mmap_buffer ~size path =
let fd = Unix.(openfile path [O_RDWR; O_CREAT; O_TRUNC] 0o644) in
Unix.set_close_on_exec fd;
Unix.ftruncate fd size;
let ba = array1_of_genarray (Unix.map_file fd char c_layout true [| size |]) in
Unix.close fd;
ba
let with_tracing ?(size=0x100000) path fn =
let buffer = mmap_buffer ~size path in
let trace_config = Ctf.Control.make ~timestamper buffer in
Ctf.Control.start trace_config;
Fun.protect fn ~finally:(fun () -> Ctf.Control.stop trace_config)

View File

@ -0,0 +1,9 @@
val timestamper : Ctf.log_buffer -> int -> unit
(** Uses [Mtime_clock] to write timestamps. *)
val mmap_buffer : size:int -> string -> Ctf.log_buffer
(** [mmap_buffer ~size path] initialises file [path] as an empty buffer for tracing. *)
val with_tracing : ?size:int -> string -> (unit -> 'a) -> 'a
(** [with_tracing path fn] is a convenience function that uses {!mmap_buffer} to create a log buffer,
calls {!Control.start} to start recording, runs [fn], and then stops recording. *)

4
lib_ctf/unix/dune Normal file
View File

@ -0,0 +1,4 @@
(library
(name ctf_unix)
(public_name ctf.unix)
(libraries ctf unix mtime.clock.os))