@@ -60,66 +60,60 @@ struct
6060 let barriers = possible_vinfos ask barrier in
6161 let mhp = MHP. current ask in
6262 let handle_one b =
63- let locks = man.ask (Queries. MustLockset ) in
64- man.sideg b (Multiprocess. bot () , Capacity. bot () , Waiters. singleton (mhp, locks));
65- let addr = ValueDomain.Addr. of_var b in
66- let (multiprocess,capacity, waiters) = man.global b in
67- let may_run, must =
63+ try
64+ let locks = man.ask (Queries. MustLockset ) in
65+ man.sideg b (Multiprocess. bot () , Capacity. bot () , Waiters. singleton (mhp, locks));
66+ let addr = ValueDomain.Addr. of_var b in
67+ let (multiprocess, capacity, waiters) = man.global b in
68+ let may = Barriers. add addr may in
6869 if multiprocess then
69- true , must
70+ (may , must)
7071 else
71- let relevant_waiters = Waiters. filter (fun other -> MHPplusLock. mhp (mhp, locks) other) waiters in
72+ let relevant_waiters = Waiters. filter (fun other -> MHPplusLock. mhp (mhp, locks) other) waiters in
7273 if Waiters. exists MHPplusLock. may_be_non_unique_thread relevant_waiters then
73- true , must
74+ (may , must)
7475 else
75- let count = Waiters. cardinal relevant_waiters in
7676 match capacity with
77+ | `Top | `Bot -> (may, must)
7778 | `Lifted c ->
79+ let count = Waiters. cardinal relevant_waiters in
7880 (* Add 1 as the thread calling wait at the moment will not be MHP with itself *)
7981 let min_cap = (BatOption. default Z. zero (Capacity.I. minimal c)) in
8082 if Z. leq min_cap Z. one then
81- true , must
83+ (may , must)
8284 else if Z. geq (Z. of_int (count + 1 )) min_cap then
8385 (* This is quite a cute problem: Do (min_cap-1) elements exist in the set such that
84- MHP is pairwise true? This solution is a sledgehammer, there should be something much
85- better algorithmically (beyond just laziness) *)
86- (
86+ MHP is pairwise true? This solution is a sledgehammer, there should be something much
87+ better algorithmically (beyond just laziness) *)
88+ let must =
8789 let waiters = Waiters. elements relevant_waiters in
8890 let min_cap = Z. to_int min_cap in
8991 let lists = List. init (min_cap - 1 ) (fun _ -> waiters) in
9092 let candidates = BatList. n_cartesian_product lists in
91- let pred = List. exists (fun candidate ->
93+ let can_proceed = List. exists (fun candidate ->
9294 let rec do_it = function
9395 | [] -> true
9496 | x ::xs -> List. for_all (fun y -> MHPplusLock. mhp x y) xs && do_it xs
9597 in
9698 do_it candidate
9799 ) candidates
98100 in
99- if pred then
100- (* limit to this case to avoid having to construct all permutations above *)
101- let must = if (List. length waiters) = min_cap-1 then
102- List. fold_left (fun acc elem ->
103- let tid = MHPplusLock. tid elem in
104- let curr = MustObserved. find tid acc in
105- let must' = MustObserved. add tid (Barriers. add addr curr) acc in
106- must'
107- ) must waiters
108- else
109- must
110- in
111- true , must
112- else
113- false , must
114- )
101+ if not can_proceed then raise Analyses. Deadcode ;
102+ (* limit to this case to avoid having to construct all permutations above *)
103+ if List. length waiters = min_cap - 1 then
104+ List. fold_left (fun acc elem ->
105+ let tid = MHPplusLock. tid elem in
106+ let curr = MustObserved. find tid acc in
107+ let must' = MustObserved. add tid (Barriers. add addr curr) acc in
108+ must'
109+ ) must waiters
110+ else
111+ must
112+ in
113+ (may, must)
115114 else
116- false , must
117- | _ -> true , must
118- in
119- if may_run then
120- (Barriers. add addr may, must)
121- else
122- D. bot ()
115+ raise Analyses. Deadcode ;
116+ with Analyses. Deadcode -> D. bot ()
123117 in
124118 let (may, must) = List. fold_left (fun acc b -> D. join acc (handle_one b)) (D. bot () ) barriers in
125119 if Barriers. is_empty may then raise Analyses. Deadcode ;
0 commit comments