github.com/zebozhuang/go@v0.0.0-20200207033046-f8a98f6f5c5d/src/runtime/cgo/gcc_linux_386.c (about) 1 // Copyright 2009 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 #include <pthread.h> 6 #include <string.h> 7 #include <signal.h> 8 #include "libcgo.h" 9 #include "libcgo_unix.h" 10 11 static void *threadentry(void*); 12 static void (*setg_gcc)(void*); 13 14 // These will be set in gcc_android_386.c for android-specific customization. 15 void (*x_cgo_inittls)(void); 16 void* (*x_cgo_threadentry)(void*); 17 18 void 19 x_cgo_init(G *g, void (*setg)(void*)) 20 { 21 pthread_attr_t attr; 22 size_t size; 23 24 setg_gcc = setg; 25 pthread_attr_init(&attr); 26 pthread_attr_getstacksize(&attr, &size); 27 g->stacklo = (uintptr)&attr - size + 4096; 28 pthread_attr_destroy(&attr); 29 30 if (x_cgo_inittls) { 31 x_cgo_inittls(); 32 } 33 } 34 35 36 void 37 _cgo_sys_thread_start(ThreadStart *ts) 38 { 39 pthread_attr_t attr; 40 sigset_t ign, oset; 41 pthread_t p; 42 size_t size; 43 int err; 44 45 sigfillset(&ign); 46 pthread_sigmask(SIG_SETMASK, &ign, &oset); 47 48 // Not sure why the memset is necessary here, 49 // but without it, we get a bogus stack size 50 // out of pthread_attr_getstacksize. C'est la Linux. 51 memset(&attr, 0, sizeof attr); 52 pthread_attr_init(&attr); 53 size = 0; 54 pthread_attr_getstacksize(&attr, &size); 55 // Leave stacklo=0 and set stackhi=size; mstart will do the rest. 56 ts->g->stackhi = size; 57 err = _cgo_try_pthread_create(&p, &attr, threadentry, ts); 58 59 pthread_sigmask(SIG_SETMASK, &oset, nil); 60 61 if (err != 0) { 62 fatalf("pthread_create failed: %s", strerror(err)); 63 } 64 } 65 66 static void* 67 threadentry(void *v) 68 { 69 if (x_cgo_threadentry) { 70 return x_cgo_threadentry(v); 71 } 72 73 ThreadStart ts; 74 75 ts = *(ThreadStart*)v; 76 free(v); 77 78 /* 79 * Set specific keys. 80 */ 81 setg_gcc((void*)ts.g); 82 83 crosscall_386(ts.fn); 84 return nil; 85 }