|
@@ -46,6 +46,7 @@
|
|
|
unsigned long rcu_gp_ctr = RCU_GP_LOCKED;
|
|
|
|
|
|
QemuEvent rcu_gp_event;
|
|
|
+static int in_drain_call_rcu;
|
|
|
static QemuMutex rcu_registry_lock;
|
|
|
static QemuMutex rcu_sync_lock;
|
|
|
|
|
@@ -107,6 +108,8 @@ static void wait_for_readers(void)
|
|
|
* get some extra futex wakeups.
|
|
|
*/
|
|
|
qatomic_set(&index->waiting, false);
|
|
|
+ } else if (qatomic_read(&in_drain_call_rcu)) {
|
|
|
+ notifier_list_notify(&index->force_rcu, NULL);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -339,8 +342,10 @@ void drain_call_rcu(void)
|
|
|
* assumed.
|
|
|
*/
|
|
|
|
|
|
+ qatomic_inc(&in_drain_call_rcu);
|
|
|
call_rcu1(&rcu_drain.rcu, drain_rcu_callback);
|
|
|
qemu_event_wait(&rcu_drain.drain_complete_event);
|
|
|
+ qatomic_dec(&in_drain_call_rcu);
|
|
|
|
|
|
if (locked) {
|
|
|
qemu_mutex_lock_iothread();
|
|
@@ -363,6 +368,20 @@ void rcu_unregister_thread(void)
|
|
|
qemu_mutex_unlock(&rcu_registry_lock);
|
|
|
}
|
|
|
|
|
|
+void rcu_add_force_rcu_notifier(Notifier *n)
|
|
|
+{
|
|
|
+ qemu_mutex_lock(&rcu_registry_lock);
|
|
|
+ notifier_list_add(&rcu_reader.force_rcu, n);
|
|
|
+ qemu_mutex_unlock(&rcu_registry_lock);
|
|
|
+}
|
|
|
+
|
|
|
+void rcu_remove_force_rcu_notifier(Notifier *n)
|
|
|
+{
|
|
|
+ qemu_mutex_lock(&rcu_registry_lock);
|
|
|
+ notifier_remove(n);
|
|
|
+ qemu_mutex_unlock(&rcu_registry_lock);
|
|
|
+}
|
|
|
+
|
|
|
static void rcu_init_complete(void)
|
|
|
{
|
|
|
QemuThread thread;
|