/*
 * Copyright (c) 2008-2009 Travis Geiselbrecht
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include <debug.h>
#include <err.h>
#include <kernel/mutex.h>
#include <kernel/thread.h>

#if DEBUGLEVEL > 1
#define MUTEX_CHECK 1
#endif

void mutex_init(mutex_t *m)
{
#if MUTEX_CHECK
//	ASSERT(m->magic != MUTEX_MAGIC);
#endif

	m->magic = MUTEX_MAGIC;
	m->count = 0;
	m->holder = 0;
	wait_queue_init(&m->wait);
}

void mutex_destroy(mutex_t *m)
{
	enter_critical_section();

#if MUTEX_CHECK
	ASSERT(m->magic == MUTEX_MAGIC);
#endif

//	if (m->holder != 0 && current_thread != m->holder)
//		panic("mutex_destroy: thread %p (%s) tried to release mutex %p it doesn't own. owned by %p (%s)\n", 
//				current_thread, current_thread->name, m, m->holder, m->holder ? m->holder->name : "none");

	m->magic = 0;
	m->count = 0;
	wait_queue_destroy(&m->wait, true);
	exit_critical_section();
}

status_t mutex_acquire(mutex_t *m)
{
	status_t ret = NO_ERROR;

	if (current_thread == m->holder)
		panic("mutex_acquire: thread %p (%s) tried to acquire mutex %p it already owns.\n",
				current_thread, current_thread->name, m);

	enter_critical_section();

#if MUTEX_CHECK
	ASSERT(m->magic == MUTEX_MAGIC);
#endif

//	dprintf("mutex_acquire: m %p, count %d, curr %p\n", m, m->count, current_thread);

	m->count++;
	if (unlikely(m->count > 1)) {
		/* 
		 * block on the wait queue. If it returns an error, it was likely destroyed
		 * out from underneath us, so make sure we dont scribble thread ownership 
		 * on the mutex.
		 */
		ret = wait_queue_block(&m->wait, INFINITE_TIME);
		if (ret < 0)
			goto err;
	}
	m->holder = current_thread;	

err:
	exit_critical_section();

	return ret;
}

status_t mutex_acquire_timeout(mutex_t *m, time_t timeout)
{
	status_t ret = NO_ERROR;

	if (current_thread == m->holder)
		panic("mutex_acquire_timeout: thread %p (%s) tried to acquire mutex %p it already owns.\n",
				current_thread, current_thread->name, m);

	if (timeout == INFINITE_TIME)
		return mutex_acquire(m);

	enter_critical_section();

#if MUTEX_CHECK
	ASSERT(m->magic == MUTEX_MAGIC);
#endif

//	dprintf("mutex_acquire_timeout: m %p, count %d, curr %p, timeout %d\n", m, m->count, current_thread, timeout);

	m->count++;
	if (unlikely(m->count > 1)) {
		ret = wait_queue_block(&m->wait, timeout);
		if (ret < NO_ERROR) {
			/* if the acquisition timed out, back out the acquire and exit */
			if (ret == ERR_TIMED_OUT) {
				/* 
				 * XXX race: the mutex may have been destroyed after the timeout,
				 * but before we got scheduled again which makes messing with the
				 * count variable dangerous.
				 */
				m->count--;
				goto err;
			}
			/* if there was a general error, it may have been destroyed out from 
			 * underneath us, so just exit (which is really an invalid state anyway)
			 */
		}	
	}
	m->holder = current_thread;	

err:
	exit_critical_section();

	return ret;
}

status_t mutex_release(mutex_t *m)
{
	if (current_thread != m->holder)
		panic("mutex_release: thread %p (%s) tried to release mutex %p it doesn't own. owned by %p (%s)\n", 
				current_thread, current_thread->name, m, m->holder, m->holder ? m->holder->name : "none");

	enter_critical_section();

#if MUTEX_CHECK
	ASSERT(m->magic == MUTEX_MAGIC);
#endif

//	dprintf("mutex_release: m %p, count %d, holder %p, curr %p\n", m, m->count, m->holder, current_thread);

	m->holder = 0;
	m->count--;
	if (unlikely(m->count >= 1)) {
		/* release a thread */
//		dprintf("releasing thread\n");
		wait_queue_wake_one(&m->wait, true, NO_ERROR);
	}

	exit_critical_section();

	return NO_ERROR;
}

