v2 / vlib / v / slow_tests / keep_args_alive_test.c.v
76 lines · 68 sloc · 1.72 KB · a87a4d73b9ab25cfff0822f4e94cf2a2d9e64323
Raw
1// vtest retry: 4
2/*
3* To verify the effect of "[keep_args_alive]", this attribute may be commented out.
4* However it is not guaranteed that then this test will fail.
5* To provoke a failure it seems to be best to use `gcc` with optimization:
6* `gcc -gc boehm -cc gcc-9 -prod test keep_args_alive_test.c.v`.
7* Without optimization, pointer variables may remain on the stack even if
8* not used any more.
9*/
10import rand
11import sync
12
13#flag -I@VEXEROOT/vlib/v/slow_tests
14#include "keep_args_alive_test_c.h"
15
16fn C.atomic_load_ptr(voidptr) voidptr
17
18fn C.atomic_store_ptr(voidptr, voidptr)
19
20@[keep_args_alive]
21fn C.calc_expr_after_delay(voidptr, i32, voidptr) i32
22
23fn set_vals() voidptr {
24 unsafe {
25 p := &int(malloc(8000000))
26 q := &int(malloc(8000000))
27 aa := p + 769345
28 *aa = -4578
29 bb := q + 572397
30 *bb = 793254
31 p = &int(0)
32 q = &int(0)
33 r := &voidptr(malloc(1000000))
34 r[456] = aa
35 r[7932] = bb
36 aa = &int(0)
37 bb = &int(0)
38 return r
39 }
40}
41
42fn tt(mut sem sync.Semaphore) int {
43 waste_mem(10000, mut sem)
44 r := &voidptr(set_vals())
45 g := unsafe { C.calc_expr_after_delay(r[456], 12, r[7932]) }
46 return g
47}
48
49fn waste_mem(n int, mut sem sync.Semaphore) {
50 mut m := []voidptr{len: 30, init: 0}
51 for j := 0; n < 0 || j < n; j++ {
52 i := rand.intn(30) or { 0 }
53 m[i] = unsafe { malloc(10000) }
54 fill := rand.intn(256) or { 0 }
55 unsafe { C.memset(m[i], fill, 10000) }
56 if n < 0 && sem.try_wait() {
57 break
58 }
59 }
60}
61
62fn test_keep_args_alive_attribute() {
63 mut sem := sync.new_semaphore()
64 $if gcboehm ? {
65 spawn waste_mem(-1, mut sem)
66 spawn waste_mem(-1, mut sem)
67 waste_mem(10000, mut sem)
68 }
69 r := &voidptr(set_vals())
70 v := unsafe { C.calc_expr_after_delay(r[456], 12, r[7932]) }
71 $if gcboehm ? {
72 sem.post()
73 sem.post()
74 }
75 assert v == 738318
76}
77