...

Text file src/runtime/testdata/testprogcgo/tracebackctxt_c.c

Documentation: runtime/testdata/testprogcgo

     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