// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include <errno.h>
#include <limits.h>
#include <signal.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>

#include "config.h"

#ifdef HAVE_DL_ITERATE_PHDR
#include <link.h>
#endif

#include "runtime.h"
#include "arch.h"
#include "defs.h"
#include "go-type.h"

#ifdef USING_SPLIT_STACK

/* FIXME: These are not declared anywhere.  */

extern void __splitstack_getcontext(void *context[10]);

extern void __splitstack_setcontext(void *context[10]);

extern void *__splitstack_makecontext(size_t, void *context[10], size_t *);

extern void * __splitstack_resetcontext(void *context[10], size_t *);

extern void __splitstack_releasecontext(void *context[10]);

extern void *__splitstack_find(void *, void *, size_t *, void **, void **,
			       void **);

extern void __splitstack_block_signals (int *, int *);

extern void __splitstack_block_signals_context (void *context[10], int *,
						int *);

#endif

#ifndef PTHREAD_STACK_MIN
# define PTHREAD_STACK_MIN 8192
#endif

#if defined(USING_SPLIT_STACK) && defined(LINKER_SUPPORTS_SPLIT_STACK)
# define StackMin PTHREAD_STACK_MIN
#else
# define StackMin ((sizeof(char *) < 8) ? 2 * 1024 * 1024 : 4 * 1024 * 1024)
#endif

uintptr runtime_stacks_sys;

void gtraceback(G*)
  __asm__(GOSYM_PREFIX "runtime.gtraceback");

#ifdef __rtems__
#define __thread
#endif

static __thread G *g;

#ifndef SETCONTEXT_CLOBBERS_TLS

static inline void
initcontext(void)
{
}

static inline void
fixcontext(ucontext_t *c __attribute__ ((unused)))
{
}

#else

# if defined(__x86_64__) && defined(__sun__)

// x86_64 Solaris 10 and 11 have a bug: setcontext switches the %fs
// register to that of the thread which called getcontext.  The effect
// is that the address of all __thread variables changes.  This bug
// also affects pthread_self() and pthread_getspecific.  We work
// around it by clobbering the context field directly to keep %fs the
// same.

static __thread greg_t fs;

static inline void
initcontext(void)
{
	ucontext_t c;

	getcontext(&c);
	fs = c.uc_mcontext.gregs[REG_FSBASE];
}

static inline void
fixcontext(ucontext_t* c)
{
	c->uc_mcontext.gregs[REG_FSBASE] = fs;
}

# elif defined(__NetBSD__)

// NetBSD has a bug: setcontext clobbers tlsbase, we need to save
// and restore it ourselves.

static __thread __greg_t tlsbase;

static inline void
initcontext(void)
{
	ucontext_t c;

	getcontext(&c);
	tlsbase = c.uc_mcontext._mc_tlsbase;
}

static inline void
fixcontext(ucontext_t* c)
{
	c->uc_mcontext._mc_tlsbase = tlsbase;
}

# elif defined(__sparc__)

static inline void
initcontext(void)
{
}

static inline void
fixcontext(ucontext_t *c)
{
	/* ??? Using 
	     register unsigned long thread __asm__("%g7");
	     c->uc_mcontext.gregs[REG_G7] = thread;
	   results in
	     error: variable ‘thread’ might be clobbered by \
		‘longjmp’ or ‘vfork’ [-Werror=clobbered]
	   which ought to be false, as %g7 is a fixed register.  */

	if (sizeof (c->uc_mcontext.gregs[REG_G7]) == 8)
		asm ("stx %%g7, %0" : "=m"(c->uc_mcontext.gregs[REG_G7]));
	else
		asm ("st %%g7, %0" : "=m"(c->uc_mcontext.gregs[REG_G7]));
}

# elif defined(_AIX)

static inline void
initcontext(void)
{
}

static inline void
fixcontext(ucontext_t* c)
{
	// Thread pointer is in r13, per 64-bit ABI.
	if (sizeof (c->uc_mcontext.jmp_context.gpr[13]) == 8)
		asm ("std 13, %0" : "=m"(c->uc_mcontext.jmp_context.gpr[13]));
}

# else

#  error unknown case for SETCONTEXT_CLOBBERS_TLS

# endif

#endif

// ucontext_arg returns a properly aligned ucontext_t value.  On some
// systems a ucontext_t value must be aligned to a 16-byte boundary.
// The g structure that has fields of type ucontext_t is defined in
// Go, and Go has no simple way to align a field to such a boundary.
// So we make the field larger in runtime2.go and pick an appropriate
// offset within the field here.
static ucontext_t*
ucontext_arg(uintptr_t* go_ucontext)
{
	uintptr_t p = (uintptr_t)go_ucontext;
	size_t align = __alignof__(ucontext_t);
	if(align > 16) {
		// We only ensured space for up to a 16 byte alignment
		// in libgo/go/runtime/runtime2.go.
		runtime_throw("required alignment of ucontext_t too large");
	}
	p = (p + align - 1) &~ (uintptr_t)(align - 1);
	return (ucontext_t*)p;
}

// We can not always refer to the TLS variables directly.  The
// compiler will call tls_get_addr to get the address of the variable,
// and it may hold it in a register across a call to schedule.  When
// we get back from the call we may be running in a different thread,
// in which case the register now points to the TLS variable for a
// different thread.  We use non-inlinable functions to avoid this
// when necessary.

G* runtime_g(void) __attribute__ ((noinline, no_split_stack));

G*
runtime_g(void)
{
	return g;
}

M* runtime_m(void) __attribute__ ((noinline, no_split_stack));

M*
runtime_m(void)
{
	if(g == nil)
		return nil;
	return g->m;
}

// Set g.
void
runtime_setg(G* gp)
{
	g = gp;
}

void runtime_newosproc(M *)
  __asm__(GOSYM_PREFIX "runtime.newosproc");

// Start a new thread.
void
runtime_newosproc(M *mp)
{
	pthread_attr_t attr;
	sigset_t clear, old;
	pthread_t tid;
	int tries;
	int ret;

	if(pthread_attr_init(&attr) != 0)
		runtime_throw("pthread_attr_init");
	if(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
		runtime_throw("pthread_attr_setdetachstate");

	// Block signals during pthread_create so that the new thread
	// starts with signals disabled.  It will enable them in minit.
	sigfillset(&clear);

#ifdef SIGTRAP
	// Blocking SIGTRAP reportedly breaks gdb on Alpha GNU/Linux.
	sigdelset(&clear, SIGTRAP);
#endif

	sigemptyset(&old);
	pthread_sigmask(SIG_BLOCK, &clear, &old);

	for (tries = 0; tries < 20; tries++) {
		ret = pthread_create(&tid, &attr, runtime_mstart, mp);
		if (ret != EAGAIN) {
			break;
		}
		runtime_usleep((tries + 1) * 1000); // Milliseconds.
	}

	pthread_sigmask(SIG_SETMASK, &old, nil);

	if (ret != 0) {
		runtime_printf("pthread_create failed: %d\n", ret);
		runtime_throw("pthread_create");
	}

	if(pthread_attr_destroy(&attr) != 0)
		runtime_throw("pthread_attr_destroy");
}

// Switch context to a different goroutine.  This is like longjmp.
void runtime_gogo(G*) __attribute__ ((noinline));
void
runtime_gogo(G* newg)
{
#ifdef USING_SPLIT_STACK
	__splitstack_setcontext((void*)(&newg->stackcontext[0]));
#endif
	g = newg;
	newg->fromgogo = true;
	fixcontext(ucontext_arg(&newg->context[0]));
	setcontext(ucontext_arg(&newg->context[0]));
	runtime_throw("gogo setcontext returned");
}

// Save context and call fn passing g as a parameter.  This is like
// setjmp.  Because getcontext always returns 0, unlike setjmp, we use
// g->fromgogo as a code.  It will be true if we got here via
// setcontext.  g == nil the first time this is called in a new m.
void runtime_mcall(FuncVal *) __attribute__ ((noinline));
void
runtime_mcall(FuncVal *fv)
{
	M *mp;
	G *gp;
#ifndef USING_SPLIT_STACK
	void *afterregs;
#endif

	// Ensure that all registers are on the stack for the garbage
	// collector.
	__builtin_unwind_init();
	flush_registers_to_secondary_stack();

	gp = g;
	mp = gp->m;
	if(gp == mp->g0)
		runtime_throw("runtime: mcall called on m->g0 stack");

	if(gp != nil) {

#ifdef USING_SPLIT_STACK
		__splitstack_getcontext((void*)(&g->stackcontext[0]));
#else
		// We have to point to an address on the stack that is
		// below the saved registers.
		gp->gcnextsp = (uintptr)(&afterregs);
		gp->gcnextsp2 = (uintptr)(secondary_stack_pointer());
#endif
		gp->fromgogo = false;
		getcontext(ucontext_arg(&gp->context[0]));

		// When we return from getcontext, we may be running
		// in a new thread.  That means that g may have
		// changed.  It is a global variables so we will
		// reload it, but the address of g may be cached in
		// our local stack frame, and that address may be
		// wrong.  Call the function to reload the value for
		// this thread.
		gp = runtime_g();
		mp = gp->m;

		if(gp->traceback != nil)
			gtraceback(gp);
	}
	if (gp == nil || !gp->fromgogo) {
#ifdef USING_SPLIT_STACK
		__splitstack_setcontext((void*)(&mp->g0->stackcontext[0]));
#endif
		mp->g0->entry = fv;
		mp->g0->param = gp;

		// It's OK to set g directly here because this case
		// can not occur if we got here via a setcontext to
		// the getcontext call just above.
		g = mp->g0;

		fixcontext(ucontext_arg(&mp->g0->context[0]));
		setcontext(ucontext_arg(&mp->g0->context[0]));
		runtime_throw("runtime: mcall function returned");
	}
}

// Goroutine scheduler
// The scheduler's job is to distribute ready-to-run goroutines over worker threads.
//
// The main concepts are:
// G - goroutine.
// M - worker thread, or machine.
// P - processor, a resource that is required to execute Go code.
//     M must have an associated P to execute Go code, however it can be
//     blocked or in a syscall w/o an associated P.
//
// Design doc at http://golang.org/s/go11sched.

extern G* allocg(void)
  __asm__ (GOSYM_PREFIX "runtime.allocg");

Sched*	runtime_sched;

bool	runtime_isarchive;

extern void kickoff(void)
  __asm__(GOSYM_PREFIX "runtime.kickoff");
extern void minit(void)
  __asm__(GOSYM_PREFIX "runtime.minit");
extern void mstart1()
  __asm__(GOSYM_PREFIX "runtime.mstart1");
extern void stopm(void)
  __asm__(GOSYM_PREFIX "runtime.stopm");
extern void mexit(bool)
  __asm__(GOSYM_PREFIX "runtime.mexit");
extern void handoffp(P*)
  __asm__(GOSYM_PREFIX "runtime.handoffp");
extern void wakep(void)
  __asm__(GOSYM_PREFIX "runtime.wakep");
extern void stoplockedm(void)
  __asm__(GOSYM_PREFIX "runtime.stoplockedm");
extern void schedule(void)
  __asm__(GOSYM_PREFIX "runtime.schedule");
extern void execute(G*, bool)
  __asm__(GOSYM_PREFIX "runtime.execute");
extern void reentersyscall(uintptr, uintptr)
  __asm__(GOSYM_PREFIX "runtime.reentersyscall");
extern void reentersyscallblock(uintptr, uintptr)
  __asm__(GOSYM_PREFIX "runtime.reentersyscallblock");
extern G* gfget(P*)
  __asm__(GOSYM_PREFIX "runtime.gfget");
extern void acquirep(P*)
  __asm__(GOSYM_PREFIX "runtime.acquirep");
extern P* releasep(void)
  __asm__(GOSYM_PREFIX "runtime.releasep");
extern void incidlelocked(int32)
  __asm__(GOSYM_PREFIX "runtime.incidlelocked");
extern void globrunqput(G*)
  __asm__(GOSYM_PREFIX "runtime.globrunqput");
extern P* pidleget(void)
  __asm__(GOSYM_PREFIX "runtime.pidleget");
extern struct mstats* getMemstats(void)
  __asm__(GOSYM_PREFIX "runtime.getMemstats");

bool runtime_isstarted;

// Used to determine the field alignment.

struct field_align
{
  char c;
  Hchan *p;
};

void getTraceback(G*, G*) __asm__(GOSYM_PREFIX "runtime.getTraceback");

// getTraceback stores a traceback of gp in the g's traceback field
// and then returns to me.  We expect that gp's traceback is not nil.
// It works by saving me's current context, and checking gp's traceback field.
// If gp's traceback field is not nil, it starts running gp.
// In places where we call getcontext, we check the traceback field.
// If it is not nil, we collect a traceback, and then return to the
// goroutine stored in the traceback field, which is me.
void getTraceback(G* me, G* gp)
{
#ifdef USING_SPLIT_STACK
	__splitstack_getcontext((void*)(&me->stackcontext[0]));
#endif
	getcontext(ucontext_arg(&me->context[0]));

	if (gp->traceback != nil) {
		runtime_gogo(gp);
	}
}

// Do a stack trace of gp, and then restore the context to
// gp->traceback->gp.

void
gtraceback(G* gp)
{
	Traceback* traceback;
	M* holdm;

	traceback = gp->traceback;
	gp->traceback = nil;
	holdm = gp->m;
	if(holdm != nil && holdm != g->m)
		runtime_throw("gtraceback: m is not nil");
	gp->m = traceback->gp->m;
	traceback->c = runtime_callers(1, traceback->locbuf,
		sizeof traceback->locbuf / sizeof traceback->locbuf[0], false);
	gp->m = holdm;
	runtime_gogo(traceback->gp);
}

// Called by pthread_create to start an M.
void*
runtime_mstart(void *arg)
{
	M* mp;
	G* gp;

	mp = (M*)(arg);
	gp = mp->g0;
	gp->m = mp;

	g = gp;

	gp->entry = nil;
	gp->param = nil;

	// We have to call minit before we call getcontext,
	// because getcontext will copy the signal mask.
	minit();

	initcontext();

	// Record top of stack for use by mcall.
	// Once we call schedule we're never coming back,
	// so other calls can reuse this stack space.
#ifdef USING_SPLIT_STACK
	__splitstack_getcontext((void*)(&gp->stackcontext[0]));
#else
	gp->gcinitialsp = &arg;
	// Setting gcstacksize to 0 is a marker meaning that gcinitialsp
	// is the top of the stack, not the bottom.
	gp->gcstacksize = 0;
	gp->gcnextsp = (uintptr)(&arg);
	gp->gcinitialsp2 = secondary_stack_pointer();
	gp->gcnextsp2 = (uintptr)(gp->gcinitialsp2);
#endif

	// Save the currently active context.  This will return
	// multiple times via the setcontext call in mcall.
	getcontext(ucontext_arg(&gp->context[0]));

	if(gp->traceback != nil) {
		// Got here from getTraceback.
		// I'm not sure this ever actually happens--getTraceback
		// may always go to the getcontext call in mcall.
		gtraceback(gp);
	}

	if(gp->entry != nil) {
		// Got here from mcall.
		FuncVal *fv = gp->entry;
		void (*pfn)(G*) = (void (*)(G*))fv->fn;
		G* gp1 = (G*)gp->param;
		gp->entry = nil;
		gp->param = nil;
		__builtin_call_with_static_chain(pfn(gp1), fv);
		*(int*)0x21 = 0x21;
	}

	if(mp->exiting) {
		mexit(true);
		return nil;
	}

	// Initial call to getcontext--starting thread.

#ifdef USING_SPLIT_STACK
	{
		int dont_block_signals = 0;
		__splitstack_block_signals(&dont_block_signals, nil);
	}
#endif

	mstart1();

	// mstart1 does not return, but we need a return statement
	// here to avoid a compiler warning.
	return nil;
}

typedef struct CgoThreadStart CgoThreadStart;
struct CgoThreadStart
{
	M *m;
	G *g;
	uintptr *tls;
	void (*fn)(void);
};

void setGContext(void) __asm__ (GOSYM_PREFIX "runtime.setGContext");

// setGContext sets up a new goroutine context for the current g.
void
setGContext(void)
{
	int val;
	G *gp;

	initcontext();
	gp = g;
	gp->entry = nil;
	gp->param = nil;
#ifdef USING_SPLIT_STACK
	__splitstack_getcontext((void*)(&gp->stackcontext[0]));
	val = 0;
	__splitstack_block_signals(&val, nil);
#else
	gp->gcinitialsp = &val;
	gp->gcstack = 0;
	gp->gcstacksize = 0;
	gp->gcnextsp = (uintptr)(&val);
	gp->gcinitialsp2 = secondary_stack_pointer();
	gp->gcnextsp2 = (uintptr)(gp->gcinitialsp2);
#endif
	getcontext(ucontext_arg(&gp->context[0]));

	if(gp->entry != nil) {
		// Got here from mcall.
		FuncVal *fv = gp->entry;
		void (*pfn)(G*) = (void (*)(G*))fv->fn;
		G* gp1 = (G*)gp->param;
		gp->entry = nil;
		gp->param = nil;
		__builtin_call_with_static_chain(pfn(gp1), fv);
		*(int*)0x22 = 0x22;
	}
}

void makeGContext(G*, byte*, uintptr)
	__asm__(GOSYM_PREFIX "runtime.makeGContext");

// makeGContext makes a new context for a g.
void
makeGContext(G* gp, byte* sp, uintptr spsize) {
	ucontext_t *uc;

	uc = ucontext_arg(&gp->context[0]);
	getcontext(uc);
	uc->uc_stack.ss_sp = sp;
	uc->uc_stack.ss_size = (size_t)spsize;
	makecontext(uc, kickoff, 0);
}

// The goroutine g is about to enter a system call.
// Record that it's not using the cpu anymore.
// This is called only from the go syscall library and cgocall,
// not from the low-level system calls used by the runtime.
//
// Entersyscall cannot split the stack: the runtime_gosave must
// make g->sched refer to the caller's stack segment, because
// entersyscall is going to return immediately after.

void runtime_entersyscall() __attribute__ ((no_split_stack));
static void doentersyscall(uintptr, uintptr)
  __attribute__ ((no_split_stack, noinline));

void
runtime_entersyscall()
{
	// Save the registers in the g structure so that any pointers
	// held in registers will be seen by the garbage collector.
	getcontext(ucontext_arg(&g->gcregs[0]));

	// Note that if this function does save any registers itself,
	// we might store the wrong value in the call to getcontext.
	// FIXME: This assumes that we do not need to save any
	// callee-saved registers to access the TLS variable g.  We
	// don't want to put the ucontext_t on the stack because it is
	// large and we can not split the stack here.
	doentersyscall((uintptr)runtime_getcallerpc(),
		       (uintptr)runtime_getcallersp());
}

static void
doentersyscall(uintptr pc, uintptr sp)
{
	// Leave SP around for GC and traceback.
#ifdef USING_SPLIT_STACK
	{
	  size_t gcstacksize;
	  g->gcstack = (uintptr)(__splitstack_find(nil, nil, &gcstacksize,
						   (void**)(&g->gcnextsegment),
						   (void**)(&g->gcnextsp),
						   &g->gcinitialsp));
	  g->gcstacksize = (uintptr)gcstacksize;
	}
#else
	{
		void *v;

		g->gcnextsp = (uintptr)(&v);
		g->gcnextsp2 = (uintptr)(secondary_stack_pointer());
	}
#endif

	reentersyscall(pc, sp);
}

static void doentersyscallblock(uintptr, uintptr)
  __attribute__ ((no_split_stack, noinline));

// The same as runtime_entersyscall(), but with a hint that the syscall is blocking.
void
runtime_entersyscallblock()
{
	// Save the registers in the g structure so that any pointers
	// held in registers will be seen by the garbage collector.
	getcontext(ucontext_arg(&g->gcregs[0]));

	// See comment in runtime_entersyscall.
	doentersyscallblock((uintptr)runtime_getcallerpc(),
			    (uintptr)runtime_getcallersp());
}

static void
doentersyscallblock(uintptr pc, uintptr sp)
{
	// Leave SP around for GC and traceback.
#ifdef USING_SPLIT_STACK
	{
	  size_t gcstacksize;
	  g->gcstack = (uintptr)(__splitstack_find(nil, nil, &gcstacksize,
						   (void**)(&g->gcnextsegment),
						   (void**)(&g->gcnextsp),
						   &g->gcinitialsp));
	  g->gcstacksize = (uintptr)gcstacksize;
	}
#else
	{
		void *v;

		g->gcnextsp = (uintptr)(&v);
		g->gcnextsp2 = (uintptr)(secondary_stack_pointer());
	}
#endif

	reentersyscallblock(pc, sp);
}

// Allocate a new g, with a stack big enough for stacksize bytes.
G*
runtime_malg(bool allocatestack, bool signalstack, byte** ret_stack, uintptr* ret_stacksize)
{
	uintptr stacksize;
	G *newg;
	byte* unused_stack;
	uintptr unused_stacksize;
#ifdef USING_SPLIT_STACK
	int dont_block_signals = 0;
	size_t ss_stacksize;
#endif

	if (ret_stack == nil) {
		ret_stack = &unused_stack;
	}
	if (ret_stacksize == nil) {
		ret_stacksize = &unused_stacksize;
	}
	newg = allocg();
	if(allocatestack) {
		stacksize = StackMin;
		if(signalstack) {
			stacksize = 32 * 1024; // OS X wants >= 8K, GNU/Linux >= 2K
#ifdef SIGSTKSZ
			if(stacksize < SIGSTKSZ)
				stacksize = SIGSTKSZ;
#endif
		}

#ifdef USING_SPLIT_STACK
		*ret_stack = __splitstack_makecontext(stacksize,
						      (void*)(&newg->stackcontext[0]),
						      &ss_stacksize);
		*ret_stacksize = (uintptr)ss_stacksize;
		__splitstack_block_signals_context((void*)(&newg->stackcontext[0]),
						   &dont_block_signals, nil);
#else
                // In 64-bit mode, the maximum Go allocation space is
                // 128G.  Our stack size is 4M, which only permits 32K
                // goroutines.  In order to not limit ourselves,
                // allocate the stacks out of separate memory.  In
                // 32-bit mode, the Go allocation space is all of
                // memory anyhow.
		if(sizeof(void*) == 8) {
			void *p = runtime_sysAlloc(stacksize, &getMemstats()->stacks_sys);
			if(p == nil)
				runtime_throw("runtime: cannot allocate memory for goroutine stack");
			*ret_stack = (byte*)p;
		} else {
			*ret_stack = runtime_mallocgc(stacksize, nil, false);
			runtime_xadd(&runtime_stacks_sys, stacksize);
		}
		*ret_stacksize = (uintptr)stacksize;
		newg->gcinitialsp = *ret_stack;
		newg->gcstacksize = (uintptr)stacksize;
		newg->gcinitialsp2 = initial_secondary_stack_pointer(*ret_stack);
#endif
	}
	return newg;
}

void stackfree(G*)
  __asm__(GOSYM_PREFIX "runtime.stackfree");

// stackfree frees the stack of a g.
void
stackfree(G* gp)
{
#ifdef USING_SPLIT_STACK
  __splitstack_releasecontext((void*)(&gp->stackcontext[0]));
#else
  // If gcstacksize is 0, the stack is allocated by libc and will be
  // released when the thread exits. Otherwise, in 64-bit mode it was
  // allocated using sysAlloc and in 32-bit mode it was allocated
  // using garbage collected memory.
  if (gp->gcstacksize != 0) {
    if (sizeof(void*) == 8) {
      runtime_sysFree(gp->gcinitialsp, gp->gcstacksize, &getMemstats()->stacks_sys);
    }
    gp->gcinitialsp = nil;
    gp->gcstacksize = 0;
  }
#endif
}

void resetNewG(G*, void **, uintptr*)
  __asm__(GOSYM_PREFIX "runtime.resetNewG");

// Reset stack information for g pulled out of the cache to start a
// new goroutine.
void
resetNewG(G *newg, void **sp, uintptr *spsize)
{
#ifdef USING_SPLIT_STACK
  int dont_block_signals = 0;
  size_t ss_spsize;

  *sp = __splitstack_resetcontext((void*)(&newg->stackcontext[0]), &ss_spsize);
  *spsize = ss_spsize;
  __splitstack_block_signals_context((void*)(&newg->stackcontext[0]),
				     &dont_block_signals, nil);
#else
  *sp = newg->gcinitialsp;
  *spsize = newg->gcstacksize;
  if(*spsize == 0)
    runtime_throw("bad spsize in resetNewG");
  newg->gcnextsp = (uintptr)(*sp);
  newg->gcnextsp2 = (uintptr)(newg->gcinitialsp2);
#endif
}

// Return whether we are waiting for a GC.  This gc toolchain uses
// preemption instead.
bool
runtime_gcwaiting(void)
{
	return runtime_sched->gcwaiting;
}
