#include <errno.h>
#include <poll.h>
#include <unistd.h>
+#include <stdbool.h>
#include <sys/mman.h>
#include "urcu/arch.h"
#endif
enum membarrier_cmd {
- MEMBARRIER_CMD_QUERY = 0,
- MEMBARRIER_CMD_SHARED = (1 << 0),
+ MEMBARRIER_CMD_QUERY = 0,
+ MEMBARRIER_CMD_SHARED = (1 << 0),
+ /* reserved for MEMBARRIER_CMD_SHARED_EXPEDITED (1 << 1) */
+ /* reserved for MEMBARRIER_CMD_PRIVATE (1 << 2) */
+ MEMBARRIER_CMD_PRIVATE_EXPEDITED = (1 << 3),
+ MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED = (1 << 4),
};
static
static void smp_mb_master(void)
{
- if (caa_likely(urcu_bp_has_sys_membarrier))
- (void) membarrier(MEMBARRIER_CMD_SHARED, 0);
- else
+ if (caa_likely(urcu_bp_has_sys_membarrier)) {
+ if (membarrier(MEMBARRIER_CMD_PRIVATE_EXPEDITED, 0))
+ urcu_die(errno);
+ } else {
cmm_smp_mb();
+ }
}
/*
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);
#ifdef CONFIG_RCU_FORCE_SYS_MEMBARRIER
static
-void rcu_sys_membarrier_status(int available)
+void rcu_sys_membarrier_status(bool available)
{
if (!available)
abort();
}
#else
static
-void rcu_sys_membarrier_status(int available)
+void rcu_sys_membarrier_status(bool available)
{
- if (available)
- urcu_bp_has_sys_membarrier = 1;
+ if (!available)
+ return;
+ urcu_bp_has_sys_membarrier = 1;
}
#endif
+static
+void rcu_sys_membarrier_init(void)
+{
+ bool available = false;
+ int mask;
+
+ mask = membarrier(MEMBARRIER_CMD_QUERY, 0);
+ if (mask >= 0) {
+ if (mask & MEMBARRIER_CMD_PRIVATE_EXPEDITED) {
+ if (membarrier(MEMBARRIER_CMD_REGISTER_PRIVATE_EXPEDITED, 0))
+ urcu_die(errno);
+ available = true;
+ }
+ }
+ rcu_sys_membarrier_status(available);
+}
+
static
void rcu_bp_init(void)
{
urcu_bp_thread_exit_notifier);
if (ret)
abort();
- ret = membarrier(MEMBARRIER_CMD_QUERY, 0);
- rcu_sys_membarrier_status(ret >= 0
- && (ret & MEMBARRIER_CMD_SHARED));
+ rcu_sys_membarrier_init();
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);