lockable: add lock guards

This patch introduces two lock guard macros that automatically unlock a
lock object (QemuMutex and others):

  void f(void) {
      QEMU_LOCK_GUARD(&mutex);
      if (!may_fail()) {
          return; /* automatically unlocks mutex */
      }
      ...
  }

and:

  WITH_QEMU_LOCK_GUARD(&mutex) {
      if (!may_fail()) {
          return; /* automatically unlocks mutex */
      }
  }
  /* automatically unlocks mutex here */
  ...

Convert qemu-timer.c functions that benefit from these macros as an
example.  Manual qemu_mutex_lock/unlock() callers are left unmodified in
cases where clarity would not improve by switching to the macros.

Many other QemuMutex users remain in the codebase that might benefit
from lock guards.  Over time they can be converted, if that is
desirable.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
[Use QEMU_MAKE_LOCKABLE_NONNULL. - Paolo]
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Stefan Hajnoczi 2020-03-16 11:09:56 +00:00 committed by Paolo Bonzini
parent 8834dcf47e
commit 3284c3ddc4
2 changed files with 76 additions and 12 deletions

View file

@ -25,6 +25,7 @@
#include "qemu/osdep.h"
#include "qemu/main-loop.h"
#include "qemu/timer.h"
#include "qemu/lockable.h"
#include "sysemu/replay.h"
#include "sysemu/cpus.h"
@ -186,13 +187,12 @@ bool timerlist_expired(QEMUTimerList *timer_list)
return false;
}
qemu_mutex_lock(&timer_list->active_timers_lock);
if (!timer_list->active_timers) {
qemu_mutex_unlock(&timer_list->active_timers_lock);
return false;
WITH_QEMU_LOCK_GUARD(&timer_list->active_timers_lock) {
if (!timer_list->active_timers) {
return false;
}
expire_time = timer_list->active_timers->expire_time;
}
expire_time = timer_list->active_timers->expire_time;
qemu_mutex_unlock(&timer_list->active_timers_lock);
return expire_time <= qemu_clock_get_ns(timer_list->clock->type);
}
@ -225,13 +225,12 @@ int64_t timerlist_deadline_ns(QEMUTimerList *timer_list)
* value but ->notify_cb() is called when the deadline changes. Therefore
* the caller should notice the change and there is no race condition.
*/
qemu_mutex_lock(&timer_list->active_timers_lock);
if (!timer_list->active_timers) {
qemu_mutex_unlock(&timer_list->active_timers_lock);
return -1;
WITH_QEMU_LOCK_GUARD(&timer_list->active_timers_lock) {
if (!timer_list->active_timers) {
return -1;
}
expire_time = timer_list->active_timers->expire_time;
}
expire_time = timer_list->active_timers->expire_time;
qemu_mutex_unlock(&timer_list->active_timers_lock);
delta = expire_time - qemu_clock_get_ns(timer_list->clock->type);