diff options
Diffstat (limited to 'include/qemu')
| -rw-r--r-- | include/qemu/lockcnt.h | 130 | ||||
| -rw-r--r-- | include/qemu/thread.h | 111 |
2 files changed, 130 insertions, 111 deletions
diff --git a/include/qemu/lockcnt.h b/include/qemu/lockcnt.h new file mode 100644 index 0000000000..2c92ae17c9 --- /dev/null +++ b/include/qemu/lockcnt.h @@ -0,0 +1,130 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * QemuLockCnt implementation + * + * Copyright Red Hat, Inc. 2017 + * + * Author: + * Paolo Bonzini <pbonzini@redhat.com> + * + */ + +#ifndef QEMU_LOCKCNT_H +#define QEMU_LOCKCNT_H + +#include "qemu/thread.h" + +typedef struct QemuLockCnt QemuLockCnt; + +struct QemuLockCnt { +#ifndef CONFIG_LINUX + QemuMutex mutex; +#endif + unsigned count; +}; + +/** + * qemu_lockcnt_init: initialize a QemuLockcnt + * @lockcnt: the lockcnt to initialize + * + * Initialize lockcnt's counter to zero and prepare its mutex + * for usage. + */ +void qemu_lockcnt_init(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_destroy: destroy a QemuLockcnt + * @lockcnt: the lockcnt to destruct + * + * Destroy lockcnt's mutex. + */ +void qemu_lockcnt_destroy(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_inc: increment a QemuLockCnt's counter + * @lockcnt: the lockcnt to operate on + * + * If the lockcnt's count is zero, wait for critical sections + * to finish and increment lockcnt's count to 1. If the count + * is not zero, just increment it. + * + * Because this function can wait on the mutex, it must not be + * called while the lockcnt's mutex is held by the current thread. + * For the same reason, qemu_lockcnt_inc can also contribute to + * AB-BA deadlocks. This is a sample deadlock scenario: + * + * thread 1 thread 2 + * ------------------------------------------------------- + * qemu_lockcnt_lock(&lc1); + * qemu_lockcnt_lock(&lc2); + * qemu_lockcnt_inc(&lc2); + * qemu_lockcnt_inc(&lc1); + */ +void qemu_lockcnt_inc(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_dec: decrement a QemuLockCnt's counter + * @lockcnt: the lockcnt to operate on + */ +void qemu_lockcnt_dec(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_dec_and_lock: decrement a QemuLockCnt's counter and + * possibly lock it. + * @lockcnt: the lockcnt to operate on + * + * Decrement lockcnt's count. If the new count is zero, lock + * the mutex and return true. Otherwise, return false. + */ +bool qemu_lockcnt_dec_and_lock(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_dec_if_lock: possibly decrement a QemuLockCnt's counter and + * lock it. + * @lockcnt: the lockcnt to operate on + * + * If the count is 1, decrement the count to zero, lock + * the mutex and return true. Otherwise, return false. + */ +bool qemu_lockcnt_dec_if_lock(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_lock: lock a QemuLockCnt's mutex. + * @lockcnt: the lockcnt to operate on + * + * Remember that concurrent visits are not blocked unless the count is + * also zero. You can use qemu_lockcnt_count to check for this inside a + * critical section. + */ +void qemu_lockcnt_lock(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_unlock: release a QemuLockCnt's mutex. + * @lockcnt: the lockcnt to operate on. + */ +void qemu_lockcnt_unlock(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_inc_and_unlock: combined unlock/increment on a QemuLockCnt. + * @lockcnt: the lockcnt to operate on. + * + * This is the same as + * + * qemu_lockcnt_unlock(lockcnt); + * qemu_lockcnt_inc(lockcnt); + * + * but more efficient. + */ +void qemu_lockcnt_inc_and_unlock(QemuLockCnt *lockcnt); + +/** + * qemu_lockcnt_count: query a LockCnt's count. + * @lockcnt: the lockcnt to query. + * + * Note that the count can change at any time. Still, while the + * lockcnt is locked, one can usefully check whether the count + * is non-zero. + */ +unsigned qemu_lockcnt_count(QemuLockCnt *lockcnt); + +#endif diff --git a/include/qemu/thread.h b/include/qemu/thread.h index fb74e21c08..7eba27a704 100644 --- a/include/qemu/thread.h +++ b/include/qemu/thread.h @@ -293,115 +293,4 @@ static inline void qemu_spin_unlock(QemuSpin *spin) #endif } -struct QemuLockCnt { -#ifndef CONFIG_LINUX - QemuMutex mutex; -#endif - unsigned count; -}; - -/** - * qemu_lockcnt_init: initialize a QemuLockcnt - * @lockcnt: the lockcnt to initialize - * - * Initialize lockcnt's counter to zero and prepare its mutex - * for usage. - */ -void qemu_lockcnt_init(QemuLockCnt *lockcnt); - -/** - * qemu_lockcnt_destroy: destroy a QemuLockcnt - * @lockcnt: the lockcnt to destruct - * - * Destroy lockcnt's mutex. - */ -void qemu_lockcnt_destroy(QemuLockCnt *lockcnt); - -/** - * qemu_lockcnt_inc: increment a QemuLockCnt's counter - * @lockcnt: the lockcnt to operate on - * - * If the lockcnt's count is zero, wait for critical sections - * to finish and increment lockcnt's count to 1. If the count - * is not zero, just increment it. - * - * Because this function can wait on the mutex, it must not be - * called while the lockcnt's mutex is held by the current thread. - * For the same reason, qemu_lockcnt_inc can also contribute to - * AB-BA deadlocks. This is a sample deadlock scenario: - * - * thread 1 thread 2 - * ------------------------------------------------------- - * qemu_lockcnt_lock(&lc1); - * qemu_lockcnt_lock(&lc2); - * qemu_lockcnt_inc(&lc2); - * qemu_lockcnt_inc(&lc1); - */ -void qemu_lockcnt_inc(QemuLockCnt *lockcnt); - -/** - * qemu_lockcnt_dec: decrement a QemuLockCnt's counter - * @lockcnt: the lockcnt to operate on - */ -void qemu_lockcnt_dec(QemuLockCnt *lockcnt); - -/** - * qemu_lockcnt_dec_and_lock: decrement a QemuLockCnt's counter and - * possibly lock it. - * @lockcnt: the lockcnt to operate on - * - * Decrement lockcnt's count. If the new count is zero, lock - * the mutex and return true. Otherwise, return false. - */ -bool qemu_lockcnt_dec_and_lock(QemuLockCnt *lockcnt); - -/** - * qemu_lockcnt_dec_if_lock: possibly decrement a QemuLockCnt's counter and - * lock it. - * @lockcnt: the lockcnt to operate on - * - * If the count is 1, decrement the count to zero, lock - * the mutex and return true. Otherwise, return false. - */ -bool qemu_lockcnt_dec_if_lock(QemuLockCnt *lockcnt); - -/** - * qemu_lockcnt_lock: lock a QemuLockCnt's mutex. - * @lockcnt: the lockcnt to operate on - * - * Remember that concurrent visits are not blocked unless the count is - * also zero. You can use qemu_lockcnt_count to check for this inside a - * critical section. - */ -void qemu_lockcnt_lock(QemuLockCnt *lockcnt); - -/** - * qemu_lockcnt_unlock: release a QemuLockCnt's mutex. - * @lockcnt: the lockcnt to operate on. - */ -void qemu_lockcnt_unlock(QemuLockCnt *lockcnt); - -/** - * qemu_lockcnt_inc_and_unlock: combined unlock/increment on a QemuLockCnt. - * @lockcnt: the lockcnt to operate on. - * - * This is the same as - * - * qemu_lockcnt_unlock(lockcnt); - * qemu_lockcnt_inc(lockcnt); - * - * but more efficient. - */ -void qemu_lockcnt_inc_and_unlock(QemuLockCnt *lockcnt); - -/** - * qemu_lockcnt_count: query a LockCnt's count. - * @lockcnt: the lockcnt to query. - * - * Note that the count can change at any time. Still, while the - * lockcnt is locked, one can usefully check whether the count - * is non-zero. - */ -unsigned qemu_lockcnt_count(QemuLockCnt *lockcnt); - #endif |