urcu-qsbr-static.h | urcu-qsbr-static.h | |||
---|---|---|---|---|
skipping to change at line 41 | skipping to change at line 41 | |||
#include <stdlib.h> | #include <stdlib.h> | |||
#include <pthread.h> | #include <pthread.h> | |||
#include <assert.h> | #include <assert.h> | |||
#include <limits.h> | #include <limits.h> | |||
#include <syscall.h> | #include <syscall.h> | |||
#include <unistd.h> | #include <unistd.h> | |||
#include <urcu/compiler.h> | #include <urcu/compiler.h> | |||
#include <urcu/arch.h> | #include <urcu/arch.h> | |||
#include <urcu/system.h> | ||||
#include <urcu/arch_uatomic.h> | #include <urcu/arch_uatomic.h> | |||
#include <urcu/list.h> | #include <urcu/list.h> | |||
/* | ||||
* Identify a shared load. A smp_rmc() or smp_mc() should come before the l | ||||
oad. | ||||
*/ | ||||
#define _LOAD_SHARED(p) ACCESS_ONCE(p) | ||||
/* | ||||
* Load a data from shared memory, doing a cache flush if required. | ||||
*/ | ||||
#define LOAD_SHARED(p) \ | ||||
({ \ | ||||
smp_rmc(); \ | ||||
_LOAD_SHARED(p); \ | ||||
}) | ||||
/* | ||||
* Identify a shared store. A smp_wmc() or smp_mc() should follow the store | ||||
. | ||||
*/ | ||||
#define _STORE_SHARED(x, v) ({ ACCESS_ONCE(x) = (v); }) | ||||
/* | ||||
* Store v into x, where x is located in shared memory. Performs the requir | ||||
ed | ||||
* cache flush after writing. Returns v. | ||||
*/ | ||||
#define STORE_SHARED(x, v) \ | ||||
({ \ | ||||
_STORE_SHARED(x, v); \ | ||||
smp_wmc(); \ | ||||
(v); \ | ||||
}) | ||||
/** | ||||
* _rcu_dereference - reads (copy) a RCU-protected pointer to a local varia | ||||
ble | ||||
* into a RCU read-side critical section. The pointer can later be safely | ||||
* dereferenced within the critical section. | ||||
* | ||||
* This ensures that the pointer copy is invariant thorough the whole criti | ||||
cal | ||||
* section. | ||||
* | ||||
* Inserts memory barriers on architectures that require them (currently on | ||||
ly | ||||
* Alpha) and documents which pointers are protected by RCU. | ||||
* | ||||
* Should match rcu_assign_pointer() or rcu_xchg_pointer(). | ||||
*/ | ||||
#define _rcu_dereference(p) ({ \ | ||||
typeof(p) _________p1 = LOAD_SHARED(p); \ | ||||
smp_read_barrier_depends(); \ | ||||
(_________p1); \ | ||||
}) | ||||
#define futex(...) syscall(__NR_futex, __VA_ARGS__) | #define futex(...) syscall(__NR_futex, __VA_ARGS__) | |||
#define FUTEX_WAIT 0 | #define FUTEX_WAIT 0 | |||
#define FUTEX_WAKE 1 | #define FUTEX_WAKE 1 | |||
/* | /* | |||
* This code section can only be included in LGPL 2.1 compatible source cod e. | * This code section can only be included in LGPL 2.1 compatible source cod e. | |||
* See below for the function call wrappers which can be used in code meant to | * See below for the function call wrappers which can be used in code meant to | |||
* be only linked with the Userspace RCU library. This comes with a small | * be only linked with the Userspace RCU library. This comes with a small | |||
* performance degradation on the read-side due to the added function calls . | * performance degradation on the read-side due to the added function calls . | |||
* This is required to permit relinking with newer versions of the library. | * This is required to permit relinking with newer versions of the library. | |||
skipping to change at line 265 | skipping to change at line 216 | |||
smp_mb(); /* write urcu_reader.ctr before read futex */ | smp_mb(); /* write urcu_reader.ctr before read futex */ | |||
wake_up_gp(); | wake_up_gp(); | |||
} | } | |||
static inline void _rcu_thread_online(void) | static inline void _rcu_thread_online(void) | |||
{ | { | |||
_STORE_SHARED(urcu_reader.ctr, LOAD_SHARED(urcu_gp_ctr)); | _STORE_SHARED(urcu_reader.ctr, LOAD_SHARED(urcu_gp_ctr)); | |||
smp_mb(); | smp_mb(); | |||
} | } | |||
/** | ||||
* _rcu_assign_pointer - assign (publicize) a pointer to a new data structu | ||||
re | ||||
* meant to be read by RCU read-side critical sections. Returns the assigne | ||||
d | ||||
* value. | ||||
* | ||||
* Documents which pointers will be dereferenced by RCU read-side critical | ||||
* sections and adds the required memory barriers on architectures requirin | ||||
g | ||||
* them. It also makes sure the compiler does not reorder code initializing | ||||
the | ||||
* data structure before its publication. | ||||
* | ||||
* Should match rcu_dereference_pointer(). | ||||
*/ | ||||
#define _rcu_assign_pointer(p, v) \ | ||||
({ \ | ||||
if (!__builtin_constant_p(v) || \ | ||||
((v) != NULL)) \ | ||||
wmb(); \ | ||||
STORE_SHARED(p, v); \ | ||||
}) | ||||
/** | ||||
* _rcu_cmpxchg_pointer - same as rcu_assign_pointer, but tests if the poin | ||||
ter | ||||
* is as expected by "old". If succeeds, returns the previous pointer to th | ||||
e | ||||
* data structure, which can be safely freed after waiting for a quiescent | ||||
state | ||||
* using synchronize_rcu(). If fails (unexpected value), returns old (which | ||||
* should not be freed !). | ||||
*/ | ||||
#define _rcu_cmpxchg_pointer(p, old, _new) \ | ||||
({ \ | ||||
if (!__builtin_constant_p(_new) || \ | ||||
((_new) != NULL)) \ | ||||
wmb(); \ | ||||
uatomic_cmpxchg(p, old, _new); \ | ||||
}) | ||||
/** | ||||
* _rcu_xchg_pointer - same as rcu_assign_pointer, but returns the previous | ||||
* pointer to the data structure, which can be safely freed after waiting f | ||||
or a | ||||
* quiescent state using synchronize_rcu(). | ||||
*/ | ||||
#define _rcu_xchg_pointer(p, v) \ | ||||
({ \ | ||||
if (!__builtin_constant_p(v) || \ | ||||
((v) != NULL)) \ | ||||
wmb(); \ | ||||
uatomic_xchg(p, v); \ | ||||
}) | ||||
/* | ||||
* Exchanges the pointer and waits for quiescent state. | ||||
* The pointer returned can be freed. | ||||
*/ | ||||
#define _rcu_publish_content(p, v) \ | ||||
({ \ | ||||
void *oldptr; \ | ||||
oldptr = _rcu_xchg_pointer(p, v); \ | ||||
synchronize_rcu(); \ | ||||
oldptr; \ | ||||
}) | ||||
#endif /* _URCU_QSBR_STATIC_H */ | #endif /* _URCU_QSBR_STATIC_H */ | |||
End of changes. 3 change blocks. | ||||
127 lines changed or deleted | 1 lines changed or added | |||
urcu-qsbr.h | urcu-qsbr.h | |||
---|---|---|---|---|
skipping to change at line 35 | skipping to change at line 35 | |||
* License along with this library; if not, write to the Free Software | * License along with this library; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
* | * | |||
* IBM's contributions to this file may be relicensed under LGPLv2 or later . | * IBM's contributions to this file may be relicensed under LGPLv2 or later . | |||
*/ | */ | |||
#include <stdlib.h> | #include <stdlib.h> | |||
#include <pthread.h> | #include <pthread.h> | |||
/* | /* | |||
* See urcu-pointer.h and urcu-pointer-static.h for pointer publication hea | ||||
ders. | ||||
*/ | ||||
#include <urcu-pointer.h> | ||||
/* | ||||
* Important ! | * Important ! | |||
* | * | |||
* Each thread containing read-side critical sections must be registered | * Each thread containing read-side critical sections must be registered | |||
* with rcu_register_thread() before calling rcu_read_lock(). | * with rcu_register_thread() before calling rcu_read_lock(). | |||
* rcu_unregister_thread() should be called before the thread exits. | * rcu_unregister_thread() should be called before the thread exits. | |||
*/ | */ | |||
#ifdef _LGPL_SOURCE | #ifdef _LGPL_SOURCE | |||
#include <urcu-qsbr-static.h> | #include <urcu-qsbr-static.h> | |||
/* | /* | |||
* Mappings for static use of the userspace RCU library. | * Mappings for static use of the userspace RCU library. | |||
* Should only be used in LGPL-compatible code. | * Should only be used in LGPL-compatible code. | |||
*/ | */ | |||
#define rcu_dereference _rcu_dereference | /* | |||
#define rcu_read_lock _rcu_read_lock | * rcu_read_lock() | |||
#define rcu_read_unlock _rcu_read_unlock | * rcu_read_unlock() | |||
* | ||||
#define rcu_quiescent_state _rcu_quiescent_state | * Mark the beginning and end of a read-side critical section. | |||
#define rcu_thread_offline _rcu_thread_offline | * DON'T FORGET TO USE RCU_REGISTER/UNREGISTER_THREAD() FOR EACH THREAD WIT | |||
#define rcu_thread_online _rcu_thread_online | H | |||
* READ-SIDE CRITICAL SECTION. | ||||
#define rcu_assign_pointer _rcu_assign_pointer | */ | |||
#define rcu_cmpxchg_pointer _rcu_cmpxchg_pointer | #define rcu_read_lock() _rcu_read_lock() | |||
#define rcu_xchg_pointer _rcu_xchg_pointer | #define rcu_read_unlock() _rcu_read_unlock() | |||
#define rcu_publish_content _rcu_publish_content | ||||
#define rcu_quiescent_state() _rcu_quiescent_state() | ||||
#define rcu_thread_offline() _rcu_thread_offline() | ||||
#define rcu_thread_online() _rcu_thread_online() | ||||
#else /* !_LGPL_SOURCE */ | #else /* !_LGPL_SOURCE */ | |||
/* | /* | |||
* library wrappers to be used by non-LGPL compatible source code. | * library wrappers to be used by non-LGPL compatible source code. | |||
*/ | */ | |||
/* | /* | |||
* QSBR read lock/unlock are guaranteed to be no-ops. Therefore, we expose them | * QSBR read lock/unlock are guaranteed to be no-ops. Therefore, we expose them | |||
* in the LGPL header for any code to use. However, the debug version is no t | * in the LGPL header for any code to use. However, the debug version is no t | |||
skipping to change at line 96 | skipping to change at line 103 | |||
{ | { | |||
} | } | |||
#else /* !URCU_DEBUG */ | #else /* !URCU_DEBUG */ | |||
extern void rcu_read_lock(void); | extern void rcu_read_lock(void); | |||
extern void rcu_read_unlock(void); | extern void rcu_read_unlock(void); | |||
#endif /* !URCU_DEBUG */ | #endif /* !URCU_DEBUG */ | |||
extern void *rcu_dereference(void *p); | ||||
extern void rcu_quiescent_state(void); | extern void rcu_quiescent_state(void); | |||
extern void rcu_thread_offline(void); | extern void rcu_thread_offline(void); | |||
extern void rcu_thread_online(void); | extern void rcu_thread_online(void); | |||
extern void *rcu_assign_pointer_sym(void **p, void *v); | ||||
#define rcu_assign_pointer(p, v) \ | ||||
rcu_assign_pointer_sym((void **)(p), (v)) | ||||
extern void *rcu_cmpxchg_pointer_sym(void **p, void *old, void *_new); | ||||
#define rcu_cmpxchg_pointer(p, old, _new) \ | ||||
rcu_cmpxchg_pointer_sym((void **)(p), (old), (_new)) | ||||
extern void *rcu_xchg_pointer_sym(void **p, void *v); | ||||
#define rcu_xchg_pointer(p, v) \ | ||||
rcu_xchg_pointer_sym((void **)(p), (v)) | ||||
extern void *rcu_publish_content_sym(void **p, void *v); | ||||
#define rcu_publish_content(p, v) \ | ||||
rcu_publish_content_sym((void **)(p), (v)) | ||||
#endif /* !_LGPL_SOURCE */ | #endif /* !_LGPL_SOURCE */ | |||
extern void synchronize_rcu(void); | extern void synchronize_rcu(void); | |||
/* | /* | |||
* Reader thread registration. | * Reader thread registration. | |||
*/ | */ | |||
extern void rcu_register_thread(void); | extern void rcu_register_thread(void); | |||
extern void rcu_unregister_thread(void); | extern void rcu_unregister_thread(void); | |||
End of changes. 4 change blocks. | ||||
31 lines changed or deleted | 21 lines changed or added | |||
urcu-static.h | urcu-static.h | |||
---|---|---|---|---|
skipping to change at line 39 | skipping to change at line 39 | |||
* IBM's contributions to this file may be relicensed under LGPLv2 or later . | * IBM's contributions to this file may be relicensed under LGPLv2 or later . | |||
*/ | */ | |||
#include <stdlib.h> | #include <stdlib.h> | |||
#include <pthread.h> | #include <pthread.h> | |||
#include <syscall.h> | #include <syscall.h> | |||
#include <unistd.h> | #include <unistd.h> | |||
#include <urcu/compiler.h> | #include <urcu/compiler.h> | |||
#include <urcu/arch.h> | #include <urcu/arch.h> | |||
#include <urcu/system.h> | ||||
#include <urcu/arch_uatomic.h> | #include <urcu/arch_uatomic.h> | |||
#include <urcu/list.h> | #include <urcu/list.h> | |||
/* | ||||
* Identify a shared load. A smp_rmc() or smp_mc() should come before the l | ||||
oad. | ||||
*/ | ||||
#define _LOAD_SHARED(p) ACCESS_ONCE(p) | ||||
/* | ||||
* Load a data from shared memory, doing a cache flush if required. | ||||
*/ | ||||
#define LOAD_SHARED(p) \ | ||||
({ \ | ||||
smp_rmc(); \ | ||||
_LOAD_SHARED(p); \ | ||||
}) | ||||
/* | ||||
* Identify a shared store. A smp_wmc() or smp_mc() should follow the store | ||||
. | ||||
*/ | ||||
#define _STORE_SHARED(x, v) ({ ACCESS_ONCE(x) = (v); }) | ||||
/* | ||||
* Store v into x, where x is located in shared memory. Performs the requir | ||||
ed | ||||
* cache flush after writing. Returns v. | ||||
*/ | ||||
#define STORE_SHARED(x, v) \ | ||||
({ \ | ||||
_STORE_SHARED(x, v); \ | ||||
smp_wmc(); \ | ||||
(v); \ | ||||
}) | ||||
/** | ||||
* _rcu_dereference - reads (copy) a RCU-protected pointer to a local varia | ||||
ble | ||||
* into a RCU read-side critical section. The pointer can later be safely | ||||
* dereferenced within the critical section. | ||||
* | ||||
* This ensures that the pointer copy is invariant thorough the whole criti | ||||
cal | ||||
* section. | ||||
* | ||||
* Inserts memory barriers on architectures that require them (currently on | ||||
ly | ||||
* Alpha) and documents which pointers are protected by RCU. | ||||
* | ||||
* The compiler memory barrier in LOAD_SHARED() ensures that value-speculat | ||||
ive | ||||
* optimizations (e.g. VSS: Value Speculation Scheduling) does not perform | ||||
the | ||||
* data read before the pointer read by speculating the value of the pointe | ||||
r. | ||||
* Correct ordering is ensured because the pointer is read as a volatile ac | ||||
cess. | ||||
* This acts as a global side-effect operation, which forbids reordering of | ||||
* dependent memory operations. Note that such concern about dependency-bre | ||||
aking | ||||
* optimizations will eventually be taken care of by the "memory_order_cons | ||||
ume" | ||||
* addition to forthcoming C++ standard. | ||||
* | ||||
* Should match rcu_assign_pointer() or rcu_xchg_pointer(). | ||||
*/ | ||||
#define _rcu_dereference(p) ({ \ | ||||
typeof(p) _________p1 = LOAD_SHARED(p); \ | ||||
smp_read_barrier_depends(); \ | ||||
(_________p1); \ | ||||
}) | ||||
#define futex(...) syscall(__NR_futex, __VA_ARGS__) | #define futex(...) syscall(__NR_futex, __VA_ARGS__) | |||
#define FUTEX_WAIT 0 | #define FUTEX_WAIT 0 | |||
#define FUTEX_WAKE 1 | #define FUTEX_WAKE 1 | |||
/* | /* | |||
* This code section can only be included in LGPL 2.1 compatible source cod e. | * This code section can only be included in LGPL 2.1 compatible source cod e. | |||
* See below for the function call wrappers which can be used in code meant to | * See below for the function call wrappers which can be used in code meant to | |||
* be only linked with the Userspace RCU library. This comes with a small | * be only linked with the Userspace RCU library. This comes with a small | |||
* performance degradation on the read-side due to the added function calls . | * performance degradation on the read-side due to the added function calls . | |||
* This is required to permit relinking with newer versions of the library. | * This is required to permit relinking with newer versions of the library. | |||
skipping to change at line 301 | skipping to change at line 243 | |||
reader_barrier(); | reader_barrier(); | |||
_STORE_SHARED(urcu_reader.ctr, urcu_reader.ctr - RCU_GP_COUN T); | _STORE_SHARED(urcu_reader.ctr, urcu_reader.ctr - RCU_GP_COUN T); | |||
/* write urcu_reader.ctr before read futex */ | /* write urcu_reader.ctr before read futex */ | |||
reader_barrier(); | reader_barrier(); | |||
wake_up_gp(); | wake_up_gp(); | |||
} else { | } else { | |||
_STORE_SHARED(urcu_reader.ctr, urcu_reader.ctr - RCU_GP_COUN T); | _STORE_SHARED(urcu_reader.ctr, urcu_reader.ctr - RCU_GP_COUN T); | |||
} | } | |||
} | } | |||
/** | ||||
* _rcu_assign_pointer - assign (publicize) a pointer to a new data structu | ||||
re | ||||
* meant to be read by RCU read-side critical sections. Returns the assigne | ||||
d | ||||
* value. | ||||
* | ||||
* Documents which pointers will be dereferenced by RCU read-side critical | ||||
* sections and adds the required memory barriers on architectures requirin | ||||
g | ||||
* them. It also makes sure the compiler does not reorder code initializing | ||||
the | ||||
* data structure before its publication. | ||||
* | ||||
* Should match rcu_dereference_pointer(). | ||||
*/ | ||||
#define _rcu_assign_pointer(p, v) \ | ||||
({ \ | ||||
if (!__builtin_constant_p(v) || \ | ||||
((v) != NULL)) \ | ||||
wmb(); \ | ||||
STORE_SHARED(p, v); \ | ||||
}) | ||||
/** | ||||
* _rcu_cmpxchg_pointer - same as rcu_assign_pointer, but tests if the poin | ||||
ter | ||||
* is as expected by "old". If succeeds, returns the previous pointer to th | ||||
e | ||||
* data structure, which can be safely freed after waiting for a quiescent | ||||
state | ||||
* using synchronize_rcu(). If fails (unexpected value), returns old (which | ||||
* should not be freed !). | ||||
*/ | ||||
#define _rcu_cmpxchg_pointer(p, old, _new) \ | ||||
({ \ | ||||
if (!__builtin_constant_p(_new) || \ | ||||
((_new) != NULL)) \ | ||||
wmb(); \ | ||||
uatomic_cmpxchg(p, old, _new); \ | ||||
}) | ||||
/** | ||||
* _rcu_xchg_pointer - same as rcu_assign_pointer, but returns the previous | ||||
* pointer to the data structure, which can be safely freed after waiting f | ||||
or a | ||||
* quiescent state using synchronize_rcu(). | ||||
*/ | ||||
#define _rcu_xchg_pointer(p, v) \ | ||||
({ \ | ||||
if (!__builtin_constant_p(v) || \ | ||||
((v) != NULL)) \ | ||||
wmb(); \ | ||||
uatomic_xchg(p, v); \ | ||||
}) | ||||
/* | ||||
* Exchanges the pointer and waits for quiescent state. | ||||
* The pointer returned can be freed. | ||||
*/ | ||||
#define _rcu_publish_content(p, v) \ | ||||
({ \ | ||||
void *oldptr; \ | ||||
oldptr = _rcu_xchg_pointer(p, v); \ | ||||
synchronize_rcu(); \ | ||||
oldptr; \ | ||||
}) | ||||
#endif /* _URCU_STATIC_H */ | #endif /* _URCU_STATIC_H */ | |||
End of changes. 3 change blocks. | ||||
142 lines changed or deleted | 1 lines changed or added | |||
urcu.h | urcu.h | |||
---|---|---|---|---|
skipping to change at line 38 | skipping to change at line 38 | |||
* License along with this library; if not, write to the Free Software | * License along with this library; if not, write to the Free Software | |||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |||
* | * | |||
* IBM's contributions to this file may be relicensed under LGPLv2 or later . | * IBM's contributions to this file may be relicensed under LGPLv2 or later . | |||
*/ | */ | |||
#include <stdlib.h> | #include <stdlib.h> | |||
#include <pthread.h> | #include <pthread.h> | |||
/* | /* | |||
* See urcu-pointer.h and urcu-pointer-static.h for pointer publication hea | ||||
ders. | ||||
*/ | ||||
#include <urcu-pointer.h> | ||||
/* | ||||
* Important ! | * Important ! | |||
* | * | |||
* Each thread containing read-side critical sections must be registered | * Each thread containing read-side critical sections must be registered | |||
* with rcu_register_thread() before calling rcu_read_lock(). | * with rcu_register_thread() before calling rcu_read_lock(). | |||
* rcu_unregister_thread() should be called before the thread exits. | * rcu_unregister_thread() should be called before the thread exits. | |||
*/ | */ | |||
#ifdef _LGPL_SOURCE | #ifdef _LGPL_SOURCE | |||
#include <urcu-static.h> | #include <urcu-static.h> | |||
/* | /* | |||
* Mappings for static use of the userspace RCU library. | * Mappings for static use of the userspace RCU library. | |||
* Should only be used in LGPL-compatible code. | * Should only be used in LGPL-compatible code. | |||
*/ | */ | |||
#define rcu_dereference _rcu_dereference | /* | |||
#define rcu_read_lock _rcu_read_lock | * rcu_read_lock() | |||
#define rcu_read_unlock _rcu_read_unlock | * rcu_read_unlock() | |||
* | ||||
#define rcu_assign_pointer _rcu_assign_pointer | * Mark the beginning and end of a read-side critical section. | |||
#define rcu_cmpxchg_pointer _rcu_cmpxchg_pointer | * DON'T FORGET TO USE RCU_REGISTER/UNREGISTER_THREAD() FOR EACH THREAD WIT | |||
#define rcu_xchg_pointer _rcu_xchg_pointer | H | |||
#define rcu_publish_content _rcu_publish_content | * READ-SIDE CRITICAL SECTION. | |||
*/ | ||||
#define rcu_read_lock() _rcu_read_lock() | ||||
#define rcu_read_unlock() _rcu_read_unlock() | ||||
#else /* !_LGPL_SOURCE */ | #else /* !_LGPL_SOURCE */ | |||
/* | /* | |||
* library wrappers to be used by non-LGPL compatible source code. | * library wrappers to be used by non-LGPL compatible source code. | |||
* See LGPL-only urcu-pointer-static.h for documentation. | ||||
*/ | */ | |||
extern void rcu_read_lock(void); | extern void rcu_read_lock(void); | |||
extern void rcu_read_unlock(void); | extern void rcu_read_unlock(void); | |||
extern void *rcu_dereference(void *p); | ||||
extern void *rcu_assign_pointer_sym(void **p, void *v); | ||||
#define rcu_assign_pointer(p, v) \ | ||||
rcu_assign_pointer_sym((void **)(p), (v)) | ||||
extern void *rcu_cmpxchg_pointer_sym(void **p, void *old, void *_new); | ||||
#define rcu_cmpxchg_pointer(p, old, _new) \ | ||||
rcu_cmpxchg_pointer_sym((void **)(p), (old), (_new)) | ||||
extern void *rcu_xchg_pointer_sym(void **p, void *v); | ||||
#define rcu_xchg_pointer(p, v) \ | ||||
rcu_xchg_pointer_sym((void **)(p), (v)) | ||||
extern void *rcu_publish_content_sym(void **p, void *v); | ||||
#define rcu_publish_content(p, v) \ | ||||
rcu_publish_content_sym((void **)(p), (v)) | ||||
#endif /* !_LGPL_SOURCE */ | #endif /* !_LGPL_SOURCE */ | |||
extern void synchronize_rcu(void); | extern void synchronize_rcu(void); | |||
/* | /* | |||
* Reader thread registration. | * Reader thread registration. | |||
*/ | */ | |||
extern void rcu_register_thread(void); | extern void rcu_register_thread(void); | |||
extern void rcu_unregister_thread(void); | extern void rcu_unregister_thread(void); | |||
End of changes. 4 change blocks. | ||||
27 lines changed or deleted | 18 lines changed or added | |||