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