#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(&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;
}

