@@ -106,6 +106,7 @@ let make_loc state id = { state = Atomic.make state; id } [@@inline]
106106*)
107107
108108let is_cmp casn state = state.casn != casn [@@ inline]
109+ let is_cas casn state = state.casn == casn [@@ inline]
109110
110111module Mode = struct
111112 type t = determined
@@ -163,10 +164,9 @@ let finish casn (`Undetermined cass as undetermined) (status : determined) =
163164 then release casn cass status
164165 else fenceless_get casn == `After
165166
166- let a_cas = 1
167- and a_cmp = 2
168-
169- let a_cas_and_a_cmp = a_cas lor a_cmp
167+ let a_cmp = 1
168+ let a_cas = 2
169+ let a_cmp_followed_by_a_cas = 4
170170
171171let rec determine casn status = function
172172 | NIL -> status
@@ -176,7 +176,11 @@ let rec determine casn status = function
176176 else
177177 let current = Atomic. get (as_atomic loc) in
178178 if state == current then
179- determine casn (status lor (1 + Bool. to_int (is_cmp casn state))) gt
179+ let a_cas_or_a_cmp = 1 + Bool. to_int (is_cas casn state) in
180+ let a_cmp_followed_by_a_cas = a_cas_or_a_cmp * 2 land (status * 4 ) in
181+ determine casn
182+ (status lor a_cas_or_a_cmp lor a_cmp_followed_by_a_cas)
183+ gt
180184 else
181185 let matches_expected () =
182186 let expected = state.before in
@@ -204,7 +208,10 @@ let rec determine casn status = function
204208 | [] -> ()
205209 | awaiters -> record.awaiters < - awaiters);
206210 if Atomic. compare_and_set (as_atomic loc) current state then
207- determine casn (status lor a_cas) gt
211+ let a_cmp_followed_by_a_cas = a_cas * 2 land (status * 4 ) in
212+ determine casn
213+ (status lor a_cas lor a_cmp_followed_by_a_cas)
214+ gt
208215 else determine casn status eq
209216 | #determined -> raise Exit
210217 else - 1
@@ -215,7 +222,7 @@ and is_after casn =
215222 match determine casn 0 cass with
216223 | status ->
217224 finish casn undetermined
218- (if a_cas_and_a_cmp = status then verify casn cass
225+ (if a_cmp_followed_by_a_cas < status then verify casn cass
219226 else if 0 < = status then `After
220227 else `Before )
221228 | exception Exit -> fenceless_get casn == `After )
@@ -229,7 +236,7 @@ let determine_for_owner casn cass =
229236 fenceless_set casn undetermined;
230237 match determine casn 0 cass with
231238 | status ->
232- if a_cas_and_a_cmp = status then
239+ if a_cmp_followed_by_a_cas < status then
233240 (* We only want to [raise Interference] in case it is the verify step
234241 that fails. The idea is that in [lock_free] mode the attempt might
235242 have succeeded as the compared locations would have been set in
0 commit comments