-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
14 changed files
with
336 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
let run_suite ~budgetf:_ = [] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
open Multicore_bench | ||
open Picos_std_structured | ||
module Multififo = Picos_mux_multififo | ||
|
||
let run_one_multififo ~budgetf ~n_domains ~n () = | ||
let context = ref (Obj.magic ()) in | ||
|
||
let before _ = context := Multififo.context () in | ||
let init _ = !context in | ||
let work i context = | ||
if i <> 0 then Multififo.runner_on_this_thread context | ||
else ignore @@ Multififo.run ~context @@ fun () -> Run.for_n n ignore | ||
in | ||
|
||
let config = | ||
Printf.sprintf "%d mfifo%s, run_n %d" n_domains | ||
(if n_domains = 1 then "" else "s") | ||
n | ||
in | ||
Times.record ~budgetf ~n_domains ~before ~init ~work () | ||
|> Times.to_thruput_metrics ~n ~singular:"ignore" ~config | ||
|
||
let run_suite ~budgetf = | ||
Util.cross [ 1; 2; 4; 8 ] | ||
[ 100; 1_000; 10_000; 100_000; 1_000_000; 10_000_000 ] | ||
|> List.concat_map @@ fun (n_domains, n) -> | ||
if Picos_domain.recommended_domain_count () < n_domains then [] | ||
else run_one_multififo ~budgetf ~n_domains ~n () |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
type _ tdt = | ||
| Empty : [> `Empty ] tdt | ||
| Range : { | ||
mutable lo : int; | ||
hi : int; | ||
parent : [ `Empty | `Range ] tdt; | ||
} | ||
-> [> `Range ] tdt | ||
|
||
let[@poll error] cas_lo (Range r : [ `Range ] tdt) before after = | ||
r.lo == before | ||
&& begin | ||
r.lo <- after; | ||
true | ||
end | ||
|
||
let rec for_out t (Range r as range : [ `Range ] tdt) action = | ||
let lo_before = r.lo in | ||
let n = r.hi - lo_before in | ||
if 0 < n then begin | ||
if Bundle.is_running t then begin | ||
let lo_after = lo_before + 1 in | ||
if cas_lo range lo_before lo_after then begin | ||
try action lo_before | ||
with exn -> Bundle.error t exn (Printexc.get_raw_backtrace ()) | ||
end; | ||
for_out t range action | ||
end | ||
end | ||
else | ||
match r.parent with | ||
| Empty -> () | ||
| Range _ as range -> for_out t range action | ||
|
||
let rec for_in t (Range r as range : [ `Range ] tdt) action = | ||
let lo_before = r.lo in | ||
let n = r.hi - lo_before in | ||
if n <= 1 then for_out t range action | ||
else | ||
let lo_after = lo_before + (n asr 1) in | ||
if cas_lo range lo_before lo_after then begin | ||
Bundle.fork t (fun () -> for_in t range action); | ||
let child = Range { lo = lo_before; hi = lo_after; parent = range } in | ||
for_in t child action | ||
end | ||
else for_in t range action | ||
|
||
let for_n ?on_terminate n action = | ||
if 0 < n then | ||
if n = 1 then | ||
try action 0 | ||
with | ||
| Control.Terminate when Bundle.on_terminate on_terminate == `Ignore -> | ||
() | ||
else | ||
let range = Range { lo = 0; hi = n; parent = Empty } in | ||
Bundle.join_after ?on_terminate @@ fun t -> for_in t range action |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
open Picos | ||
|
||
type per_fiber = { mutable lo : int; mutable hi : int } | ||
|
||
type _ tdt = | ||
| Empty : [> `Empty ] tdt | ||
| Range : { | ||
mutable _lo : int; | ||
hi : int; | ||
parent : [ `Empty | `Range ] tdt; | ||
} | ||
-> [> `Range ] tdt | ||
|
||
external lo_as_atomic : [ `Range ] tdt -> int Atomic.t = "%identity" | ||
|
||
let rec for_out t (Range r as range : [ `Range ] tdt) per_fiber action = | ||
let lo_before = Atomic.get (lo_as_atomic range) in | ||
let n = r.hi - lo_before in | ||
if 0 < n then begin | ||
let lo_after = lo_before + 1 + (n asr 1) in | ||
if Atomic.compare_and_set (lo_as_atomic range) lo_before lo_after then begin | ||
per_fiber.lo <- lo_before; | ||
per_fiber.hi <- lo_after; | ||
while Bundle.is_running t && per_fiber.lo < per_fiber.hi do | ||
try | ||
while per_fiber.lo < per_fiber.hi do | ||
let i = per_fiber.lo in | ||
per_fiber.lo <- i + 1; | ||
action i | ||
done | ||
with exn -> Bundle.error t exn (Printexc.get_raw_backtrace ()) | ||
done | ||
end; | ||
for_out t range per_fiber action | ||
end | ||
else | ||
match r.parent with | ||
| Empty -> () | ||
| Range _ as range -> for_out t range per_fiber action | ||
|
||
let rec for_in t (Range r as range : [ `Range ] tdt) per_fiber action = | ||
let lo_before = Atomic.get (lo_as_atomic range) in | ||
let n = r.hi - lo_before in | ||
if n <= 1 then for_out t range per_fiber action | ||
else | ||
let lo_after = lo_before + (n asr 1) in | ||
if Atomic.compare_and_set (lo_as_atomic range) lo_before lo_after then begin | ||
Bundle.fork t (fun () -> for_in_enter t range action); | ||
let child = Range { _lo = lo_before; hi = lo_after; parent = range } in | ||
for_in t child per_fiber action | ||
end | ||
else for_in t range per_fiber action | ||
|
||
and for_in_enter bundle range action = | ||
let per_fiber = { lo = 0; hi = 0 } in | ||
let effc (type a) : | ||
a Effect.t -> ((a, _) Effect.Deep.continuation -> _) option = function | ||
| Fiber.Spawn _ | Fiber.Current | Computation.Cancel_after _ -> None | ||
| _ -> | ||
(* Might be blocking, so fork any remaining work to another fiber. *) | ||
if per_fiber.lo < per_fiber.hi then begin | ||
let range = | ||
Range { _lo = per_fiber.lo; hi = per_fiber.hi; parent = Empty } | ||
in | ||
per_fiber.lo <- per_fiber.hi; | ||
Bundle.fork bundle (fun () -> for_in_enter bundle range action) | ||
end; | ||
None | ||
in | ||
let handler = Effect.Deep.{ effc } in | ||
Effect.Deep.try_with (for_in bundle range per_fiber) action handler | ||
|
||
let for_n ?on_terminate n action = | ||
if 0 < n then | ||
if n = 1 then | ||
try action 0 | ||
with | ||
| Control.Terminate when Bundle.on_terminate on_terminate == `Ignore -> | ||
() | ||
else | ||
let range = Range { _lo = 0; hi = n; parent = Empty } in | ||
Bundle.join_after ?on_terminate @@ fun t -> for_in_enter t range action |
Oops, something went wrong.