/* Copyright (c) 2013 The Regents of the University of California
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * Reader-writer queue locks (sleeping locks).
 *
 * We favor readers when reading, meaning new readers can move ahead of writers.
 * Ex: If i have some readers, then a writer, clearly the writer blocks.  If
 * more readers come in, they can just come in and the presence of the writer
 * doesn't stop them.
 *
 * You get potential writer starvation, but you also get the property that
 * if a thread holds a read-lock, that thread can grab the same reader
 * lock again.  A more general statement would be "if some reader holds
 * a rwlock, then any other thread (including itself) can get an rlock".
 *
 * Similarly, writers favor other writers.  So if a writer is unlocking, it'll
 * pass the lock to another writer first.  Here, there is potential reader
 * starvation.
 *
 * We also pass locks, instead of letting recently woken threads fight for it.
 * In the case of a reader wakeup, we know that they all will wake up and read.
 * Instead of having them fight for a lock and then incref, the waker (the last
 * writer) will up the count and just wake everyone.
 *
 * This also helps when a writer wants to favor another writer.  If we didn't
 * pass the lock, then a new reader could squeeze in after our old writer
 * signalled the new writer.  Even worse, in this case, the readers that we
 * didn't wake up are still sleeping, even though a reader now holds the lock.
 * It won't deadlock, (since eventually the reader will wake the writer, who
 * wakes the old readers) but it breaks the notion of a RW lock a bit. */

#include <rwlock.h>
#include <atomic.h>
#include <kthread.h>

void rwinit(struct rwlock *rw_lock)
{
	spinlock_init(&rw_lock->lock);
	atomic_init(&rw_lock->nr_readers, 0);
	rw_lock->writing = FALSE;
	cv_init_with_lock(&rw_lock->readers, &rw_lock->lock);
	cv_init_with_lock(&rw_lock->writers, &rw_lock->lock);
}

void rlock(struct rwlock *rw_lock)
{
	/* If we already have a reader, we can just increment and return.  This is
	 * the only access to nr_readers outside the lock.  All locked uses need to
	 * be aware that the nr could be concurrently increffed (unless it is 0). */
	if (atomic_add_not_zero(&rw_lock->nr_readers, 1))
		return;
	/* Here's an alternate style: the broadcaster (a writer) will up the readers
	 * count and just wake us.  All readers just proceed, instead of fighting to
	 * lock and up the count.  The writer 'passed' the rlock to us. */
	spin_lock(&rw_lock->lock);
	if (rw_lock->writing) {
		cv_wait_and_unlock(&rw_lock->readers);
		return;
	}
	atomic_inc(&rw_lock->nr_readers);
	spin_unlock(&rw_lock->lock);
}

bool canrlock(struct rwlock *rw_lock)
{
	if (atomic_add_not_zero(&rw_lock->nr_readers, 1))
		return TRUE;
	spin_lock(&rw_lock->lock);
	if (rw_lock->writing) {
		spin_unlock(&rw_lock->lock);
		return FALSE;
	}
	atomic_inc(&rw_lock->nr_readers);
	spin_unlock(&rw_lock->lock);
	return TRUE;
}

void runlock(struct rwlock *rw_lock)
{
	spin_lock(&rw_lock->lock);
	/* sub and test will tell us if we got the refcnt to 0, atomically.  syncing
	 * with the atomic_add_not_zero of new readers.  Since we're passing the
	 * lock, we need to make sure someone is sleeping.  Contrast to the wunlock,
	 * where we can just blindly broadcast and add (potentially == 0). */
	if (atomic_sub_and_test(&rw_lock->nr_readers, 1) &&
	        rw_lock->writers.nr_waiters) {
		/* passing the lock to the one writer we signal. */
		rw_lock->writing = TRUE;
		__cv_signal(&rw_lock->writers);
	}
	spin_unlock(&rw_lock->lock);
}

void wlock(struct rwlock *rw_lock)
{
	spin_lock(&rw_lock->lock);
	if (atomic_read(&rw_lock->nr_readers) || rw_lock->writing) {
		/* If we slept, the lock was passed to us */
		cv_wait_and_unlock(&rw_lock->writers);
		return;
	}
	rw_lock->writing = TRUE;
	spin_unlock(&rw_lock->lock);
}

void wunlock(struct rwlock *rw_lock)
{
	/* Pass the lock to another writer (we leave writing = TRUE) */
	spin_lock(&rw_lock->lock);
	if (rw_lock->writers.nr_waiters) {
		/* Just waking one */
		__cv_signal(&rw_lock->writers);
		spin_unlock(&rw_lock->lock);
		return;
	}
	rw_lock->writing = FALSE;
	atomic_set(&rw_lock->nr_readers, rw_lock->readers.nr_waiters);
	__cv_broadcast(&rw_lock->readers);
	spin_unlock(&rw_lock->lock);
}
