@@ -148,62 +148,129 @@ let test_set () =
148148
149149(* *)
150150
151- let test_casn () =
152- let barrier = Barrier. make 3 in
153- let test_finished = Atomic. make false in
151+ let test_no_skew () =
152+ [ Mode. obstruction_free; Mode. lock_free ]
153+ |> List. iter @@ fun mode ->
154+ let barrier = Barrier. make 3 in
155+ let test_finished = Atomic. make false in
154156
155- let a1 = Loc. make 0 in
156- let a2 = Loc. make 0 in
157+ let a1 = Loc. make ~mode 0 in
158+ let a2 = Loc. make ~mode 0 in
157159
158- let thread1 () =
159- let c1 = [ Op. make_cas a1 0 1 ; Op. make_cas a2 0 1 ] in
160- let c2 = [ Op. make_cas a1 1 0 ; Op. make_cas a2 1 0 ] in
160+ let thread1 () =
161+ let c1 = [ Op. make_cas a1 0 1 ; Op. make_cas a2 0 1 ] in
162+ let c2 = [ Op. make_cas a1 1 0 ; Op. make_cas a2 1 0 ] in
161163
162- Barrier. await barrier;
164+ Barrier. await barrier;
163165
164- for _ = 1 to nb_iter do
165- assert_kcas a1 0 ;
166- assert_kcas a2 0 ;
166+ for _ = 1 to nb_iter do
167+ assert_kcas a1 0 ;
168+ assert_kcas a2 0 ;
167169
168- let out1 = Op. atomically c1 in
169- assert out1;
170+ let out1 = Op. atomically c1 in
171+ assert out1;
170172
171- assert_kcas a1 1 ;
172- assert_kcas a2 1 ;
173+ assert_kcas a1 1 ;
174+ assert_kcas a2 1 ;
173175
174- let out2 = Op. atomically c2 in
175- assert out2
176- done ;
177- Atomic. set test_finished true
178- and thread2 () =
179- let c1 = [ Op. make_cas a1 1 0 ; Op. make_cas a2 0 1 ] in
180- let c2 = [ Op. make_cas a1 0 1 ; Op. make_cas a2 1 0 ] in
176+ let out2 = Op. atomically c2 in
177+ assert out2
178+ done ;
179+ Atomic. set test_finished true
180+ and thread2 () =
181+ let c1 = [ Op. make_cas a1 1 0 ; Op. make_cas a2 0 1 ] in
182+ let c2 = [ Op. make_cas a1 0 1 ; Op. make_cas a2 1 0 ] in
181183
182- Barrier. await barrier;
184+ Barrier. await barrier;
183185
184- while not (Atomic. get test_finished) do
185- let out1 = Op. atomically c1 in
186- let out2 = Op. atomically c2 in
187- assert (not out1);
188- assert (not out2);
189- if is_single then Domain. cpu_relax ()
190- done
191- and thread3 () =
192- let c1 = [ Op. make_cas a1 0 1 ; Op. make_cas a2 1 0 ] in
193- let c2 = [ Op. make_cas a1 1 0 ; Op. make_cas a2 0 1 ] in
186+ while not (Atomic. get test_finished) do
187+ let out1 = Op. atomically c1 in
188+ let out2 = Op. atomically c2 in
189+ assert (not out1);
190+ assert (not out2);
191+ if is_single then Domain. cpu_relax ()
192+ done
193+ and thread3 () =
194+ let c1 = [ Op. make_cas a1 0 1 ; Op. make_cas a2 1 0 ] in
195+ let c2 = [ Op. make_cas a1 1 0 ; Op. make_cas a2 0 1 ] in
194196
195- Barrier. await barrier;
197+ Barrier. await barrier;
196198
197- while not (Atomic. get test_finished) do
198- let out1 = Op. atomically c1 in
199- let out2 = Op. atomically c2 in
200- assert (not out1);
201- assert (not out2);
202- if is_single then Domain. cpu_relax ()
203- done
204- in
199+ while not (Atomic. get test_finished) do
200+ let out1 = Op. atomically c1 in
201+ let out2 = Op. atomically c2 in
202+ assert (not out1);
203+ assert (not out2);
204+ if is_single then Domain. cpu_relax ()
205+ done
206+ in
207+
208+ run_domains [ thread1; thread2; thread3 ]
209+
210+ (* *)
211+
212+ let test_no_skew_xt () =
213+ [ Mode. obstruction_free; Mode. lock_free ]
214+ |> List. iter @@ fun mode ->
215+ let barrier = Barrier. make 3 in
216+ let test_finished = Atomic. make false in
217+
218+ let a1 = Loc. make ~mode 0 in
219+ let a2 = Loc. make ~mode 0 in
220+
221+ let thread1 () =
222+ let c1 ~xt =
223+ Xt. compare_and_set ~xt a1 0 1 && Xt. compare_and_set ~xt a2 0 1
224+ in
225+ let c2 ~xt =
226+ Xt. compare_and_set ~xt a1 1 0 && Xt. compare_and_set ~xt a2 1 0
227+ in
228+
229+ Barrier. await barrier;
230+
231+ for _ = 1 to nb_iter do
232+ assert_kcas a1 0 ;
233+ assert_kcas a2 0 ;
234+
235+ let out1 = Xt. commit { tx = c1 } in
236+ assert out1;
237+
238+ assert_kcas a1 1 ;
239+ assert_kcas a2 1 ;
240+
241+ let out2 = Xt. commit { tx = c2 } in
242+ assert out2
243+ done ;
244+ Atomic. set test_finished true
245+ and thread2 () =
246+ let c1 ~xt = Xt. get ~xt a1 == 0 && Xt. get ~xt a2 == 1 in
247+ let c2 ~xt = Xt. get ~xt a2 == 1 && Xt. get ~xt a2 == 0 in
248+
249+ Barrier. await barrier;
250+
251+ while not (Atomic. get test_finished) do
252+ let out1 = Xt. commit { tx = c1 } in
253+ let out2 = Xt. commit { tx = c2 } in
254+ assert (not out1);
255+ assert (not out2);
256+ if is_single then Domain. cpu_relax ()
257+ done
258+ and thread3 () =
259+ let c1 ~xt = Xt. get ~xt a1 == 1 && Xt. get ~xt a2 == 0 in
260+ let c2 ~xt = Xt. get ~xt a2 == 0 && Xt. get ~xt a2 == 1 in
261+
262+ Barrier. await barrier;
263+
264+ while not (Atomic. get test_finished) do
265+ let out1 = Xt. commit { tx = c1 } in
266+ let out2 = Xt. commit { tx = c2 } in
267+ assert (not out1);
268+ assert (not out2);
269+ if is_single then Domain. cpu_relax ()
270+ done
271+ in
205272
206- run_domains [ thread1; thread2; thread3 ]
273+ run_domains [ thread1; thread2; thread3 ]
207274
208275(* *)
209276
@@ -705,7 +772,8 @@ let () =
705772 ( " non linearizable xt" ,
706773 [ Alcotest. test_case " " `Quick test_non_linearizable_xt ] );
707774 (" set" , [ Alcotest. test_case " " `Quick test_set ]);
708- (" casn" , [ Alcotest. test_case " " `Quick test_casn ]);
775+ (" no skew" , [ Alcotest. test_case " " `Quick test_no_skew ]);
776+ (" no skew xt" , [ Alcotest. test_case " " `Quick test_no_skew_xt ]);
709777 (" read casn" , [ Alcotest. test_case " " `Quick test_read_casn ]);
710778 ( " stress" ,
711779 [
0 commit comments