github.com/aloncn/graphics-go@v0.0.1/src/runtime/cgo/gcc_freebsd_arm.c (about) 1 // Copyright 2012 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 // +build cgo 6 7 #include <sys/types.h> 8 #include <machine/sysarch.h> 9 #include <sys/signalvar.h> 10 #include <pthread.h> 11 #include <signal.h> 12 #include <string.h> 13 #include "libcgo.h" 14 15 #ifdef ARM_TP_ADDRESS 16 // ARM_TP_ADDRESS is (ARM_VECTORS_HIGH + 0x1000) or 0xffff1000 17 // and is known to runtime.read_tls_fallback. Verify it with 18 // cpp. 19 #if ARM_TP_ADDRESS != 0xffff1000 20 #error Wrong ARM_TP_ADDRESS! 21 #endif 22 #endif 23 24 static void *threadentry(void*); 25 26 static void (*setg_gcc)(void*); 27 28 void 29 x_cgo_init(G *g, void (*setg)(void*)) 30 { 31 pthread_attr_t attr; 32 size_t size; 33 34 setg_gcc = setg; 35 pthread_attr_init(&attr); 36 pthread_attr_getstacksize(&attr, &size); 37 g->stacklo = (uintptr)&attr - size + 4096; 38 pthread_attr_destroy(&attr); 39 } 40 41 42 void 43 _cgo_sys_thread_start(ThreadStart *ts) 44 { 45 pthread_attr_t attr; 46 sigset_t ign, oset; 47 pthread_t p; 48 size_t size; 49 int err; 50 51 SIGFILLSET(ign); 52 pthread_sigmask(SIG_SETMASK, &ign, &oset); 53 54 // Not sure why the memset is necessary here, 55 // but without it, we get a bogus stack size 56 // out of pthread_attr_getstacksize. C'est la Linux. 57 memset(&attr, 0, sizeof attr); 58 pthread_attr_init(&attr); 59 size = 0; 60 pthread_attr_getstacksize(&attr, &size); 61 // Leave stacklo=0 and set stackhi=size; mstack will do the rest. 62 ts->g->stackhi = size; 63 err = pthread_create(&p, &attr, threadentry, ts); 64 65 pthread_sigmask(SIG_SETMASK, &oset, nil); 66 67 if (err != 0) { 68 fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err)); 69 abort(); 70 } 71 } 72 73 extern void crosscall_arm1(void (*fn)(void), void (*setg_gcc)(void*), void *g); 74 static void* 75 threadentry(void *v) 76 { 77 ThreadStart ts; 78 79 ts = *(ThreadStart*)v; 80 free(v); 81 82 crosscall_arm1(ts.fn, setg_gcc, (void*)ts.g); 83 return nil; 84 }