#include <parlib/uthread.h>
#include <semaphore.h>
#include <parlib/mcs.h>
#include <stdio.h>
#include <benchutil/alarm.h>
#include <errno.h>

int sem_init (sem_t *__sem, int __pshared, unsigned int __value)
{
	if(__pshared == TRUE) {
		printf("__pshared functionality of sem_init is not yet implemented!");
		return -1;
	}
	__sem->count = __value;
	TAILQ_INIT(&__sem->queue);
	spin_pdr_init(&__sem->lock);
	return 0;
}

int sem_destroy (sem_t *__sem)
{
	return 0;
}

sem_t *sem_open (__const char *__name, int __oflag, ...)
{
	printf("sem_open is not yet implemented!");
	return NULL;
}

int sem_close (sem_t *__sem)
{
	printf("sem_close is not yet implemented!");
	return -1;
}

int sem_unlink (__const char *__name)
{
	printf("sem_unlink is not yet implemented!");
	return -1;
}

static void __sem_timeout(struct alarm_waiter *awaiter)
{
	struct sem_queue_element *e = awaiter->data;
	struct sem_queue_element *__e = NULL;

	/* Try and yank out the thread. */
	spin_pdr_lock(&e->sem->lock);
	TAILQ_FOREACH(__e, &e->sem->queue, next)
		if (__e == e) break;
	if (__e) {
		TAILQ_REMOVE(&e->sem->queue, e, next);
		e->timedout = true;
	}
	spin_pdr_unlock(&e->sem->lock);

	/* If we were able to yank it out, wake it up. */
	if (__e)
		uthread_runnable((struct uthread*)e->pthread);

	/* Set this as the very last thing we do whether we
	 * successfully woke the thread blocked on the futex or not.
	 * Either we set this or post() sets this, not both.  Spin on
	 * this in the bottom-half of the wait() code to ensure there
	 * are no more references to awaiter before freeing the
	 * memory for it. */
	e->awaiter.data = NULL;
}

static void __sem_block(struct uthread *uthread, void *arg)
{
	struct sem_queue_element *e = (struct sem_queue_element *)arg;
	pthread_t pthread = (pthread_t)uthread;
	__pthread_generic_yield(pthread);
	pthread->state = PTH_BLK_MUTEX;
	TAILQ_INSERT_TAIL(&e->sem->queue, e, next);
	spin_pdr_unlock(&e->sem->lock);
}

static void __sem_timedblock(struct uthread *uthread, void *arg)
{
	struct sem_queue_element *e = (struct sem_queue_element *)arg;
	e->awaiter.data = e;
	init_awaiter(&e->awaiter, __sem_timeout);
	set_awaiter_abs_unix(&e->awaiter, e->us_timeout);
	set_alarm(&e->awaiter);
	__sem_block(uthread, e);
}

int sem_wait (sem_t *__sem)
{
	pthread_t pthread = (pthread_t)current_uthread;
	struct sem_queue_element e = {{0}, __sem, pthread, -1, {0}, false};

	spin_pdr_lock(&__sem->lock);
	if(__sem->count > 0) {
		__sem->count--;
		spin_pdr_unlock(&__sem->lock);
	}
	else {
		/* We unlock in the body of __sem_block */
		uthread_yield(TRUE, __sem_block, &e);
	}
	return 0;
}

int sem_timedwait(sem_t *__sem, const struct timespec *abs_timeout)
{
	int ret = 0;
	uint64_t us = abs_timeout->tv_nsec/1000 + (abs_timeout->tv_sec)*1000000L;
	pthread_t pthread = (pthread_t)current_uthread;
	struct sem_queue_element e = {{0}, __sem, pthread, us, {0}, false};

	spin_pdr_lock(&__sem->lock);
	if(__sem->count > 0) {
		__sem->count--;
		spin_pdr_unlock(&__sem->lock);
	}
	else {
		/* We unlock in the body of __sem_block */
		uthread_yield(TRUE, __sem_timedblock, &e);

		/* Spin briefly to make sure that all references to e are
		 * gone between the post() and the timeout() code. We use
		 * e.awaiter.data to do this. */
		while (e.awaiter.data != NULL)
			cpu_relax();

		if (e.timedout) {
			errno = ETIMEDOUT;
			ret = -1;
		}
	}
	return ret;
}

int sem_trywait (sem_t *__sem)
{
	int ret = -1;
	spin_pdr_lock(&__sem->lock);
	if(__sem->count > 0) {
		__sem->count--;
		ret = 0;
	}
	spin_pdr_unlock(&__sem->lock);
	return ret;
}

int sem_post (sem_t *__sem)
{
	spin_pdr_lock(&__sem->lock);
	struct sem_queue_element *e = TAILQ_FIRST(&__sem->queue);
	if (e)
		TAILQ_REMOVE(&__sem->queue, e, next);
	else
		__sem->count++;	
	spin_pdr_unlock(&__sem->lock);

	if (e) {
		if(e->us_timeout != (uint64_t)-1) {
			/* Try and unset the alarm.  If this fails, then we
			 * have already started running the alarm callback.  If
			 * it succeeds, then we can set awaiter->data to NULL
			 * so that the bottom half of wake can proceed. Either
			 * we set awaiter->data to NULL or __sem_timeout
			 * does. The fact that we made it here though, means
			 * that WE are the one who removed e from the queue, so
			 * we are basically just deciding who should set
			 * awaiter->data to NULL to indicate that there are no
			 * more references to it. */
			if(unset_alarm(&e->awaiter))
				e->awaiter.data = NULL;
		}
		uthread_runnable((struct uthread*)e->pthread);
	}
	return 0;
}

int sem_getvalue (sem_t *__restrict __sem, int *__restrict __sval)
{
	spin_pdr_lock(&__sem->lock);
	*__sval = __sem->count;
	spin_pdr_unlock(&__sem->lock);
	return 0;
}

