1
2
3
4
5
6
7
8 package main
9
10
29 import "C"
30
31 import (
32 "fmt"
33 "os"
34 "runtime"
35 "sync/atomic"
36 _ "unsafe"
37 )
38
39 func init() {
40 register("CgoCallbackGC", CgoCallbackGC)
41 }
42
43
44 func go_callback() {
45 if e := extraMInUse.Load(); e == 0 {
46 fmt.Printf("in callback extraMInUse got %d want >0\n", e)
47 os.Exit(1)
48 }
49
50 runtime.GC()
51 grow()
52 runtime.GC()
53 }
54
55 var cnt int
56
57 func grow() {
58 x := 10000
59 sum := 0
60 if grow1(&x, &sum) == 0 {
61 panic("bad")
62 }
63 }
64
65 func grow1(x, sum *int) int {
66 if *x == 0 {
67 return *sum + 1
68 }
69 *x--
70 sum1 := *sum + *x
71 return grow1(x, &sum1)
72 }
73
74 func CgoCallbackGC() {
75 P := 100
76 if os.Getenv("RUNTIME_TEST_SHORT") != "" {
77 P = 10
78 }
79
80 if e := extraMInUse.Load(); e != 0 {
81 fmt.Printf("before testing extraMInUse got %d want 0\n", e)
82 os.Exit(1)
83 }
84
85 done := make(chan bool)
86
87 for i := 0; i < P; i++ {
88 go func() {
89 grow()
90 done <- true
91 }()
92 }
93 for i := 0; i < P; i++ {
94 <-done
95 }
96
97 for i := 0; i < P; i++ {
98 go func() {
99 C.foo()
100 done <- true
101 }()
102 }
103 for i := 0; i < P; i++ {
104 <-done
105 }
106
107 if e := extraMInUse.Load(); e != 0 {
108 fmt.Printf("after testing extraMInUse got %d want 0\n", e)
109 os.Exit(1)
110 }
111
112 fmt.Printf("OK\n")
113 }
114
115
116 var extraMInUse atomic.Uint32
117
View as plain text