// 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 <sys/types.h>
#include <dlfcn.h>
#include <errno.h>
#include <pthread.h>
#include <signal.h>
#include <string.h>
#include "libcgo.h"

static void* threadentry(void*);

// TCB_SIZE is sizeof(struct thread_control_block),
// as defined in /usr/src/lib/librthread/tcb.h
#define TCB_SIZE (4 * sizeof(void *))
#define TLS_SIZE (2 * sizeof(void *))

void *__get_tcb(void);
void __set_tcb(void *);

static int (*sys_pthread_create)(pthread_t *thread, const pthread_attr_t *attr,
	void *(*start_routine)(void *), void *arg);

struct thread_args {
	void *(*func)(void *);
	void *arg;
};

static void
tcb_fixup(int mainthread)
{
	void *newtcb, *oldtcb;

	// The OpenBSD ld.so(1) does not currently support PT_TLS. As a result,
	// we need to allocate our own TLS space while preserving the existing
	// TCB that has been setup via librthread.

	newtcb = malloc(TCB_SIZE + TLS_SIZE);
	if(newtcb == NULL)
		abort();

	// The signal trampoline expects the TLS slots to be zeroed.
	bzero(newtcb, TLS_SIZE);

	oldtcb = __get_tcb();
	bcopy(oldtcb, newtcb + TLS_SIZE, TCB_SIZE);
	__set_tcb(newtcb + TLS_SIZE);

	// The main thread TCB is a static allocation - do not try to free it.
	if(!mainthread)
		free(oldtcb);
}

static void *
thread_start_wrapper(void *arg)
{
	struct thread_args args = *(struct thread_args *)arg;

	free(arg);
	tcb_fixup(0);

	return args.func(args.arg);
}

int
pthread_create(pthread_t *thread, const pthread_attr_t *attr,
	void *(*start_routine)(void *), void *arg)
{
	struct thread_args *p;

	p = malloc(sizeof(*p));
	if(p == NULL) {
		errno = ENOMEM;
		return -1;
	}
	p->func = start_routine;
	p->arg = arg;

	return sys_pthread_create(thread, attr, thread_start_wrapper, p);
}

static void
xinitcgo(G *g)
{
	pthread_attr_t attr;
	size_t size;
	void *handle;

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

	// Locate symbol for the system pthread_create function.
	handle = dlopen("libpthread.so", RTLD_LAZY);
	if(handle == NULL) {
		fprintf(stderr, "dlopen: failed to load libpthread: %s\n", dlerror());
		abort();
	}
	sys_pthread_create = dlsym(handle, "pthread_create");
	if(sys_pthread_create == NULL) {
		fprintf(stderr, "dlsym: failed to find pthread_create: %s\n", dlerror());
		abort();
	}
	dlclose(handle);

	tcb_fixup(1);
}

void (*initcgo)(G*) = xinitcgo;

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

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

	pthread_attr_init(&attr);
	pthread_attr_getstacksize(&attr, &size);

	ts->g->stackguard = size;
	err = sys_pthread_create(&p, &attr, threadentry, ts);

	sigprocmask(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;

	tcb_fixup(0);

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

	ts.g->stackbase = (uintptr)&ts;

	/*
	 * libcgo_sys_thread_start set stackguard to stack size;
	 * change to actual guard pointer.
	 */
	ts.g->stackguard = (uintptr)&ts - ts.g->stackguard + 4096;

	/*
	 * Set specific keys.  On OpenBSD/ELF, the thread local storage
	 * is just before %fs:0.  Our dynamic 6.out's reserve 16 bytes
	 * for the two words g and m at %fs:-16 and %fs:-8.
	 */
	asm volatile (
		"movq %0, %%fs:-16\n"	// MOVL g, -16(FS)
		"movq %1, %%fs:-8\n"	// MOVL m, -8(FS)
		:: "r"(ts.g), "r"(ts.m)
	);
	crosscall_amd64(ts.fn);
	return nil;
}
