Ejemplo n.º 1
0
status_t
rw_lock_read_unlock(rw_lock *lock)
{
	MutexLocker locker(lock->lock);

	if (lock->holder == find_thread(NULL)) {
		if (--lock->owner_count > 0)
			return B_OK;

		// this originally has been a write lock
		lock->writer_count--;
		lock->holder = -1;

		rw_lock_unblock(lock);
		return B_OK;
	}

	if (lock->reader_count <= 0) {
		debugger("rw_lock not read locked");
		return B_ERROR;
	}

	lock->reader_count--;
	rw_lock_unblock(lock);
	return B_OK;
}
Ejemplo n.º 2
0
void
_rw_lock_write_unlock(rw_lock* lock)
{
	InterruptsSpinLocker locker(lock->lock);

	if (thread_get_current_thread_id() != lock->holder) {
		panic("rw_lock_write_unlock(): lock %p not write-locked by this thread",
			lock);
		return;
	}

	ASSERT(lock->owner_count >= RW_LOCK_WRITER_COUNT_BASE);

	lock->owner_count -= RW_LOCK_WRITER_COUNT_BASE;
	if (lock->owner_count >= RW_LOCK_WRITER_COUNT_BASE)
		return;

	// We gave up our last write lock -- clean up and unblock waiters.
	int32 readerCount = lock->owner_count;
	lock->holder = -1;
	lock->owner_count = 0;

	int32 oldCount = atomic_add(&lock->count, -RW_LOCK_WRITER_COUNT_BASE);
	oldCount -= RW_LOCK_WRITER_COUNT_BASE;

	if (oldCount != 0) {
		// If writers are waiting, take over our reader count.
		if (oldCount >= RW_LOCK_WRITER_COUNT_BASE) {
			lock->active_readers = readerCount;
			rw_lock_unblock(lock);
		} else {
			// No waiting writer, but there are one or more readers. We will
			// unblock all waiting readers -- that's the easy part -- and must
			// also make sure that all readers that haven't entered the critical
			// section yet, won't start to wait. Otherwise a writer overtaking
			// such a reader will correctly start to wait, but the reader,
			// seeing the writer count > 0, would also start to wait. We set
			// pending_readers to the number of readers that are still expected
			// to enter the critical section.
			lock->pending_readers = oldCount - readerCount
				- rw_lock_unblock(lock);
		}
	}
}
Ejemplo n.º 3
0
status_t
rw_lock_write_unlock(rw_lock *lock)
{
	MutexLocker locker(lock->lock);

	if (lock->holder != find_thread(NULL)) {
		debugger("rw_lock not write locked");
		return B_ERROR;
	}

	if (--lock->owner_count > 0)
		return B_OK;

	lock->writer_count--;
	lock->holder = -1;
	rw_lock_unblock(lock);
	return B_OK;
}
Ejemplo n.º 4
0
void
_rw_lock_read_unlock(rw_lock* lock)
{
	InterruptsSpinLocker locker(lock->lock);

	// If we're still holding the write lock or if there are other readers,
	// no-one can be woken up.
	if (lock->holder == thread_get_current_thread_id()) {
		ASSERT(lock->owner_count % RW_LOCK_WRITER_COUNT_BASE > 0);
		lock->owner_count--;
		return;
	}

	if (--lock->active_readers > 0)
		return;

 	if (lock->active_readers < 0) {
 		panic("rw_lock_read_unlock(): lock %p not read-locked", lock);
		lock->active_readers = 0;
 		return;
 	}

	rw_lock_unblock(lock);
}