#include "threadimpl.h"

#undef exits
#undef _exits

static pthread_mutex_t initmutex = PTHREAD_MUTEX_INITIALIZER;

static void
lockinit(Lock *lk)
{
	pthread_mutexattr_t attr;

	pthread_mutex_lock(&initmutex);
	if(lk->init == 0){
		pthread_mutexattr_init(&attr);
		pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL);
		pthread_mutex_init(&lk->mutex, &attr);
		pthread_mutexattr_destroy(&attr);
		lk->init = 1;
	}
	pthread_mutex_unlock(&initmutex);
}

int
_threadlock(Lock *lk, int block, ulong pc)
{
	int r;

	if(!lk->init)
		lockinit(lk);
	if(block){
		if(pthread_mutex_lock(&lk->mutex) != 0)
			abort();
		return 1;
	}else{
		r = pthread_mutex_trylock(&lk->mutex);
		if(r == 0)
			return 1;
		if(r == EBUSY)
			return 0;
		abort();
		return 0;
	}
}

void
_threadunlock(Lock *lk, ulong pc)
{
	if(pthread_mutex_unlock(&lk->mutex) != 0)
		abort();
}

void
_procsleep(_Procrendez *r)
{
	/* r is protected by r->l, which we hold */
	pthread_cond_init(&r->cond, 0);
	r->asleep = 1;
	pthread_cond_wait(&r->cond, &r->l->mutex);
	pthread_cond_destroy(&r->cond);
	r->asleep = 0;
}

void
_procwakeup(_Procrendez *r)
{
	if(r->asleep){
		r->asleep = 0;
		pthread_cond_signal(&r->cond);
	}
}

void
_procwakeupandunlock(_Procrendez *r)
{
	if(r->asleep){
		r->asleep = 0;
		pthread_cond_signal(&r->cond);
	}
	unlock(r->l);
}

static void
startprocfn(void *v)
{
	void **a;
	void (*fn)(void*);
	Proc *p;

	a = (void**)v;
	fn = (void(*)(void*))a[0];
	p = a[1];
	free(a);
	p->osprocid = pthread_self();
	pthread_detach(p->osprocid);

	(*fn)(p);

	pthread_exit(0);
}

void
_procstart(Proc *p, void (*fn)(Proc*))
{
	void **a;

	a = malloc(2*sizeof a[0]);
	if(a == nil)
		sysfatal("_procstart malloc: %r");
	a[0] = (void*)fn;
	a[1] = p;

	if(pthread_create(&p->osprocid, nil, (void*(*)(void*))startprocfn, (void*)a) < 0){
		fprint(2, "pthread_create: %r\n");
		abort();
	}
}

static pthread_key_t prockey;

Proc*
_threadproc(void)
{
	Proc *p;

	p = pthread_getspecific(prockey);
	return p;
}

void
_threadsetproc(Proc *p)
{
	pthread_setspecific(prockey, p);
}

void
_pthreadinit(void)
{
	static struct utsname un;
	pthread_t id;

	if(uname(&un) < 0)
		fprint(2, "warning: uname failed: %r\n");
	if(strcmp(un.sysname, "Linux") == 0){
		/*
		 * Want to distinguish between the old LinuxThreads pthreads
		 * and the new NPTL implementation.  NPTL uses much bigger
		 * thread IDs.
		 */
		id = pthread_self();
		if(*(ulong*)(void*)&id < 1024*1024)
			sysfatal("cannot use LinuxThreads as pthread library; see %s/src/libthread/README.Linux", get9root());
	}
	pthread_key_create(&prockey, 0);
}

void
threadexitsall(char *msg)
{
	exits(msg);
}

void
_threadpexit(void)
{
	pthread_exit(0);
}
