Skip to content

Commit

Permalink
chore: use janestreet style and update ocamlformat (#33)
Browse files Browse the repository at this point in the history
Signed-off-by: Rudi Grinberg <[email protected]>
  • Loading branch information
rgrinberg authored Dec 1, 2023
1 parent 73f2253 commit bbe8b51
Show file tree
Hide file tree
Showing 19 changed files with 646 additions and 556 deletions.
13 changes: 2 additions & 11 deletions .ocamlformat
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
version=0.24.1
profile=conventional
version=0.26.1
profile=janestreet
ocaml-version=4.08.0
break-separators=before
dock-collection-brackets=false
doc-comments=before
let-and=sparse
type-decl=sparse
cases-exp-indent=2
break-cases=fit-or-vertical
parse-docstrings=true
module-item-spacing=sparse
22 changes: 12 additions & 10 deletions fiber-lwt/fiber_lwt.ml
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,25 @@ module Fiber_inside_lwt = struct
| Fiber.Scheduler.Done x -> Lwt.return x
| Fiber.Scheduler.Stalled stalled ->
Lwt.bind (Lwt_stream.next fills) (fun fill ->
loop (Fiber.Scheduler.advance stalled [ fill ]))
loop (Fiber.Scheduler.advance stalled [ fill ]))
in
loop (Fiber.Scheduler.start fiber)
;;

let callback_to_lwt f =
Fiber.bind (Fiber.Var.get key) ~f:(function
| None ->
failwith "Fiber_lwt.Fiber_inside_lwt.run_lwt: called outside [run]"
| None -> failwith "Fiber_lwt.Fiber_inside_lwt.run_lwt: called outside [run]"
| Some push_fill ->
let ivar = Fiber.Ivar.create () in
Lwt.async (fun () ->
Lwt.bind
(Lwt.try_bind f
(fun x -> Lwt.return (Ok x))
(fun exn -> Lwt.return (Error exn)))
(fun x ->
push_fill (Some (Fiber.Fill (ivar, x)));
Lwt.return_unit));
Lwt.bind
(Lwt.try_bind
f
(fun x -> Lwt.return (Ok x))
(fun exn -> Lwt.return (Error exn)))
(fun x ->
push_fill (Some (Fiber.Fill (ivar, x)));
Lwt.return_unit));
Fiber.Ivar.read ivar)
;;
end
49 changes: 28 additions & 21 deletions fiber/bench/fiber_bench.ml
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,24 @@ open Fiber.O
let n = 1000

let%bench_fun "bind" =
fun () ->
fun () ->
Fiber.run
~iter:(fun () -> assert false)
(let rec loop = function
| 0 -> Fiber.return ()
| n -> Fiber.return () >>= fun () -> loop (n - 1)
in
loop n)
;;

let%bench_fun "create ivar and immediately read" =
fun () ->
fun () ->
let ivar = Fiber.Ivar.create () in
Fiber.run ~iter:(fun () -> [ Fiber.Fill (ivar, ()) ]) (Fiber.Ivar.read ivar)
;;

let%bench_fun "ivar" =
fun () ->
fun () ->
let ivar = ref (Fiber.Ivar.create ()) in
Fiber.run
~iter:(fun () -> [ Fiber.Fill (!ivar, ()) ])
Expand All @@ -31,6 +33,7 @@ let%bench_fun "ivar" =
loop (n - 1)
in
loop n)
;;

let%bench_fun "Var.set" =
let var = Fiber.Var.create () in
Expand All @@ -42,6 +45,7 @@ let%bench_fun "Var.set" =
| n -> Fiber.Var.set var n (fun () -> loop (n - 1))
in
loop n)
;;

let%bench_fun "Var.get" =
let var = Fiber.Var.create () in
Expand All @@ -55,12 +59,12 @@ let%bench_fun "Var.get" =
loop (n - 1)
in
Fiber.Var.set var 0 (fun () -> loop n))
;;

let exns =
List.init n ~f:(fun _ ->
{ Exn_with_backtrace.exn = Exit
; backtrace = Printexc.get_raw_backtrace ()
})
{ Exn_with_backtrace.exn = Exit; backtrace = Printexc.get_raw_backtrace () })
;;

let%bench "catching exceptions" =
Fiber.run
Expand All @@ -70,6 +74,7 @@ let%bench "catching exceptions" =
~on_error:(fun _ -> Fiber.return ())
(fun () -> Fiber.reraise_all exns))
|> ignore
;;

let%bench "installing handlers" =
Fiber.run
Expand All @@ -87,45 +92,46 @@ let%bench "installing handlers" =
in
loop n)
|> ignore
;;

let%bench_fun "Fiber.fork_and_join" =
fun () ->
fun () ->
Fiber.run
~iter:(fun () -> assert false)
(let rec loop = function
| 0 -> Fiber.return ()
| n ->
let+ (), () =
Fiber.fork_and_join Fiber.return (fun () -> loop (n - 1))
in
let+ (), () = Fiber.fork_and_join Fiber.return (fun () -> loop (n - 1)) in
()
in
loop 1000)
;;

let%bench_fun "Fiber.fork_and_join_unit" =
fun () ->
fun () ->
Fiber.run
~iter:(fun () -> assert false)
(let rec loop = function
| 0 -> Fiber.return ()
| n -> Fiber.fork_and_join_unit Fiber.return (fun () -> loop (n - 1))
in
loop 1000)
;;

let%bench_fun "Fiber.parallel_iter" =
let l = List.init 1000 ~f:Fun.id in
fun () ->
Fiber.run
~iter:(fun () -> assert false)
(Fiber.parallel_iter l ~f:(fun _ -> Fiber.return ()))
;;

let%bench_fun "Fiber.parallel_map" =
let l = List.init 1000 ~f:Fun.id in
fun () ->
Fiber.run
~iter:(fun () -> assert false)
(Fiber.parallel_map l ~f:Fiber.return)
Fiber.run ~iter:(fun () -> assert false) (Fiber.parallel_map l ~f:Fiber.return)
|> ignore
;;

let pool_run tasks =
Fiber.run
Expand All @@ -136,36 +142,37 @@ let pool_run tasks =
(fun () ->
let* () =
Fiber.parallel_iter tasks ~f:(fun (_ : int) ->
Fiber.Pool.task pool ~f:Fiber.return)
Fiber.Pool.task pool ~f:Fiber.return)
in
Fiber.Pool.close pool))
|> ignore
;;

(* some pools are used to run many fibers *)
let%bench_fun "Fiber.Pool.run - big" =
let l = List.init 1000 ~f:Fun.id in
fun () -> pool_run l
;;

(* other pools are one-off transients that are created and discarded *)
let%bench_fun "Fiber.Pool.run - small" =
let l = List.init 2 ~f:Fun.id in
fun () -> pool_run l
;;

module M = Fiber.Make_parallel_map (Int.Map)

let map =
List.init 1000 ~f:Fun.id
|> List.map ~f:(fun i -> (i, i))
|> Int.Map.of_list_exn
let map = List.init 1000 ~f:Fun.id |> List.map ~f:(fun i -> i, i) |> Int.Map.of_list_exn

let%bench "Fiber.parallel_iter_seq" =
Fiber.run
~iter:(fun () -> assert false)
(Fiber.parallel_iter_seq (Int.Map.to_seq map) ~f:(fun (_, _) ->
Fiber.return ()))
(Fiber.parallel_iter_seq (Int.Map.to_seq map) ~f:(fun (_, _) -> Fiber.return ()))
;;

let%bench "Fiber.Map.parallel_map" =
Fiber.run
~iter:(fun () -> assert false)
(M.parallel_map map ~f:(fun _ x -> Fiber.return x))
|> ignore
;;
57 changes: 32 additions & 25 deletions fiber/src/cancel.ml
Original file line number Diff line number Diff line change
Expand Up @@ -28,68 +28,75 @@ let rec invoke_handlers = function
let* () = Ivar.fill ivar (Cancelled ()) in
invoke_handlers next
| End_of_handlers -> return ()
;;

let fire t =
of_thunk (fun () ->
match t.state with
| Cancelled -> return ()
| Not_cancelled { handlers } ->
t.state <- Cancelled;
invoke_handlers handlers)
match t.state with
| Cancelled -> return ()
| Not_cancelled { handlers } ->
t.state <- Cancelled;
invoke_handlers handlers)
;;

let rec fills_of_handlers acc = function
| Handler { ivar; next; prev = _ } ->
fills_of_handlers (Scheduler.Fill (ivar, Cancelled ()) :: acc) next
| End_of_handlers -> List.rev acc
;;

let fire' t =
match t.state with
| Cancelled -> []
| Not_cancelled { handlers } ->
t.state <- Cancelled;
fills_of_handlers [] handlers
;;

let fired t =
match t.state with
| Cancelled -> true
| Not_cancelled _ -> false
;;

let with_handler t f ~on_cancel =
match t.state with
| Cancelled ->
let+ x, y = fork_and_join f on_cancel in
(x, Cancelled y)
x, Cancelled y
| Not_cancelled h ->
let ivar = Ivar.create () in
let node = Handler { ivar; next = h.handlers; prev = End_of_handlers } in
(match h.handlers with
| End_of_handlers -> ()
| Handler first -> first.prev <- node);
| End_of_handlers -> ()
| Handler first -> first.prev <- node);
h.handlers <- node;
fork_and_join
(fun () ->
let* y = f () in
match t.state with
| Cancelled -> return y
| Not_cancelled h -> (
match node with
| End_of_handlers ->
(* We could avoid this [assert false] with GADT sorcery given that
we created [node] just above and we know for sure it is the
[Handler _] case, but it's not worth the code complexity. *)
assert false
| Handler node ->
(match node.prev with
| End_of_handlers -> h.handlers <- node.next
| Handler prev -> prev.next <- node.next);
(match node.next with
| End_of_handlers -> ()
| Handler next -> next.prev <- node.prev);
let+ () = Ivar.fill ivar Not_cancelled in
y))
| Not_cancelled h ->
(match node with
| End_of_handlers ->
(* We could avoid this [assert false] with GADT sorcery given that
we created [node] just above and we know for sure it is the
[Handler _] case, but it's not worth the code complexity. *)
assert false
| Handler node ->
(match node.prev with
| End_of_handlers -> h.handlers <- node.next
| Handler prev -> prev.next <- node.next);
(match node.next with
| End_of_handlers -> ()
| Handler next -> next.prev <- node.prev);
let+ () = Ivar.fill ivar Not_cancelled in
y))
(fun () ->
Ivar.read ivar >>= function
Ivar.read ivar
>>= function
| Cancelled () ->
let+ x = on_cancel () in
Cancelled x
| Not_cancelled -> return Not_cancelled)
;;
Loading

0 comments on commit bbe8b51

Please sign in to comment.