diff options
author | Dr. David Alan Gilbert <dgilbert@redhat.com> | 2019-10-07 15:36:37 +0100 |
---|---|---|
committer | Dr. David Alan Gilbert <dgilbert@redhat.com> | 2019-10-11 14:19:49 +0100 |
commit | 5626f8c6d46832b02ce4fdc0bd109516bc812043 (patch) | |
tree | 1f5ebde7290eb695f62e050a047168cc5c745feb /include/qemu | |
parent | 8f8d528e73144c063deafc534df0a04c67f6f98e (diff) | |
download | qemu-5626f8c6d46832b02ce4fdc0bd109516bc812043.zip qemu-5626f8c6d46832b02ce4fdc0bd109516bc812043.tar.gz qemu-5626f8c6d46832b02ce4fdc0bd109516bc812043.tar.bz2 |
rcu: Add automatically released rcu_read_lock variants
RCU_READ_LOCK_GUARD() takes the rcu_read_lock and then uses glib's
g_auto infrastructure (and thus whatever the compiler's hooks are) to
release it on all exits of the block.
WITH_RCU_READ_LOCK_GUARD() is similar but is used as a wrapper for the
lock, i.e.:
WITH_RCU_READ_LOCK_GUARD() {
stuff under lock
}
Note the 'unused' attribute is needed to work around clang bug:
https://bugs.llvm.org/show_bug.cgi?id=43482
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Acked-by: Paolo Bonzini <pbonzini@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Message-Id: <20191007143642.301445-2-dgilbert@redhat.com>
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Diffstat (limited to 'include/qemu')
-rw-r--r-- | include/qemu/rcu.h | 25 |
1 files changed, 25 insertions, 0 deletions
diff --git a/include/qemu/rcu.h b/include/qemu/rcu.h index 22876d1..9c82683 100644 --- a/include/qemu/rcu.h +++ b/include/qemu/rcu.h @@ -154,6 +154,31 @@ extern void call_rcu1(struct rcu_head *head, RCUCBFunc *func); }), \ (RCUCBFunc *)g_free); +typedef void RCUReadAuto; +static inline RCUReadAuto *rcu_read_auto_lock(void) +{ + rcu_read_lock(); + /* Anything non-NULL causes the cleanup function to be called */ + return (void *)(uintptr_t)0x1; +} + +static inline void rcu_read_auto_unlock(RCUReadAuto *r) +{ + rcu_read_unlock(); +} + +G_DEFINE_AUTOPTR_CLEANUP_FUNC(RCUReadAuto, rcu_read_auto_unlock) + +#define WITH_RCU_READ_LOCK_GUARD() \ + WITH_RCU_READ_LOCK_GUARD_(_rcu_read_auto##__COUNTER__) + +#define WITH_RCU_READ_LOCK_GUARD_(var) \ + for (g_autoptr(RCUReadAuto) var = rcu_read_auto_lock(); \ + (var); rcu_read_auto_unlock(var), (var) = NULL) + +#define RCU_READ_LOCK_GUARD() \ + g_autoptr(RCUReadAuto) _rcu_read_auto __attribute__((unused)) = rcu_read_auto_lock() + #ifdef __cplusplus } #endif |