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);
|
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);
|
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 */
|
#endif /* QEMU_COROUTINE_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user