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 <sys/types.h>
6#include <sys/signalvar.h>
7#include <pthread.h>
8#include <signal.h>
9#include <string.h>
10#include "libcgo.h"
11#include "libcgo_unix.h"
12
13static void* threadentry(void*);
14static void (*setg_gcc)(void*);
15
16void
17x_cgo_init(G *g, void (*setg)(void*))
18{
19	pthread_attr_t attr;
20	size_t size;
21
22	setg_gcc = setg;
23	pthread_attr_init(&attr);
24	pthread_attr_getstacksize(&attr, &size);
25	g->stacklo = (uintptr)&attr - size + 4096;
26	pthread_attr_destroy(&attr);
27}
28
29void
30_cgo_sys_thread_start(ThreadStart *ts)
31{
32	pthread_attr_t attr;
33	sigset_t ign, oset;
34	pthread_t p;
35	size_t size;
36	int err;
37
38	SIGFILLSET(ign);
39	pthread_sigmask(SIG_SETMASK, &ign, &oset);
40
41	pthread_attr_init(&attr);
42	pthread_attr_getstacksize(&attr, &size);
43
44	// Leave stacklo=0 and set stackhi=size; mstart will do the rest.
45	ts->g->stackhi = size;
46	err = _cgo_try_pthread_create(&p, &attr, threadentry, ts);
47
48	pthread_sigmask(SIG_SETMASK, &oset, nil);
49
50	if (err != 0) {
51		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
52		abort();
53	}
54}
55
56static void*
57threadentry(void *v)
58{
59	ThreadStart ts;
60
61	ts = *(ThreadStart*)v;
62	free(v);
63
64	/*
65	 * Set specific keys.
66	 */
67	setg_gcc((void*)ts.g);
68
69	crosscall_amd64(ts.fn);
70	return nil;
71}
72