// 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 <string.h> /* for strerror */
#include <pthread.h>
#include <signal.h>
#include "libcgo.h"

static void* threadentry(void*);
static pthread_key_t k1;

#define magic1 (0x23581321U)

static void
inittls(void)
{
	uint32 x;
	pthread_key_t tofree[128], k;
	int i, ntofree;

	/*
	 * Allocate thread-local storage slot for g.
	 * The key numbers start at 0x100, and we expect to be
	 * one of the early calls to pthread_key_create, so we
	 * should be able to get a pretty low number.
	 *
	 * In Darwin/386 pthreads, %gs points at the thread
	 * structure, and each key is an index into the thread-local
	 * storage array that begins at offset 0x48 within in that structure.
	 * It may happen that we are not quite the first function to try
	 * to allocate thread-local storage keys, so instead of depending
	 * on getting 0x100, we try for 0x108, allocating keys until
	 * we get the one we want and then freeing the ones we didn't want.
	 *
	 * Thus the final offset to use in %gs references is
	 * 0x48+4*0x108 = 0x468.
	 *
	 * The linker and runtime hard-code this constant offset
	 * from %gs where we expect to find g.
	 * Known to ../../../liblink/sym.c:/468
	 * and to ../sys_darwin_386.s:/468
	 *
	 * This is truly disgusting and a bit fragile, but taking care
	 * of it here protects the rest of the system from damage.
	 * The alternative would be to use a global variable that
	 * held the offset and refer to that variable each time we
	 * need a %gs variable (g).  That approach would
	 * require an extra instruction and memory reference in
	 * every stack growth prolog and would also require
	 * rewriting the code that 8c generates for extern registers.
	 *
	 * Things get more disgusting on OS X 10.7 Lion.
	 * The 0x48 base mentioned above is the offset of the tsd
	 * array within the per-thread structure on Leopard and Snow Leopard.
	 * On Lion, the base moved a little, so while the math above
	 * still applies, the base is different.  Thus, we cannot
	 * look for specific key values if we want to build binaries
	 * that run on both systems.  Instead, forget about the
	 * specific key values and just allocate and initialize per-thread
	 * storage until we find a key that writes to the memory location
	 * we want.  Then keep that key.
	 */
	ntofree = 0;
	for(;;) {
		if(pthread_key_create(&k, nil) < 0) {
			fprintf(stderr, "runtime/cgo: pthread_key_create failed\n");
			abort();
		}
		pthread_setspecific(k, (void*)magic1);
		asm volatile("movl %%gs:0x468, %0" : "=r"(x));
		pthread_setspecific(k, 0);
		if(x == magic1) {
			k1 = k;
			break;
		}
		if(ntofree >= nelem(tofree)) {
			fprintf(stderr, "runtime/cgo: could not obtain pthread_keys\n");
			fprintf(stderr, "\ttried");
			for(i=0; i<ntofree; i++)
				fprintf(stderr, " %#x", (unsigned)tofree[i]);
			fprintf(stderr, "\n");
			abort();
		}
		tofree[ntofree++] = k;
	}

	/*
	 * We got the key we wanted.  Free the others.
	 */
	for(i=0; i<ntofree; i++)
		pthread_key_delete(tofree[i]);
}

void
x_cgo_init(G *g)
{
	pthread_attr_t attr;
	size_t size;

	pthread_attr_init(&attr);
	pthread_attr_getstacksize(&attr, &size);
	g->stacklo = (uintptr)&attr - size + 4096;
	pthread_attr_destroy(&attr);

	inittls();
}


void
_cgo_sys_thread_start(ThreadStart *ts)
{
	pthread_attr_t attr;
	sigset_t ign, oset;
	pthread_t p;
	size_t size;
	int err;

	sigfillset(&ign);
	pthread_sigmask(SIG_SETMASK, &ign, &oset);

	pthread_attr_init(&attr);
	pthread_attr_getstacksize(&attr, &size);
	// Leave stacklo=0 and set stackhi=size; mstack will do the rest.
	ts->g->stackhi = size;
	err = pthread_create(&p, &attr, threadentry, ts);

	pthread_sigmask(SIG_SETMASK, &oset, nil);

	if (err != 0) {
		fprintf(stderr, "runtime/cgo: pthread_create failed: %s\n", strerror(err));
		abort();
	}
}

static void*
threadentry(void *v)
{
	ThreadStart ts;

	ts = *(ThreadStart*)v;
	free(v);

	pthread_setspecific(k1, (void*)ts.g);

	crosscall_386(ts.fn);
	return nil;
}
