static
void __attribute__((destructor)) rcu_bp_exit(void);
+#ifndef CONFIG_RCU_FORCE_SYS_MEMBARRIER
int urcu_bp_has_sys_membarrier;
+#endif
/*
* rcu_gp_lock ensures mutual exclusion between threads calling
sizeof(struct registry_chunk)
+ sizeof(struct rcu_reader));
new_chunk_len = ARENA_INIT_ALLOC;
- new_chunk = mmap(NULL, new_chunk_len,
+ new_chunk = (struct registry_chunk *) mmap(NULL,
+ new_chunk_len,
PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE,
-1, 0);
}
/* Remap did not succeed, we need to add a new chunk. */
- new_chunk = mmap(NULL, new_chunk_len,
+ new_chunk = (struct registry_chunk *) mmap(NULL,
+ new_chunk_len,
PROT_READ | PROT_WRITE,
MAP_ANONYMOUS | MAP_PRIVATE,
-1, 0);
rcu_bp_unregister(rcu_key);
}
+#ifdef CONFIG_RCU_FORCE_SYS_MEMBARRIER
+static
+void rcu_sys_membarrier_status(int available)
+{
+ if (!available)
+ abort();
+}
+#else
+static
+void rcu_sys_membarrier_status(int available)
+{
+ /*
+ * membarrier has blocking behavior, which changes the
+ * application behavior too much compared to using barriers when
+ * synchronize_rcu is used repeatedly (without using call_rcu).
+ * Don't use membarrier for now, unless its use has been
+ * explicitly forced when building liburcu.
+ */
+}
+#endif
+
static
void rcu_bp_init(void)
{
if (ret)
abort();
ret = membarrier(MEMBARRIER_CMD_QUERY, 0);
- if (ret >= 0 && (ret & MEMBARRIER_CMD_SHARED)) {
- urcu_bp_has_sys_membarrier = 1;
- }
+ rcu_sys_membarrier_status(ret >= 0
+ && (ret & MEMBARRIER_CMD_SHARED));
initialized = 1;
}
mutex_unlock(&init_lock);
cds_list_for_each_entry_safe(chunk, tmp,
®istry_arena.chunk_list, node) {
- munmap(chunk, chunk->data_len
+ munmap((void *) chunk, chunk->data_len
+ sizeof(struct registry_chunk));
}
CDS_INIT_LIST_HEAD(®istry_arena.chunk_list);