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 11static void *threadentry(void*); 12static void (*setg_gcc)(void*); 13 14// These will be set in gcc_android_386.c for android-specific customization. 15void (*x_cgo_inittls)(void); 16void* (*x_cgo_threadentry)(void*); 17 18void 19x_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 36void 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; mstack 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 66static void* 67threadentry(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} 86