Skip to content

Commit db33868

Browse files
committed
Hmm
1 parent 3f4dd2b commit db33868

File tree

2 files changed

+42
-19
lines changed

2 files changed

+42
-19
lines changed

lib/picos_std.structured/run.ml

Lines changed: 36 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -51,45 +51,64 @@ type _ tdt =
5151

5252
external lo_as_atomic : [ `Range ] tdt -> int Atomic.t = "%identity"
5353

54-
let rec for_out (Range r as range : [ `Range ] tdt) action =
54+
let rec for_out (Range r as range : [ `Range ] tdt) per_fiber action =
5555
let lo_before = Atomic.get (lo_as_atomic range) in
5656
let n = r.hi - lo_before in
5757
if 0 < n then begin
58-
if Atomic.compare_and_set (lo_as_atomic range) lo_before (lo_before + 1)
59-
then begin
60-
action lo_before;
61-
for_out range action
58+
let lo_after = lo_before + ((n + 1) asr 1) in
59+
if Atomic.compare_and_set (lo_as_atomic range) lo_before lo_after then begin
60+
per_fiber := lo_before;
61+
while !per_fiber < lo_after do
62+
let i = !per_fiber in
63+
per_fiber := i + 1;
64+
action i
65+
done;
66+
for_out range per_fiber action
6267
end
6368
else begin
6469
(* Contention, bail out... *)
6570
match r.parent with
6671
| Empty -> ()
67-
| Range _ as range -> for_out range action
72+
| Range _ as range -> for_out range per_fiber action
6873
end
6974
end
7075
else
71-
match r.parent with Empty -> () | Range _ as range -> for_out range action
76+
match r.parent with
77+
| Empty -> ()
78+
| Range _ as range -> for_out range per_fiber action
7279

73-
let rec for_in bundle (Range r as range : [ `Range ] tdt) action =
80+
let rec for_in bundle (Range r as range : [ `Range ] tdt) per_fiber action =
7481
let lo_before = Atomic.get (lo_as_atomic range) in
7582
let n = r.hi - lo_before in
76-
if n <= 1 then begin
77-
if n = 1 && Atomic.compare_and_set (lo_as_atomic range) lo_before r.hi then
78-
action lo_before;
79-
match r.parent with Empty -> () | Range _ as range -> for_out range action
80-
end
83+
if n <= 2 then for_out range per_fiber action
8184
else
8285
let lo_after = lo_before + (n asr 1) in
8386
if Atomic.compare_and_set (lo_as_atomic range) lo_before lo_after then begin
84-
Bundle.fork bundle (fun () -> for_in bundle range action);
87+
Bundle.fork bundle (fun () -> for_in_enter bundle range action);
8588
let child = Range { _lo = lo_before; hi = lo_after; parent = range } in
86-
for_in bundle child action
89+
for_in bundle child per_fiber action
8790
end
88-
else for_in bundle range action
91+
else for_in bundle range per_fiber action
92+
93+
and for_in_enter bundle (Range r as range : [ `Range ] tdt) action =
94+
let per_fiber = ref r.hi in
95+
let effc (type a) :
96+
a Effect.t -> ((a, _) Effect.Deep.continuation -> _) option = function
97+
| Fiber.Spawn _ -> None
98+
| _ ->
99+
if !per_fiber < r.hi then begin
100+
let range = Range { _lo = !per_fiber; hi = r.hi; parent = Empty } in
101+
per_fiber := r.hi;
102+
Bundle.fork bundle (fun () -> for_in_enter bundle range action)
103+
end;
104+
None
105+
in
106+
let handler = Effect.Deep.{ effc } in
107+
Effect.Deep.try_with (for_in bundle range per_fiber) action handler
89108

90109
let for_n n action =
91110
if 0 < n then
92111
if n = 1 then action 0
93112
else
94113
let range = Range { _lo = 0; hi = n; parent = Empty } in
95-
Bundle.join_after @@ fun bundle -> for_in bundle range action
114+
Bundle.join_after @@ fun bundle -> for_in_enter bundle range action

test/test_structured.ml

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -263,9 +263,13 @@ let test_for_n_basic () =
263263
@@ fun () ->
264264
for n = 0 to 128 do
265265
let bytes = Bytes.create n in
266-
Run.for_n n (fun i -> Bytes.set bytes i (Char.chr i));
267266
for i = 0 to n - 1 do
268-
assert (Bytes.get bytes i = Char.chr i)
267+
Bytes.set bytes i (Char.chr 0)
268+
done;
269+
Run.for_n n (fun i ->
270+
Bytes.set bytes i (Char.chr (Char.code (Bytes.get bytes i) + 1)));
271+
for i = 0 to n - 1 do
272+
assert (Bytes.get bytes i = Char.chr 1)
269273
done
270274
done
271275

0 commit comments

Comments
 (0)