mirror of
https://github.com/ocaml-multicore/eio.git
synced 2025-10-17 00:05:25 -04:00
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:
parent
0b364581d7
commit
d8e91951e8
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
19
lib_ctf/unix/ctf_unix.ml
Normal 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)
|
9
lib_ctf/unix/ctf_unix.mli
Normal file
9
lib_ctf/unix/ctf_unix.mli
Normal 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
4
lib_ctf/unix/dune
Normal file
@ -0,0 +1,4 @@
|
||||
(library
|
||||
(name ctf_unix)
|
||||
(public_name ctf.unix)
|
||||
(libraries ctf unix mtime.clock.os))
|
Loading…
x
Reference in New Issue
Block a user