Skip to content

Commit 6c48557

Browse files
committed
fix: atomic ops categorization
1 parent 8a6e504 commit 6c48557

File tree

1 file changed

+33
-12
lines changed

1 file changed

+33
-12
lines changed

src/tracedAtomic.ml

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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

2634
let 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

3750
let 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 =
231247
let 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

237259
let 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

242264
let 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

Comments
 (0)