/* Copyright (c) 2016-2017 Google, Inc.
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details. */

/* Generic Uthread Semaphores, Mutexes, CVs, and other synchronization
 * functions.  2LSs implement their own sync objects (bottom of the file). */

#include <parlib/uthread.h>
#include <sys/queue.h>
#include <parlib/spinlock.h>
#include <parlib/alarm.h>
#include <parlib/assert.h>
#include <malloc.h>

struct timeout_blob {
	bool				timed_out;
	struct uthread			*uth;
	uth_sync_t			*sync_ptr;
	struct spin_pdr_lock		*lock_ptr;
};

/* When sync primitives want to time out, they can use this alarm handler.  It
 * needs a timeout_blob, which is independent of any particular sync method. */
static void timeout_handler(struct alarm_waiter *waiter)
{
	struct timeout_blob *blob = (struct timeout_blob*)waiter->data;

	spin_pdr_lock(blob->lock_ptr);
	if (__uth_sync_get_uth(blob->sync_ptr, blob->uth))
		blob->timed_out = TRUE;
	spin_pdr_unlock(blob->lock_ptr);
	if (blob->timed_out)
		uthread_runnable(blob->uth);
}

/* Minor helper, sets a blob's fields */
static void set_timeout_blob(struct timeout_blob *blob, uth_sync_t *sync_ptr,
                             struct spin_pdr_lock *lock_ptr)
{
	blob->timed_out = FALSE;
	blob->uth = current_uthread;
	blob->sync_ptr = sync_ptr;
	blob->lock_ptr = lock_ptr;
}

/* Minor helper, sets an alarm for blob and a timespec */
static void set_timeout_alarm(struct alarm_waiter *waiter,
                              struct timeout_blob *blob,
                              const struct timespec *abs_timeout)
{
	init_awaiter(waiter, timeout_handler);
	waiter->data = blob;
	set_awaiter_abs_unix(waiter, timespec_to_alarm_time(abs_timeout));
	set_alarm(waiter);
}

/************** Semaphores and Mutexes **************/

static void __uth_semaphore_init(void *arg)
{
	struct uth_semaphore *sem = (struct uth_semaphore*)arg;

	spin_pdr_init(&sem->lock);
	__uth_sync_init(&sem->sync_obj);
	/* If we used a static initializer for a semaphore, count is already
	 * set.  o/w it will be set by _alloc() or _init() (via
	 * uth_semaphore_init()). */
}

/* Initializes a sem acquired from somewhere else.  POSIX's sem_init() needs
 * this. */
void uth_semaphore_init(uth_semaphore_t *sem, unsigned int count)
{
	__uth_semaphore_init(sem);
	sem->count = count;
	/* The once is to make sure the object is initialized. */
	parlib_set_ran_once(&sem->once_ctl);
}

/* Undoes whatever was done in init. */
void uth_semaphore_destroy(uth_semaphore_t *sem)
{
	__uth_sync_destroy(&sem->sync_obj);
}

uth_semaphore_t *uth_semaphore_alloc(unsigned int count)
{
	struct uth_semaphore *sem;

	sem = malloc(sizeof(struct uth_semaphore));
	assert(sem);
	uth_semaphore_init(sem, count);
	return sem;
}

void uth_semaphore_free(uth_semaphore_t *sem)
{
	uth_semaphore_destroy(sem);
	free(sem);
}

static void __semaphore_cb(struct uthread *uth, void *arg)
{
	struct uth_semaphore *sem = (struct uth_semaphore*)arg;

	/* We need to tell the 2LS that its thread blocked.  We need to do this
	 * before unlocking the sem, since as soon as we unlock, the sem could
	 * be released and our thread restarted.
	 *
	 * Also note the lock-ordering rule.  The sem lock is grabbed before any
	 * locks the 2LS might grab. */
	uthread_has_blocked(uth, UTH_EXT_BLK_MUTEX);
	__uth_sync_enqueue(uth, &sem->sync_obj);
	spin_pdr_unlock(&sem->lock);
}

bool uth_semaphore_timed_down(uth_semaphore_t *sem,
                              const struct timespec *abs_timeout)
{
	struct alarm_waiter waiter[1];
	struct timeout_blob blob[1];

	assert_can_block();
	parlib_run_once(&sem->once_ctl, __uth_semaphore_init, sem);
	spin_pdr_lock(&sem->lock);
	if (sem->count > 0) {
		/* Only down if we got one.  This means a sem with no more
		 * counts is 0, not negative (where -count == nr_waiters).
		 * Doing it this way means our timeout function works for sems
		 * and CVs. */
		sem->count--;
		spin_pdr_unlock(&sem->lock);
		return TRUE;
	}
	if (abs_timeout) {
		set_timeout_blob(blob, &sem->sync_obj, &sem->lock);
		set_timeout_alarm(waiter, blob, abs_timeout);
	}
	/* the unlock and sync enqueuing is done in the yield callback.  as
	 * always, we need to do this part in vcore context, since as soon as we
	 * unlock the uthread could restart.  (atomically yield and unlock). */
	uthread_yield(TRUE, __semaphore_cb, sem);
	if (abs_timeout) {
		/* We're guaranteed the alarm will either be cancelled or the
		 * handler complete when unset_alarm() returns. */
		unset_alarm(waiter);
		return blob->timed_out ? FALSE : TRUE;
	}
	return TRUE;
}

void uth_semaphore_down(uth_semaphore_t *sem)
{
	uth_semaphore_timed_down(sem, NULL);
}

bool uth_semaphore_trydown(uth_semaphore_t *sem)
{
	bool ret = FALSE;

	assert_can_block();
	parlib_run_once(&sem->once_ctl, __uth_semaphore_init, sem);
	spin_pdr_lock(&sem->lock);
	if (sem->count > 0) {
		sem->count--;
		ret = TRUE;
	}
	spin_pdr_unlock(&sem->lock);
	return ret;
}

void uth_semaphore_up(uth_semaphore_t *sem)
{
	struct uthread *uth;

	/* once-ing the 'up', unlike mtxs 'unlock', since sems can be special.
	 */
	parlib_run_once(&sem->once_ctl, __uth_semaphore_init, sem);
	spin_pdr_lock(&sem->lock);
	uth = __uth_sync_get_next(&sem->sync_obj);
	/* If there was a waiter, we pass our resource/count to them. */
	if (!uth)
		sem->count++;
	spin_pdr_unlock(&sem->lock);
	if (uth)
		uthread_runnable(uth);
}

/* Takes a void * since it's called by parlib_run_once(), which enables us to
 * statically initialize the mutex.  This init does everything not done by the
 * static initializer.  Note we do not allow 'static' destruction.  (No one
 * calls free). */
static void __uth_mutex_init(void *arg)
{
	struct uth_semaphore *mtx = (struct uth_semaphore*)arg;

	__uth_semaphore_init(mtx);
	mtx->count = 1;
}

void uth_mutex_init(uth_mutex_t *mtx)
{
	__uth_mutex_init(mtx);
	parlib_set_ran_once(&mtx->once_ctl);
}

void uth_mutex_destroy(uth_mutex_t *mtx)
{
	uth_semaphore_destroy(mtx);
}

uth_mutex_t *uth_mutex_alloc(void)
{
	struct uth_semaphore *mtx;

	mtx = malloc(sizeof(struct uth_semaphore));
	assert(mtx);
	uth_mutex_init(mtx);
	return mtx;
}

void uth_mutex_free(uth_mutex_t *mtx)
{
	uth_semaphore_free(mtx);
}

bool uth_mutex_timed_lock(uth_mutex_t *mtx, const struct timespec *abs_timeout)
{
	parlib_run_once(&mtx->once_ctl, __uth_mutex_init, mtx);
	return uth_semaphore_timed_down(mtx, abs_timeout);
}

void uth_mutex_lock(uth_mutex_t *mtx)
{
	parlib_run_once(&mtx->once_ctl, __uth_mutex_init, mtx);
	uth_semaphore_down(mtx);
}

bool uth_mutex_trylock(uth_mutex_t *mtx)
{
	parlib_run_once(&mtx->once_ctl, __uth_mutex_init, mtx);
	return uth_semaphore_trydown(mtx);
}

void uth_mutex_unlock(uth_mutex_t *mtx)
{
	uth_semaphore_up(mtx);
}

/************** Recursive mutexes **************/

static void __uth_recurse_mutex_init(void *arg)
{
	struct uth_recurse_mutex *r_mtx = (struct uth_recurse_mutex*)arg;

	__uth_mutex_init(&r_mtx->mtx);
	/* Since we always manually call __uth_mutex_init(), there's no reason
	 * to mess with the regular mutex's static initializer.  Just say it's
	 * been done. */
	parlib_set_ran_once(&r_mtx->mtx.once_ctl);
	r_mtx->lockholder = NULL;
	r_mtx->count = 0;
}

void uth_recurse_mutex_init(uth_recurse_mutex_t *r_mtx)
{
	__uth_recurse_mutex_init(r_mtx);
	parlib_set_ran_once(&r_mtx->once_ctl);
}

void uth_recurse_mutex_destroy(uth_recurse_mutex_t *r_mtx)
{
	uth_semaphore_destroy(&r_mtx->mtx);
}

uth_recurse_mutex_t *uth_recurse_mutex_alloc(void)
{
	struct uth_recurse_mutex *r_mtx =
		malloc(sizeof(struct uth_recurse_mutex));

	assert(r_mtx);
	uth_recurse_mutex_init(r_mtx);
	return r_mtx;
}

void uth_recurse_mutex_free(uth_recurse_mutex_t *r_mtx)
{
	uth_recurse_mutex_destroy(r_mtx);
	free(r_mtx);
}

bool uth_recurse_mutex_timed_lock(uth_recurse_mutex_t *r_mtx,
                                  const struct timespec *abs_timeout)
{
	assert_can_block();
	parlib_run_once(&r_mtx->once_ctl, __uth_recurse_mutex_init, r_mtx);
	/* We don't have to worry about races on current_uthread or count.  They
	 * are only written by the initial lockholder, and this check will only
	 * be true for the initial lockholder, which cannot concurrently call
	 * this function twice (a thread is single-threaded).
	 *
	 * A signal handler running for a thread should not attempt to grab a
	 * recursive mutex (that's probably a bug).  If we need to support that,
	 * we'll have to disable notifs temporarily. */
	if (r_mtx->lockholder == current_uthread) {
		r_mtx->count++;
		return TRUE;
	}
	if (!uth_mutex_timed_lock(&r_mtx->mtx, abs_timeout))
		return FALSE;
	r_mtx->lockholder = current_uthread;
	r_mtx->count = 1;
	return TRUE;
}

void uth_recurse_mutex_lock(uth_recurse_mutex_t *r_mtx)
{
	uth_recurse_mutex_timed_lock(r_mtx, NULL);
}

bool uth_recurse_mutex_trylock(uth_recurse_mutex_t *r_mtx)
{
	bool ret;

	assert_can_block();
	parlib_run_once(&r_mtx->once_ctl, __uth_recurse_mutex_init, r_mtx);
	if (r_mtx->lockholder == current_uthread) {
		r_mtx->count++;
		return TRUE;
	}
	ret = uth_mutex_trylock(&r_mtx->mtx);
	if (ret) {
		r_mtx->lockholder = current_uthread;
		r_mtx->count = 1;
	}
	return ret;
}

void uth_recurse_mutex_unlock(uth_recurse_mutex_t *r_mtx)
{
	r_mtx->count--;
	if (!r_mtx->count) {
		r_mtx->lockholder = NULL;
		uth_mutex_unlock(&r_mtx->mtx);
	}
}


/************** Condition Variables **************/


static void __uth_cond_var_init(void *arg)
{
	struct uth_cond_var *cv = (struct uth_cond_var*)arg;

	spin_pdr_init(&cv->lock);
	__uth_sync_init(&cv->sync_obj);
}

void uth_cond_var_init(uth_cond_var_t *cv)
{
	__uth_cond_var_init(cv);
	parlib_set_ran_once(&cv->once_ctl);
}

void uth_cond_var_destroy(uth_cond_var_t *cv)
{
	__uth_sync_destroy(&cv->sync_obj);
}

uth_cond_var_t *uth_cond_var_alloc(void)
{
	struct uth_cond_var *cv;

	cv = malloc(sizeof(struct uth_cond_var));
	assert(cv);
	uth_cond_var_init(cv);
	return cv;
}

void uth_cond_var_free(uth_cond_var_t *cv)
{
	uth_cond_var_destroy(cv);
	free(cv);
}

struct uth_cv_link {
	struct uth_cond_var			*cv;
	struct uth_semaphore		*mtx;
};

static void __cv_wait_cb(struct uthread *uth, void *arg)
{
	struct uth_cv_link *link = (struct uth_cv_link*)arg;
	struct uth_cond_var *cv = link->cv;
	struct uth_semaphore *mtx = link->mtx;

	/* We need to tell the 2LS that its thread blocked.  We need to do this
	 * before unlocking the cv, since as soon as we unlock, the cv could be
	 * signalled and our thread restarted.
	 *
	 * Also note the lock-ordering rule.  The cv lock is grabbed before any
	 * locks the 2LS might grab. */
	uthread_has_blocked(uth, UTH_EXT_BLK_MUTEX);
	__uth_sync_enqueue(uth, &cv->sync_obj);
	spin_pdr_unlock(&cv->lock);
	/* This looks dangerous, since both the CV and MTX could use the
	 * uth->sync_next TAILQ_ENTRY (or whatever the 2LS uses), but the
	 * uthread never sleeps on both at the same time.  We *hold* the mtx -
	 * we aren't *sleeping* on it.  Sleeping uses the sync_next.  Holding it
	 * doesn't.
	 *
	 * Next, consider what happens as soon as we unlock the CV.  Our thread
	 * could get woken up, and then immediately try to grab the mtx and go
	 * to sleep! (see below).  If that happens, the uthread is no longer
	 * sleeping on the CV, and the sync_next is free.  The invariant is that
	 * a uthread can only sleep on one sync_object at a time. */
	if (mtx)
		uth_mutex_unlock(mtx);
}

/* Caller holds mtx.  We will 'atomically' release it and wait.  On return,
 * caller holds mtx again.  Once our uth is on the CV's list, we can release the
 * mtx without fear of missing a signal.
 *
 * POSIX refers to atomicity in this context as "atomically with respect to
 * access by another thread to the mutex and then the condition variable"
 *
 * The idea is that we hold the mutex to protect some invariant; we check it,
 * and decide to sleep.  Now we get on the list before releasing so that any
 * changes to that invariant (e.g. a flag is now TRUE) happen after we're on the
 * list, and so that we don't miss the signal.  To be more clear, the invariant
 * in a basic wake-up flag scenario is: "whenever a flag is set from FALSE to
 * TRUE, all waiters that saw FALSE are on the CV's waitqueue."  The mutex is
 * required for this invariant.
 *
 * Note that signal/broadcasters do not *need* to hold the mutex, in general,
 * but they do in the basic wake-up flag scenario.  If not, the race is this:
 *
 * Sleeper:					Waker:
 * -----------------------------------------------------------------
 * Hold mutex
 *   See flag is False
 *   Decide to sleep
 *						Set flag True
 * PAUSE!					Grab CV lock
 *						See list is empty, unlock
 *
 *   Grab CV lock
 *     Get put on list
 *   Unlock CV lock
 * Unlock mutex
 * (Never wake up; we missed the signal)
 *
 * For those familiar with the kernel's CVs, we don't couple mutexes with CVs.
 * cv_lock() actually grabs the spinlock inside the CV and uses *that* to
 * protect the invariant.  The signallers always grab that lock, so the sleeper
 * is not in danger of missing the signal.  The tradeoff is that the kernel CVs
 * use a spinlock instead of a mutex for protecting its invariant; there might
 * be some case that preferred blocking sync.
 *
 * The uthread CVs take a mutex, unlike the kernel CVs, to map more cleanly to
 * POSIX CVs.  Maybe one approach or the other is a bad idea; we'll see.
 * However, we need both approaces in userspace.  To that end, we also support
 * mutex-less CVs, where the synchronization typically provided by the mutex is
 * provided by the CV's spinlock.  Just pass NULL for the mutex.  This is
 * primarily useful for CVs that are signalled from event handlers in vcore
 * context, since that code cannot block on a mutex and thus cannot use the
 * mutex to avoid the races mentioned above.
 *
 * As far as lock ordering goes, once the sleeper holds the mutex and is on the
 * CV's list, it can unlock in any order it wants.  However, unlocking a mutex
 * actually requires grabbing its spinlock.  So as to not have a lock ordering
 * between *spinlocks*, we let go of the CV's spinlock before unlocking the
 * mutex.  There is an ordering between the mutex and the CV spinlock (mutex->cv
 * spin), but there is no ordering between the mutex spin and cv spin.  And of
 * course, we need to unlock the CV spinlock in the yield callback.
 *
 * Also note that we use the external API for the mutex operations.  A 2LS could
 * have their own mutex ops but still use the generic cv ops. */
bool uth_cond_var_timed_wait(uth_cond_var_t *cv, uth_mutex_t *mtx,
                             const struct timespec *abs_timeout)
{
	struct uth_cv_link link;
	struct alarm_waiter waiter[1];
	struct timeout_blob blob[1];
	bool ret = TRUE;

	/* We're holding the CV PDR lock, so we lose the ability to detect
	 * blocking violations. */
	if (mtx)
		assert_can_block();
	parlib_run_once(&cv->once_ctl, __uth_cond_var_init, cv);
	link.cv = cv;
	link.mtx = mtx;
	if (mtx)
		spin_pdr_lock(&cv->lock);
	if (abs_timeout) {
		set_timeout_blob(blob, &cv->sync_obj, &cv->lock);
		set_timeout_alarm(waiter, blob, abs_timeout);
	}
	uthread_yield(TRUE, __cv_wait_cb, &link);
	if (abs_timeout) {
		unset_alarm(waiter);
		ret = blob->timed_out ? FALSE : TRUE;
	}
	if (mtx)
		uth_mutex_lock(mtx);
	else
		spin_pdr_lock(&cv->lock);
	return ret;
}

void uth_cond_var_wait(uth_cond_var_t *cv, uth_mutex_t *mtx)
{
	uth_cond_var_timed_wait(cv, mtx, NULL);
}

/* GCC doesn't list this as one of the C++0x functions, but it's easy to do and
 * implement uth_cond_var_wait_recurse() with it, just like for all the other
 * 'timed' functions.
 *
 * Note the timeout applies to getting the signal on the CV, not on reacquiring
 * the mutex. */
bool uth_cond_var_timed_wait_recurse(uth_cond_var_t *cv,
                                     uth_recurse_mutex_t *r_mtx,
                                     const struct timespec *abs_timeout)
{
	unsigned int old_count = r_mtx->count;
	bool ret;

	/* In cond_wait, we're going to unlock the internal mutex.  We'll do the
	 * prep-work for that now.  (invariant is that an unlocked r_mtx has no
	 * lockholder and count == 0. */
	r_mtx->lockholder = NULL;
	r_mtx->count = 0;
	ret = uth_cond_var_timed_wait(cv, &r_mtx->mtx, abs_timeout);
	/* Now we hold the internal mutex again.  Need to restore the tracking.
	 */
	r_mtx->lockholder = current_uthread;
	r_mtx->count = old_count;
	return ret;
}

/* GCC wants this function, though its semantics are a little unclear.  I
 * imagine you'd want to completely unlock it (say you locked it 3 times), and
 * when you get it back, that you have your three locks back. */
void uth_cond_var_wait_recurse(uth_cond_var_t *cv, uth_recurse_mutex_t *r_mtx)
{
	uth_cond_var_timed_wait_recurse(cv, r_mtx, NULL);
}

/* Caller holds the CV lock.  Returns a uth that needs to be woken up (or NULL),
 * which the caller needs to do with uthread_runnable(). */
struct uthread *__uth_cond_var_wake_one(uth_cond_var_t *cv)
{
	return __uth_sync_get_next(&cv->sync_obj);
}

/* Caller holds the CV lock. */
void __uth_cond_var_signal_and_unlock(uth_cond_var_t *cv)
{
	struct uthread *uth = __uth_cond_var_wake_one(cv);

	spin_pdr_unlock(&cv->lock);
	if (uth)
		uthread_runnable(uth);
}

void uth_cond_var_signal(uth_cond_var_t *cv)
{
	parlib_run_once(&cv->once_ctl, __uth_cond_var_init, cv);

	spin_pdr_lock(&cv->lock);
	__uth_cond_var_signal_and_unlock(cv);
}

/* Caller holds the CV lock.  Returns true if the restartees need to be woken
 * up, which the caller needs to do with __uth_sync_wake_all(). */
bool __uth_cond_var_wake_all(uth_cond_var_t *cv, uth_sync_t *restartees)
{
	if (__uth_sync_is_empty(&cv->sync_obj))
		return false;
	__uth_sync_init(restartees);
	__uth_sync_swap(restartees, &cv->sync_obj);
	return true;
}

/* Caller holds the CV lock. */
void __uth_cond_var_broadcast_and_unlock(uth_cond_var_t *cv)
{
	uth_sync_t restartees;
	bool wake;

	wake = __uth_cond_var_wake_all(cv, &restartees);
	spin_pdr_unlock(&cv->lock);
	if (wake)
		__uth_sync_wake_all(&restartees);
}

void uth_cond_var_broadcast(uth_cond_var_t *cv)
{
	parlib_run_once(&cv->once_ctl, __uth_cond_var_init, cv);

	spin_pdr_lock(&cv->lock);
	__uth_cond_var_broadcast_and_unlock(cv);
}

/* Similar to the kernel, we can grab the CV's spinlock directly and use that
 * for synchronization.  This is primarily so we can signal/broadcast from vcore
 * context, and you typically need to hold some lock when changing state before
 * signalling. */
void uth_cond_var_lock(uth_cond_var_t *cv)
{
	parlib_run_once(&cv->once_ctl, __uth_cond_var_init, cv);

	spin_pdr_lock(&cv->lock);
}

void uth_cond_var_unlock(uth_cond_var_t *cv)
{
	spin_pdr_unlock(&cv->lock);
}

/************** Reader-writer Sleeping Locks **************/


static void __uth_rwlock_init(void *arg)
{
	struct uth_rwlock *rwl = (struct uth_rwlock*)arg;

	spin_pdr_init(&rwl->lock);
	rwl->nr_readers = 0;
	rwl->has_writer = FALSE;
	__uth_sync_init(&rwl->readers);
	__uth_sync_init(&rwl->writers);
}

void uth_rwlock_init(uth_rwlock_t *rwl)
{
	__uth_rwlock_init(rwl);
	parlib_set_ran_once(&rwl->once_ctl);
}

void uth_rwlock_destroy(uth_rwlock_t *rwl)
{
	__uth_sync_destroy(&rwl->readers);
	__uth_sync_destroy(&rwl->writers);
}

uth_rwlock_t *uth_rwlock_alloc(void)
{
	struct uth_rwlock *rwl;

	rwl = malloc(sizeof(struct uth_rwlock));
	assert(rwl);
	uth_rwlock_init(rwl);
	return rwl;
}

void uth_rwlock_free(uth_rwlock_t *rwl)
{
	uth_rwlock_destroy(rwl);
	free(rwl);
}

/* Readers and writers block until they have the lock.  The delicacies are dealt
 * with by the unlocker. */
static void __rwlock_rd_cb(struct uthread *uth, void *arg)
{
	struct uth_rwlock *rwl = (struct uth_rwlock*)arg;

	uthread_has_blocked(uth, UTH_EXT_BLK_MUTEX);
	__uth_sync_enqueue(uth, &rwl->readers);
	spin_pdr_unlock(&rwl->lock);
}

void uth_rwlock_rdlock(uth_rwlock_t *rwl)
{
	assert_can_block();
	parlib_run_once(&rwl->once_ctl, __uth_rwlock_init, rwl);
	spin_pdr_lock(&rwl->lock);
	/* Readers always make progress when there is no writer */
	if (!rwl->has_writer) {
		rwl->nr_readers++;
		spin_pdr_unlock(&rwl->lock);
		return;
	}
	uthread_yield(TRUE, __rwlock_rd_cb, rwl);
}

bool uth_rwlock_try_rdlock(uth_rwlock_t *rwl)
{
	bool ret = FALSE;

	assert_can_block();
	parlib_run_once(&rwl->once_ctl, __uth_rwlock_init, rwl);
	spin_pdr_lock(&rwl->lock);
	if (!rwl->has_writer) {
		rwl->nr_readers++;
		ret = TRUE;
	}
	spin_pdr_unlock(&rwl->lock);
	return ret;
}

static void __rwlock_wr_cb(struct uthread *uth, void *arg)
{
	struct uth_rwlock *rwl = (struct uth_rwlock*)arg;

	uthread_has_blocked(uth, UTH_EXT_BLK_MUTEX);
	__uth_sync_enqueue(uth, &rwl->writers);
	spin_pdr_unlock(&rwl->lock);
}

void uth_rwlock_wrlock(uth_rwlock_t *rwl)
{
	assert_can_block();
	parlib_run_once(&rwl->once_ctl, __uth_rwlock_init, rwl);
	spin_pdr_lock(&rwl->lock);
	/* Writers require total mutual exclusion - no writers or readers */
	if (!rwl->has_writer && !rwl->nr_readers) {
		rwl->has_writer = TRUE;
		spin_pdr_unlock(&rwl->lock);
		return;
	}
	uthread_yield(TRUE, __rwlock_wr_cb, rwl);
}

bool uth_rwlock_try_wrlock(uth_rwlock_t *rwl)
{
	bool ret = FALSE;

	assert_can_block();
	parlib_run_once(&rwl->once_ctl, __uth_rwlock_init, rwl);
	spin_pdr_lock(&rwl->lock);
	if (!rwl->has_writer && !rwl->nr_readers) {
		rwl->has_writer = TRUE;
		ret = TRUE;
	}
	spin_pdr_unlock(&rwl->lock);
	return ret;
}

/* Let's try to wake writers (yes, this is a policy decision), and if none, wake
 * all the readers.  The invariant there is that if there is no writer, then
 * there are no waiting readers. */
static void __rw_unlock_writer(struct uth_rwlock *rwl,
                               struct uth_tailq *restartees)
{
	struct uthread *uth;

	uth = __uth_sync_get_next(&rwl->writers);
	if (uth) {
		TAILQ_INSERT_TAIL(restartees, uth, sync_next);
	} else {
		rwl->has_writer = FALSE;
		while ((uth = __uth_sync_get_next(&rwl->readers))) {
			TAILQ_INSERT_TAIL(restartees, uth, sync_next);
			rwl->nr_readers++;
		}
	}
}

static void __rw_unlock_reader(struct uth_rwlock *rwl,
                               struct uth_tailq *restartees)
{
	struct uthread *uth;

	rwl->nr_readers--;
	if (!rwl->nr_readers) {
		uth = __uth_sync_get_next(&rwl->writers);
		if (uth) {
			TAILQ_INSERT_TAIL(restartees, uth, sync_next);
			rwl->has_writer = TRUE;
		}
	}
}

/* Unlock works for either readers or writer locks.  You can tell which you were
 * based on whether has_writer is set or not. */
void uth_rwlock_unlock(uth_rwlock_t *rwl)
{
	struct uth_tailq restartees = TAILQ_HEAD_INITIALIZER(restartees);
	struct uthread *i, *safe;

	spin_pdr_lock(&rwl->lock);
	if (rwl->has_writer)
		__rw_unlock_writer(rwl, &restartees);
	else
		__rw_unlock_reader(rwl, &restartees);
	spin_pdr_unlock(&rwl->lock);
	TAILQ_FOREACH_SAFE(i, &restartees, sync_next, safe)
		uthread_runnable(i);
}


/************** Default Sync Obj Implementation **************/

static void uth_default_sync_init(uth_sync_t *sync)
{
	struct uth_tailq *tq = (struct uth_tailq*)sync;

	parlib_static_assert(sizeof(struct uth_tailq) <= sizeof(uth_sync_t));
	TAILQ_INIT(tq);
}

static void uth_default_sync_destroy(uth_sync_t *sync)
{
	struct uth_tailq *tq = (struct uth_tailq*)sync;

	assert(TAILQ_EMPTY(tq));
}

static void uth_default_sync_enqueue(struct uthread *uth, uth_sync_t *sync)
{
	struct uth_tailq *tq = (struct uth_tailq*)sync;

	TAILQ_INSERT_TAIL(tq, uth, sync_next);
}

static struct uthread *uth_default_sync_get_next(uth_sync_t *sync)
{
	struct uth_tailq *tq = (struct uth_tailq*)sync;
	struct uthread *first;

	first = TAILQ_FIRST(tq);
	if (first)
		TAILQ_REMOVE(tq, first, sync_next);
	return first;
}

static bool uth_default_sync_get_uth(uth_sync_t *sync, struct uthread *uth)
{
	struct uth_tailq *tq = (struct uth_tailq*)sync;
	struct uthread *i;

	TAILQ_FOREACH(i, tq, sync_next) {
		if (i == uth) {
			TAILQ_REMOVE(tq, i, sync_next);
			return TRUE;
		}
	}
	return FALSE;
}

static void uth_default_sync_swap(uth_sync_t *a, uth_sync_t *b)
{
	struct uth_tailq *tq_a = (struct uth_tailq*)a;
	struct uth_tailq *tq_b = (struct uth_tailq*)b;

	TAILQ_SWAP(tq_a, tq_b, uthread, sync_next);
}

static bool uth_default_sync_is_empty(uth_sync_t *sync)
{
	struct uth_tailq *tq = (struct uth_tailq*)sync;

	return TAILQ_EMPTY(tq);
}

/************** External uthread sync interface **************/

/* Called by 2LS-independent sync code when a sync object needs initialized. */
void __uth_sync_init(uth_sync_t *sync)
{
	if (sched_ops->sync_init) {
		sched_ops->sync_init(sync);
		return;
	}
	uth_default_sync_init(sync);
}

/* Called by 2LS-independent sync code when a sync object is destroyed. */
void __uth_sync_destroy(uth_sync_t *sync)
{
	if (sched_ops->sync_destroy) {
		sched_ops->sync_destroy(sync);
		return;
	}
	uth_default_sync_destroy(sync);
}

/* Called by 2LS-independent sync code when a thread blocks on sync */
void __uth_sync_enqueue(struct uthread *uth, uth_sync_t *sync)
{
	if (sched_ops->sync_enqueue) {
		sched_ops->sync_enqueue(uth, sync);
		return;
	}
	uth_default_sync_enqueue(uth, sync);
}

/* Called by 2LS-independent sync code when a thread needs to be woken. */
struct uthread *__uth_sync_get_next(uth_sync_t *sync)
{
	if (sched_ops->sync_get_next)
		return sched_ops->sync_get_next(sync);
	return uth_default_sync_get_next(sync);
}

/* Called by 2LS-independent sync code when a specific thread needs to be woken.
 * Returns TRUE if the uthread was blocked on the object, FALSE o/w. */
bool __uth_sync_get_uth(uth_sync_t *sync, struct uthread *uth)
{
	if (sched_ops->sync_get_uth)
		return sched_ops->sync_get_uth(sync, uth);
	return uth_default_sync_get_uth(sync, uth);
}

/* Called by 2LS-independent sync code to swap members of sync objects. */
void __uth_sync_swap(uth_sync_t *a, uth_sync_t *b)
{
	if (sched_ops->sync_swap) {
		sched_ops->sync_swap(a, b);
		return;
	}
	uth_default_sync_swap(a, b);
}

/* Called by 2LS-independent sync code */
bool __uth_sync_is_empty(uth_sync_t *sync)
{
	if (sched_ops->sync_is_empty)
		return sched_ops->sync_is_empty(sync);
	return uth_default_sync_is_empty(sync);
}

/* Called by 2LS-independent sync code to wake up all uths on sync.  You should
 * probably not hold locks while you do this - swap the items to a local sync
 * object first. */
void __uth_sync_wake_all(uth_sync_t *wakees)
{
	struct uthread *uth_i;

	if (sched_ops->thread_bulk_runnable) {
		sched_ops->thread_bulk_runnable(wakees);
	} else {
		while ((uth_i = __uth_sync_get_next(wakees)))
			uthread_runnable(uth_i);
	}
}
