X-Git-Url: http://git.liburcu.org/?a=blobdiff_plain;f=src%2Furcu-bp.c;h=46397c712683b2fdc48b54b329d75630cbd3a9a3;hb=601922a81d884e16ff404cee7534ede56fb87d0a;hp=a097d7f00312a1372123f5c61a732f0e8270354d;hpb=014775106c60f02818ca755b331f887030bd440f;p=userspace-rcu.git diff --git a/src/urcu-bp.c b/src/urcu-bp.c index a097d7f..46397c7 100644 --- a/src/urcu-bp.c +++ b/src/urcu-bp.c @@ -1,25 +1,11 @@ +// SPDX-FileCopyrightText: 2009 Mathieu Desnoyers +// SPDX-FileCopyrightText: 2009 Paul E. McKenney, IBM Corporation. +// +// SPDX-License-Identifier: LGPL-2.1-or-later + /* - * urcu-bp.c - * * Userspace RCU library, "bulletproof" version. * - * Copyright (c) 2009 Mathieu Desnoyers - * Copyright (c) 2009 Paul E. McKenney, IBM Corporation. - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * 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. */ @@ -36,6 +22,7 @@ #include #include +#include #include #include #include @@ -120,7 +107,10 @@ enum membarrier_cmd { static void __attribute__((constructor)) _urcu_bp_init(void); static -void __attribute__((destructor)) urcu_bp_exit(void); +void urcu_bp_exit(void); +static +void __attribute__((destructor)) urcu_bp_exit_destructor(void); +static void urcu_call_rcu_exit(void); #ifndef CONFIG_RCU_FORCE_SYS_MEMBARRIER int urcu_bp_has_sys_membarrier; @@ -217,7 +207,8 @@ static void smp_mb_master(void) */ static void wait_for_readers(struct cds_list_head *input_readers, struct cds_list_head *cur_snap_readers, - struct cds_list_head *qsreaders) + struct cds_list_head *qsreaders, + cmm_annotate_t *group) { unsigned int wait_loops = 0; struct urcu_bp_reader *index, *tmp; @@ -232,7 +223,7 @@ static void wait_for_readers(struct cds_list_head *input_readers, wait_loops++; cds_list_for_each_entry_safe(index, tmp, input_readers, node) { - switch (urcu_bp_reader_state(&index->ctr)) { + switch (urcu_bp_reader_state(&index->ctr, group)) { case URCU_BP_READER_ACTIVE_CURRENT: if (cur_snap_readers) { cds_list_move(&index->node, @@ -271,6 +262,8 @@ static void wait_for_readers(struct cds_list_head *input_readers, void urcu_bp_synchronize_rcu(void) { + cmm_annotate_define(acquire_group); + cmm_annotate_define(release_group); CDS_LIST_HEAD(cur_snap_readers); CDS_LIST_HEAD(qsreaders); sigset_t newmask, oldmask; @@ -292,13 +285,14 @@ void urcu_bp_synchronize_rcu(void) * where new ptr points to. */ /* Write new ptr before changing the qparity */ smp_mb_master(); + cmm_annotate_group_mb_release(&release_group); /* * Wait for readers to observe original parity or be quiescent. * wait_for_readers() can release and grab again rcu_registry_lock * internally. */ - wait_for_readers(®istry, &cur_snap_readers, &qsreaders); + wait_for_readers(®istry, &cur_snap_readers, &qsreaders, &acquire_group); /* * Adding a cmm_smp_mb() which is _not_ formally required, but makes the @@ -308,7 +302,8 @@ void urcu_bp_synchronize_rcu(void) cmm_smp_mb(); /* Switch parity: 0 -> 1, 1 -> 0 */ - CMM_STORE_SHARED(rcu_gp.ctr, rcu_gp.ctr ^ URCU_BP_GP_CTR_PHASE); + cmm_annotate_group_mem_release(&release_group, &rcu_gp.ctr); + uatomic_store(&rcu_gp.ctr, rcu_gp.ctr ^ URCU_BP_GP_CTR_PHASE, CMM_RELAXED); /* * Must commit qparity update to memory before waiting for other parity @@ -329,7 +324,7 @@ void urcu_bp_synchronize_rcu(void) * wait_for_readers() can release and grab again rcu_registry_lock * internally. */ - wait_for_readers(&cur_snap_readers, NULL, &qsreaders); + wait_for_readers(&cur_snap_readers, NULL, &qsreaders, &acquire_group); /* * Put quiescent reader list back into registry. @@ -341,6 +336,7 @@ void urcu_bp_synchronize_rcu(void) * freed. */ smp_mb_master(); + cmm_annotate_group_mb_acquire(&acquire_group); out: mutex_unlock(&rcu_registry_lock); mutex_unlock(&rcu_gp_lock); @@ -673,6 +669,13 @@ void urcu_bp_exit(void) mutex_unlock(&init_lock); } +static +void urcu_bp_exit_destructor(void) +{ + urcu_call_rcu_exit(); + urcu_bp_exit(); +} + /* * Holding the rcu_gp_lock and rcu_registry_lock across fork will make * sure we fork() don't race with a concurrent thread executing with @@ -769,3 +772,4 @@ DEFINE_RCU_FLAVOR(rcu_flavor); #include "urcu-call-rcu-impl.h" #include "urcu-defer-impl.h" +#include "urcu-poll-impl.h"