@@ -61,7 +61,10 @@ module Timeout = struct
6161 let [@ inline never] await state release =
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 () -> Release. signal release |> ignore))
67+ then alive
6568 else timeout ()
6669 | Unset | Elapsed -> timeout ()
6770
@@ -114,9 +117,9 @@ end = struct
114117 x
115118end
116119
117- type awaiter = unit -> unit
120+ type awaiter = [ `Signal ] Release .t
118121
119- let [@ inline] resume_awaiter awaiter = awaiter ()
122+ let [@ inline] resume_awaiter awaiter = Release. signal awaiter |> ignore
120123
121124let [@ inline] resume_awaiters = function
122125 | [] -> ()
@@ -405,10 +408,11 @@ let add_awaiter loc before awaiter =
405408 (* Fenceless is safe as we have fence after. *)
406409 let state_old = fenceless_get (as_atomic loc) in
407410 let state_new =
408- let awaiters = awaiter :: state_old.awaiters in
411+ let awaiters = ( awaiter :> [ `Signal ] Release.t ) :: state_old.awaiters in
409412 { before; after = before; casn = casn_after; awaiters }
410413 in
411- before == eval state_old
414+ Release. is_initial awaiter
415+ && before == eval state_old
412416 && Atomic. compare_and_set (as_atomic loc) state_old state_new
413417
414418let [@ tail_mod_cons] rec remove_first x' removed = function
@@ -422,19 +426,21 @@ let rec remove_awaiter loc before awaiter =
422426 let state_old = fenceless_get (as_atomic loc) in
423427 if before == eval state_old then
424428 let removed = ref true in
425- let awaiters = remove_first awaiter removed state_old.awaiters in
429+ let awaiters =
430+ remove_first (awaiter :> [ `Signal ] Release.t ) removed state_old.awaiters
431+ in
426432 if ! removed then
427433 let state_new = { before; after = before; casn = casn_after; awaiters } in
428434 if not (Atomic. compare_and_set (as_atomic loc) state_old state_new) then
429435 remove_awaiter loc before awaiter
430436
431437let 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 ()
438+ let t = Release. create () in
439+ let alive = Timeout. await timeout t in
440+ if add_awaiter loc before t then begin
441+ try Release . await t
436442 with cancellation_exn ->
437- remove_awaiter loc before t.release ;
443+ remove_awaiter loc before t;
438444 Timeout. cancel_alive alive;
439445 raise cancellation_exn
440446 end ;
@@ -969,22 +975,22 @@ module Xt = struct
969975 commit (Backoff. once backoff) mode (reset_quick xt) tx
970976 | exception Retry. Later -> begin
971977 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
978+ let t = Release. create () in
979+ let alive = Timeout. await (timeout_as_atomic xt) t in
980+ match add_awaiters t xt.casn xt.cass with
975981 | NIL -> begin
976- match t .await () with
982+ match Release . await t with
977983 | () ->
978- remove_awaiters t.release xt.casn NIL xt.cass;
984+ remove_awaiters t xt.casn NIL xt.cass;
979985 Timeout. unawait (timeout_as_atomic xt) alive;
980986 commit (Backoff. reset backoff) mode (reset_quick xt) tx
981987 | exception cancellation_exn ->
982- remove_awaiters t.release xt.casn NIL xt.cass;
988+ remove_awaiters t xt.casn NIL xt.cass;
983989 Timeout. cancel_alive alive;
984990 raise cancellation_exn
985991 end
986992 | CASN _ as stop ->
987- remove_awaiters t.release xt.casn stop xt.cass;
993+ remove_awaiters t xt.casn stop xt.cass;
988994 Timeout. unawait (timeout_as_atomic xt) alive;
989995 commit (Backoff. once backoff) mode (reset_quick xt) tx
990996 end
0 commit comments