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