From 26387f86c9d6ac3a7a93b76108c502646afb6c25 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Mon, 13 May 2013 17:49:24 +0200 Subject: rcu: add call_rcu Asynchronous callbacks provided by call_rcu are particularly important for QEMU, because the BQL makes it hard to use synchronize_rcu. In addition, the current RCU implementation is not particularly friendly to multiple concurrent synchronize_rcu callers, making call_rcu even more important. Reviewed-by: Fam Zheng Signed-off-by: Paolo Bonzini --- include/qemu/rcu.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'include') diff --git a/include/qemu/rcu.h b/include/qemu/rcu.h index da043f2..068a279 100644 --- a/include/qemu/rcu.h +++ b/include/qemu/rcu.h @@ -118,6 +118,28 @@ extern void synchronize_rcu(void); extern void rcu_register_thread(void); extern void rcu_unregister_thread(void); +struct rcu_head; +typedef void RCUCBFunc(struct rcu_head *head); + +struct rcu_head { + struct rcu_head *next; + RCUCBFunc *func; +}; + +extern void call_rcu1(struct rcu_head *head, RCUCBFunc *func); + +/* The operands of the minus operator must have the same type, + * which must be the one that we specify in the cast. + */ +#define call_rcu(head, func, field) \ + call_rcu1(({ \ + char __attribute__((unused)) \ + offset_must_be_zero[-offsetof(typeof(*(head)), field)], \ + func_type_invalid = (func) - (void (*)(typeof(head)))(func); \ + &(head)->field; \ + }), \ + (RCUCBFunc *)(func)) + #ifdef __cplusplus } #endif -- cgit v1.1