Skip to content

Commit e3fd82b

Browse files
committed
Add a new test (tests/parallel/churn.ml) stressing cross-domain promotion
(cherry picked from commit 2368930)
1 parent 8353c5a commit e3fd82b

File tree

2 files changed

+70
-0
lines changed

2 files changed

+70
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
(* TEST
2+
runtime5;
3+
{ bytecode; }
4+
{ native; }
5+
*)
6+
7+
type t = {
8+
sender: int;
9+
code: int;
10+
msgsize: int;
11+
message: int array;
12+
}
13+
14+
let size = 20_000
15+
let table = Array.init size (fun _ -> Atomic.make None)
16+
let go = Atomic.make true
17+
let log = false
18+
19+
let run me msgsize iters =
20+
(* domain 0 keeps a bunch of extra local data,
21+
to unbalance sweeping loads *)
22+
let kept = ref [] in
23+
if me = 0 then kept := [Array.init 10000 ref];
24+
let count = ref iters in
25+
let from0 = ref 0 in
26+
while !count > 0 && Atomic.get go do
27+
ignore (Sys.opaque_identity (ref []));
28+
let slot = Random.int size in
29+
match Atomic.get table.(slot) with
30+
| None as prev ->
31+
let code = Random.bits () in
32+
let msg = {sender = me; code; msgsize; message = Array.make msgsize code} in
33+
if me = 0 then kept := Array.init 5 ref :: !kept;
34+
(* pointless string formatting to create minor garbage *)
35+
let dbg =
36+
Printf.sprintf "[%d]: %03d: %d %08x --->\n" me slot msg.msgsize msg.code in
37+
if Sys.opaque_identity log then print_string dbg;
38+
if Atomic.compare_and_set table.(slot) prev (Some msg) then
39+
decr count
40+
| Some msg as prev when
41+
msg.sender <> me &&
42+
Atomic.compare_and_set table.(slot) prev None ->
43+
44+
let dbg = Printf.sprintf "[%d]: ---> %03d: %d %08x\n" me slot msg.msgsize msg.code in
45+
if Sys.opaque_identity log then print_string dbg;
46+
assert (Array.length msg.message = msg.msgsize);
47+
for i = 0 to msg.msgsize - 1 do
48+
assert (msg.message.(i) = msg.code)
49+
done;
50+
if msg.sender = 0 then incr from0;
51+
| Some _ -> ()
52+
done;
53+
ignore (Sys.opaque_identity !kept);
54+
!from0
55+
56+
let () =
57+
let iters = 200_000 in
58+
let d1 = Domain.spawn (fun () -> run 1 100 max_int) in
59+
let d2 = Domain.spawn (fun () -> run 2 5 max_int) in
60+
let recv_local = run 0 20 iters in
61+
assert (recv_local = 0);
62+
Atomic.set go false;
63+
let r = Domain.join d1 + Domain.join d2 in
64+
let remaining =
65+
table
66+
|> Array.to_list
67+
|> List.filter (fun x -> match Atomic.get x with Some {sender=0; _} -> true | _ -> false)
68+
|> List.length in
69+
Printf.printf "%d\n" (r+remaining)
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
200000

0 commit comments

Comments
 (0)