File: util.ml

package info (click to toggle)
ocaml-multicore-bench 0.1.7-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 320 kB
  • sloc: ml: 1,476; sh: 60; makefile: 6
file content (71 lines) | stat: -rw-r--r-- 2,251 bytes parent folder | download
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
let iter_factor =
  let factor b = if b then 10 else 1 in
  factor (64 <= Sys.word_size)
  * factor (Sys.backend_type = Native)
  * factor (1 < Domain.recommended_domain_count ())

let rec alloc ?(batch = 1000) counter =
  let n = Atomic.get counter in
  if n = 0 then 0
  else
    let batch = Int_ext.min n batch in
    if Atomic.compare_and_set counter n (n - batch) then batch
    else alloc ~batch counter

let cross xs ys =
  xs |> List.concat_map @@ fun x -> ys |> List.map @@ fun y -> (x, y)

module Bits = struct
  type t = { mutable bytes : Bytes.t; mutable length : int }

  let create () = { bytes = Bytes.create 1; length = 0 }

  let push t bool =
    let capacity = Bytes.length t.bytes lsl 3 in
    if t.length == capacity then
      t.bytes <- Bytes.extend t.bytes 0 (capacity lsr 3);
    let byte_i = t.length lsr 3 in
    let mask = 1 lsl (t.length land 7) in
    t.length <- t.length + 1;
    let byte = Char.code (Bytes.unsafe_get t.bytes byte_i) in
    let byte = if bool then byte lor mask else byte land lnot mask in
    Bytes.unsafe_set t.bytes byte_i (Char.chr byte)

  let length t = t.length

  let iter fn t =
    let i = ref 0 in
    let n = t.length in
    while !i < n do
      let ix = !i in
      i := !i + 8;
      let byte = Char.code (Bytes.unsafe_get t.bytes (ix lsr 3)) in
      let n = n - ix in
      fn (0 <> byte land 1);
      if 1 < n then fn (0 <> byte land 2);
      if 2 < n then fn (0 <> byte land 4);
      if 3 < n then fn (0 <> byte land 8);
      if 4 < n then fn (0 <> byte land 16);
      if 5 < n then fn (0 <> byte land 32);
      if 6 < n then fn (0 <> byte land 64);
      if 7 < n then fn (0 <> byte land 128)
    done
end

let generate_push_and_pop_sequence ?(state = Random.State.make_self_init ())
    n_msgs =
  let bits = Bits.create () in
  let rec loop length n_push n_pop =
    if 0 < n_push || 0 < n_pop then begin
      let push = Random.State.bool state && 0 < n_push in
      Bits.push bits push;
      loop
        (if push then length + 1 else if 0 < length then length - 1 else length)
        (n_push - Bool.to_int push)
        (n_pop - Bool.to_int ((not push) && 0 < length))
    end
    else length
  in
  let length = loop 0 n_msgs n_msgs in
  assert (length = 0);
  bits