v / vlib / sync / channel_select_6_test.v
77 lines · 71 sloc · 1.84 KB · 99be39cbd15d4bbb5ab14d2f870199908c00bc8d
Raw
1// vtest retry: 5
2
3// This test case runs concurrent 3 instances of `do_select` that
4// communicate with 6 other threads doing send and receive operations.
5// There are buffered and unbuffered channels - handled by one or two
6// concurrend threads on the other side
7
8fn do_select(ch1 chan int, ch2 chan int, chf1 chan f64, chf2 chan f64, sumch1 chan i64, sumch2 chan i64) {
9 mut sum1 := i64(0)
10 mut sum2 := i64(0)
11 f1 := 17.0
12 f2 := 7.0
13 for _ in 0 .. 20000 + chf1.cap / 3 {
14 select {
15 chf1 <- f1 {}
16 i := <-ch1 {
17 sum1 += i
18 }
19 j := <-ch2 {
20 sum2 += j
21 }
22 chf2 <- f2 {}
23 }
24 }
25 sumch1 <- sum1
26 sumch2 <- sum2
27}
28
29fn do_send_int(ch chan int, factor int) {
30 for i in 0 .. 10000 {
31 ch <- (i * factor)
32 }
33}
34
35fn do_rec_f64(ch chan f64, sumch chan f64) {
36 mut sum := 0.0
37 for _ in 0 .. 10000 {
38 sum += <-ch
39 }
40 sumch <- sum
41}
42
43fn test_select() {
44 ch1 := chan int{cap: 3}
45 ch2 := chan int{}
46 // buffer length of chf1 mus be multiple of 3 (# select threads)
47 chf1 := chan f64{cap: 30}
48 chf2 := chan f64{}
49 chsum1 := chan i64{}
50 chsum2 := chan i64{}
51 chsumf1 := chan f64{}
52 chsumf2 := chan f64{}
53 spawn do_send_int(ch1, 3)
54 spawn do_select(ch1, ch2, chf1, chf2, chsum1, chsum2)
55 spawn do_rec_f64(chf1, chsumf1)
56 spawn do_rec_f64(chf2, chsumf2)
57 spawn do_rec_f64(chf2, chsumf2)
58 spawn do_select(ch1, ch2, chf1, chf2, chsum1, chsum2)
59 spawn do_send_int(ch2, 7)
60 spawn do_send_int(ch2, 17)
61 spawn do_select(ch1, ch2, chf1, chf2, chsum1, chsum2)
62
63 sum1 := <-chsum1 + <-chsum1 + <-chsum1
64 sum2 := <-chsum2 + <-chsum2 + <-chsum2
65 mut sumf1 := <-chsumf1
66 // empty channel buffer
67 for _ in 0 .. chf1.cap {
68 sumf1 += <-chf1
69 }
70 sumf2 := <-chsumf2 + <-chsumf2
71 // Use Gauß' formula
72 expected_sum := i64(10000) * (10000 - 1) / 2
73 assert sum1 == 3 * expected_sum
74 assert sum2 == (7 + 17) * expected_sum
75 assert sumf1 == 17.0 * f64(10000 + chf1.cap)
76 assert sumf2 == 7.0 * 20000
77}
78