# be more selective with liburcu
race:rcu_barrier
-race:rcu_memb_barrier
+race:rcu_*_barrier
thread:*
/* paired with chunk_free() */
isc_refcount_increment(&qp->base->refcount);
- /* reader_open() below has the matching atomic_load_acquire() */
- atomic_store_release(&multi->reader, reader); /* COMMIT */
+ rcu_assign_pointer(multi->reader, reader); /* COMMIT */
/* clean up what we can right now */
if (qp->transaction_mode == QP_UPDATE || QP_NEEDGC(qp)) {
static dns_qpmulti_t *
reader_open(dns_qpmulti_t *multi, dns_qpreadable_t qpr) {
dns_qpreader_t *qp = dns_qpreader(qpr);
- /* dns_qpmulti_commit() has the matching atomic_store_release() */
- qp_node_t *reader = atomic_load_acquire(&multi->reader);
+ qp_node_t *reader = rcu_dereference(multi->reader);
if (reader == NULL) {
QP_INIT(qp, multi->writer.methods, multi->writer.uctx);
} else {
*/
struct dns_qpmulti {
uint32_t magic;
- /*% pointer to current packed reader */
- atomic_ptr(qp_node_t) reader;
+ /*% RCU-protected pointer to current packed reader */
+ qp_node_t *reader;
/*% the mutex protects the rest of this structure */
isc_mutex_t mutex;
/*% ref_ptr(writer, reader_ref) == reader */
#define synchronize_rcu() isc_qsbr_syncronize_rcu()
#define isc_qsbr_rcu_dereference(ptr) \
- { \
+ ({ \
if (!urcu_qsbr_read_ongoing()) { \
urcu_qsbr_thread_online(); \
} \
- urcu_qsbr_dereference(ptr); \
- }
+ _rcu_dereference(ptr); \
+ })
#undef rcu_dereference
#define rcu_dereference(ptr) isc_qsbr_rcu_dereference(ptr)
#include <isc/mem.h>
#include <isc/os.h>
#include <isc/tls.h>
+#include <isc/urcu.h>
#include <isc/util.h>
#include <isc/uv.h>
#include <isc/xml.h>
isc__md_initialize();
isc__iterated_hash_initialize();
(void)isc_os_ncpus();
+ rcu_register_thread();
}
void
isc__mem_shutdown();
isc__mutex_shutdown();
isc__os_shutdown();
+ /* should be after isc__mem_shutdown() which calls rcu_barrier() */
+ rcu_unregister_thread();
}
bool free_call_rcu_data = !create_all_cpu_call_rcu_data(0);
- rcu_register_thread();
-
/*
* The thread 0 is this one.
*/
isc_thread_main(loop_thread, &loopmgr->loops[0]);
- rcu_unregister_thread();
-
rcu_barrier();
if (free_call_rcu_data) {
void
qp_test_dumpmulti(dns_qpmulti_t *multi) {
dns_qpreader_t qpr;
- qp_node_t *reader = atomic_load(&multi->reader);
+ qp_node_t *reader = rcu_dereference(multi->reader);
dns_qpmulti_t *whence = unpack_reader(&qpr, reader);
dumpqp(&multi->writer, "qpmulti->writer");
printf("qpmulti->reader %p root_ref %u %u:%u base %p\n", reader,