File: test_condition.ml

package info (click to toggle)
ocaml-eio 1.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,548 kB
  • sloc: ml: 14,608; ansic: 1,237; makefile: 25
file content (46 lines) | stat: -rw-r--r-- 1,248 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
let debug = false

exception Abort

module T = Condition

(* [prod] threads increment a counter and notify a condition.
   A consumer watches the condition and waits until it has seen
   all of them. We check that the client always sees the final value.
   If [cancel] is set, we also try to cancel the client and accept
   that as success too. *)
let test ~prod ~cancel () =
  let t = T.create () in
  let sent = Atomic.make 0 in
  for _ = 1 to prod do
    Atomic.spawn (fun () ->
        Atomic.incr sent;
        T.broadcast t
      )
  done;
  let finished = ref false in
  Atomic.spawn (fun () ->
      let ctx =
        Fake_sched.run @@ fun () ->
        try
          T.loop_no_mutex t (fun () ->
              if Atomic.get sent = prod && not cancel then Some ()
              else None
            );
          finished := true
        with T.Cancel.Cancelled Abort ->
          finished := true
       in
       if cancel then
         Option.iter (fun c -> T.Cancel.cancel c Abort) ctx
    );
  Atomic.final (fun () ->
      Atomic.check (fun () -> !finished);
      if debug then (
        Fmt.pr "%a@." Broadcast.dump t;
      );
    )

let () =
  Atomic.trace (test ~prod:2 ~cancel:false);
  Atomic.trace (test ~prod:2 ~cancel:true)