/* * rcuclassic.h: user-level prototype of hierarchical classic RCU. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * Copyright (c) 2008 Paul E. McKenney, IBM Corporation. */ #define RCU_DONE_TAIL 0 /* Also RCU_WAIT head. */ #define RCU_WAIT_TAIL 1 /* Also RCU_NEXT_READY head. */ #define RCU_NEXT_READY_TAIL 2 /* Also RCU_NEXT head. */ #define RCU_NEXT_TAIL 3 #define RCU_NEXT_SIZE 4 /* Per-CPU data for Read-Copy UPdate. */ struct rcu_data { /* 1) quiescent-state and grace-period handling : */ long completed; /* Track rsp->completed gp number */ /* in order to detect GP end. */ long gpnum; /* Highest gp number that this CPU */ /* is aware of having started. */ int passed_quiesc; /* User-mode/idle loop etc. */ int qs_pending; /* core waits for quiesc state */ /* rdp->completed!=rsp->completed, */ /* but with less cache thrashing. */ struct rcu_node *mynode; /* this CPU's leaf of hierarchy */ /* 2) batch handling */ /* * If nxtlist is not NULL, it is partitioned as follows. * Any of the partitions might be empty, in which case the * pointer to that partition will be equal to the pointer for * the following partition. When the list is empty, all of * the nxttail elements point to nxtlist, which is NULL. * * [*nxttail[2], NULL = *nxttail[3]): * Entries that might have arrived after current GP ended * [*nxttail[1], *nxttail[2]): * Entries known to have arrived before current GP ended * [*nxttail[0], *nxttail[1]): * Entries that batch # <= ->completed - 1: waiting for current GP * [nxtlist, *nxttail[0]): * Entries that batch # <= ->completed * The grace period for these entries has completed, and * the other grace-period-completed entries may be moved * here temporarily in rcu_process_callbacks(). */ struct rcu_head *nxtlist; struct rcu_head **nxttail[RCU_NEXT_SIZE]; long qlen; /* # of queued callbacks */ /* @@@ struct rcu_head *donelist; */ /* @@@ struct rcu_head **donetail; */ long blimit; /* Upper limit on a processed batch */ int cpu; /* struct rcu_head barrier; */ }; /* @@@ DECLARE_PER_CPU(struct rcu_data, rcu_data); */ /* @@@ DECLARE_PER_CPU(struct rcu_data, rcu_bh_data); */ DEFINE_PER_CPU(struct rcu_data, rcu_data); DEFINE_PER_CPU(struct rcu_data, rcu_bh_data); /* * Increment the quiescent state "counter". * This used to really be a counter, but has atrophied. The reason is * that we do not need to know how many quiescent states passed, just * if there was at least one since the start of the grace period. * The counter has therefore become a simple flag. */ static inline void rcu_qsctr_inc(int cpu) { struct rcu_data *rdp = &per_cpu(rcu_data, cpu); rdp->passed_quiesc = 1; } static inline void rcu_bh_qsctr_inc(int cpu) { struct rcu_data *rdp = &per_cpu(rcu_bh_data, cpu); rdp->passed_quiesc = 1; }