void
callback(void *f)
{
+ // use some stack space
+ volatile char data[64*1024];
+
+ data[0] = 0;
goCallback(f);
+ data[sizeof(data)-1] = 0;
}
// we set up GS ourselves.
MOVL initcgo(SB), AX
TESTL AX, AX
- JZ 4(PC)
+ JZ needtls
+ PUSHL $runtime·g0(SB)
CALL AX
+ POPL AX
// skip runtime·ldt0setup(SB) and tls test after initcgo for non-windows
CMPL runtime·iswindows(SB), $0
JEQ ok
-
+needtls:
// skip runtime·ldt0setup(SB) and tls test on Plan 9 in all cases
CMPL runtime·isplan9(SB), $1
JEQ ok
MOVL CX, m_g0(AX)
// create istack out of the OS stack
+ // if there is an initcgo, it had setup stackguard for us
+ MOVL initcgo(SB), AX
+ TESTL AX, AX
+ JNZ stackok
LEAL (-64*1024+104)(SP), AX // TODO: 104?
MOVL AX, g_stackguard(CX)
+stackok:
MOVL SP, g_stackbase(CX)
+
CALL runtime·emptyfunc(SB) // fault if stack check is wrong
// convention is D is always cleared
MOVQ initcgo(SB), AX
TESTQ AX, AX
JZ needtls
+ LEAQ runtime·g0(SB), DI
CALL AX
CMPL runtime·iswindows(SB), $0
JEQ ok
MOVQ CX, m_g0(AX)
// create istack out of the given (operating system) stack
+ // if there is an initcgo, it had setup stackguard for us
+ MOVQ initcgo(SB), AX
+ TESTQ AX, AX
+ JNZ stackok
LEAQ (-8192+104)(SP), AX
MOVQ AX, g_stackguard(CX)
+stackok:
MOVQ SP, g_stackbase(CX)
CLD // convention is D is always left cleared
}
static void
-xinitcgo(void)
+xinitcgo(G *g)
{
+ pthread_attr_t attr;
+ size_t size;
+
+ pthread_attr_init(&attr);
+ pthread_attr_getstacksize(&attr, &size);
+ g->stackguard = (uintptr)&attr - size + 4096;
+ pthread_attr_destroy(&attr);
+
inittls();
}
-void (*initcgo)(void) = xinitcgo;
+void (*initcgo)(G*) = xinitcgo;
void
libcgo_sys_thread_start(ThreadStart *ts)
}
void
-xinitcgo(void)
+xinitcgo(G *g)
{
+ pthread_attr_t attr;
+ size_t size;
+
+ pthread_attr_init(&attr);
+ pthread_attr_getstacksize(&attr, &size);
+ g->stackguard = (uintptr)&attr - size + 4096;
+ pthread_attr_destroy(&attr);
+
inittls();
}
-void (*initcgo) = xinitcgo;
+void (*initcgo)(G*) = xinitcgo;
void
libcgo_sys_thread_start(ThreadStart *ts)
static void* threadentry(void*);
static void
-xinitcgo(void)
+xinitcgo(G *g)
{
+ pthread_attr_t attr;
+ size_t size;
+
+ pthread_attr_init(&attr);
+ pthread_attr_getstacksize(&attr, &size);
+ g->stackguard = (uintptr)&attr - size + 4096;
+ pthread_attr_destroy(&attr);
}
-void (*initcgo)(void) = xinitcgo;
+void (*initcgo)(G*) = xinitcgo;
void
libcgo_sys_thread_start(ThreadStart *ts)
static void* threadentry(void*);
static void
-xinitcgo(void)
+xinitcgo(G *g)
{
+ pthread_attr_t attr;
+ size_t size;
+
+ pthread_attr_init(&attr);
+ pthread_attr_getstacksize(&attr, &size);
+ g->stackguard = (uintptr)&attr - size + 4096;
+ pthread_attr_destroy(&attr);
}
-void (*initcgo)(void) = xinitcgo;
+void (*initcgo)(G*) = xinitcgo;
void
libcgo_sys_thread_start(ThreadStart *ts)
static void *threadentry(void*);
static void
-xinitcgo(void)
+xinitcgo(G *g)
{
+ pthread_attr_t attr;
+ size_t size;
+
+ pthread_attr_init(&attr);
+ pthread_attr_getstacksize(&attr, &size);
+ g->stackguard = (uintptr)&attr - size + 4096;
+ pthread_attr_destroy(&attr);
}
-void (*initcgo) = xinitcgo;
+void (*initcgo)(G*) = xinitcgo;
void
libcgo_sys_thread_start(ThreadStart *ts)
// license that can be found in the LICENSE file.
#include <pthread.h>
+#include <string.h> // strerror
#include "libcgo.h"
static void* threadentry(void*);
void
-xinitcgo(void)
+xinitcgo(G* g)
{
+ pthread_attr_t attr;
+ size_t size;
+
+ pthread_attr_init(&attr);
+ pthread_attr_getstacksize(&attr, &size);
+ g->stackguard = (uintptr)&attr - size + 4096;
+ pthread_attr_destroy(&attr);
}
-void (*initcgo)(void) = xinitcgo;
+void (*initcgo)(G*) = xinitcgo;
void
libcgo_sys_thread_start(ThreadStart *ts)
#include "libcgo.h"
static void
-xinitcgo(void)
+xinitcgo(G *g)
{
+ // unimplemented
}
-void (*initcgo)(void) = xinitcgo;
+void (*initcgo)(G*) = xinitcgo;
void
libcgo_sys_thread_start(ThreadStart *ts)
#define STACKSIZE (1*1024*1024)
static void
-xinitcgo(void)
+xinitcgo(G *g)
{
+ int tmp;
+ g->stackguard = (uintptr)&tmp - STACKSIZE + 4096;
}
-void (*initcgo)(void) = xinitcgo;
+void (*initcgo)(G*) = xinitcgo;
void
libcgo_sys_thread_start(ThreadStart *ts)
#define STACKSIZE (2*1024*1024)
static void
-xinitcgo(void)
+xinitcgo(G *g)
{
+ int tmp;
+ g->stackguard = (uintptr)&tmp - STACKSIZE + 4096;
}
-void (*initcgo)(void) = xinitcgo;
+void (*initcgo)(G*) = xinitcgo;
void
libcgo_sys_thread_start(ThreadStart *ts)