coroutine: Add CoRwlock support
Signed-off-by: Aneesh Kumar K.V <aneesh.kumar@linux.vnet.ibm.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
parent
b861b7419c
commit
12888904fe
@ -115,3 +115,47 @@ void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex)
|
||||
|
||||
trace_qemu_co_mutex_unlock_return(mutex, self);
|
||||
}
|
||||
|
||||
void qemu_co_rwlock_init(CoRwlock *lock)
|
||||
{
|
||||
memset(lock, 0, sizeof(*lock));
|
||||
qemu_co_queue_init(&lock->queue);
|
||||
}
|
||||
|
||||
void qemu_co_rwlock_rdlock(CoRwlock *lock)
|
||||
{
|
||||
while (lock->writer) {
|
||||
qemu_co_queue_wait(&lock->queue);
|
||||
}
|
||||
lock->reader++;
|
||||
}
|
||||
|
||||
void qemu_co_rwlock_unlock(CoRwlock *lock)
|
||||
{
|
||||
assert(qemu_in_coroutine());
|
||||
if (lock->writer) {
|
||||
lock->writer = false;
|
||||
while (!qemu_co_queue_empty(&lock->queue)) {
|
||||
/*
|
||||
* Wakeup every body. This will include some
|
||||
* writers too.
|
||||
*/
|
||||
qemu_co_queue_next(&lock->queue);
|
||||
}
|
||||
} else {
|
||||
lock->reader--;
|
||||
assert(lock->reader >= 0);
|
||||
/* Wakeup only one waiting writer */
|
||||
if (!lock->reader) {
|
||||
qemu_co_queue_next(&lock->queue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void qemu_co_rwlock_wrlock(CoRwlock *lock)
|
||||
{
|
||||
while (lock->writer || lock->reader) {
|
||||
qemu_co_queue_wait(&lock->queue);
|
||||
}
|
||||
lock->writer = true;
|
||||
}
|
||||
|
@ -156,4 +156,36 @@ void coroutine_fn qemu_co_mutex_lock(CoMutex *mutex);
|
||||
*/
|
||||
void coroutine_fn qemu_co_mutex_unlock(CoMutex *mutex);
|
||||
|
||||
typedef struct CoRwlock {
|
||||
bool writer;
|
||||
int reader;
|
||||
CoQueue queue;
|
||||
} CoRwlock;
|
||||
|
||||
/**
|
||||
* Initialises a CoRwlock. This must be called before any other operation
|
||||
* is used on the CoRwlock
|
||||
*/
|
||||
void qemu_co_rwlock_init(CoRwlock *lock);
|
||||
|
||||
/**
|
||||
* Read locks the CoRwlock. If the lock cannot be taken immediately because
|
||||
* of a parallel writer, control is transferred to the caller of the current
|
||||
* coroutine.
|
||||
*/
|
||||
void qemu_co_rwlock_rdlock(CoRwlock *lock);
|
||||
|
||||
/**
|
||||
* Write Locks the mutex. If the lock cannot be taken immediately because
|
||||
* of a parallel reader, control is transferred to the caller of the current
|
||||
* coroutine.
|
||||
*/
|
||||
void qemu_co_rwlock_wrlock(CoRwlock *lock);
|
||||
|
||||
/**
|
||||
* Unlocks the read/write lock and schedules the next coroutine that was
|
||||
* waiting for this lock to be run.
|
||||
*/
|
||||
void qemu_co_rwlock_unlock(CoRwlock *lock);
|
||||
|
||||
#endif /* QEMU_COROUTINE_H */
|
||||
|
Loading…
Reference in New Issue
Block a user