...

Text file src/runtime/cgo/gcc_linux_386.c

     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	// This will be set in gcc_android.c for android-specific customization.
    15	void (*x_cgo_inittls)(void **tlsg, void **tlsbase);
    16	
    17	void
    18	x_cgo_init(G *g, void (*setg)(void*), void **tlsg, void **tlsbase)
    19	{
    20		pthread_attr_t attr;
    21		size_t size;
    22	
    23		setg_gcc = setg;
    24		pthread_attr_init(&attr);
    25		pthread_attr_getstacksize(&attr, &size);
    26		g->stacklo = (uintptr)&attr - size + 4096;
    27		pthread_attr_destroy(&attr);
    28	
    29		if (x_cgo_inittls) {
    30			x_cgo_inittls(tlsg, tlsbase);
    31		}
    32	}
    33	
    34	void
    35	_cgo_sys_thread_start(ThreadStart *ts)
    36	{
    37		pthread_attr_t attr;
    38		sigset_t ign, oset;
    39		pthread_t p;
    40		size_t size;
    41		int err;
    42	
    43		sigfillset(&ign);
    44		pthread_sigmask(SIG_SETMASK, &ign, &oset);
    45	
    46		// Not sure why the memset is necessary here,
    47		// but without it, we get a bogus stack size
    48		// out of pthread_attr_getstacksize. C'est la Linux.
    49		memset(&attr, 0, sizeof attr);
    50		pthread_attr_init(&attr);
    51		size = 0;
    52		pthread_attr_getstacksize(&attr, &size);
    53		// Leave stacklo=0 and set stackhi=size; mstart will do the rest.
    54		ts->g->stackhi = size;
    55		err = _cgo_try_pthread_create(&p, &attr, threadentry, ts);
    56	
    57		pthread_sigmask(SIG_SETMASK, &oset, nil);
    58	
    59		if (err != 0) {
    60			fatalf("pthread_create failed: %s", strerror(err));
    61		}
    62	}
    63	
    64	static void*
    65	threadentry(void *v)
    66	{
    67		ThreadStart ts;
    68	
    69		ts = *(ThreadStart*)v;
    70		free(v);
    71	
    72		/*
    73		 * Set specific keys.
    74		 */
    75		setg_gcc((void*)ts.g);
    76	
    77		crosscall_386(ts.fn);
    78		return nil;
    79	}

View as plain text