Skip to content

Commit 69b6b0e

Browse files
committed
Change to use single-use-event instead of domain-local-await
1 parent 4c16f6b commit 69b6b0e

File tree

9 files changed

+50
-80
lines changed

9 files changed

+50
-80
lines changed

bench/bench.ml

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -30,37 +30,11 @@ module Times = struct
3030
results.(domain_i)
3131
done
3232
in
33-
let prepare_for_await () =
34-
let open struct
35-
type state = Init | Released | Awaiting of { mutable released : bool }
36-
end in
37-
let state = Atomic.make Init in
38-
let release () =
39-
if Multicore_magic.fenceless_get state != Released then
40-
match Atomic.exchange state Released with
41-
| Awaiting r -> r.released <- true
42-
| _ -> ()
43-
in
44-
let await () =
45-
if Multicore_magic.fenceless_get state != Released then
46-
let awaiting = Awaiting { released = false } in
47-
if Atomic.compare_and_set state Init awaiting then
48-
match awaiting with
49-
| Awaiting r ->
50-
(* Avoid sleeping *)
51-
while not r.released do
52-
Domain.cpu_relax ()
53-
done
54-
| _ -> ()
55-
in
56-
Domain_local_await.{ release; await }
33+
let domains =
34+
Array.init n_domains @@ fun domain_i ->
35+
Domain.spawn @@ fun () -> main domain_i
5736
in
58-
Domain_local_await.using ~prepare_for_await ~while_running:(fun () ->
59-
let domains =
60-
Array.init n_domains @@ fun domain_i ->
61-
Domain.spawn @@ fun () -> main domain_i
62-
in
63-
Array.iter Domain.join domains);
37+
Array.iter Domain.join domains;
6438
let n = Stack.length results.(0) in
6539
let times = Array.create_float n in
6640
for run_i = 0 to n - 1 do

bench/dune

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
(package kcas_data)
44
(libraries
55
kcas_data
6-
domain-local-await
6+
single-use-event
77
multicore-magic
88
yojson
99
domain_shims

doc/scheduler-interop.md

Lines changed: 11 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ implementations that are conveniently provided by
2121
```ocaml
2222
# #thread
2323
# #require "kcas_data"
24+
# #require "single-use-event"
2425
# open Kcas_data
2526
# open Kcas
2627
```
@@ -36,45 +37,30 @@ module Scheduler : sig
3637
val fiber : t -> (unit -> 'a) -> 'a Promise.t
3738
end = struct
3839
open Effect.Deep
39-
type _ Effect.t +=
40-
| Suspend : (('a, unit) continuation -> unit) -> 'a Effect.t
4140
type t = {
4241
queue: (unit -> unit) Queue.t;
4342
domain: unit Domain.t
4443
}
4544
let spawn () =
46-
let queue = Queue.create () in
45+
let queue: (unit -> unit) Queue.t = Queue.create () in
4746
let rec scheduler work =
4847
let effc (type a) : a Effect.t -> _ = function
49-
| Suspend ef -> Some ef
50-
| _ -> None in
48+
| Single_use_event.Await sue ->
49+
Some (fun (k: (a, _) continuation) ->
50+
if not (Single_use_event.is_initial sue) ||
51+
not (Single_use_event.try_attach sue @@ fun () ->
52+
Queue.add (continue k) queue) then
53+
continue k ())
54+
| _ ->
55+
None in
5156
try_with work () { effc };
5257
match Queue.take_opt queue with
5358
| Some work -> scheduler work
5459
| None -> () in
55-
let prepare_for_await _ =
56-
let state = Atomic.make `Init in
57-
let release () =
58-
if Atomic.get state != `Released then
59-
match Atomic.exchange state `Released with
60-
| `Awaiting k ->
61-
Queue.add (continue k) queue
62-
| _ -> () in
63-
let await () =
64-
if Atomic.get state != `Released then
65-
Effect.perform @@ Suspend (fun k ->
66-
if not (Atomic.compare_and_set state `Init
67-
(`Awaiting k)) then
68-
continue k ())
69-
in
70-
Domain_local_await.{ release; await } in
7160
let domain = Domain.spawn @@ fun () ->
7261
try
7362
while true do
74-
let work = Queue.take_blocking queue in
75-
Domain_local_await.using
76-
~prepare_for_await
77-
~while_running:(fun () -> scheduler work)
63+
scheduler (Queue.take_blocking queue)
7864
done
7965
with Exit -> () in
8066
{ queue; domain }

dune-project

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
(depends
1414
(ocaml (>= 4.13.0))
1515
(backoff (>= 0.1.0))
16-
(domain-local-await (>= 1.0.0))
16+
single-use-event
1717
(domain-local-timeout (>= 1.0.0))
1818
(multicore-magic (>= 2.0.0))
1919
(domain_shims (and (>= 0.1.0) :with-test))
@@ -26,7 +26,7 @@
2626
(depends
2727
(kcas (= :version))
2828
(multicore-magic (>= 2.0.0))
29-
(domain-local-await (and (>= 1.0.0) :with-test))
29+
single-use-event
3030
(domain_shims (and (>= 0.1.0) :with-test))
3131
(mtime (and (>= 2.0.0) :with-test))
3232
(alcotest (and (>= 1.7.0) :with-test))

kcas.opam

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ depends: [
1616
"dune" {>= "3.8"}
1717
"ocaml" {>= "4.13.0"}
1818
"backoff" {>= "0.1.0"}
19-
"domain-local-await" {>= "1.0.0"}
19+
"single-use-event"
2020
"domain-local-timeout" {>= "1.0.0"}
2121
"multicore-magic" {>= "2.0.0"}
2222
"domain_shims" {>= "0.1.0" & with-test}
@@ -40,3 +40,6 @@ build: [
4040
]
4141
dev-repo: "git+https://github.com/ocaml-multicore/kcas.git"
4242
doc: "https://ocaml-multicore.github.io/kcas/doc/kcas/Kcas/"
43+
pin-depends: [
44+
[ "single-use-event.dev" "git+https://github.com/ocaml-multicore/single-use-event#89a920f0d9bef9ff4b082b3021dea562dcf9c129"]
45+
]

kcas.opam.template

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,4 @@
11
doc: "https://ocaml-multicore.github.io/kcas/doc/kcas/Kcas/"
2+
pin-depends: [
3+
[ "single-use-event.dev" "git+https://github.com/ocaml-multicore/single-use-event#89a920f0d9bef9ff4b082b3021dea562dcf9c129"]
4+
]

kcas_data.opam

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ depends: [
1616
"dune" {>= "3.8"}
1717
"kcas" {= version}
1818
"multicore-magic" {>= "2.0.0"}
19-
"domain-local-await" {>= "1.0.0" & with-test}
19+
"single-use-event"
2020
"domain_shims" {>= "0.1.0" & with-test}
2121
"mtime" {>= "2.0.0" & with-test}
2222
"alcotest" {>= "1.7.0" & with-test}

src/kcas/dune

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
(library
22
(name kcas)
33
(public_name kcas)
4-
(libraries domain-local-await domain-local-timeout backoff multicore-magic))
4+
(libraries single-use-event domain-local-timeout backoff multicore-magic))
55

66
(mdx
77
(package kcas)

src/kcas/kcas.ml

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,19 @@ module Timeout = struct
5858
let[@inline] set_opt state seconds =
5959
if seconds != None then set_opt state seconds
6060

61-
let[@inline never] await state release =
61+
let[@inline never] await state sue =
6262
match fenceless_get state with
6363
| Call _ as alive ->
64-
if Atomic.compare_and_set state alive (Call release) then alive
64+
if
65+
Atomic.compare_and_set state alive
66+
(Call (fun () -> Single_use_event.signal sue))
67+
then alive
6568
else timeout ()
6669
| Unset | Elapsed -> timeout ()
6770

68-
let[@inline] await state release =
71+
let[@inline] await state sue =
6972
let alive = fenceless_get state in
70-
if alive == Unset then Unset else await state release
73+
if alive == Unset then Unset else await state sue
7174

7275
let[@inline never] unawait state alive =
7376
match fenceless_get state with
@@ -114,9 +117,9 @@ end = struct
114117
x
115118
end
116119

117-
type awaiter = unit -> unit
120+
type awaiter = Single_use_event.t
118121

119-
let[@inline] resume_awaiter awaiter = awaiter ()
122+
let[@inline] resume_awaiter awaiter = Single_use_event.signal awaiter
120123

121124
let[@inline] resume_awaiters = function
122125
| [] -> ()
@@ -408,7 +411,8 @@ let add_awaiter loc before awaiter =
408411
let awaiters = awaiter :: state_old.awaiters in
409412
{ before; after = before; casn = casn_after; awaiters }
410413
in
411-
before == eval state_old
414+
Single_use_event.is_initial awaiter
415+
&& before == eval state_old
412416
&& Atomic.compare_and_set (as_atomic loc) state_old state_new
413417

414418
let[@tail_mod_cons] rec remove_first x' removed = function
@@ -429,12 +433,12 @@ let rec remove_awaiter loc before awaiter =
429433
remove_awaiter loc before awaiter
430434

431435
let block timeout loc before =
432-
let t = Domain_local_await.prepare_for_await () in
433-
let alive = Timeout.await timeout t.release in
434-
if add_awaiter loc before t.release then begin
435-
try t.await ()
436+
let t = Single_use_event.create () in
437+
let alive = Timeout.await timeout t in
438+
if add_awaiter loc before t then begin
439+
try Single_use_event.await t
436440
with cancellation_exn ->
437-
remove_awaiter loc before t.release;
441+
remove_awaiter loc before t;
438442
Timeout.cancel_alive alive;
439443
raise cancellation_exn
440444
end;
@@ -969,22 +973,22 @@ module Xt = struct
969973
commit (Backoff.once backoff) mode (reset_quick xt) tx
970974
| exception Retry.Later -> begin
971975
if xt.cass == NIL then invalid_retry ();
972-
let t = Domain_local_await.prepare_for_await () in
973-
let alive = Timeout.await (timeout_as_atomic xt) t.release in
974-
match add_awaiters t.release xt.casn xt.cass with
976+
let t = Single_use_event.create () in
977+
let alive = Timeout.await (timeout_as_atomic xt) t in
978+
match add_awaiters t xt.casn xt.cass with
975979
| NIL -> begin
976-
match t.await () with
980+
match Single_use_event.await t with
977981
| () ->
978-
remove_awaiters t.release xt.casn NIL xt.cass;
982+
remove_awaiters t xt.casn NIL xt.cass;
979983
Timeout.unawait (timeout_as_atomic xt) alive;
980984
commit (Backoff.reset backoff) mode (reset_quick xt) tx
981985
| exception cancellation_exn ->
982-
remove_awaiters t.release xt.casn NIL xt.cass;
986+
remove_awaiters t xt.casn NIL xt.cass;
983987
Timeout.cancel_alive alive;
984988
raise cancellation_exn
985989
end
986990
| CASN _ as stop ->
987-
remove_awaiters t.release xt.casn stop xt.cass;
991+
remove_awaiters t xt.casn stop xt.cass;
988992
Timeout.unawait (timeout_as_atomic xt) alive;
989993
commit (Backoff.once backoff) mode (reset_quick xt) tx
990994
end

0 commit comments

Comments
 (0)