v2 / vlib / v / tests / concurrency / shared_unordered_mixed_test.v
89 lines · 85 sloc · 1.51 KB · 6488041a749df9762348d019c4223908c476f2e2
Raw
1// integer values from -2^191 .. 2^191-1
2struct Large {
3mut:
4 l u64
5 m u64
6 h u64
7}
8
9fn (a Large) clone() Large {
10 r := Large{
11 l: a.l
12 m: a.m
13 h: a.h
14 }
15 return r
16}
17
18fn (mut a Large) add(b Large) {
19 oldl := a.l
20 a.l += b.l
21 oldm := a.m
22 if a.l < oldl {
23 a.m++
24 }
25 a.m += b.m
26 if a.m < oldm || (a.l < oldl && a.m <= oldm) {
27 a.h++
28 }
29 a.h += b.h
30}
31
32fn doub_large(shared a Large, shared b Large, shared c Large, shared d Large, shared e Large) {
33 for _ in 0 .. 50 {
34 lock a, b; rlock c, d, e {
35 // double the sum by adding all objects to a or b
36 old_a := a.clone()
37 a.add(b)
38 b.add(old_a)
39 a.add(c)
40 b.add(d)
41 a.add(e)
42 }
43 }
44}
45
46fn test_mixed_order_lock_rlock() {
47 // initialize objects so that their sum = 1
48 shared a := Large{
49 l: 4
50 }
51 shared b := Large{
52 l: u64(-7)
53 m: u64(-1)
54 h: u64(-1)
55 }
56 shared c := Large{
57 l: 17
58 }
59 shared d := Large{
60 l: u64(-11)
61 m: u64(-1)
62 h: u64(-1)
63 }
64 shared e := Large{
65 l: u64(-2)
66 m: u64(-1)
67 h: u64(-1)
68 }
69 // spawn 3 threads for doubling with different orders of objects
70 t1 := spawn doub_large(shared a, shared b, shared c, shared d, shared e)
71 t2 := spawn doub_large(shared e, shared b, shared a, shared c, shared d)
72 t3 := spawn doub_large(shared b, shared a, shared e, shared d, shared c)
73 t1.wait()
74 t2.wait()
75 t3.wait()
76 // calculate the sum after 3*50 doublings
77 mut sum := Large{}
78 rlock a, b, c, d, e {
79 sum.add(a)
80 sum.add(b)
81 sum.add(c)
82 sum.add(d)
83 sum.add(e)
84 }
85 // the sum should be 2^150
86 assert sum.l == 0
87 assert sum.m == 0
88 assert sum.h == 4194304
89}
90