package trace-fuchsia

  1. Overview
  2. Docs
A high-performance backend for trace, emitting a Fuchsia trace into a file

Install

Dune Dependency

Authors

Maintainers

Sources

trace-0.8.tbz
sha256=34cfa5662b611c1e246f0fb8131ee605eeb90b359c105e882f51adc7e70878c3
sha512=ea47974a77a0ab26c58fe6d1bc898d4f3e6a5f865e4c1acb4188b9acd7ba8e7527d0ea7f2ae66574ceccc14f11127ee203aedba2be334d17b36c83dabff61261

doc/src/trace-fuchsia.write/output.ml.html

Source file output.ml

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
type t = {
  mutable buf: Buf.t;
  mutable send_buf: Buf.t -> unit;
  buf_pool: Buf_pool.t;
}

let create ~(buf_pool : Buf_pool.t) ~send_buf () : t =
  let buf_size = buf_pool.buf_size in
  let buf = Buf.create buf_size in
  { buf; send_buf; buf_pool }

open struct
  (* NOTE: there is a potential race condition if an output is
     flushed from the main thread upon closing, while
     the local thread is blissfully writing new records to it
     as we're winding down the collector. This is trying to reduce
     the likelyhood of a race happening. *)
  let[@poll error] replace_buf_ (self : t) (new_buf : Buf.t) : Buf.t =
    let old_buf = self.buf in
    self.buf <- new_buf;
    old_buf

  let flush_ (self : t) : unit =
    let new_buf = Buf_pool.alloc self.buf_pool in
    let old_buf = replace_buf_ self new_buf in
    self.send_buf old_buf

  let[@inline never] cycle_buf (self : t) ~available : Buf.t =
    flush_ self;
    let buf = self.buf in

    if Buf.available buf < available then (
      let msg =
        Printf.sprintf
          "fuchsia: buffer is too small (available: %d bytes, needed: %d bytes)"
          (Buf.available buf) available
      in
      failwith msg
    );
    buf
end

let[@inline] flush (self : t) : unit = if Buf.size self.buf > 0 then flush_ self

(** Maximum size available, in words, for a single message *)
let[@inline] max_size_word (self : t) : int = self.buf_pool.buf_size lsr 3

(** Obtain a buffer with at least [available] bytes *)
let[@inline] get_buf (self : t) ~(available_word : int) : Buf.t =
  let available = available_word lsl 3 in
  if Buf.available self.buf >= available then
    self.buf
  else
    cycle_buf self ~available

let into_buffer ~buf_pool (buffer : Buffer.t) : t =
  let send_buf (buf : Buf.t) =
    Buffer.add_subbytes buffer buf.buf 0 buf.offset
  in
  create ~buf_pool ~send_buf ()

let dispose (self : t) : unit =
  flush_ self;
  Buf_pool.recycle self.buf_pool self.buf;
  self.buf <- Buf.empty
OCaml

Innovation. Community. Security.