Skip to content

Commit d7572aa

Browse files
committed
CSE workarounds
1 parent eda5722 commit d7572aa

File tree

1 file changed

+15
-8
lines changed

1 file changed

+15
-8
lines changed

src/kcas/kcas.ml

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
* Copyright (c) 2023, Vesa Karvonen <[email protected]>
44
*)
55

6+
(** Work around CSE bug in OCaml 5-5.1. *)
7+
let[@inline] atomic_get x =
8+
Atomic.get ((* Prevents CSE *) Sys.opaque_identity x)
9+
610
(* NOTE: You can adjust comment blocks below to select whether or not to use
711
fenceless operations where it is safe to do so. Fenceless operations have
812
been seen to provide significant performance improvements on ARM (Apple
@@ -11,9 +15,12 @@
1115
(**)
1216
external fenceless_get : 'a Atomic.t -> 'a = "%field0"
1317
external fenceless_set : 'a Atomic.t -> 'a -> unit = "%setfield0"
18+
19+
let[@inline] fenceless_get x =
20+
fenceless_get ((* Prevents CSE *) Sys.opaque_identity x)
1421
(**)
1522
(*
16-
let fenceless_get = Atomic.get
23+
let fenceless_get = atomic_get
1724
let fenceless_set = Atomic.set
1825
*)
1926

@@ -260,7 +267,7 @@ let rec determine casn status = function
260267
if status < 0 then status
261268
else
262269
let loc = r.loc in
263-
let current = Atomic.get (as_atomic loc) in
270+
let current = atomic_get (as_atomic loc) in
264271
let state = r.state in
265272
if state == current then
266273
let a_cas_or_a_cmp = 1 + Bool.to_int (is_cas casn state) in
@@ -490,7 +497,7 @@ let update_with_state timeout backoff loc f state_old =
490497
raise exn
491498

492499
let rec exchange_no_alloc backoff loc state =
493-
let state_old = Atomic.get (as_atomic loc) in
500+
let state_old = atomic_get (as_atomic loc) in
494501
let before = eval state_old in
495502
if before == state.after then before
496503
else if Atomic.compare_and_set (as_atomic loc) state_old state then begin
@@ -546,7 +553,7 @@ module Loc = struct
546553
Array.init n @@ fun i -> make_loc padded state (id + i)
547554

548555
let[@inline] get_id loc = loc.id
549-
let get loc = eval (Atomic.get (as_atomic loc))
556+
let get loc = eval (atomic_get (as_atomic loc))
550557

551558
let rec get_as timeout f loc state =
552559
let before = eval state in
@@ -563,14 +570,14 @@ module Loc = struct
563570
raise exn
564571

565572
let[@inline] get_as ?timeoutf f loc =
566-
get_as (Timeout.alloc_opt timeoutf) f loc (Atomic.get (as_atomic loc))
573+
get_as (Timeout.alloc_opt timeoutf) f loc (atomic_get (as_atomic loc))
567574

568575
let[@inline] get_mode loc =
569576
if loc.id < 0 then Mode.lock_free else Mode.obstruction_free
570577

571578
let compare_and_set loc before after =
572579
let state = new_state after in
573-
let state_old = Atomic.get (as_atomic loc) in
580+
let state_old = atomic_get (as_atomic loc) in
574581
cas_with_state loc before state state_old
575582

576583
let fenceless_update ?timeoutf ?(backoff = Backoff.default) loc f =
@@ -582,7 +589,7 @@ module Loc = struct
582589

583590
let update ?timeoutf ?(backoff = Backoff.default) loc f =
584591
let timeout = Timeout.alloc_opt timeoutf in
585-
update_with_state timeout backoff loc f (Atomic.get (as_atomic loc))
592+
update_with_state timeout backoff loc f (atomic_get (as_atomic loc))
586593

587594
let[@inline] modify ?timeoutf ?backoff loc f =
588595
update ?timeoutf ?backoff loc f |> ignore
@@ -607,7 +614,7 @@ module Loc = struct
607614
fenceless_update ?backoff loc dec |> ignore
608615

609616
let has_awaiters loc =
610-
let state = Atomic.get (as_atomic loc) in
617+
let state = atomic_get (as_atomic loc) in
611618
state.awaiters != []
612619

613620
let fenceless_get loc = eval (fenceless_get (as_atomic loc))

0 commit comments

Comments
 (0)