@@ -56,7 +56,7 @@ let resume_awaiters result = function
5656
5757type determined = [ `After | `Before ]
5858
59- type 'a loc = { state : 'a state Atomic .t ; id : int }
59+ type 'a loc = { mutable _state : 'a state ; id : int }
6060
6161and 'a state = {
6262 mutable before : 'a ;
@@ -79,6 +79,8 @@ and cass =
7979and casn = status Atomic. t
8080and status = [ `Undetermined of cass | determined ]
8181
82+ external as_atomic : 'a loc -> 'a state Atomic .t = " %identity"
83+
8284let is_cmp casn state = state.casn != casn [@@ inline]
8385
8486module Mode = struct
@@ -121,12 +123,13 @@ let rec verify casn = function
121123 | NIL -> `After
122124 | CASN { loc; state; lt; gt; _ } -> (
123125 if lt == NIL then
124- if is_cmp casn state && fenceless_get loc.state != state then `Before
126+ if is_cmp casn state && fenceless_get (as_atomic loc) != state then
127+ `Before
125128 else verify casn gt
126129 else
127130 match verify casn lt with
128131 | `After ->
129- if is_cmp casn state && fenceless_get loc.state != state then
132+ if is_cmp casn state && fenceless_get (as_atomic loc) != state then
130133 `Before
131134 else verify casn gt
132135 | `Before -> `Before )
@@ -147,7 +150,7 @@ let rec determine casn status = function
147150 let status = if lt != NIL then determine casn status lt else status in
148151 if status < 0 then status
149152 else
150- let current = Atomic. get loc.state in
153+ let current = Atomic. get (as_atomic loc) in
151154 if state == current then
152155 determine casn (status lor (1 + Bool. to_int (is_cmp casn state))) gt
153156 else
@@ -176,7 +179,7 @@ let rec determine casn status = function
176179 (match current.awaiters with
177180 | [] -> ()
178181 | awaiters -> record.awaiters < - awaiters);
179- if Atomic. compare_and_set loc.state current state then
182+ if Atomic. compare_and_set (as_atomic loc) current state then
180183 determine casn (status lor a_cas) gt
181184 else determine casn status eq
182185 | #determined -> raise Exit
@@ -267,13 +270,13 @@ module Retry = struct
267270end
268271
269272let add_awaiter loc before awaiter =
270- let state_old = fenceless_get loc.state in
273+ let state_old = fenceless_get (as_atomic loc) in
271274 let state_new =
272275 let awaiters = awaiter :: state_old.awaiters in
273276 { before; after = before; casn = casn_after; awaiters }
274277 in
275278 before == eval state_old
276- && Atomic. compare_and_set loc.state state_old state_new
279+ && Atomic. compare_and_set (as_atomic loc) state_old state_new
277280
278281let [@ tail_mod_cons] rec remove_first x' removed = function
279282 | [] ->
@@ -282,13 +285,13 @@ let[@tail_mod_cons] rec remove_first x' removed = function
282285 | x :: xs -> if x == x' then xs else x :: remove_first x' removed xs
283286
284287let rec remove_awaiter loc before awaiter =
285- let state_old = fenceless_get loc.state in
288+ let state_old = fenceless_get (as_atomic loc) in
286289 if before == eval state_old then
287290 let removed = ref true in
288291 let awaiters = remove_first awaiter removed state_old.awaiters in
289292 if ! removed then
290293 let state_new = { before; after = before; casn = casn_after; awaiters } in
291- if not (Atomic. compare_and_set loc.state state_old state_new) then
294+ if not (Atomic. compare_and_set (as_atomic loc) state_old state_new) then
292295 remove_awaiter loc before awaiter
293296
294297let block loc before =
@@ -300,13 +303,13 @@ let block loc before =
300303 raise cancellation_exn)
301304
302305let rec update_no_alloc backoff loc state f =
303- let state' = fenceless_get loc.state in
306+ let state' = fenceless_get (as_atomic loc) in
304307 let before = eval state' in
305308 match f before with
306309 | after ->
307310 state.after < - after;
308311 if before == after then before
309- else if Atomic. compare_and_set loc.state state' state then (
312+ else if Atomic. compare_and_set (as_atomic loc) state' state then (
310313 state.before < - after;
311314 resume_awaiters before state'.awaiters)
312315 else update_no_alloc (Backoff. once backoff) loc state f
@@ -315,23 +318,24 @@ let rec update_no_alloc backoff loc state f =
315318 update_no_alloc backoff loc state f
316319
317320let rec exchange_no_alloc backoff loc state =
318- let state' = fenceless_get loc.state in
321+ let state' = fenceless_get (as_atomic loc) in
319322 let before = eval state' in
320- if before == state.after || Atomic. compare_and_set loc.state state' state then
321- resume_awaiters before state'.awaiters
323+ if
324+ before == state.after || Atomic. compare_and_set (as_atomic loc) state' state
325+ then resume_awaiters before state'.awaiters
322326 else exchange_no_alloc (Backoff. once backoff) loc state
323327
324328let is_obstruction_free casn =
325329 fenceless_get casn == (Mode. obstruction_free :> status )
326330 [@@ inline]
327331
328332let cas loc before state =
329- let state' = fenceless_get loc.state in
333+ let state' = fenceless_get (as_atomic loc) in
330334 let before' = state'.before and after' = state'.after in
331335 ((before == before' && before == after')
332336 || before == if is_after state'.casn then after' else before')
333337 && (before == state.after
334- || Atomic. compare_and_set loc.state state' state
338+ || Atomic. compare_and_set (as_atomic loc) state' state
335339 && resume_awaiters true state'.awaiters)
336340 [@@ inline]
337341
@@ -342,11 +346,11 @@ module Loc = struct
342346 type 'a t = 'a loc
343347
344348 let make after =
345- let state = Atomic. make @@ new_state after and id = Id. get_unique () in
346- { state ; id }
349+ let _state = new_state after and id = Id. get_unique () in
350+ { _state ; id }
347351
348352 let get_id loc = loc.id [@@ inline]
349- let get loc = eval (Atomic. get loc.state )
353+ let get loc = eval (Atomic. get (as_atomic loc) )
350354
351355 let rec get_as f loc =
352356 let before = get loc in
@@ -361,14 +365,14 @@ module Loc = struct
361365 cas loc before state
362366
363367 let update ?(backoff = Backoff. default) loc f =
364- let state' = fenceless_get loc.state in
368+ let state' = fenceless_get (as_atomic loc) in
365369 let before = eval state' in
366370 match f before with
367371 | after ->
368372 if before == after then before
369373 else
370374 let state = new_state after in
371- if Atomic. compare_and_set loc.state state' state then
375+ if Atomic. compare_and_set (as_atomic loc) state' state then
372376 resume_awaiters before state'.awaiters
373377 else update_no_alloc (Backoff. once backoff) loc state f
374378 | exception Retry. Later ->
@@ -387,7 +391,7 @@ module Loc = struct
387391 let decr ?backoff loc = update ?backoff loc dec |> ignore
388392
389393 let has_awaiters loc =
390- let state = Atomic. get loc.state in
394+ let state = Atomic. get (as_atomic loc) in
391395 state.awaiters != []
392396end
393397
@@ -430,7 +434,7 @@ module Op = struct
430434 | [] -> determine_for_owner casn cass
431435 | CAS (loc , before , after ) :: rest ->
432436 if before == after && is_obstruction_free casn then
433- let state = fenceless_get loc.state in
437+ let state = fenceless_get (as_atomic loc) in
434438 before == eval state && run (insert cass loc state) rest
435439 else
436440 run
@@ -439,7 +443,7 @@ module Op = struct
439443 in
440444 let (CAS (loc, before, after)) = first in
441445 if before == after && is_obstruction_free casn then
442- let state = fenceless_get loc.state in
446+ let state = fenceless_get (as_atomic loc) in
443447 before == eval state
444448 && run (CASN { loc; state; lt = NIL ; gt = NIL ; awaiters = [] }) rest
445449 else
@@ -455,7 +459,7 @@ module Xt = struct
455459 }
456460
457461 let update0 loc f xt lt gt =
458- let state = fenceless_get loc.state in
462+ let state = fenceless_get (as_atomic loc) in
459463 let before = eval state in
460464 let after = f before in
461465 let state =
0 commit comments