@@ -61,9 +61,7 @@ let resume_awaiters result = function
6161
6262type determined = [ `After | `Before ]
6363
64- type 'a loc = { state : 'a state Atomic .t ; id : int }
65-
66- and 'a state = {
64+ type 'a state = {
6765 mutable before : 'a ;
6866 mutable after : 'a ;
6967 mutable casn : casn ;
@@ -84,6 +82,21 @@ and cass =
8482and casn = status Atomic. t
8583and status = [ `Undetermined of cass | determined ]
8684
85+ (* *)
86+ and 'a loc = { mutable _state : 'a state ; id : int }
87+
88+ external as_atomic : 'a loc -> 'a state Atomic .t = " %identity"
89+
90+ let make_loc state id = { _state = state; id } [@@ inline]
91+ (* *)
92+
93+ (*
94+ and 'a loc = { state : 'a state Atomic.t; id : int }
95+
96+ let as_atomic loc = loc.state [@@inline]
97+ let make_loc state id = { state = Atomic.make state; id } [@@inline]
98+ *)
99+
87100let is_cmp casn state = state.casn != casn [@@ inline]
88101
89102module Mode = struct
@@ -126,12 +139,13 @@ let rec verify casn = function
126139 | NIL -> `After
127140 | CASN { loc; state; lt; gt; _ } -> (
128141 if lt == NIL then
129- if is_cmp casn state && fenceless_get loc.state != state then `Before
142+ if is_cmp casn state && fenceless_get (as_atomic loc) != state then
143+ `Before
130144 else verify casn gt
131145 else
132146 match verify casn lt with
133147 | `After ->
134- if is_cmp casn state && fenceless_get loc.state != state then
148+ if is_cmp casn state && fenceless_get (as_atomic loc) != state then
135149 `Before
136150 else verify casn gt
137151 | `Before -> `Before )
@@ -152,7 +166,7 @@ let rec determine casn status = function
152166 let status = if lt != NIL then determine casn status lt else status in
153167 if status < 0 then status
154168 else
155- let current = Atomic. get loc.state in
169+ let current = Atomic. get (as_atomic loc) in
156170 if state == current then
157171 determine casn (status lor (1 + Bool. to_int (is_cmp casn state))) gt
158172 else
@@ -181,7 +195,7 @@ let rec determine casn status = function
181195 (match current.awaiters with
182196 | [] -> ()
183197 | awaiters -> record.awaiters < - awaiters);
184- if Atomic. compare_and_set loc.state current state then
198+ if Atomic. compare_and_set (as_atomic loc) current state then
185199 determine casn (status lor a_cas) gt
186200 else determine casn status eq
187201 | #determined -> raise Exit
@@ -272,13 +286,13 @@ module Retry = struct
272286end
273287
274288let add_awaiter loc before awaiter =
275- let state_old = fenceless_get loc.state in
289+ let state_old = fenceless_get (as_atomic loc) in
276290 let state_new =
277291 let awaiters = awaiter :: state_old.awaiters in
278292 { before; after = before; casn = casn_after; awaiters }
279293 in
280294 before == eval state_old
281- && Atomic. compare_and_set loc.state state_old state_new
295+ && Atomic. compare_and_set (as_atomic loc) state_old state_new
282296
283297let [@ tail_mod_cons] rec remove_first x' removed = function
284298 | [] ->
@@ -287,13 +301,13 @@ let[@tail_mod_cons] rec remove_first x' removed = function
287301 | x :: xs -> if x == x' then xs else x :: remove_first x' removed xs
288302
289303let rec remove_awaiter loc before awaiter =
290- let state_old = fenceless_get loc.state in
304+ let state_old = fenceless_get (as_atomic loc) in
291305 if before == eval state_old then
292306 let removed = ref true in
293307 let awaiters = remove_first awaiter removed state_old.awaiters in
294308 if ! removed then
295309 let state_new = { before; after = before; casn = casn_after; awaiters } in
296- if not (Atomic. compare_and_set loc.state state_old state_new) then
310+ if not (Atomic. compare_and_set (as_atomic loc) state_old state_new) then
297311 remove_awaiter loc before awaiter
298312
299313let block loc before =
@@ -305,13 +319,13 @@ let block loc before =
305319 raise cancellation_exn)
306320
307321let rec update_no_alloc backoff loc state f =
308- let state' = fenceless_get loc.state in
322+ let state' = fenceless_get (as_atomic loc) in
309323 let before = eval state' in
310324 match f before with
311325 | after ->
312326 state.after < - after;
313327 if before == after then before
314- else if Atomic. compare_and_set loc.state state' state then (
328+ else if Atomic. compare_and_set (as_atomic loc) state' state then (
315329 state.before < - after;
316330 resume_awaiters before state'.awaiters)
317331 else update_no_alloc (Backoff. once backoff) loc state f
@@ -320,23 +334,24 @@ let rec update_no_alloc backoff loc state f =
320334 update_no_alloc backoff loc state f
321335
322336let rec exchange_no_alloc backoff loc state =
323- let state' = fenceless_get loc.state in
337+ let state' = fenceless_get (as_atomic loc) in
324338 let before = eval state' in
325- if before == state.after || Atomic. compare_and_set loc.state state' state then
326- resume_awaiters before state'.awaiters
339+ if
340+ before == state.after || Atomic. compare_and_set (as_atomic loc) state' state
341+ then resume_awaiters before state'.awaiters
327342 else exchange_no_alloc (Backoff. once backoff) loc state
328343
329344let is_obstruction_free casn =
330345 fenceless_get casn == (Mode. obstruction_free :> status )
331346 [@@ inline]
332347
333348let cas loc before state =
334- let state' = fenceless_get loc.state in
349+ let state' = fenceless_get (as_atomic loc) in
335350 let before' = state'.before and after' = state'.after in
336351 ((before == before' && before == after')
337352 || before == if is_after state'.casn then after' else before')
338353 && (before == state.after
339- || Atomic. compare_and_set loc.state state' state
354+ || Atomic. compare_and_set (as_atomic loc) state' state
340355 && resume_awaiters true state'.awaiters)
341356 [@@ inline]
342357
@@ -347,11 +362,11 @@ module Loc = struct
347362 type 'a t = 'a loc
348363
349364 let make after =
350- let state = Atomic. make @@ new_state after and id = Id. get_unique () in
351- { state; id }
365+ let state = new_state after and id = Id. get_unique () in
366+ make_loc state id
352367
353368 let get_id loc = loc.id [@@ inline]
354- let get loc = eval (Atomic. get loc.state )
369+ let get loc = eval (Atomic. get (as_atomic loc) )
355370
356371 let rec get_as f loc =
357372 let before = get loc in
@@ -366,14 +381,14 @@ module Loc = struct
366381 cas loc before state
367382
368383 let update ?(backoff = Backoff. default) loc f =
369- let state' = fenceless_get loc.state in
384+ let state' = fenceless_get (as_atomic loc) in
370385 let before = eval state' in
371386 match f before with
372387 | after ->
373388 if before == after then before
374389 else
375390 let state = new_state after in
376- if Atomic. compare_and_set loc.state state' state then
391+ if Atomic. compare_and_set (as_atomic loc) state' state then
377392 resume_awaiters before state'.awaiters
378393 else update_no_alloc (Backoff. once backoff) loc state f
379394 | exception Retry. Later ->
@@ -392,7 +407,7 @@ module Loc = struct
392407 let decr ?backoff loc = update ?backoff loc dec |> ignore
393408
394409 let has_awaiters loc =
395- let state = Atomic. get loc.state in
410+ let state = Atomic. get (as_atomic loc) in
396411 state.awaiters != []
397412end
398413
@@ -435,7 +450,7 @@ module Op = struct
435450 | [] -> determine_for_owner casn cass
436451 | CAS (loc , before , after ) :: rest ->
437452 if before == after && is_obstruction_free casn then
438- let state = fenceless_get loc.state in
453+ let state = fenceless_get (as_atomic loc) in
439454 before == eval state && run (insert cass loc state) rest
440455 else
441456 run
@@ -444,7 +459,7 @@ module Op = struct
444459 in
445460 let (CAS (loc, before, after)) = first in
446461 if before == after && is_obstruction_free casn then
447- let state = fenceless_get loc.state in
462+ let state = fenceless_get (as_atomic loc) in
448463 before == eval state
449464 && run (CASN { loc; state; lt = NIL ; gt = NIL ; awaiters = [] }) rest
450465 else
@@ -460,7 +475,7 @@ module Xt = struct
460475 }
461476
462477 let update0 loc f xt lt gt =
463- let state = fenceless_get loc.state in
478+ let state = fenceless_get (as_atomic loc) in
464479 let before = eval state in
465480 let after = f before in
466481 let state =
0 commit comments