linux/include/linux/rcu_sync.h
<<
>>
Prefs
   1/*
   2 * RCU-based infrastructure for lightweight reader-writer locking
   3 *
   4 * This program is free software; you can redistribute it and/or modify
   5 * it under the terms of the GNU General Public License as published by
   6 * the Free Software Foundation; either version 2 of the License, or
   7 * (at your option) any later version.
   8 *
   9 * This program is distributed in the hope that it will be useful,
  10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12 * GNU General Public License for more details.
  13 *
  14 * You should have received a copy of the GNU General Public License
  15 * along with this program; if not, you can access it online at
  16 * http://www.gnu.org/licenses/gpl-2.0.html.
  17 *
  18 * Copyright (c) 2015, Red Hat, Inc.
  19 *
  20 * Author: Oleg Nesterov <oleg@redhat.com>
  21 */
  22
  23#ifndef _LINUX_RCU_SYNC_H_
  24#define _LINUX_RCU_SYNC_H_
  25
  26#include <linux/wait.h>
  27#include <linux/rcupdate.h>
  28
  29enum rcu_sync_type { RCU_SYNC, RCU_SCHED_SYNC, RCU_BH_SYNC };
  30
  31/* Structure to mediate between updaters and fastpath-using readers.  */
  32struct rcu_sync {
  33        int                     gp_state;
  34        int                     gp_count;
  35        wait_queue_head_t       gp_wait;
  36
  37        int                     cb_state;
  38        struct rcu_head         cb_head;
  39
  40        enum rcu_sync_type      gp_type;
  41};
  42
  43extern void rcu_sync_lockdep_assert(struct rcu_sync *);
  44
  45/**
  46 * rcu_sync_is_idle() - Are readers permitted to use their fastpaths?
  47 * @rsp: Pointer to rcu_sync structure to use for synchronization
  48 *
  49 * Returns true if readers are permitted to use their fastpaths.
  50 * Must be invoked within an RCU read-side critical section whose
  51 * flavor matches that of the rcu_sync struture.
  52 */
  53static inline bool rcu_sync_is_idle(struct rcu_sync *rsp)
  54{
  55#ifdef CONFIG_PROVE_RCU
  56        rcu_sync_lockdep_assert(rsp);
  57#endif
  58        return !rsp->gp_state; /* GP_IDLE */
  59}
  60
  61extern void rcu_sync_init(struct rcu_sync *, enum rcu_sync_type);
  62extern void rcu_sync_enter_start(struct rcu_sync *);
  63extern void rcu_sync_enter(struct rcu_sync *);
  64extern void rcu_sync_exit(struct rcu_sync *);
  65extern void rcu_sync_dtor(struct rcu_sync *);
  66
  67#define __RCU_SYNC_INITIALIZER(name, type) {                            \
  68                .gp_state = 0,                                          \
  69                .gp_count = 0,                                          \
  70                .gp_wait = __WAIT_QUEUE_HEAD_INITIALIZER(name.gp_wait), \
  71                .cb_state = 0,                                          \
  72                .gp_type = type,                                        \
  73        }
  74
  75#define __DEFINE_RCU_SYNC(name, type)   \
  76        struct rcu_sync_struct name = __RCU_SYNC_INITIALIZER(name, type)
  77
  78#define DEFINE_RCU_SYNC(name)           \
  79        __DEFINE_RCU_SYNC(name, RCU_SYNC)
  80
  81#define DEFINE_RCU_SCHED_SYNC(name)     \
  82        __DEFINE_RCU_SYNC(name, RCU_SCHED_SYNC)
  83
  84#define DEFINE_RCU_BH_SYNC(name)        \
  85        __DEFINE_RCU_SYNC(name, RCU_BH_SYNC)
  86
  87#endif /* _LINUX_RCU_SYNC_H_ */
  88