#include <unistd.h>
#include <sys/mman.h>
+#include "urcu/arch.h"
#include "urcu/wfcqueue.h"
#include "urcu/map/urcu-bp.h"
#include "urcu/static/urcu-bp.h"
static
int rcu_bp_refcount;
-/*
- * RCU_MEMBARRIER is only possibly available on Linux.
- */
-#ifdef __linux__
-#include <urcu/syscall-compat.h>
-#endif
-
-/* If the headers do not support SYS_membarrier, fall back on RCU_MB */
-#ifdef SYS_membarrier
-# define membarrier(...) syscall(SYS_membarrier, __VA_ARGS__)
+/* If the headers do not support membarrier system call, fall back smp_mb. */
+#ifdef __NR_membarrier
+# define membarrier(...) syscall(__NR_membarrier, __VA_ARGS__)
#else
# define membarrier(...) -ENOSYS
#endif
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);
if (new_chunk == MAP_FAILED)
abort();
- bzero(new_chunk, new_chunk_len);
+ memset(new_chunk, 0, new_chunk_len);
new_chunk->data_len =
new_chunk_len - sizeof(struct registry_chunk);
cds_list_add_tail(&new_chunk->node, &arena->chunk_list);
if (new_chunk != MAP_FAILED) {
/* Should not have moved. */
assert(new_chunk == last_chunk);
- bzero((char *) last_chunk + old_chunk_len,
+ memset((char *) last_chunk + old_chunk_len, 0,
new_chunk_len - old_chunk_len);
last_chunk->data_len =
new_chunk_len - sizeof(struct registry_chunk);
}
/* 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);
if (new_chunk == MAP_FAILED)
abort();
- bzero(new_chunk, new_chunk_len);
+ memset(new_chunk, 0, new_chunk_len);
new_chunk->data_len =
new_chunk_len - sizeof(struct registry_chunk);
cds_list_add_tail(&new_chunk->node, &arena->chunk_list);
rcu_bp_unregister(rcu_key);
}
+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.
+ */
+}
+
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);
ret = pthread_key_delete(urcu_bp_key);
if (ret)
abort();