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 72 73 74
|
module Tests_spsc (Spsc_queue : Spsc_queues.SPSC_tests) = struct
(** Tests *)
let test_empty () =
let q = Spsc_queue.create ~size_exponent:3 in
assert (Option.is_none (Spsc_queue.pop_opt q));
assert (Spsc_queue.length q == 0);
Printf.printf "test_%s_empty: ok\n" Spsc_queue.name
let push_not_full q elt =
try
Spsc_queue.push_exn q elt;
true
with Spsc_queue.Full -> false
let test_full () =
let q = Spsc_queue.create ~size_exponent:3 in
while push_not_full q () do
Domain.cpu_relax ()
done;
assert (Spsc_queue.length q == 8);
Printf.printf "test_%s_full: ok\n" Spsc_queue.name
let test_parallel () =
let count =
let ocaml_4 =
Char.code (String.get Sys.ocaml_version 0) < Char.code '5'
in
match ocaml_4 with true -> 100 | false -> 100_000
in
let q = Spsc_queue.create ~size_exponent:2 in
(* producer *)
let producer =
Domain.spawn (fun () ->
for i = 1 to count do
while not (push_not_full q (Float.of_int i)) do
Domain.cpu_relax ()
done
done)
in
(* consumer *)
let last_num = ref 0 in
while !last_num < count do
match Spsc_queue.pop_opt q with
| None -> Domain.cpu_relax ()
| Some v ->
assert (v = Float.of_int (!last_num + 1));
last_num := Float.to_int v
done;
assert (Option.is_none (Spsc_queue.pop_opt q));
assert (Spsc_queue.length q == 0);
Domain.join producer;
Printf.printf "test_%s_parallel: ok (transferred = %d)\n" Spsc_queue.name
!last_num
let test_float () =
let q = Spsc_queue.create ~size_exponent:1 in
assert (Spsc_queue.try_push q 1.01);
assert (Spsc_queue.pop_opt q = Some 1.01)
let run () =
test_empty ();
test_full ();
test_parallel ();
test_float ()
end
let run () =
let module Safe = Tests_spsc (Spsc_queues.Spsc_queue) in
Safe.run ();
let module Unsafe = Tests_spsc (Spsc_queues.Spsc_queue_unsafe) in
Unsafe.run ()
let () = if Domain.recommended_domain_count () >= 2 then run ()
|