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