@@ -208,18 +208,42 @@ let do_run init_schedule =
208208 let (run_proc, run_op, run_ptr) = List. hd init_schedule in
209209 { procs; enabled = current_enabled; run_proc; run_op; run_ptr; backtrack = IntSet. empty }
210210
211- let rec explore func time state current_schedule clock last_access =
211+ type category =
212+ | Ignore
213+ | Read
214+ | Write
215+ | Read_write
216+
217+ let categorize = function
218+ | Start | Make -> Ignore
219+ | Get -> Read
220+ | Set | Exchange -> Write
221+ | CompareAndSwap | FetchAndAdd -> Read_write
222+
223+ let rec explore func time state current_schedule clock (last_read , last_write ) =
212224 let s = List. hd state in
213225 List. iter (fun proc ->
214226 let j = proc.proc_id in
215- let i = Option. bind proc.obj_ptr (fun ptr -> IntMap. find_opt ptr last_access) |> Option. value ~default: 0 in
216- if i != 0 then begin
227+ let find ptr map = match IntMap. find_opt ptr map with
228+ | None -> None
229+ | Some lst ->
230+ List. find_opt (fun (_ , proc_id ) -> proc_id <> j) lst
231+ in
232+ let i = match categorize proc.op, proc.obj_ptr with
233+ | Ignore , _ -> None
234+ | Read , Some ptr -> find ptr last_write
235+ | Write , Some ptr -> find ptr last_read
236+ | Read_write , Some ptr -> max (find ptr last_read) (find ptr last_write)
237+ | _ -> assert false
238+ in
239+ match i with
240+ | None -> ()
241+ | Some (i , _ ) ->
217242 let pre_s = List. nth state (time - i + 1 ) in
218243 if IntSet. mem j pre_s.enabled then
219244 pre_s.backtrack < - IntSet. add j pre_s.backtrack
220245 else
221246 pre_s.backtrack < - IntSet. union pre_s.backtrack pre_s.enabled
222- end
223247 ) s.procs;
224248 if IntSet. cardinal s.enabled > 0 then begin
225249 let p = IntSet. min_elt s.enabled in
@@ -244,11 +268,25 @@ let rec explore func time state current_schedule clock last_access =
244268 [new_step]
245269 end
246270 in
247- let s = do_run schedule in
248- let new_state = s :: state in
249- let new_schedule = (s .run_proc, s .run_op, s .run_ptr) :: current_schedule in
271+ let step = do_run schedule in
272+ let new_state = step :: state in
273+ let new_schedule = (step .run_proc, step .run_op, step .run_ptr) :: current_schedule in
250274 let new_time = time + 1 in
251- let new_last_access = match j_proc.obj_ptr with Some (ptr ) -> IntMap. add ptr new_time last_access | None -> last_access in
275+ let add ptr map =
276+ IntMap. update
277+ ptr
278+ (function None -> Some [time, step.run_proc]
279+ | Some steps -> Some ((time, step.run_proc) :: steps))
280+ map
281+ in
282+ let new_last_access =
283+ match categorize step.run_op, step.run_ptr with
284+ | Ignore , _ -> last_read, last_write
285+ | Read , Some ptr -> add ptr last_read, last_write
286+ | Write , Some ptr -> last_read, add ptr last_write
287+ | Read_write , Some ptr -> add ptr last_read, add ptr last_write
288+ | _ -> assert false
289+ in
252290 let new_clock = IntMap. add j new_time clock in
253291 explore func new_time new_state new_schedule new_clock new_last_access
254292 done
@@ -283,6 +321,6 @@ let trace func =
283321 setup_run func empty_schedule ;
284322 let empty_state = do_run empty_schedule :: [] in
285323 let empty_clock = IntMap. empty in
286- let empty_last_access = IntMap. empty in
324+ let empty_last_access = IntMap. empty, IntMap. empty in
287325 explore func 1 empty_state empty_schedule empty_clock empty_last_access ;
288326 Printf. printf " Finished after %i runs.\n %!" ! num_runs
0 commit comments