diff --git a/test/fiber/t_fib1.expected b/test/fiber/t_fib1.expected index 7e103bd5..3bdb68c2 100644 --- a/test/fiber/t_fib1.expected +++ b/test/fiber/t_fib1.expected @@ -1,62 +1,61 @@ ============ start -1: wait for subs -1.0.0: await fiber 0 -1.0.1: cur fiber[0] is some: true -1.0.2: cur fiber[0] is some: true -1.0.3: res 0 = 0 -1.1.0: await fiber 1 -1.1.1: cur fiber[1] is some: true -1.1.2: cur fiber[1] is some: true -1.1.3: res 1 = 1 -1.2.0: await fiber 2 -1.2.1: cur fiber[2] is some: true -1.2.2: cur fiber[2] is some: true -1.2.3: res 2 = 2 -1.3.0: await fiber 3 -1.3.1: cur fiber[3] is some: true -1.3.2: cur fiber[3] is some: true -1.3.3: res 3 = 3 -1.4.0: await fiber 4 -1.4.1: cur fiber[4] is some: true -1.4.2: cur fiber[4] is some: true -1.4.3: res 4 = 4 -2: main fiber done -3: other fib done -4: main fiber exited +wait for subs +await fiber 0 +cur fiber[0] is some: true +cur fiber[0] is some: true +res 0 = 0 +await fiber 1 +cur fiber[1] is some: true +cur fiber[1] is some: true +res 1 = 1 +await fiber 2 +cur fiber[2] is some: true +cur fiber[2] is some: true +res 2 = 2 +await fiber 3 +cur fiber[3] is some: true +cur fiber[3] is some: true +res 3 = 3 +await fiber 4 +cur fiber[4] is some: true +cur fiber[4] is some: true +res 4 = 4 +main fiber done +main fiber exited ============ start -1: start fibers -1.7.1: I'm fiber 7 and I'm about to fail… -1.8.1: sub-fiber 8 was cancelled -1.9.1: sub-fiber 9 was cancelled -2.0: fiber 0 resolved as ok -2.1: fiber 1 resolved as ok -2.2: fiber 2 resolved as ok -2.3: fiber 3 resolved as ok -2.4: fiber 4 resolved as ok -2.5: fiber 5 resolved as ok -2.6: fiber 6 resolved as ok -2.7: fiber 7 resolved as error -2.8: fiber 8 resolved as error -2.9: fiber 9 resolved as error -3: wait for subs -4: await fiber 0 -5: res 0 = 0 -6: await fiber 1 -7: res 1 = 1 -8: await fiber 2 -9: res 2 = 2 -10: await fiber 3 -11: res 3 = 3 -12: await fiber 4 -13: res 4 = 4 -14: await fiber 5 -15: res 5 = 5 -16: await fiber 6 -17: res 6 = 6 -18: await fiber 7 -19: main fiber cancelled with Failure("oh no!") -20: main fiber result: error Failure("oh no!") -21: main fib failed with "oh no!" -22: main fiber exited +start fibers +wait for subs +await fiber 0 +fiber 0 resolved as ok +res 0 = 0 +await fiber 1 +fiber 1 resolved as ok +res 1 = 1 +await fiber 2 +res 2 = 2 +await fiber 3 +fiber 2 resolved as ok +fiber 3 resolved as ok +fiber 4 resolved as ok +res 3 = 3 +await fiber 4 +res 4 = 4 +await fiber 5 +fiber 5 resolved as ok +res 5 = 5 +await fiber 6 +fiber 6 resolved as ok +res 6 = 6 +await fiber 7 +I'm fiber 7 and I'm about to fail… +fiber 7 resolved as error +sub-fiber 8 was cancelled +fiber 8 resolved as error +sub-fiber 9 was cancelled +fiber 9 resolved as error +main fiber cancelled with Failure("oh no!") +main fiber result: error Failure("oh no!") +main fib failed with "oh no!" +main fiber exited diff --git a/test/fiber/t_fib1.ml b/test/fiber/t_fib1.ml index 1eb3a2cc..5c85f38c 100644 --- a/test/fiber/t_fib1.ml +++ b/test/fiber/t_fib1.ml @@ -5,51 +5,30 @@ module F = Moonpool_fib.Fiber let ( let@ ) = ( @@ ) let runner = Ws_pool.create ~num_threads:8 () -module TS = struct - type t = int list - - let show (s : t) = String.concat "." @@ List.map string_of_int s - let init = [ 0 ] - - let next_ = function - | [] -> [ 0 ] - | n :: tl -> (n + 1) :: tl - - let tick (t : t ref) = t := next_ !t - - let tick_get t = - tick t; - !t -end - (* more deterministic logging of events *) module Log_ = struct - let events : (TS.t * string) list A.t = A.make [] + let events : string list A.t = A.make [] - let add_event t msg : unit = + let add_event msg : unit = while let old = A.get events in - not (A.compare_and_set events old ((t, msg) :: old)) + not (A.compare_and_set events old (msg :: old)) do () done - let logf t fmt = Printf.ksprintf (add_event t) fmt + let logf fmt = Printf.ksprintf add_event fmt let print_and_clear () = - let l = - A.exchange events [] - |> List.map (fun (ts, msg) -> List.rev ts, msg) - |> List.sort Stdlib.compare - in - List.iter (fun (ts, msg) -> Printf.printf "%s: %s\n" (TS.show ts) msg) l + let l = A.exchange events [] |> List.rev in + List.iter (fun msg -> Printf.printf "%s\n" msg) l end let logf = Log_.logf let () = + let@ _r = Moonpool_fib.main in Printf.printf "============\nstart\n"; - let clock = ref TS.init in let fib = F.spawn_top ~on:runner @@ fun () -> let subs = @@ -59,29 +38,24 @@ let () = i) in - F.spawn_ignore ~protect:false (fun _n -> - Thread.delay 0.4; - TS.tick clock; - logf !clock "other fib done"); + logf "wait for subs"; - logf (TS.tick_get clock) "wait for subs"; List.iteri (fun i f -> - let clock = ref (0 :: i :: !clock) in - logf !clock "await fiber %d" i; - logf (TS.tick_get clock) "cur fiber[%d] is some: %b" i + logf "await fiber %d" i; + logf "cur fiber[%d] is some: %b" i (Option.is_some @@ F.Private_.get_cur ()); let res = F.await f in - logf (TS.tick_get clock) "cur fiber[%d] is some: %b" i + logf "cur fiber[%d] is some: %b" i (Option.is_some @@ F.Private_.get_cur ()); F.yield (); - logf (TS.tick_get clock) "res %d = %d" i res) + logf "res %d = %d" i res) subs; - logf (TS.tick_get clock) "main fiber done" + logf "main fiber done" in Fut.wait_block_exn @@ F.res fib; - logf (TS.tick_get clock) "main fiber exited"; + logf "main fiber exited"; Log_.print_and_clear (); () @@ -90,26 +64,22 @@ let () = (* same but now, cancel one of the sub-fibers *) Printf.printf "============\nstart\n"; - let clock = ref TS.init in let fib = F.spawn_top ~on:runner @@ fun () -> let@ () = F.with_on_self_cancel (fun ebt -> - logf (TS.tick_get clock) "main fiber cancelled with %s" - @@ Exn_bt.show ebt) + logf "main fiber cancelled with %s" @@ Exn_bt.show ebt) in let chans_unblock = Array.init 10 (fun _i -> Chan.create ()) in let chan_progress = Chan.create () in - logf (TS.tick_get clock) "start fibers"; + logf "start fibers"; let subs = List.init 10 (fun i -> - let clock = ref (0 :: i :: !clock) in F.spawn ~protect:false @@ fun _n -> let@ () = - F.with_on_self_cancel (fun _ -> - logf (TS.tick_get clock) "sub-fiber %d was cancelled" i) + F.with_on_self_cancel (fun _ -> logf "sub-fiber %d was cancelled" i) in Thread.delay 0.002; @@ -118,7 +88,7 @@ let () = Chan.push chan_progress i; if i = 7 then ( - logf (TS.tick_get clock) "I'm fiber %d and I'm about to fail…" i; + logf "I'm fiber %d and I'm about to fail…" i; failwith "oh no!" ); @@ -127,14 +97,15 @@ let () = i) in - let post = TS.tick_get clock in List.iteri (fun i fib -> F.on_result fib (function - | Ok _ -> logf (i :: post) "fiber %d resolved as ok" i - | Error _ -> logf (i :: post) "fiber %d resolved as error" i)) + | Ok _ -> logf "fiber %d resolved as ok" i + | Error _ -> logf "fiber %d resolved as error" i)) subs; + logf "wait for subs"; + (* sequentialize the fibers, for determinism *) F.spawn_ignore (fun () -> for j = 0 to 9 do @@ -143,26 +114,24 @@ let () = assert (j = j') done); - logf (TS.tick_get clock) "wait for subs"; List.iteri (fun i f -> - logf (TS.tick_get clock) "await fiber %d" i; + logf "await fiber %d" i; let res = F.await f in - logf (TS.tick_get clock) "res %d = %d" i res) + logf "res %d = %d" i res) subs; - logf (TS.tick_get clock) "yield"; + logf "yield"; F.yield (); - logf (TS.tick_get clock) "yielded"; - logf (TS.tick_get clock) "main fiber done" + logf "yielded"; + logf "main fiber done" in F.on_result fib (function - | Ok () -> logf (TS.tick_get clock) "main fiber result: ok" - | Error ebt -> - logf (TS.tick_get clock) "main fiber result: error %s" (Exn_bt.show ebt)); + | Ok () -> logf "main fiber result: ok" + | Error ebt -> logf "main fiber result: error %s" (Exn_bt.show ebt)); (try Fut.wait_block_exn @@ F.res fib - with Failure msg -> logf (TS.tick_get clock) "main fib failed with %S" msg); - logf (TS.tick_get clock) "main fiber exited"; + with Failure msg -> logf "main fib failed with %S" msg); + logf "main fiber exited"; Log_.print_and_clear (); ()