...
1// Copyright 2016 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// The C definitions for tracebackctxt.go. That file uses //export so
6// it can't put function definitions in the "C" import comment.
7
8#include <stdlib.h>
9#include <stdint.h>
10
11// Functions exported from Go.
12extern void G1(void);
13extern void G2(void);
14extern void TracebackContextPreemptionGoFunction(int);
15extern void TracebackContextProfileGoFunction(void);
16
17void C1() {
18 G1();
19}
20
21void C2() {
22 G2();
23}
24
25struct cgoContextArg {
26 uintptr_t context;
27};
28
29struct cgoTracebackArg {
30 uintptr_t context;
31 uintptr_t sigContext;
32 uintptr_t* buf;
33 uintptr_t max;
34};
35
36struct cgoSymbolizerArg {
37 uintptr_t pc;
38 const char* file;
39 uintptr_t lineno;
40 const char* func;
41 uintptr_t entry;
42 uintptr_t more;
43 uintptr_t data;
44};
45
46// Uses atomic adds and subtracts to catch the possibility of
47// erroneous calls from multiple threads; that should be impossible in
48// this test case, but we check just in case.
49static int contextCount;
50
51int getContextCount() {
52 return __sync_add_and_fetch(&contextCount, 0);
53}
54
55void tcContext(void* parg) {
56 struct cgoContextArg* arg = (struct cgoContextArg*)(parg);
57 if (arg->context == 0) {
58 arg->context = __sync_add_and_fetch(&contextCount, 1);
59 } else {
60 if (arg->context != __sync_add_and_fetch(&contextCount, 0)) {
61 abort();
62 }
63 __sync_sub_and_fetch(&contextCount, 1);
64 }
65}
66
67void tcContextSimple(void* parg) {
68 struct cgoContextArg* arg = (struct cgoContextArg*)(parg);
69 if (arg->context == 0) {
70 arg->context = 1;
71 }
72}
73
74void tcTraceback(void* parg) {
75 int base, i;
76 struct cgoTracebackArg* arg = (struct cgoTracebackArg*)(parg);
77 if (arg->context == 0 && arg->sigContext == 0) {
78 // This shouldn't happen in this program.
79 abort();
80 }
81 // Return a variable number of PC values.
82 base = arg->context << 8;
83 for (i = 0; i < arg->context; i++) {
84 if (i < arg->max) {
85 arg->buf[i] = base + i;
86 }
87 }
88}
89
90void tcSymbolizer(void *parg) {
91 struct cgoSymbolizerArg* arg = (struct cgoSymbolizerArg*)(parg);
92 if (arg->pc == 0) {
93 return;
94 }
95 // Report two lines per PC returned by traceback, to test more handling.
96 arg->more = arg->file == NULL;
97 arg->file = "tracebackctxt.go";
98 arg->func = "cFunction";
99 arg->lineno = arg->pc + (arg->more << 16);
100}
101
102void TracebackContextPreemptionCallGo(int i) {
103 TracebackContextPreemptionGoFunction(i);
104}
105
106void TracebackContextProfileCallGo(void) {
107 TracebackContextProfileGoFunction();
108}
View as plain text