1efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen// Copyright 2015 The Go Authors. All rights reserved.
2efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen// Use of this source code is governed by a BSD-style
3efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen// license that can be found in the LICENSE file.
4efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen
5efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen#include <pthread.h>
6efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen#include <string.h>
7efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen#include <signal.h>
8efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen#include <ucontext.h>
9efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen#include "libcgo.h"
10efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen#include "libcgo_unix.h"
11efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen
12efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsenstatic void* threadentry(void*);
13efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsenstatic void (*setg_gcc)(void*);
14efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen
15efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsenvoid
16efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsenx_cgo_init(G *g, void (*setg)(void*))
17efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen{
18efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	ucontext_t ctx;
19efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen
20efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	setg_gcc = setg;
21efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	if (getcontext(&ctx) != 0)
22efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen		perror("runtime/cgo: getcontext failed");
23efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	g->stacklo = (uintptr_t)ctx.uc_stack.ss_sp;
24efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen
25efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	// Solaris processes report a tiny stack when run with "ulimit -s unlimited".
26efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	// Correct that as best we can: assume it's at least 1 MB.
27efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	// See golang.org/issue/12210.
28efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	if(ctx.uc_stack.ss_size < 1024*1024)
29efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen		g->stacklo -= 1024*1024 - ctx.uc_stack.ss_size;
30efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen}
31efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen
32efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsenvoid
33efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen_cgo_sys_thread_start(ThreadStart *ts)
34efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen{
35efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	pthread_attr_t attr;
36efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	sigset_t ign, oset;
37efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	pthread_t p;
38efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	void *base;
39efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	size_t size;
40efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	int err;
41efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen
42efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	sigfillset(&ign);
43efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	pthread_sigmask(SIG_SETMASK, &ign, &oset);
44efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen
45efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	pthread_attr_init(&attr);
46efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen
47efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	if (pthread_attr_getstack(&attr, &base, &size) != 0)
48efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen		perror("runtime/cgo: pthread_attr_getstack failed");
49efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	if (size == 0) {
50efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen		ts->g->stackhi = 2 << 20;
51efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen		if (pthread_attr_setstack(&attr, NULL, ts->g->stackhi) != 0)
52efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen			perror("runtime/cgo: pthread_attr_setstack failed");
53efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	} else {
54efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen		ts->g->stackhi = size;
55efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	}
56efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
57efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	err = _cgo_try_pthread_create(&p, &attr, threadentry, ts);
58efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen
59efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	pthread_sigmask(SIG_SETMASK, &oset, nil);
60efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen
61efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	if (err != 0) {
62efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
63efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen		abort();
64efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	}
65efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen}
66efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen
67efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsenstatic void*
68efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsenthreadentry(void *v)
69efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen{
70efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	ThreadStart ts;
71efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen
72efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	ts = *(ThreadStart*)v;
73efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	free(v);
74efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen
75efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	/*
76efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	 * Set specific keys.
77efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	 */
78efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	setg_gcc((void*)ts.g);
79efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen
80efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	crosscall_amd64(ts.fn);
81efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen	return nil;
82efea46b87b2dcc66da02dfbf66fd901d24c7a09Dan Willemsen}
83