// 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"
#include "libcgo_unix.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 src/cmd/link/internal/ld/sym.go:/0x468
	 * and to src/runtime/sys_darwin_386.s:/0x468
	 *
	 * 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; mstart will do the rest.
	ts->g->stackhi = size;
	err = _cgo_try_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);

	if (pthread_setspecific(k1, (void*)ts.g) != 0) {
		fprintf(stderr, "runtime/cgo: pthread_setspecific failed\n");
		abort();
	}

	crosscall_386(ts.fn);
	return nil;
}
