@@ -8,7 +8,7 @@ let create ?padded () = Awaitable.make ?padded 0
88let [@ inline] wait t lock ~acquire ~release =
99 let before = Awaitable. get t in
1010 release lock;
11- let lock_forbidden lock =
11+ let lock_forbidden lock ~ acquire =
1212 let fiber = Fiber. current () in
1313 let forbid = Fiber. exchange fiber ~forbid: true in
1414 match acquire lock with
@@ -19,17 +19,40 @@ let[@inline] wait t lock ~acquire ~release =
1919 Fiber. set fiber ~forbid ;
2020 Printexc. raise_with_backtrace exn bt
2121 in
22- match if Awaitable. get t == before then Awaitable. await t before with
23- | () -> lock_forbidden lock
24- | exception exn ->
25- let bt = Printexc. get_raw_backtrace () in
26- lock_forbidden lock;
27- Printexc. raise_with_backtrace exn bt
22+ let await t lock ~acquire before =
23+ match if Awaitable. get t == before then Awaitable. await t before with
24+ | () ->
25+ let before = Awaitable. get t in
26+ if before land 1 = 0 then begin
27+ let after = before lor 1 in
28+ if
29+ (not (Awaitable. compare_and_set t before after))
30+ && Awaitable. get t land 1 = 0
31+ then Awaitable. signal t
32+ end ;
33+ lock_forbidden lock ~acquire
34+ | exception exn ->
35+ let bt = Printexc. get_raw_backtrace () in
36+ lock_forbidden lock ~acquire ;
37+ Printexc. raise_with_backtrace exn bt
38+ in
39+ if before land 1 = 0 then
40+ let after = before lor 1 in
41+ if Awaitable. compare_and_set t before after || Awaitable. get t == after then
42+ await t lock ~acquire after
43+ else lock_forbidden lock ~acquire
44+ else await t lock ~acquire before
2845
2946let signal t =
30- Awaitable. incr t;
31- Awaitable. signal t
47+ let prior = Awaitable. fetch_and_add t 2 in
48+ if prior land 1 <> 0 then begin
49+ if Awaitable. compare_and_set t (prior + 2 ) (prior + 1 ) then () ;
50+ Awaitable. signal t
51+ end
3252
3353let broadcast t =
34- Awaitable. incr t;
35- Awaitable. broadcast t
54+ let prior = Awaitable. fetch_and_add t 2 in
55+ if prior land 1 <> 0 then begin
56+ if Awaitable. compare_and_set t (prior + 2 ) (prior + 1 ) then () ;
57+ Awaitable. broadcast t
58+ end
0 commit comments