diff options
| author | Lai Jiangshan <laijs@cn.fujitsu.com> | 2010-12-21 17:55:14 +0800 | 
|---|---|---|
| committer | Steven Rostedt <rostedt@goodmis.org> | 2011-03-11 15:13:26 -0500 | 
| commit | bf6a9b8336ba12672755c2ae898b0abe42c7a5ac (patch) | |
| tree | c85f2b2acac9bf9b88e0c19d90d252b1780e0d35 /lib | |
| parent | 017f2b239dabb2740b91df162e004371b861f371 (diff) | |
plist: Shrink struct plist_head
struct plist_head is used in struct task_struct as well as struct
rtmutex. If we can make it smaller, it will also make these structures
smaller as well.
The field prio_list in struct plist_head is seldom used and we can get
its information from the plist_nodes. Removing this field will decrease
the size of plist_head by half.
Signed-off-by:  Lai Jiangshan <laijs@cn.fujitsu.com>
LKML-Reference: <4D107982.9090700@cn.fujitsu.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/plist.c | 54 | 
1 files changed, 35 insertions, 19 deletions
| diff --git a/lib/plist.c b/lib/plist.c index 1471988d9190..8c614d0e6c35 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -59,7 +59,8 @@ static void plist_check_head(struct plist_head *head)  		WARN_ON_SMP(!raw_spin_is_locked(head->rawlock));  	if (head->spinlock)  		WARN_ON_SMP(!spin_is_locked(head->spinlock)); -	plist_check_list(&head->prio_list); +	if (!plist_head_empty(head)) +		plist_check_list(&plist_first(head)->prio_list);  	plist_check_list(&head->node_list);  } @@ -75,25 +76,33 @@ static void plist_check_head(struct plist_head *head)   */  void plist_add(struct plist_node *node, struct plist_head *head)  { -	struct plist_node *iter; +	struct plist_node *first, *iter, *prev = NULL; +	struct list_head *node_next = &head->node_list;  	plist_check_head(head);  	WARN_ON(!plist_node_empty(node)); +	WARN_ON(!list_empty(&node->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 = list_entry(iter->plist.prio_list.next, -					struct plist_node, plist.prio_list); -			goto eq_prio; +	if (plist_head_empty(head)) +		goto ins_node; + +	first = iter = plist_first(head); + +	do { +		if (node->prio < iter->prio) { +			node_next = &iter->node_list; +			break;  		} -	} -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); +		prev = iter; +		iter = list_entry(iter->prio_list.next, +				struct plist_node, prio_list); +	} while (iter != first); + +	if (!prev || prev->prio != node->prio) +		list_add_tail(&node->prio_list, &iter->prio_list); +ins_node: +	list_add_tail(&node->node_list, node_next);  	plist_check_head(head);  } @@ -108,14 +117,21 @@ void plist_del(struct plist_node *node, struct plist_head *head)  {  	plist_check_head(head); -	if (!list_empty(&node->plist.prio_list)) { -		struct plist_node *next = plist_first(&node->plist); +	if (!list_empty(&node->prio_list)) { +		if (node->node_list.next != &head->node_list) { +			struct plist_node *next; + +			next = list_entry(node->node_list.next, +					struct plist_node, node_list); -		list_move_tail(&next->plist.prio_list, &node->plist.prio_list); -		list_del_init(&node->plist.prio_list); +			/* add the next plist_node into prio_list */ +			if (list_empty(&next->prio_list)) +				list_add(&next->prio_list, &node->prio_list); +		} +		list_del_init(&node->prio_list);  	} -	list_del_init(&node->plist.node_list); +	list_del_init(&node->node_list);  	plist_check_head(head);  } | 
