From: Mathieu Desnoyers Date: Sun, 2 Oct 2011 16:56:36 +0000 (-0400) Subject: Merge branch 'master' into urcu/ht-shrink X-Git-Tag: v0.7.0~43^2~102 X-Git-Url: http://git.liburcu.org/?a=commitdiff_plain;h=f96d597f3a04010d432c36b9bb07e910720000ab;hp=dc35de0cb35eb2866d5d0d7eb87c7a249ed072c9;p=userspace-rcu.git Merge branch 'master' into urcu/ht-shrink Conflicts: urcu-call-rcu.h Signed-off-by: Mathieu Desnoyers --- diff --git a/API.txt b/API.txt index a7cd5a2..72430f7 100644 --- a/API.txt +++ b/API.txt @@ -16,14 +16,14 @@ void rcu_read_unlock(void); End an RCU read-side critical section. -void rcu_register_thread(void) +void rcu_register_thread(void); Each thread must invoke this function before its first call to rcu_read_lock(). Threads that never call rcu_read_lock() need not invoke this function. In addition, rcu-bp ("bullet proof" RCU) does not require any thread to invoke rcu_register_thread(). -void rcu_unregister_thread(void) +void rcu_unregister_thread(void); Each thread that invokes rcu_register_thread() must invoke rcu_unregister_thread() before invoking pthread_exit() @@ -59,6 +59,9 @@ void call_rcu(struct rcu_head *head, call_rcu(&p->rcu, func); + call_rcu should be called from registered RCU read-side threads. + For the QSBR flavor, the caller should be online. + struct call_rcu_data *create_call_rcu_data(unsigned long flags, int cpu_affinity); @@ -77,6 +80,28 @@ struct call_rcu_data *get_call_rcu_data(void); Returns the handle of the current thread's call_rcu() helper thread, which might well be the default helper thread. + get_call_rcu_data should be called from registered RCU read-side + threads. For the QSBR flavor, the caller should be online. + +void call_rcu_data_free(struct call_rcu_data *crdp); + + Terminates a call_rcu() helper thread and frees its associated + data. The caller must have ensured that this thread is no longer + in use, for example, by passing NULL to set_thread_call_rcu_data() + and set_cpu_call_rcu_data() as required. + +struct call_rcu_data *get_default_call_rcu_data(void); + + Returns the handle for the default call_rcu() helper thread. + Creates it if necessary. + +struct call_rcu_data *get_cpu_call_rcu_data(int cpu); + + Returns the handle for the current cpu's call_rcu() helper + thread, or NULL if the current CPU has no helper thread + currently assigned. The call to this function and use of the + returned call_rcu_data should be protected by RCU read-side + lock. struct call_rcu_data *get_thread_call_rcu_data(void); @@ -84,6 +109,18 @@ struct call_rcu_data *get_thread_call_rcu_data(void); call_rcu() helper thread, or NULL if the current thread is instead using a per-CPU or the default helper thread. +struct call_rcu_data *get_call_rcu_data(void); + + Returns the handle for the current thread's call_rcu() helper + thread, which is either, in increasing order of preference: + per-thread hard-assigned helper thread, per-cpu helper thread, + or default helper thread. + +pthread_t get_call_rcu_thread(struct call_rcu_data *crdp); + + Returns the helper thread's pthread identifier linked to a call + rcu helper thread data. + void set_thread_call_rcu_data(struct call_rcu_data *crdp); Sets the current thread's hard-assigned call_rcu() helper to the @@ -100,7 +137,10 @@ int set_cpu_call_rcu_data(int cpu, struct call_rcu_data *crdp); this CPU from its helper thread. Once a CPU has been disassociated from its helper, further call_rcu() invocations that would otherwise have used this CPU's helper will instead - use the default helper. + use the default helper. The caller must wait for a grace-period + to pass between return from set_cpu_call_rcu_data() and call to + call_rcu_data_free() passing the previous call rcu data as + argument. int create_all_cpu_call_rcu_data(unsigned long flags) @@ -115,9 +155,17 @@ int create_all_cpu_call_rcu_data(unsigned long flags) then that executable will have only the single global default call_rcu() helper thread. This will suffice in most cases. -void call_rcu_data_free(struct call_rcu_data *crdp) +void free_all_cpu_call_rcu_data(void); - Terminates a call_rcu() helper thread and frees its associated - data. The caller must have ensured that this thread is no longer - in use, for example, by passing NULL to set_thread_call_rcu_data() - and set_cpu_call_rcu_data() as required. + Clean up all the per-CPU call_rcu threads. Should be paired with + create_all_cpu_call_rcu_data() to perform teardown. Note that + this function invokes synchronize_rcu() internally, so the + caller should be careful not to hold mutexes (or mutexes within a + dependency chain) that are also taken within a RCU read-side + critical section, or in a section where QSBR threads are online. + +void call_rcu_after_fork_child(void); + + Should be used as pthread_atfork() handler for programs using + call_rcu and performing fork() or clone() without a following + exec(). diff --git a/ChangeLog b/ChangeLog index e355ee8..30e7b41 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,70 @@ +2011-09-29 Userspace RCU 0.6.5 + * call_rcu: Document call_rcu requirements + * call_rcu: fix error handling of malloc error + * urcu call_rcu: Use RCU read-side protection for per-cpu call_rcu data + * urcu,call_rcu: Cleanup call_rcu_data pointers before use in child + * urcu,call_rcu: avoid create call_rcu_data for child when unneed + * urcu,defer_rcu: Make defer_rcu encoding more compact for marker + * urcu_defer: Use cancellation flag instead of pthread_cancel() + * urcu,call_rcu: protects call_rcu_data_list when remove node + * Create default call rcu data upon per-cpu call-rcu teardown + * powerpc: use __NO_LWSYNC__ check to use appropriate lwsync/sync opcode + * cmm: provide lightweight smp_rmb/smp_wmb on PPC + * atomic: provide seq_cst semantics on powerpc + * avoid leaking crdp for failed path + * Return -EEXIST when the old cpu call_rcu_data has not been removed + * protect writing to per_cpu_call_rcu_data[*] + * wake up default call_rcu thread after we move the leftover callbacks + * avoid memory leak in call_rcu_data_free() + * urcu call_rcu: fix use after free() + * use get_cpu_call_rcu_data() for get_call_rcu_data() + * init maxcpus before use + * call_rcu implementation: add missing static + * Document QSBR interaction with mutexes + * urcu-pointer: implement URCU_FORCE_CAST for C++ compatibility of urcu-pointer.h + * urcu-qsbr: use rcu_thread_offline/rcu_thread_online instead of inlining them + * Pair all_cpu call_rcu create with free + * QSBR: add missing wakeups in synchronize_rcu code + * cmm: do not generate code for smp_rmb/smp_wmb on x86_64 + * cmm: let per-arch files provide cmm_smp_* barriers + * Optimize caa_get_cycles() for PowerPC64 + * lfq/lfs tests: use call_rcu + * list: Add cds_list_first_entry + * rculfstack/queue: define _LGPL_SOURCE around static header include + * Add __rcu annotation (unimplemented) + * Fix incorrect fsf address in header files + * wfstack: push returns prior stack emptiness state + * Make lf stack push return if the stack was empty + * Document caa_container_of + * urcu-bp: do not call munmap for NULL registry at exit + * urcu libraries can directly use the _LGPL_SOURCE wfqueue + * rculfstack: document "push" + * Add runall.sh to tarball + * Fix build order of liburcu-cds-common + * Fix missing check for SYS_membarrier in map header + * urcu-qsbr: avoid useless futex wakeups and burning CPU for long grace periods + * api: reimplement BUILD_BUG_ON in compiler.h + * test api cleanup: remove unused primitives + * put thread offline while waiting for the init flag + * urcu: move private definitions to .c file + * urcu-bp: move private definitions to .c file + * urcu-qsbr: move private definitions to .c file + * rcutorture: fix rcutorture-qsbr + * wfqueue: fix type-incorrect assignment + * Fix tests Makefile EXTRA_DIST to use api.h + * Fix choice of default flavour in urcu/map/urcu.h + * api: remove list/hlist + * api: remove arch-specific files + * api: make api_gcc.h a superset of the other headers + * tests api: remove atomics + * put thread offline while waiting for the init flag + * urcu: move private definitions to .c file + * urcu-bp: move private definitions to .c file + * urcu-qsbr: move private definitions to .c file + * rcutorture: fix rcutorture-qsbr + * wfqueue: fix type-incorrect assignment + * Use caa_ prefix for min() and max() + 2011-07-21 Userspace RCU 0.6.4 * uatomic: Fix ARM build errors in uatomic. * urcu tests: hold mutex across use of custom allocator. diff --git a/Makefile.am b/Makefile.am index ff7f1bb..4e4ce89 100644 --- a/Makefile.am +++ b/Makefile.am @@ -22,7 +22,7 @@ EXTRA_DIST = $(top_srcdir)/urcu/arch/*.h $(top_srcdir)/urcu/uatomic/*.h \ gpl-2.0.txt lgpl-2.1.txt lgpl-relicensing.txt \ README LICENSE compat_arch_x86.c \ urcu-call-rcu-impl.h urcu-defer-impl.h \ - ChangeLog + ChangeLog API.txt if COMPAT_ARCH COMPAT=compat_arch_@ARCHTYPE@.c diff --git a/configure.ac b/configure.ac index c4bd10a..68dc190 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. -AC_INIT([userspace-rcu], [0.6.4], [mathieu dot desnoyers at efficios dot com]) +AC_INIT([userspace-rcu], [0.6.5], [mathieu dot desnoyers at efficios dot com]) # Following the numbering scheme proposed by libtool for the library version # http://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html diff --git a/urcu-call-rcu-impl.h b/urcu-call-rcu-impl.h index 29c4e28..182e9b1 100644 --- a/urcu-call-rcu-impl.h +++ b/urcu-call-rcu-impl.h @@ -396,6 +396,10 @@ struct call_rcu_data *create_call_rcu_data(unsigned long flags, * the caller's responsibility to dispose of the removed structure. * Use get_cpu_call_rcu_data() to obtain a pointer to the old structure * (prior to NULLing it out, of course). + * + * The caller must wait for a grace-period to pass between return from + * set_cpu_call_rcu_data() and call to call_rcu_data_free() passing the + * previous call rcu data as argument. */ int set_cpu_call_rcu_data(int cpu, struct call_rcu_data *crdp) @@ -612,6 +616,10 @@ void call_rcu(struct rcu_head *head, * * We also silently refuse to free NULL pointers. This simplifies * the calling code. + * + * The caller must wait for a grace-period to pass between return from + * set_cpu_call_rcu_data() and call to call_rcu_data_free() passing the + * previous call rcu data as argument. */ void call_rcu_data_free(struct call_rcu_data *crdp) { diff --git a/urcu-call-rcu.h b/urcu-call-rcu.h index d00bb4a..8df44ef 100644 --- a/urcu-call-rcu.h +++ b/urcu-call-rcu.h @@ -61,34 +61,31 @@ struct rcu_head { /* * Exported functions + * + * Important: see userspace RCU API.txt for call_rcu family of functions + * usage detail, including the surrounding RCU usage required when using + * these primitives. */ -/* - * get_cpu_call_rcu_data should be called with RCU read-side lock held. - * Callers should be registered RCU read-side threads. - */ -struct call_rcu_data *get_cpu_call_rcu_data(int cpu); -pthread_t get_call_rcu_thread(struct call_rcu_data *crdp); +void call_rcu(struct rcu_head *head, + void (*func)(struct rcu_head *head)); + struct call_rcu_data *create_call_rcu_data(unsigned long flags, int cpu_affinity); -int set_cpu_call_rcu_data(int cpu, struct call_rcu_data *crdp); +void call_rcu_data_free(struct call_rcu_data *crdp); + struct call_rcu_data *get_default_call_rcu_data(void); -/* - * get_call_rcu_data should be called from registered RCU read-side - * threads. For the QSBR flavor, the caller should be online. - */ -struct call_rcu_data *get_call_rcu_data(void); +struct call_rcu_data *get_cpu_call_rcu_data(int cpu); struct call_rcu_data *get_thread_call_rcu_data(void); +struct call_rcu_data *get_call_rcu_data(void); +pthread_t get_call_rcu_thread(struct call_rcu_data *crdp); + void set_thread_call_rcu_data(struct call_rcu_data *crdp); +int set_cpu_call_rcu_data(int cpu, struct call_rcu_data *crdp); + int create_all_cpu_call_rcu_data(unsigned long flags); -/* - * call_rcu should be called from registered RCU read-side threads. - * For the QSBR flavor, the caller should be online. - */ -void call_rcu(struct rcu_head *head, - void (*func)(struct rcu_head *head)); -void call_rcu_data_free(struct call_rcu_data *crdp); void free_all_cpu_call_rcu_data(void); + void call_rcu_after_fork_child(void); #ifdef __cplusplus