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
open! Core_kernel
open! Import
type ('a, 'permission) t = ('a, 'permission) Types.Bvar.t
type 'a repr = 'a Types.Bvar.repr =
{ mutable has_any_waiters : bool
; mutable ivar : 'a Ivar.t
}
[@@deriving fields, sexp_of]
let invariant invariant_a _ t =
let repr = Types.Bvar.to_repr t in
Invariant.invariant [%here] repr [%sexp_of: _ repr] (fun () ->
let check f = Invariant.check_field repr f in
Fields_of_repr.iter
~has_any_waiters:
(check (fun has_any_waiters ->
if Ivar.has_handlers repr.ivar then assert has_any_waiters))
~ivar:
(check (fun ivar ->
Ivar.invariant invariant_a ivar;
assert (Ivar.is_empty ivar))))
;;
let sexp_of_t _ _ t =
let { has_any_waiters; ivar = _ } = Types.Bvar.to_repr t in
[%message (has_any_waiters : bool)]
;;
include Scheduler1.Bvar
let broadcast t a =
let repr = Types.Bvar.to_repr t in
if repr.has_any_waiters
then (
repr.has_any_waiters <- false;
Ivar.fill repr.ivar a;
repr.ivar <- Ivar.create ())
;;
let wait t =
let repr = Types.Bvar.to_repr t in
repr.has_any_waiters <- true;
Ivar.read repr.ivar
;;
let has_any_waiters t =
let repr = Types.Bvar.to_repr t in
repr.has_any_waiters
;;