v2 / vlib / v / tests / concurrency / spawn_ref_arg_stack_escape_test.v
53 lines · 48 sloc · 1.29 KB · fc6d5cd12ed7fd580ef8d19e49885e98d59b25be
Raw
1struct SpawnRefArgStackValue {
2 conn int
3}
4
5struct SpawnRefReceiverStackValue {
6 conn int
7}
8
9fn read_spawned_value(v &SpawnRefArgStackValue, expected int, start chan int) bool {
10 _ := <-start or { return false }
11 return v.conn == expected
12}
13
14fn (v &SpawnRefReceiverStackValue) read_after_start(expected int, start chan int) bool {
15 _ := <-start or { return false }
16 return v.conn == expected
17}
18
19fn test_spawn_ref_arg_from_stack_is_auto_heap_promoted() {
20 thread_count := 64
21 start := chan int{cap: thread_count}
22 mut threads := []thread bool{cap: thread_count}
23 for i in 0 .. thread_count {
24 value := SpawnRefArgStackValue{
25 conn: i
26 }
27 threads << spawn read_spawned_value(&value, i, start)
28 }
29 for _ in 0 .. thread_count {
30 start <- 1
31 }
32 for i, th in threads {
33 assert th.wait(), 'spawned thread ${i} observed a reused stack value'
34 }
35}
36
37fn test_spawn_ref_receiver_from_stack_is_auto_heap_promoted() {
38 thread_count := 64
39 start := chan int{cap: thread_count}
40 mut threads := []thread bool{cap: thread_count}
41 for i in 0 .. thread_count {
42 value := SpawnRefReceiverStackValue{
43 conn: i
44 }
45 threads << spawn (&value).read_after_start(i, start)
46 }
47 for _ in 0 .. thread_count {
48 start <- 1
49 }
50 for i, th in threads {
51 assert th.wait(), 'spawned method receiver ${i} observed a reused stack value'
52 }
53}
54