github.com/lovishpuri/go-40569/src@v0.0.0-20230519171745-f8623e7c56cf/runtime/testdata/testprogcgo/tracebackctxt_c.c (about) 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. 12 extern void G1(void); 13 extern void G2(void); 14 extern void TracebackContextPreemptionGoFunction(int); 15 16 void C1() { 17 G1(); 18 } 19 20 void C2() { 21 G2(); 22 } 23 24 struct cgoContextArg { 25 uintptr_t context; 26 }; 27 28 struct cgoTracebackArg { 29 uintptr_t context; 30 uintptr_t sigContext; 31 uintptr_t* buf; 32 uintptr_t max; 33 }; 34 35 struct 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. 48 static int contextCount; 49 50 int getContextCount() { 51 return __sync_add_and_fetch(&contextCount, 0); 52 } 53 54 void 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 66 void tcContextSimple(void* parg) { 67 struct cgoContextArg* arg = (struct cgoContextArg*)(parg); 68 if (arg->context == 0) { 69 arg->context = 1; 70 } 71 } 72 73 void 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 89 void 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 101 void TracebackContextPreemptionCallGo(int i) { 102 TracebackContextPreemptionGoFunction(i); 103 }