+
+static int atfork_depth = 1;
+
+void rcu_enable_atfork(void)
+{
+ atfork_depth++;
+}
+
+void rcu_disable_atfork(void)
+{
+ atfork_depth--;
+}
+
+#ifdef CONFIG_POSIX
+static void rcu_init_lock(void)
+{
+ if (atfork_depth < 1) {
+ return;
+ }
+
+ qemu_mutex_lock(&rcu_sync_lock);
+ qemu_mutex_lock(&rcu_registry_lock);
+}
+
+static void rcu_init_unlock(void)
+{
+ if (atfork_depth < 1) {
+ return;
+ }
+
+ qemu_mutex_unlock(&rcu_registry_lock);
+ qemu_mutex_unlock(&rcu_sync_lock);
+}
+
+static void rcu_init_child(void)
+{
+ if (atfork_depth < 1) {
+ return;
+ }
+
+ memset(®istry, 0, sizeof(registry));
+ rcu_init_complete();
+}
+#endif
+
+static void __attribute__((__constructor__)) rcu_init(void)
+{
+ smp_mb_global_init();
+#ifdef CONFIG_POSIX
+ pthread_atfork(rcu_init_lock, rcu_init_unlock, rcu_init_child);
+#endif
+ rcu_init_complete();
+}