@@ -21,7 +21,15 @@ type _ Effect.t +=
2121 | FetchAndAdd : (int t * int ) -> int Effect .t
2222 | Spawn : (unit -> unit ) -> unit Effect .t
2323
24- type atomic_op = Start | Make | Get | Set | Exchange | CompareAndSwap | FetchAndAdd | Spawn
24+ type cas_result = Unknown | Success | Failed
25+
26+ type atomic_op =
27+ | Start | Make | Get | Set | Exchange | FetchAndAdd | Spawn
28+ | CompareAndSwap of cas_result ref
29+
30+ let atomic_op_equal a b = match a, b with
31+ | CompareAndSwap _ , CompareAndSwap _ -> true
32+ | _ -> a = b
2533
2634let atomic_op_str x =
2735 match x with
@@ -30,9 +38,14 @@ let atomic_op_str x =
3038 | Get -> " get"
3139 | Set -> " set"
3240 | Exchange -> " exchange"
33- | CompareAndSwap -> " compare_and_swap"
3441 | FetchAndAdd -> " fetch_and_add"
3542 | Spawn -> " spawn"
43+ | CompareAndSwap cas ->
44+ begin match ! cas with
45+ | Unknown -> " compare_and_swap?"
46+ | Success -> " compare_and_swap"
47+ | Failed -> " compare_and_no_swap"
48+ end
3649
3750let tracing = ref false
3851
@@ -135,8 +148,11 @@ let handler current_process runner =
135148 | CompareAndSwap ((x ,i ), s , v ) ->
136149 Some
137150 (fun (k : (a, _) continuation ) ->
151+ let res = ref Unknown in
138152 update_process_data current_process.uid (fun h ->
139- continue_with k (Atomic. compare_and_set x s v) h) CompareAndSwap (Some i);
153+ let ok = Atomic. compare_and_set x s v in
154+ res := if ok then Success else Failed ;
155+ continue_with k ok h) (CompareAndSwap res) (Some i);
140156 runner () )
141157 | FetchAndAdd ((v ,i ), x ) ->
142158 Some
@@ -203,7 +219,7 @@ let do_run init_schedule =
203219 | { proc_id = process_id_to_run ; op = next_op ; obj_ptr = next_ptr } :: schedule ->
204220 let process_to_run = get_process process_id_to_run in
205221 assert (not process_to_run.finished);
206- assert (process_to_run.next_op = next_op);
222+ assert (atomic_op_equal process_to_run.next_op next_op);
207223 assert (process_to_run.next_repr = next_ptr);
208224 process_to_run.resume_func (handler process_to_run (run_trace schedule))
209225 in
@@ -231,8 +247,14 @@ type category =
231247let categorize = function
232248 | Spawn | Start | Make -> Ignore
233249 | Get -> Read
234- | Set | Exchange -> Write
235- | CompareAndSwap | FetchAndAdd -> Read_write
250+ | Set -> Write
251+ | Exchange | FetchAndAdd -> Read_write
252+ | CompareAndSwap res ->
253+ begin match ! res with
254+ | Unknown -> failwith " CAS unknown outcome" (* should not happen *)
255+ | Success -> Read_write
256+ | Failed -> Read_write
257+ end
236258
237259let rec list_findi predicate lst i = match lst with
238260 | [] -> None
@@ -241,26 +263,25 @@ let rec list_findi predicate lst i = match lst with
241263
242264let list_findi predicate lst = list_findi predicate lst 0
243265
244- let mark_backtrack ~ is_last proc time state (last_read , last_write ) =
266+ let mark_backtrack proc time state (last_read , last_write ) =
245267 let j = proc.proc_id in
246268 let find ptr map = match IdMap. find_opt ptr map with
247269 | None -> None
248270 | Some lst ->
249271 List. find_opt (fun (_ , proc_id ) -> proc_id <> j) lst
250272 in
251- let find_loc ~ is_last proc =
273+ let find_loc proc =
252274 match categorize proc.op, proc.obj_ptr with
253275 | Ignore , _ -> None
254276 | Read , Some ptr -> find ptr last_write
255- | Write , Some ptr when not is_last -> find ptr last_read
256277 | (Write | Read_write ), Some ptr -> max (find ptr last_read) (find ptr last_write)
257278 | _ -> assert false
258279 in
259280 let rec find_replay_trace ~lower ~upper proc_id =
260281 let pre_s = List. nth state (time - upper + 1 ) in
261282 let replay_steps = List. filteri (fun k s -> k > = lower && k < = time - upper && s.run.proc_id = proc_id) state in
262283 let replay_steps = List. rev_map (fun s -> s.run) replay_steps in
263- let causal p = match find_loc ~is_last: false p with
284+ let causal p = match find_loc p with
264285 | None -> true
265286 | Some (k , _ ) -> k < = upper in
266287 if List. for_all causal replay_steps
@@ -277,7 +298,7 @@ let mark_backtrack ~is_last proc time state (last_read, last_write) =
277298 end
278299 else None
279300 in
280- match find_loc ~is_last proc with
301+ match find_loc proc with
281302 | None -> ()
282303 | Some (i , _ ) ->
283304 assert (List. length state = time) ;
@@ -338,7 +359,7 @@ let rec explore func time state (explored, state_planned) current_schedule clock
338359 :: state
339360 in
340361 let new_time = time + 1 in
341- mark_backtrack ~is_last: ( IdSet. is_empty step.enabled) step.run new_time new_state (last_read, last_write);
362+ mark_backtrack step.run new_time new_state (last_read, last_write);
342363 let add ptr map =
343364 IdMap. update
344365 ptr
0 commit comments