Skip to content

Commit 2b30947

Browse files
committed
fix sequencing for assertion failures
1 parent d6f8152 commit 2b30947

File tree

2 files changed

+21
-37
lines changed

2 files changed

+21
-37
lines changed

src/test_atomics.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,4 @@ let create_test upto () =
4444
)
4545

4646
let () =
47-
Atomic.trace (create_test 2)
47+
Atomic.trace (create_test 8)

src/tracedAtomic.ml

Lines changed: 20 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -161,16 +161,17 @@ let rec last_element l =
161161
| _ :: tl -> last_element tl
162162

163163
type proc_rec = { proc_id: int; op: atomic_op; obj_ptr : int option }
164-
type state_cell = { procs: proc_rec list; run_proc: int; enabled : IntSet.t; mutable backtrack : IntSet.t }
164+
type state_cell = { procs: proc_rec list; run_proc: int; run_op: atomic_op; run_ptr: int option; enabled : IntSet.t; mutable backtrack : IntSet.t }
165165

166166
let num_runs = ref 0
167167

168168
(* we stash the current state in case a check fails and we need to log it *)
169-
let state_for_checks = ref []
169+
let schedule_for_checks = ref []
170170

171171
let do_run init_func init_schedule =
172172
init_func (); (*set up run *)
173173
tracing := true;
174+
schedule_for_checks := init_schedule;
174175
(* cache the number of processes in case it's expensive*)
175176
let num_processes = CCVector.length processes in
176177
(* current number of ops we are through the current run *)
@@ -181,29 +182,18 @@ let do_run init_func init_schedule =
181182
match s with
182183
| [] -> if !finished_processes == num_processes then begin
183184
tracing := false;
184-
Printf.printf "Running finish\n";
185185
!final_func ();
186-
let last_state = ref None in
187-
List.iter (fun s ->
188-
begin match !last_state with
189-
| None -> Printf.printf "Process %d: start\n" s.run_proc
190-
| Some(x) -> begin
191-
let last_run_proc = List.nth x.procs s.run_proc in
192-
let last_run_ptr = Option.map string_of_int last_run_proc.obj_ptr |> Option.value ~default:"" in
193-
Printf.printf "Process %d: %s %s\n" s.run_proc (atomic_op_str last_run_proc.op) last_run_ptr
194-
end;
195-
end;
196-
last_state := (Some s)
197-
) !state_for_checks;
198186
tracing := true
199187
end
200-
| process_id_to_run :: schedule -> begin
188+
| (process_id_to_run, next_op, next_ptr) :: schedule -> begin
201189
if !finished_processes == num_processes then
202190
(* this should never happen *)
203191
failwith("no enabled processes")
204192
else
205193
begin
206194
let process_to_run = CCVector.get processes process_id_to_run in
195+
assert(process_to_run.next_op = next_op);
196+
assert(process_to_run.next_repr = next_ptr);
207197
process_to_run.resume_func (handler process_id_to_run (run_trace schedule))
208198
end
209199
end
@@ -213,7 +203,7 @@ let do_run init_func init_schedule =
213203
finished_processes := 0;
214204
tracing := false;
215205
num_runs := !num_runs + 1;
216-
if !num_runs mod 1 == 0 then
206+
if !num_runs mod 1000 == 0 then
217207
Printf.printf "run: %d\n" !num_runs;
218208
let procs = CCVector.mapi (fun i p -> { proc_id = i; op = p.next_op; obj_ptr = p.next_repr }) processes |> CCVector.to_list in
219209
let current_enabled = CCVector.to_seq processes
@@ -223,16 +213,16 @@ let do_run init_func init_schedule =
223213
|> IntSet.of_seq in
224214
CCVector.clear processes;
225215
atomics_counter := 1;
226-
{ procs; enabled = current_enabled; run_proc = last_element init_schedule; backtrack = IntSet.empty }
216+
match last_element init_schedule with
217+
| (run_proc, run_op, run_ptr) ->
218+
{ procs; enabled = current_enabled; run_proc; run_op; run_ptr; backtrack = IntSet.empty }
227219

228220
let rec explore func state clock last_access =
229221
let s = last_element state in
230222
List.iter (fun proc ->
231223
let j = proc.proc_id in
232224
let i = Option.bind proc.obj_ptr (fun ptr -> IntMap.find_opt ptr last_access) |> Option.value ~default:0 in
233-
let last_hb_p = IntMap.find_opt j clock |> Option.value ~default:0 in
234-
Printf.printf "Checking proc: %d, i: %d, last_hb_p: %d\n" j i last_hb_p;
235-
if i != 0 (*&& i > last_hb_p*) then begin
225+
if i != 0 then begin
236226
let pre_s = List.nth state (i-1) in
237227
if IntSet.mem j pre_s.enabled then
238228
pre_s.backtrack <- IntSet.add j pre_s.backtrack
@@ -247,11 +237,10 @@ let rec explore func state clock last_access =
247237
while IntSet.(cardinal (diff s.backtrack !dones)) > 0 do
248238
let j = IntSet.min_elt (IntSet.diff s.backtrack !dones) in
249239
dones := IntSet.add j !dones;
250-
let schedule = (List.map (fun s -> s.run_proc) state) @ [j] in
251-
state_for_checks := state;
240+
let j_proc = List.nth s.procs j in
241+
let schedule = (List.map (fun s -> (s.run_proc, s.run_op, s.run_ptr)) state) @ [(j, j_proc.op, j_proc.obj_ptr)] in
252242
let statedash = state @ [do_run func schedule] in
253243
let state_time = (List.length statedash)-1 in
254-
let j_proc = List.nth s.procs j in
255244
let new_last_access = match j_proc.obj_ptr with Some(ptr) -> IntMap.add ptr state_time last_access | None -> last_access in
256245
let new_clock = IntMap.add j state_time clock in
257246
explore func statedash new_clock new_last_access
@@ -268,27 +257,22 @@ let check f =
268257
let tracing_at_start = !tracing in
269258
tracing := false;
270259
if not (f ()) then begin
271-
let state = !state_for_checks in
272260
Printf.printf "Found assertion violation at run %d:\n" !num_runs;
273-
let last_state = ref None in
274261
List.iter (fun s ->
275-
begin match !last_state with
276-
| None -> Printf.printf "Process %d: start\n" s.run_proc
277-
| Some(x) -> begin
278-
let last_run_proc = List.nth x.procs s.run_proc in
279-
let last_run_ptr = Option.map string_of_int last_run_proc.obj_ptr |> Option.value ~default:"" in
280-
Printf.printf "Process %d: %s %s\n" s.run_proc (atomic_op_str last_run_proc.op) last_run_ptr
281-
end;
262+
begin match s with
263+
| (last_run_proc, last_run_op, last_run_ptr) -> begin
264+
let last_run_ptr = Option.map string_of_int last_run_ptr |> Option.value ~default:"" in
265+
Printf.printf "Process %d: %s %s\n" last_run_proc (atomic_op_str last_run_op) last_run_ptr
282266
end;
283-
last_state := (Some s)
284-
) state;
267+
end;
268+
) !schedule_for_checks;
285269
assert(false)
286270
end;
287271
tracing := tracing_at_start
288272

289273

290274
let trace func =
291-
let empty_state = do_run func [0] :: [] in
275+
let empty_state = do_run func [(0, Start, None)] :: [] in
292276
let empty_clock = IntMap.empty in
293277
let empty_last_access = IntMap.empty in
294278
explore func empty_state empty_clock empty_last_access

0 commit comments

Comments
 (0)