1;;! threads = true
2
3(module $Mem
4  (memory (export "shared") 1 1 shared)
5)
6
7(thread $T1 (shared (module $Mem))
8  (register "mem" $Mem)
9  (module
10    (memory (import "mem" "shared") 1 10 shared)
11    (func (export "run")
12      (local i32)
13      (i32.atomic.load (i32.const 4))
14      (local.set 0)
15      (i32.atomic.store (i32.const 0) (i32.const 1))
16
17      ;; store results for checking
18      (i32.store (i32.const 24) (local.get 0))
19    )
20  )
21  (invoke "run")
22)
23
24(thread $T2 (shared (module $Mem))
25  (register "mem" $Mem)
26  (module
27    (memory (import "mem" "shared") 1 1 shared)
28    (func (export "run")
29      (local i32)
30      (i32.atomic.load (i32.const 0))
31      (local.set 0)
32      (i32.atomic.store (i32.const 4) (i32.const 1))
33
34      ;; store results for checking
35      (i32.store (i32.const 32) (local.get 0))
36    )
37  )
38
39  (invoke "run")
40)
41
42(wait $T1)
43(wait $T2)
44
45(module $Check
46  (memory (import "Mem" "shared") 1 1 shared)
47
48  (func (export "check") (result i32)
49    (local i32 i32)
50    (i32.load (i32.const 24))
51    (local.set 0)
52    (i32.load (i32.const 32))
53    (local.set 1)
54
55    ;; allowed results: (L_0 = 0 && L_1 = 0) || (L_0 = 0 && L_1 = 1) || (L_0 = 1 && L_1 = 0)
56
57    (i32.and (i32.eq (local.get 0) (i32.const 0)) (i32.eq (local.get 1) (i32.const 0)))
58    (i32.and (i32.eq (local.get 0) (i32.const 0)) (i32.eq (local.get 1) (i32.const 1)))
59    (i32.and (i32.eq (local.get 0) (i32.const 1)) (i32.eq (local.get 1) (i32.const 0)))
60    (i32.or)
61    (i32.or)
62    (return)
63  )
64)
65
66(assert_return (invoke $Check "check") (i32.const 1))
67