linux/include/linux/plist.h
<<
>>
Prefs
   1/*
   2 * Descending-priority-sorted double-linked list
   3 *
   4 * (C) 2002-2003 Intel Corp
   5 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>.
   6 *
   7 * 2001-2005 (c) MontaVista Software, Inc.
   8 * Daniel Walker <dwalker@mvista.com>
   9 *
  10 * (C) 2005 Thomas Gleixner <tglx@linutronix.de>
  11 *
  12 * Simplifications of the original code by
  13 * Oleg Nesterov <oleg@tv-sign.ru>
  14 *
  15 * Licensed under the FSF's GNU Public License v2 or later.
  16 *
  17 * Based on simple lists (include/linux/list.h).
  18 *
  19 * This is a priority-sorted list of nodes; each node has a
  20 * priority from INT_MIN (highest) to INT_MAX (lowest).
  21 *
  22 * Addition is O(K), removal is O(1), change of priority of a node is
  23 * O(K) and K is the number of RT priority levels used in the system.
  24 * (1 <= K <= 99)
  25 *
  26 * This list is really a list of lists:
  27 *
  28 *  - The tier 1 list is the prio_list, different priority nodes.
  29 *
  30 *  - The tier 2 list is the node_list, serialized nodes.
  31 *
  32 * Simple ASCII art explanation:
  33 *
  34 * pl:prio_list (only for plist_node)
  35 * nl:node_list
  36 *   HEAD|             NODE(S)
  37 *       |
  38 *       ||------------------------------------|
  39 *       ||->|pl|<->|pl|<--------------->|pl|<-|
  40 *       |   |10|   |21|   |21|   |21|   |40|   (prio)
  41 *       |   |  |   |  |   |  |   |  |   |  |
  42 *       |   |  |   |  |   |  |   |  |   |  |
  43 * |->|nl|<->|nl|<->|nl|<->|nl|<->|nl|<->|nl|<-|
  44 * |-------------------------------------------|
  45 *
  46 * The nodes on the prio_list list are sorted by priority to simplify
  47 * the insertion of new nodes. There are no nodes with duplicate
  48 * priorites on the list.
  49 *
  50 * The nodes on the node_list are ordered by priority and can contain
  51 * entries which have the same priority. Those entries are ordered
  52 * FIFO
  53 *
  54 * Addition means: look for the prio_list node in the prio_list
  55 * for the priority of the node and insert it before the node_list
  56 * entry of the next prio_list node. If it is the first node of
  57 * that priority, add it to the prio_list in the right position and
  58 * insert it into the serialized node_list list
  59 *
  60 * Removal means remove it from the node_list and remove it from
  61 * the prio_list if the node_list list_head is non empty. In case
  62 * of removal from the prio_list it must be checked whether other
  63 * entries of the same priority are on the list or not. If there
  64 * is another entry of the same priority then this entry has to
  65 * replace the removed entry on the prio_list. If the entry which
  66 * is removed is the only entry of this priority then a simple
  67 * remove from both list is sufficient.
  68 *
  69 * INT_MIN is the highest priority, 0 is the medium highest, INT_MAX
  70 * is lowest priority.
  71 *
  72 * No locking is done, up to the caller.
  73 *
  74 */
  75#ifndef _LINUX_PLIST_H_
  76#define _LINUX_PLIST_H_
  77
  78#include <linux/kernel.h>
  79#include <linux/list.h>
  80#include <linux/spinlock_types.h>
  81
  82struct plist_head {
  83        struct list_head node_list;
  84#ifdef CONFIG_DEBUG_PI_LIST
  85        raw_spinlock_t *rawlock;
  86        spinlock_t *spinlock;
  87#endif
  88};
  89
  90struct plist_node {
  91        int                     prio;
  92        struct list_head        prio_list;
  93        struct list_head        node_list;
  94};
  95
  96#ifdef CONFIG_DEBUG_PI_LIST
  97# define PLIST_HEAD_LOCK_INIT(_lock)            .spinlock = _lock
  98# define PLIST_HEAD_LOCK_INIT_RAW(_lock)        .rawlock = _lock
  99#else
 100# define PLIST_HEAD_LOCK_INIT(_lock)
 101# define PLIST_HEAD_LOCK_INIT_RAW(_lock)
 102#endif
 103
 104#define _PLIST_HEAD_INIT(head)                          \
 105        .node_list = LIST_HEAD_INIT((head).node_list)
 106
 107/**
 108 * PLIST_HEAD_INIT - static struct plist_head initializer
 109 * @head:       struct plist_head variable name
 110 * @_lock:      lock to initialize for this list
 111 */
 112#define PLIST_HEAD_INIT(head, _lock)                    \
 113{                                                       \
 114        _PLIST_HEAD_INIT(head),                         \
 115        PLIST_HEAD_LOCK_INIT(&(_lock))                  \
 116}
 117
 118/**
 119 * PLIST_HEAD_INIT_RAW - static struct plist_head initializer
 120 * @head:       struct plist_head variable name
 121 * @_lock:      lock to initialize for this list
 122 */
 123#define PLIST_HEAD_INIT_RAW(head, _lock)                \
 124{                                                       \
 125        _PLIST_HEAD_INIT(head),                         \
 126        PLIST_HEAD_LOCK_INIT_RAW(&(_lock))              \
 127}
 128
 129/**
 130 * PLIST_NODE_INIT - static struct plist_node initializer
 131 * @node:       struct plist_node variable name
 132 * @__prio:     initial node priority
 133 */
 134#define PLIST_NODE_INIT(node, __prio)                   \
 135{                                                       \
 136        .prio  = (__prio),                              \
 137        .prio_list = LIST_HEAD_INIT((node).prio_list),  \
 138        .node_list = LIST_HEAD_INIT((node).node_list),  \
 139}
 140
 141/**
 142 * plist_head_init - dynamic struct plist_head initializer
 143 * @head:       &struct plist_head pointer
 144 * @lock:       spinlock protecting the list (debugging)
 145 */
 146static inline void
 147plist_head_init(struct plist_head *head, spinlock_t *lock)
 148{
 149        INIT_LIST_HEAD(&head->node_list);
 150#ifdef CONFIG_DEBUG_PI_LIST
 151        head->spinlock = lock;
 152        head->rawlock = NULL;
 153#endif
 154}
 155
 156/**
 157 * plist_head_init_raw - dynamic struct plist_head initializer
 158 * @head:       &struct plist_head pointer
 159 * @lock:       raw_spinlock protecting the list (debugging)
 160 */
 161static inline void
 162plist_head_init_raw(struct plist_head *head, raw_spinlock_t *lock)
 163{
 164        INIT_LIST_HEAD(&head->node_list);
 165#ifdef CONFIG_DEBUG_PI_LIST
 166        head->rawlock = lock;
 167        head->spinlock = NULL;
 168#endif
 169}
 170
 171/**
 172 * plist_node_init - Dynamic struct plist_node initializer
 173 * @node:       &struct plist_node pointer
 174 * @prio:       initial node priority
 175 */
 176static inline void plist_node_init(struct plist_node *node, int prio)
 177{
 178        node->prio = prio;
 179        INIT_LIST_HEAD(&node->prio_list);
 180        INIT_LIST_HEAD(&node->node_list);
 181}
 182
 183extern void plist_add(struct plist_node *node, struct plist_head *head);
 184extern void plist_del(struct plist_node *node, struct plist_head *head);
 185
 186/**
 187 * plist_for_each - iterate over the plist
 188 * @pos:        the type * to use as a loop counter
 189 * @head:       the head for your list
 190 */
 191#define plist_for_each(pos, head)       \
 192         list_for_each_entry(pos, &(head)->node_list, node_list)
 193
 194/**
 195 * plist_for_each_safe - iterate safely over a plist of given type
 196 * @pos:        the type * to use as a loop counter
 197 * @n:  another type * to use as temporary storage
 198 * @head:       the head for your list
 199 *
 200 * Iterate over a plist of given type, safe against removal of list entry.
 201 */
 202#define plist_for_each_safe(pos, n, head)       \
 203         list_for_each_entry_safe(pos, n, &(head)->node_list, node_list)
 204
 205/**
 206 * plist_for_each_entry - iterate over list of given type
 207 * @pos:        the type * to use as a loop counter
 208 * @head:       the head for your list
 209 * @mem:        the name of the list_struct within the struct
 210 */
 211#define plist_for_each_entry(pos, head, mem)    \
 212         list_for_each_entry(pos, &(head)->node_list, mem.node_list)
 213
 214/**
 215 * plist_for_each_entry_safe - iterate safely over list of given type
 216 * @pos:        the type * to use as a loop counter
 217 * @n:          another type * to use as temporary storage
 218 * @head:       the head for your list
 219 * @m:          the name of the list_struct within the struct
 220 *
 221 * Iterate over list of given type, safe against removal of list entry.
 222 */
 223#define plist_for_each_entry_safe(pos, n, head, m)      \
 224        list_for_each_entry_safe(pos, n, &(head)->node_list, m.node_list)
 225
 226/**
 227 * plist_head_empty - return !0 if a plist_head is empty
 228 * @head:       &struct plist_head pointer
 229 */
 230static inline int plist_head_empty(const struct plist_head *head)
 231{
 232        return list_empty(&head->node_list);
 233}
 234
 235/**
 236 * plist_node_empty - return !0 if plist_node is not on a list
 237 * @node:       &struct plist_node pointer
 238 */
 239static inline int plist_node_empty(const struct plist_node *node)
 240{
 241        return list_empty(&node->node_list);
 242}
 243
 244/* All functions below assume the plist_head is not empty. */
 245
 246/**
 247 * plist_first_entry - get the struct for the first entry
 248 * @head:       the &struct plist_head pointer
 249 * @type:       the type of the struct this is embedded in
 250 * @member:     the name of the list_struct within the struct
 251 */
 252#ifdef CONFIG_DEBUG_PI_LIST
 253# define plist_first_entry(head, type, member)  \
 254({ \
 255        WARN_ON(plist_head_empty(head)); \
 256        container_of(plist_first(head), type, member); \
 257})
 258#else
 259# define plist_first_entry(head, type, member)  \
 260        container_of(plist_first(head), type, member)
 261#endif
 262
 263/**
 264 * plist_last_entry - get the struct for the last entry
 265 * @head:       the &struct plist_head pointer
 266 * @type:       the type of the struct this is embedded in
 267 * @member:     the name of the list_struct within the struct
 268 */
 269#ifdef CONFIG_DEBUG_PI_LIST
 270# define plist_last_entry(head, type, member)   \
 271({ \
 272        WARN_ON(plist_head_empty(head)); \
 273        container_of(plist_last(head), type, member); \
 274})
 275#else
 276# define plist_last_entry(head, type, member)   \
 277        container_of(plist_last(head), type, member)
 278#endif
 279
 280/**
 281 * plist_first - return the first node (and thus, highest priority)
 282 * @head:       the &struct plist_head pointer
 283 *
 284 * Assumes the plist is _not_ empty.
 285 */
 286static inline struct plist_node *plist_first(const struct plist_head *head)
 287{
 288        return list_entry(head->node_list.next,
 289                          struct plist_node, node_list);
 290}
 291
 292/**
 293 * plist_last - return the last node (and thus, lowest priority)
 294 * @head:       the &struct plist_head pointer
 295 *
 296 * Assumes the plist is _not_ empty.
 297 */
 298static inline struct plist_node *plist_last(const struct plist_head *head)
 299{
 300        return list_entry(head->node_list.prev,
 301                          struct plist_node, node_list);
 302}
 303
 304#endif
 305