mirror of
https://github.com/Motorhead1991/qemu.git
synced 2025-08-02 07:13:54 -06:00
qemu-thread: Assert locks are initialized before using
Not all platforms check whether a lock is initialized before used. In particular Linux seems to be more permissive than OSX. Check initialization state explicitly in our code to catch such bugs earlier. Signed-off-by: Fam Zheng <famz@redhat.com> Message-Id: <20170704122325.25634-1-famz@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
025bdeab3c
commit
c096358e74
4 changed files with 69 additions and 1 deletions
|
@ -46,15 +46,19 @@ static void error_exit(int err, const char *msg)
|
|||
void qemu_mutex_init(QemuMutex *mutex)
|
||||
{
|
||||
InitializeSRWLock(&mutex->lock);
|
||||
mutex->initialized = true;
|
||||
}
|
||||
|
||||
void qemu_mutex_destroy(QemuMutex *mutex)
|
||||
{
|
||||
assert(mutex->initialized);
|
||||
mutex->initialized = false;
|
||||
InitializeSRWLock(&mutex->lock);
|
||||
}
|
||||
|
||||
void qemu_mutex_lock(QemuMutex *mutex)
|
||||
{
|
||||
assert(mutex->initialized);
|
||||
AcquireSRWLockExclusive(&mutex->lock);
|
||||
trace_qemu_mutex_locked(mutex);
|
||||
}
|
||||
|
@ -63,6 +67,7 @@ int qemu_mutex_trylock(QemuMutex *mutex)
|
|||
{
|
||||
int owned;
|
||||
|
||||
assert(mutex->initialized);
|
||||
owned = TryAcquireSRWLockExclusive(&mutex->lock);
|
||||
if (owned) {
|
||||
trace_qemu_mutex_locked(mutex);
|
||||
|
@ -73,6 +78,7 @@ int qemu_mutex_trylock(QemuMutex *mutex)
|
|||
|
||||
void qemu_mutex_unlock(QemuMutex *mutex)
|
||||
{
|
||||
assert(mutex->initialized);
|
||||
trace_qemu_mutex_unlocked(mutex);
|
||||
ReleaseSRWLockExclusive(&mutex->lock);
|
||||
}
|
||||
|
@ -80,25 +86,31 @@ void qemu_mutex_unlock(QemuMutex *mutex)
|
|||
void qemu_rec_mutex_init(QemuRecMutex *mutex)
|
||||
{
|
||||
InitializeCriticalSection(&mutex->lock);
|
||||
mutex->initialized = true;
|
||||
}
|
||||
|
||||
void qemu_rec_mutex_destroy(QemuRecMutex *mutex)
|
||||
{
|
||||
assert(mutex->initialized);
|
||||
mutex->initialized = false;
|
||||
DeleteCriticalSection(&mutex->lock);
|
||||
}
|
||||
|
||||
void qemu_rec_mutex_lock(QemuRecMutex *mutex)
|
||||
{
|
||||
assert(mutex->initialized);
|
||||
EnterCriticalSection(&mutex->lock);
|
||||
}
|
||||
|
||||
int qemu_rec_mutex_trylock(QemuRecMutex *mutex)
|
||||
{
|
||||
assert(mutex->initialized);
|
||||
return !TryEnterCriticalSection(&mutex->lock);
|
||||
}
|
||||
|
||||
void qemu_rec_mutex_unlock(QemuRecMutex *mutex)
|
||||
{
|
||||
assert(mutex->initialized);
|
||||
LeaveCriticalSection(&mutex->lock);
|
||||
}
|
||||
|
||||
|
@ -106,25 +118,31 @@ void qemu_cond_init(QemuCond *cond)
|
|||
{
|
||||
memset(cond, 0, sizeof(*cond));
|
||||
InitializeConditionVariable(&cond->var);
|
||||
cond->initialized = true;
|
||||
}
|
||||
|
||||
void qemu_cond_destroy(QemuCond *cond)
|
||||
{
|
||||
assert(cond->initialized);
|
||||
cond->initialized = false;
|
||||
InitializeConditionVariable(&cond->var);
|
||||
}
|
||||
|
||||
void qemu_cond_signal(QemuCond *cond)
|
||||
{
|
||||
assert(cond->initialized);
|
||||
WakeConditionVariable(&cond->var);
|
||||
}
|
||||
|
||||
void qemu_cond_broadcast(QemuCond *cond)
|
||||
{
|
||||
assert(cond->initialized);
|
||||
WakeAllConditionVariable(&cond->var);
|
||||
}
|
||||
|
||||
void qemu_cond_wait(QemuCond *cond, QemuMutex *mutex)
|
||||
{
|
||||
assert(cond->initialized);
|
||||
trace_qemu_mutex_unlocked(mutex);
|
||||
SleepConditionVariableSRW(&cond->var, &mutex->lock, INFINITE, 0);
|
||||
trace_qemu_mutex_locked(mutex);
|
||||
|
@ -134,21 +152,28 @@ void qemu_sem_init(QemuSemaphore *sem, int init)
|
|||
{
|
||||
/* Manual reset. */
|
||||
sem->sema = CreateSemaphore(NULL, init, LONG_MAX, NULL);
|
||||
sem->initialized = true;
|
||||
}
|
||||
|
||||
void qemu_sem_destroy(QemuSemaphore *sem)
|
||||
{
|
||||
assert(sem->initialized);
|
||||
sem->initialized = false;
|
||||
CloseHandle(sem->sema);
|
||||
}
|
||||
|
||||
void qemu_sem_post(QemuSemaphore *sem)
|
||||
{
|
||||
assert(sem->initialized);
|
||||
ReleaseSemaphore(sem->sema, 1, NULL);
|
||||
}
|
||||
|
||||
int qemu_sem_timedwait(QemuSemaphore *sem, int ms)
|
||||
{
|
||||
int rc = WaitForSingleObject(sem->sema, ms);
|
||||
int rc;
|
||||
|
||||
assert(sem->initialized);
|
||||
rc = WaitForSingleObject(sem->sema, ms);
|
||||
if (rc == WAIT_OBJECT_0) {
|
||||
return 0;
|
||||
}
|
||||
|
@ -160,6 +185,7 @@ int qemu_sem_timedwait(QemuSemaphore *sem, int ms)
|
|||
|
||||
void qemu_sem_wait(QemuSemaphore *sem)
|
||||
{
|
||||
assert(sem->initialized);
|
||||
if (WaitForSingleObject(sem->sema, INFINITE) != WAIT_OBJECT_0) {
|
||||
error_exit(GetLastError(), __func__);
|
||||
}
|
||||
|
@ -193,15 +219,19 @@ void qemu_event_init(QemuEvent *ev, bool init)
|
|||
/* Manual reset. */
|
||||
ev->event = CreateEvent(NULL, TRUE, TRUE, NULL);
|
||||
ev->value = (init ? EV_SET : EV_FREE);
|
||||
ev->initialized = true;
|
||||
}
|
||||
|
||||
void qemu_event_destroy(QemuEvent *ev)
|
||||
{
|
||||
assert(ev->initialized);
|
||||
ev->initialized = false;
|
||||
CloseHandle(ev->event);
|
||||
}
|
||||
|
||||
void qemu_event_set(QemuEvent *ev)
|
||||
{
|
||||
assert(ev->initialized);
|
||||
/* qemu_event_set has release semantics, but because it *loads*
|
||||
* ev->value we need a full memory barrier here.
|
||||
*/
|
||||
|
@ -218,6 +248,7 @@ void qemu_event_reset(QemuEvent *ev)
|
|||
{
|
||||
unsigned value;
|
||||
|
||||
assert(ev->initialized);
|
||||
value = atomic_read(&ev->value);
|
||||
smp_mb_acquire();
|
||||
if (value == EV_SET) {
|
||||
|
@ -232,6 +263,7 @@ void qemu_event_wait(QemuEvent *ev)
|
|||
{
|
||||
unsigned value;
|
||||
|
||||
assert(ev->initialized);
|
||||
value = atomic_read(&ev->value);
|
||||
smp_mb_acquire();
|
||||
if (value != EV_SET) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue