]> Cypherpunks.ru repositories - gostls13.git/blob - src/runtime/testdata/testprogcgo/cgonoescape.go
056be44889b26405c3fd3dfd32fdc7e99d87b53a
[gostls13.git] / src / runtime / testdata / testprogcgo / cgonoescape.go
1 // Copyright 2023 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package main
6
7 // #cgo noescape annotations for a C function means its arguments won't escape to heap.
8
9 // We assume that there won't be 100 new allocated heap objects in other places,
10 // i.e. runtime.ReadMemStats or other runtime background works.
11 // So, the tests are:
12 // 1. at least 100 new allocated heap objects after invoking withoutNoEscape 100 times.
13 // 2. less than 100 new allocated heap objects after invoking withoutNoEscape 100 times.
14
15 /*
16 #cgo noescape runCWithNoEscape
17
18 void runCWithNoEscape(void *p) {
19 }
20 void runCWithoutNoEscape(void *p) {
21 }
22 */
23 import "C"
24
25 import (
26         "fmt"
27         "runtime"
28         "runtime/debug"
29         "unsafe"
30 )
31
32 const num = 100
33
34 func init() {
35         register("CgoNoEscape", CgoNoEscape)
36 }
37
38 //go:noinline
39 func withNoEscape() {
40         var str string
41         C.runCWithNoEscape(unsafe.Pointer(&str))
42 }
43
44 //go:noinline
45 func withoutNoEscape() {
46         var str string
47         C.runCWithoutNoEscape(unsafe.Pointer(&str))
48 }
49
50 func CgoNoEscape() {
51         // make GC stop to see the heap objects allocated
52         debug.SetGCPercent(-1)
53
54         var stats runtime.MemStats
55         runtime.ReadMemStats(&stats)
56         preHeapObjects := stats.HeapObjects
57
58         for i := 0; i < num; i++ {
59                 withNoEscape()
60         }
61
62         runtime.ReadMemStats(&stats)
63         nowHeapObjects := stats.HeapObjects
64
65         if nowHeapObjects-preHeapObjects >= num {
66                 fmt.Printf("too many heap objects allocated, pre: %v, now: %v\n", preHeapObjects, nowHeapObjects)
67         }
68
69         runtime.ReadMemStats(&stats)
70         preHeapObjects = stats.HeapObjects
71
72         for i := 0; i < num; i++ {
73                 withoutNoEscape()
74         }
75
76         runtime.ReadMemStats(&stats)
77         nowHeapObjects = stats.HeapObjects
78
79         if nowHeapObjects-preHeapObjects < num {
80                 fmt.Printf("too few heap objects allocated, pre: %v, now: %v\n", preHeapObjects, nowHeapObjects)
81         }
82
83         fmt.Println("OK")
84 }