Rename all data structure with prefix cds_ This is the third and last patch of the namespace refactoring. The prefix cds_ stands for Concurrent Data Structure and is use for queue, list, hlist and stack. For RCU protected data strucutre, the prefix is also added but the suffix _rcu is appended. This suffix indicate and RCU protection. Signed-off-by: David Goulet <david.goulet@polymtl.ca> Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Rename all arch primitives with prefix caa_ This is the second patch for reducing namespace pollution. The caa_ prefix stands for Concurrent Architecture Abstraction. Again, suggested by Mathieu Desnoyers and Paul E. Mckenney. Every define, macro and function specific to the architecture abstraction of liburcu is modified with that prefix Signed-off-by: David Goulet <david.goulet@polymtl.ca> Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
Rename all memory primitives with prefix cmm_ In order to not pollute the userspace namespace for application using liburcu or any lib/apps linked with urcu, this patch if the first of three major refactor for naming convention. The cmm_ prefix is a short name for Concurrent Memory Model and was suggested by Mathieu Desnoyers and Paul E. Mckenney. Every memory primitives such as mb, wmb, rmb, and so on are renamed. Signed-off-by: David Goulet <david.goulet@polymtl.ca> Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
urcu-defer: remove call_rcu() API, replace by defer_rcu() Ensure we do not expose an API different from the kernel with the same name and different semantic. defer_rcu() cannot be called from within a RCU read-side C.S.. call_rcu() should eventually be re-implemented with struct rcu_head, permitting to be called from within a RCU read-side C.S. Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Cleanup headers * atomic_ -> uatomic (to remove namespace clash with libkcompat) * moved arch.h, compiler.h, arch_uatomic.h to /usr/include/urcu/ to make sure we do not pollute system headers. Also add call_rcu() documentation to README. Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
urcu-defer: remove dependency on linux/futex.h > cc -fPIC -Wall -I. -O2 -g -lpthread -c -o urcu-defer.o `echo urcu-defer.c urcu-defer.h | sed 's/[^ ]*\.h//g'` > In file included from urcu-defer.c:31: > /usr/include/linux/futex.h:96: error: expected ‘)’ before ‘*’ token > /usr/include/linux/futex.h:100: error: expected ‘)’ before ‘*’ token Seems broken on ppc. Just for two defines, it's not worth depending on it. Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
urcu-defer: ensure callbacks will never be enqueued forever Even if there are no further callbacks enqueued, ensure that after a 100ms delay, the callback queue will be dealt with. Required proper ordering of queue vs futex. e.g. The idea is to perform the "check for empty queue" between the &defer_thread_futex decrement and the test in wait_defer. It skips the futex call and proceed if the list is non-empty. As I am drilling into the problem, it looks very much like an attempt to implement efficient wait queues in userspace based on sys_futex(). /* * Wake-up any waiting defer thread. Called from many concurrent * threads. */ static void wake_up_defer(void) { if (unlikely(atomic_read(&defer_thread_futex) == -1)) { atomic_set(&defer_thread_futex, 0); futex(&defer_thread_futex, FUTEX_WAKE, 0, NULL, NULL, 0); } } /* * Defer thread waiting. Single thread. */ static void wait_defer(void) { atomic_dec(&defer_thread_futex); smp_mb(); /* Write futex before read queue */ if (rcu_defer_num_callbacks()) { smp_mb(); /* Read queue before write futex */ /* Callbacks are queued, don't wait. */ atomic_set(&defer_thread_futex, 0); } else { smp_rmb(); /* Read queue before read futex */ if (atomic_read(&defer_thread_futex) == -1) futex(&defer_thread_futex, FUTEX_WAIT, -1, NULL, NULL, 0); } } - call_rcu(): * queue callbacks to perform * smp_mb() * wake_up_defer() - defer thread: * for (;;) * wait_defer() * sleep 100ms (wait for more callbacks to be enqueued) * dequeue callbacks, execute them The goal here is that if call_rcu() enqueues a callback (even if it races with defer thread going to sleep), there should not be a potentially infinite delay before it gets executed. Therefore, being blocked in sys_futex while there is a callback to execute, without any hope to be woken up unless another callback is queued, would not meet that design requirement. I think that checking the number of queued callbacks within wait_defer() as I propose here should address this situation. Signed-off-by: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>