RT: add back plist docs
PATCH 1/2 RT: add back plist docs
Add back copyrights, documentation, and function descriptions.
include/linux/plist.h +152 -0
@@ -1,3 +1,79 @@ +/* +* Descending-priority-sorted double-linked list +* +* (C) 2002-2003 Intel Corp +* Inaky Perez-Gonzalez <[email protected]>. +* +* 2001-2005 (c) MontaVista Software, Inc. +* Daniel Walker <[email protected]> +* +* (C) 2005 Thomas Gleixner <[email protected]> +* Tested and made it functional. +* +* Licensed under the FSF's GNU Public License v2 or later. +* +* Based on simple lists (include/linux/list.h). +* +* +* This is a priority-sorted list of nodes; each node has a >= 0 +* priority from 0 (highest) to INT_MAX (lowest). The list itself has +* a priority too (the highest of all the nodes), stored in the head +* of the list (that is a node itself). +* +* Addition is O(K), removal is O(1), change of priority of a node is +* O(K) and K is the number of RT priority levels used in the system. +* (1 <= K <= 99) +* +* This list is really a list of lists: +* +* - The tier 1 list is the prio_list, different priority nodes. +* +* - The tier 2 list is the node_list, serialized nodes. +* +* Simple ASCII art explanation: +* +* |HEAD | +* | | +* |prio_list.prev|<------------------------------------| +* |prio_list.next|<->|pl|<->|pl|<--------------->|pl|<-| +* |10 | |10| |21| |21| |21| |40| (prio) +* | | | | | | | | | | | | +* | | | | | | | | | | | | +* |node_list.next|<->|nl|<->|nl|<->|nl|<->|nl|<->|nl|<-| +* |node_list.prev|<------------------------------------| +* +* The nodes on the prio_list list are sorted by priority to simplify +* the insertion of new nodes. There are no nodes with duplicate +* priorites on the list. +* +* The nodes on the node_list is ordered by priority and can contain +* entries which have the same priority. Those entries are ordered +* FIFO +* +* Addition means: look for the prio_list node in the prio_list +* for the priority of the node and insert it before the node_list +* entry of the next prio_list node. If it is the first node of +* that priority, add it to the prio_list in the right position and +* insert it into the serialized node_list list +* +* Removal means remove it from the node_list and remove it from +* the prio_list if the node_list list_head is non empty. In case +* of removal from the prio_list it must be checked whether other +* entries of the same priority are on the list or not. If there +* is another entry of the same priority then this entry has to +* replace the removed entry on the prio_list. If the entry which +* is removed is the only entry of this priority then a simple +* remove from both list is sufficient. +* +* INT_MIN is the highest priority, 0 is the medium highest, INT_MAX +* is lowest priority. +* +* No locking is done, up to the caller. +* +* NOTE: This implementation does not offer as many interfaces as +* linux/list.h does -- it is lazily minimal. You are welcome to +* add them. +*/ #ifndef _LINUX_PLIST_H_#define _LINUX_PLIST_H_
@@ -13,24 +89,46 @@ struct pl_node {struct pl_head plist; }; +/** +* #PL_HEAD_INIT - static struct pl_head initializer +* +* @head: struct pl_head variable name +*/ #define PL_HEAD_INIT (head) \ { \ .prio_list = LIST_HEAD_INIT((head).prio_list), \ .node_list = LIST_HEAD_INIT((head).node_list), \ } +/** +* #PL_NODE_INIT - static struct pl_node initializer +* +* @node: struct pl_node variable name +* @__prio: initial node priority +*/ #define PL_NODE_INIT (node, __prio) \ { \ .prio = (__prio), \ .plist = PL_HEAD_INIT((node).plist), \ } +/** +* pl_head_init - dynamic struct pl_head initializer +* +* @head: &struct pl_head pointer +*/ static inline void pl_head_init (struct pl_head *head) {INIT_LIST_HEAD (&head->prio_list);INIT_LIST_HEAD (&head->node_list); } +/** +* pl_node_init - Dynamic struct pl_node initializer +* +* @node: &struct pl_node pointer +* @prio: initial node priority +*/ static inline void pl_node_init (struct pl_node *node,int prio) { node->prio = prio;
@@ -40,23 +138,63 @@ static inline void pl_node_init(struct pextern void plist_add (struct pl_node *node,struct pl_head *head);extern void plist_del (struct pl_node *node); +/** +* plist_for_each - iterate over the plist +* +* @pos1: the type * to use as a loop counter. +* @head: the head for your list. +*/ #define plist_for_each (pos, head) \ list_for_each_entry(pos, &(head)->node_list, plist.node_list) +/** +* plist_for_each_entry_safe - iterate over a plist of given type safe +* against removal of list entry +* +* @pos1: the type * to use as a loop counter. +* @n1: another type * to use as temporary storage +* @head: the head for your list. +*/ #define plist_for_each_safe (pos, n, head) \ list_for_each_entry_safe(pos, n, &(head)->node_list, plist.node_list) +/** +* plist_for_each_entry - iterate over list of given type +* +* @pos: the type * to use as a loop counter. +* @head: the head for your list. +* @member: the name of the list_struct within the struct. +*/ #define plist_for_each_entry (pos, head, mem) \ list_for_each_entry(pos, &(head)->node_list, mem.plist.node_list) +/** +* plist_for_each_entry_safe - iterate over list of given type safe against +* removal of list entry +* +* @pos: the type * to use as a loop counter. +* @n: another type * to use as temporary storage +* @head: the head for your list. +* @member: the name of the list_struct within the struct. +*/ #define plist_for_each_entry_safe (pos, n, head, mem) \ list_for_each_entry_safe(pos, n, &(head)->node_list, mem.plist.node_list) +/** +* plist_empty - return !0 if plist is empty +* +* @head: &struct pl_head pointer +*/ static inline int plist_empty (const struct pl_head *head) {return list_empty (&head->node_list); } +/** +* plist_unhashed - return !0 if plist node is not on a list +* +* @node: &struct pl_node pointer +*/ static inline int plist_unhashed (const struct pl_node *node) {return list_empty (&node->plist.node_list);
@@ -64,9 +202,23 @@ static inline int plist_unhashed(const s/* All functions below assume the pl_head is not empty. */ +/** +* plist_first_entry - get the struct for the first entry +* +* @ptr: the &struct pl_head pointer. +* @type: the type of the struct this is embedded in. +* @member: the name of the list_struct within the struct. +*/ #define plist_first_entry (head, type, member) \ container_of(plist_first(head), type, member) +/** +* plist_first - return the first node (and thus, highest priority) +* +* @head: the &struct pl_head pointer +* +* Assumes the plist is _not_ empty. +*/ static inline struct pl_node *plist_first (const struct pl_head *head) { return list_entry(head->node_list.next, struct pl_node, plist.node_list);
lib/plist.c +30 -1
@@ -1,9 +1,32 @@ +/* -* lib/plist.c - Priority List implementation. +* lib/plist.c +* +* Descending-priority-sorted double-linked list +* +* (C) 2002-2003 Intel Corp +* Inaky Perez-Gonzalez <[email protected]>. +* +* 2001-2005 (c) MontaVista Software, Inc. +* Daniel Walker <[email protected]> +* +* (C) 2005 Thomas Gleixner <[email protected]> +* Tested and made it functional. +* +* Licensed under the FSF's GNU Public License v2 or later. +* +* Based on simple lists (include/linux/list.h). */ #include <linux/plist.h> +/** +* plist_add - add @node to @head returns !0 if the plist prio changed, 0 +* otherwise. XXX: Fix return code. +* +* @node: &struct pl_node pointer +* @head: &struct pl_head pointer +*/ void plist_add (struct pl_node *node,struct pl_head *head) {struct pl_node *iter;
@@ -25,6 +48,12 @@ eq_prio:list_add_tail (&node->plist.node_list, &iter->plist.node_list); } +/** +* plist_del - Remove a @node from plist. returns !0 if the plist prio +* changed, 0 otherwise. XXX: Fix return code. +* +* @node: &struct pl_node pointer +*/ void plist_del (struct pl_node *node) {if (!list_empty (&node->plist.prio_list)) {
Quoted 2 lines · Daniel Walker
Add back copyrights, documentation, and function descriptions.
Thank you for doing that!
Quoted 2 lines
+ * This is a priority-sorted list of nodes; each node has a >= 0
+ * priority from 0 (highest) toINT_MAX(lowest).
Why >= 0 ? ->prio is just integer, it can be < 0.
The list itself has
Quoted 2 lines
+ * a priority too (the highest of all the nodes), stored in the head
+ * of the list (that is a node itself).
No, the head is not a node, and does not have ->prio field. It is easy to get plist's priority:
plist_empty(head) ? INT_MAX // or 0? : plist_last(head)->prio
Quoted 2 lines
+ *
INT_MINis the highest priority, 0 is the medium highest,INT_MAX
+ * is lowest priority.
This is right, but contradicts with 'each node has a >= 0 priority' above.
Actually I don't understand why should we talk about min/max at all. plist is sorted by ->prio which is integer. That's all.
Quoted 12 lines
+ *
plist_add- add @node to @head returns !0 if the plist prio changed, 0
+ * otherwise. XXX: Fix return code.
+ *
+ * @node: &structpl_nodepointer
+ * @head: &structpl_headpointer
+ */
voidplist_add(struct pl_node *node, struct pl_head *head)
{lib/plist.c +0
-0struct pl_node *iter;@@ -25,6 +48,12 @@ eq_prio:list_add_tail (&node->plist.node_list, &iter->plist.node_list); }
lib/plist.c eq_prio: · line 59
Quoted 10 lines
lib/plist.c +6
-0+/** +* plist_del - Remove a @node from plist. returns !0 if the plist prio +* changed, 0 otherwise. XXX: Fix return code. +* +* @node: &struct pl_node pointer +*/ void plist_del (struct pl_node *node) {if (!list_empty (&node->plist.prio_list)) {
Both of them have 'void' return type.
Oleg.