@@ -234,6 +234,13 @@ let categorize = function
234234 | Set | Exchange -> Write
235235 | CompareAndSwap | FetchAndAdd -> Read_write
236236
237+ let rec list_findi predicate lst i = match lst with
238+ | [] -> None
239+ | x ::_ when predicate i x -> Some (i, x)
240+ | _ ::xs -> list_findi predicate xs (i + 1 )
241+
242+ let list_findi predicate lst = list_findi predicate lst 0
243+
237244let mark_backtrack ~is_last proc time state (last_read , last_write ) =
238245 let j = proc.proc_id in
239246 let find ptr map = match IdMap. find_opt ptr map with
@@ -249,27 +256,39 @@ let mark_backtrack ~is_last proc time state (last_read, last_write) =
249256 | (Write | Read_write ), Some ptr -> max (find ptr last_read) (find ptr last_write)
250257 | _ -> assert false
251258 in
259+ let rec find_replay_trace ~lower ~upper proc_id =
260+ let pre_s = List. nth state (time - upper + 1 ) in
261+ let replay_steps = List. filteri (fun k s -> k > = lower && k < = time - upper && s.run.proc_id = proc_id) state in
262+ 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
264+ | None -> true
265+ | Some (k , _ ) -> k < = upper in
266+ if List. for_all causal replay_steps
267+ then if IdSet. mem proc_id pre_s.enabled
268+ then Some replay_steps
269+ else let is_parent k s = k > lower && k < time - upper && s.run.op = Spawn && s.run.obj_ptr = Some proc_id in
270+ match list_findi is_parent state with
271+ | None -> None
272+ | Some (parent_i , spawn ) ->
273+ assert (parent_i > lower) ;
274+ begin match find_replay_trace ~lower: parent_i ~upper spawn.run.proc_id with
275+ | None -> None
276+ | Some spawn_steps -> Some (spawn_steps @ replay_steps)
277+ end
278+ else None
279+ in
252280 match find_loc ~is_last proc with
253281 | None -> ()
254282 | Some (i , _ ) ->
255283 assert (List. length state = time) ;
256284 let pre_s = List. nth state (time - i + 1 ) in
257- if IdSet. mem j pre_s.enabled then begin
258- let replay_steps = List. filteri (fun k s -> k < = time - i && s.run.proc_id = j) state in
259- let replay_steps = List. map (fun s -> s.run) replay_steps in
260- let todo =
261- match IdMap. find_opt j pre_s.backtrack with
285+ match find_replay_trace ~lower: 0 ~upper: i proc.proc_id with
286+ | None -> ()
287+ | Some replay_steps ->
288+ if match IdMap. find_opt j pre_s.backtrack with
262289 | None -> true
263290 | Some lst -> List. length lst > List. length replay_steps
264- in
265- let causal p = match find_loc ~is_last: false p with
266- | None -> true
267- | Some (k , _ ) -> k < = i in
268- if todo && List. for_all causal replay_steps
269- then pre_s.backtrack < - IdMap. add j (List. rev replay_steps) pre_s.backtrack
270- end
271- else
272- () (* failwith "TODO: currently untested" *)
291+ then pre_s.backtrack < - IdMap. add j replay_steps pre_s.backtrack
273292
274293let map_diff_set map set =
275294 IdMap. filter (fun key _ -> not (IdSet. mem key set)) map
0 commit comments