rt_mutex: add new plist implementation
PATCH 2/4 rt_mutex: add new plist implementation
This patch adds new plist implementation, see
http://marc.theaimsgroup.com/?l=linux-kernel&m=111547290706136
Changes:
added plist_next_entry() helper (was plist_entry)
added plist_unhashed() helper, see PATCH 4/4
include/linux/plist.h renamed from include/linux/plist.h~1_PLIST +97 -0
@@ -0,0 +1,97 @@ +#ifndef _LINUX_PLIST_H_ +#define _LINUX_PLIST_H_ + +#include <linux/list.h> + +struct pl_head { +struct list_head prio_list; +struct list_head node_list; +}; + +struct pl_node { +int prio; +struct pl_head plist; +}; + +#define PL_HEAD_INIT (head) \ +{ \ + .prio_list = LIST_HEAD_INIT((head).prio_list), \ + .node_list = LIST_HEAD_INIT((head).node_list), \ +} + +#define PL_NODE_INIT (node, __prio) \ +{ \ + .prio = (__prio), \ + .plist = PL_HEAD_INIT((node).plist), \ +} + +static inline void pl_head_init (struct pl_head *head) +{ +INIT_LIST_HEAD (&head->prio_list); +INIT_LIST_HEAD (&head->node_list); +} + +static inline void pl_node_init (struct pl_node *node,int prio) +{ + node->prio = prio; +pl_head_init (&node->plist); +} + +extern void plist_add (struct pl_node *node,struct pl_head *head); +extern void plist_del (struct pl_node *node); + +#define plist_for_each (pos, head) \ + list_for_each_entry(pos, &(head)->node_list, plist.node_list) + +#define plist_for_each_safe (pos, n, head) \ + list_for_each_entry_safe(pos, n, &(head)->node_list, plist.node_list) + +#define plist_for_each_entry (pos, head, mem) \ + list_for_each_entry(pos, &(head)->node_list, mem.plist.node_list) + +#define plist_for_each_entry_safe (pos, n, head, mem) \ + list_for_each_entry_safe(pos, n, &(head)->node_list, mem.plist.node_list) + +static inline int plist_empty (const struct pl_head *head) +{ +return list_empty (&head->node_list); +} + +static inline int plist_unhashed (const struct pl_node *node) +{ +return list_empty (&node->plist.node_list); +} + +/* All functions below assume the pl_head is not empty. */ + +#define plist_next_entry (head, type, member) \ + container_of(plist_next(head), type, member) + +#define plist_prev_entry (head, type, member) \ + container_of(plist_prev(head), type, member) + +#define __pl_head_node (head, list, dir) \ + list_entry((head)->list.dir, struct pl_node, plist.list) + +static inline struct pl_node *plist_next (const struct pl_head *head) +{ +return __pl_head_node (head, node_list, next); +} + +static inline struct pl_node *plist_prev (const struct pl_head *head) +{ +return __pl_head_node (head, node_list, prev); +} + +static inline struct pl_node *plist_prio_next (const struct pl_head *head) +{ +return __pl_head_node (head, prio_list, next); +} + +static inline struct pl_node *plist_prio_prev (const struct pl_head *head) +{ +return __pl_head_node (head, prio_list, prev); +} + +#undef __pl_head_node +#endif
lib/plist.c renamed from lib/plist.c~1_PLIST +36 -0
@@ -0,0 +1,36 @@ +/* +* lib/plist.c - Priority List implementation. +*/ + +#include <linux/plist.h> + +void plist_add (struct pl_node *node,struct pl_head *head) +{ +struct pl_node *iter; + +INIT_LIST_HEAD (&node->plist.prio_list); + +list_for_each_entry (iter, &head->prio_list, plist.prio_list) +if (node->prio < iter->prio) + goto lt_prio; +else if (node->prio == iter->prio) { + iter =plist_prio_next (&iter->plist); + goto eq_prio; + } + +lt_prio: +list_add_tail (&node->plist.prio_list, &iter->plist.prio_list); +eq_prio: +list_add_tail (&node->plist.node_list, &iter->plist.node_list); +} + +void plist_del (struct pl_node *node) +{ +if (!list_empty (&node->plist.prio_list)) { +struct pl_node *next =plist_next (&node->plist); +list_move_tail (&next->plist.prio_list, &node->plist.prio_list); +list_del_init (&node->plist.prio_list); + } + +list_del_init (&node->plist.node_list); +}
lib/Makefile renamed from lib/Makefile~1_PLIST +2 -0
@@ -15,6 +15,8 @@ CFLAGS_kobject.o += -DDEBUG CFLAGS_kobject_uevent.o += -DDEBUG endif +obj-$(CONFIG_PREEMPT_RT) += plist.o + obj-$(CONFIG_RWSEM_GENERIC_SPINLOCK) += rwsem-spinlock.o lib-$(CONFIG_RWSEM_XCHGADD_ALGORITHM) += rwsem.o lib-$(CONFIG_GENERIC_FIND_NEXT_BIT) += find_next_bit.o
Quoted 9 lines · Oleg Nesterov
This patch adds new plist implementation, see
http://marc.theaimsgroup.com/?l=linux-kernel&m=111547290706136Changes:
added
plist_next_entry()helper (wasplist_entry)added
plist_unhashed()helper, see PATCH 4/4
Naw , stick with Inaky's API .. Your stuff looks nothing likelist.h ..
Daniel
Quoted 6 lines · Daniel Walker
Quoted 3 lines · Oleg Nesterov
This patch adds new plist implementation, see
http://marc.theaimsgroup.com/?l=linux-kernel&m=111547290706136
Quoted 8 lines
Quoted 6 lines
Changes:
added
plist_next_entry()helper (wasplist_entry)added
plist_unhashed()helper, see PATCH 4/4Naw , stick with Inaky's API ..
This patch breaks Inaky's API anyway, plist_del() now has only one argument, and I think this is good.
I don't mind doing s/plist_next_entry/plist_entry/ if you wish, but I think this is consistent with plist_next/plist_prev helpers.
And original plist_empty() is confusing. When used on plist's head it is ok, but it is wrong to use plist_empty(&plist_node).
Quoted 1 line
Your stuff looks nothing like
list.h..
Is it bad?
Yes, plist_empty/plist_unhashed mimics hlist_empty/hlist_unhashed.
Oleg.