Line data Source code
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 : * |HEAD |
35 : * | |
36 : * |prio_list.prev|<------------------------------------|
37 : * |prio_list.next|<->|pl|<->|pl|<--------------->|pl|<-|
38 : * |10 | |10| |21| |21| |21| |40| (prio)
39 : * | | | | | | | | | | | |
40 : * | | | | | | | | | | | |
41 : * |node_list.next|<->|nl|<->|nl|<->|nl|<->|nl|<->|nl|<-|
42 : * |node_list.prev|<------------------------------------|
43 : *
44 : * The nodes on the prio_list list are sorted by priority to simplify
45 : * the insertion of new nodes. There are no nodes with duplicate
46 : * priorites on the list.
47 : *
48 : * The nodes on the node_list is ordered by priority and can contain
49 : * entries which have the same priority. Those entries are ordered
50 : * FIFO
51 : *
52 : * Addition means: look for the prio_list node in the prio_list
53 : * for the priority of the node and insert it before the node_list
54 : * entry of the next prio_list node. If it is the first node of
55 : * that priority, add it to the prio_list in the right position and
56 : * insert it into the serialized node_list list
57 : *
58 : * Removal means remove it from the node_list and remove it from
59 : * the prio_list if the node_list list_head is non empty. In case
60 : * of removal from the prio_list it must be checked whether other
61 : * entries of the same priority are on the list or not. If there
62 : * is another entry of the same priority then this entry has to
63 : * replace the removed entry on the prio_list. If the entry which
64 : * is removed is the only entry of this priority then a simple
65 : * remove from both list is sufficient.
66 : *
67 : * INT_MIN is the highest priority, 0 is the medium highest, INT_MAX
68 : * is lowest priority.
69 : *
70 : * No locking is done, up to the caller.
71 : *
72 : */
73 : #ifndef _LINUX_PLIST_H_
74 : #define _LINUX_PLIST_H_
75 :
76 : #include <linux/kernel.h>
77 : #include <linux/list.h>
78 : #include <linux/spinlock_types.h>
79 :
80 : struct plist_head {
81 : struct list_head prio_list;
82 : struct list_head node_list;
83 : #ifdef CONFIG_DEBUG_PI_LIST
84 1 : raw_spinlock_t *rawlock;
85 : spinlock_t *spinlock;
86 : #endif
87 : };
88 :
89 : struct plist_node {
90 : int prio;
91 : struct plist_head plist;
92 : };
93 :
94 : #ifdef CONFIG_DEBUG_PI_LIST
95 : # define PLIST_HEAD_LOCK_INIT(_lock) .spinlock = _lock
96 : # define PLIST_HEAD_LOCK_INIT_RAW(_lock) .rawlock = _lock
97 : #else
98 : # define PLIST_HEAD_LOCK_INIT(_lock)
99 : # define PLIST_HEAD_LOCK_INIT_RAW(_lock)
100 : #endif
101 :
102 : #define _PLIST_HEAD_INIT(head) \
103 : .prio_list = LIST_HEAD_INIT((head).prio_list), \
104 : .node_list = LIST_HEAD_INIT((head).node_list)
105 :
106 : /**
107 : * PLIST_HEAD_INIT - static struct plist_head initializer
108 : * @head: struct plist_head variable name
109 : * @_lock: lock to initialize for this list
110 : */
111 : #define PLIST_HEAD_INIT(head, _lock) \
112 : { \
113 : _PLIST_HEAD_INIT(head), \
114 : PLIST_HEAD_LOCK_INIT(&(_lock)) \
115 : }
116 :
117 : /**
118 : * PLIST_HEAD_INIT_RAW - static struct plist_head initializer
119 : * @head: struct plist_head variable name
120 : * @_lock: lock to initialize for this list
121 : */
122 : #define PLIST_HEAD_INIT_RAW(head, _lock) \
123 : { \
124 : _PLIST_HEAD_INIT(head), \
125 : PLIST_HEAD_LOCK_INIT_RAW(&(_lock)) \
126 : }
127 :
128 : /**
129 : * PLIST_NODE_INIT - static struct plist_node initializer
130 : * @node: struct plist_node variable name
131 : * @__prio: initial node priority
132 : */
133 : #define PLIST_NODE_INIT(node, __prio) \
134 : { \
135 : .prio = (__prio), \
136 : .plist = { _PLIST_HEAD_INIT((node).plist) }, \
137 : }
138 :
139 : /**
140 : * plist_head_init - dynamic struct plist_head initializer
141 : * @head: &struct plist_head pointer
142 : * @lock: spinlock protecting the list (debugging)
143 : */
144 : static inline void
145 : plist_head_init(struct plist_head *head, spinlock_t *lock)
146 : {
147 : INIT_LIST_HEAD(&head->prio_list);
148 : INIT_LIST_HEAD(&head->node_list);
149 : #ifdef CONFIG_DEBUG_PI_LIST
150 : head->spinlock = lock;
151 : head->rawlock = NULL;
152 : #endif
153 : }
154 :
155 : /**
156 : * plist_head_init_raw - dynamic struct plist_head initializer
157 : * @head: &struct plist_head pointer
158 : * @lock: raw_spinlock protecting the list (debugging)
159 : */
160 : static inline void
161 : plist_head_init_raw(struct plist_head *head, raw_spinlock_t *lock)
162 : {
163 : INIT_LIST_HEAD(&head->prio_list);
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 : */
176 : static inline void plist_node_init(struct plist_node *node, int prio)
177 : {
178 : node->prio = prio;
179 : plist_head_init(&node->plist, NULL);
180 : }
181 :
182 : extern void plist_add(struct plist_node *node, struct plist_head *head);
183 : extern void plist_del(struct plist_node *node, struct plist_head *head);
184 :
185 : /**
186 : * plist_for_each - iterate over the plist
187 : * @pos: the type * to use as a loop counter
188 : * @head: the head for your list
189 : */
190 : #define plist_for_each(pos, head) \
191 : list_for_each_entry(pos, &(head)->node_list, plist.node_list)
192 :
193 : /**
194 : * plist_for_each_safe - iterate safely over a plist of given type
195 : * @pos: the type * to use as a loop counter
196 : * @n: another type * to use as temporary storage
197 : * @head: the head for your list
198 : *
199 : * Iterate over a plist of given type, safe against removal of list entry.
200 : */
201 : #define plist_for_each_safe(pos, n, head) \
202 : list_for_each_entry_safe(pos, n, &(head)->node_list, plist.node_list)
203 :
204 : /**
205 : * plist_for_each_entry - iterate over list of given type
206 : * @pos: the type * to use as a loop counter
207 : * @head: the head for your list
208 : * @mem: the name of the list_struct within the struct
209 : */
210 : #define plist_for_each_entry(pos, head, mem) \
211 : list_for_each_entry(pos, &(head)->node_list, mem.plist.node_list)
212 :
213 : /**
214 : * plist_for_each_entry_safe - iterate safely over list of given type
215 : * @pos: the type * to use as a loop counter
216 : * @n: another type * to use as temporary storage
217 : * @head: the head for your list
218 : * @m: the name of the list_struct within the struct
219 : *
220 : * Iterate over list of given type, safe against removal of list entry.
221 : */
222 : #define plist_for_each_entry_safe(pos, n, head, m) \
223 : list_for_each_entry_safe(pos, n, &(head)->node_list, m.plist.node_list)
224 :
225 : /**
226 : * plist_head_empty - return !0 if a plist_head is empty
227 : * @head: &struct plist_head pointer
228 : */
229 : static inline int plist_head_empty(const struct plist_head *head)
230 : {
231 : return list_empty(&head->node_list);
232 : }
233 :
234 : /**
235 : * plist_node_empty - return !0 if plist_node is not on a list
236 : * @node: &struct plist_node pointer
237 : */
238 : static inline int plist_node_empty(const struct plist_node *node)
239 : {
240 : return plist_head_empty(&node->plist);
241 : }
242 :
243 : /* All functions below assume the plist_head is not empty. */
244 :
245 : /**
246 : * plist_first_entry - get the struct for the first entry
247 : * @head: the &struct plist_head pointer
248 : * @type: the type of the struct this is embedded in
249 : * @member: the name of the list_struct within the struct
250 : */
251 : #ifdef CONFIG_DEBUG_PI_LIST
252 : # define plist_first_entry(head, type, member) \
253 : ({ \
254 : WARN_ON(plist_head_empty(head)); \
255 : container_of(plist_first(head), type, member); \
256 : })
257 : #else
258 : # define plist_first_entry(head, type, member) \
259 : container_of(plist_first(head), type, member)
260 : #endif
261 :
262 : /**
263 : * plist_first - return the first node (and thus, highest priority)
264 : * @head: the &struct plist_head pointer
265 : *
266 : * Assumes the plist is _not_ empty.
267 : */
268 : static inline struct plist_node* plist_first(const struct plist_head *head)
269 : {
270 : return list_entry(head->node_list.next,
271 : struct plist_node, plist.node_list);
272 : }
273 :
274 : #endif
|