kernel-list.h revision 65f0aab98b20b5994a726ab90d355248bcddfffd
1311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#ifndef _LINUX_LIST_H
2311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#define _LINUX_LIST_H
3311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
4311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff/*
5311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * Simple doubly linked list implementation.
6311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff *
7311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * Some of the internal functions ("__xxx") are useful when
8311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * manipulating whole lists rather than single entries, as
9311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * sometimes we already know the next/prev entries and we can
10311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * generate better code by using them directly rather than
11311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * using the generic single-entry routines.
12311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff */
13311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
14311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffstruct list_head {
15311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff	struct list_head *next, *prev;
16311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff};
17311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
18311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#define LIST_HEAD_INIT(name) { &(name), &(name) }
19311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
20311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#define LIST_HEAD(name) \
21311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff	struct list_head name = { &name, &name }
22311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
23311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#define INIT_LIST_HEAD(ptr) do { \
24311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff	(ptr)->next = (ptr); (ptr)->prev = (ptr); \
25311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff} while (0)
26311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
27311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#if (!defined(__GNUC__) && !defined(__WATCOMC__))
28311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#define __inline__
29311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff#endif
30311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
31311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff/*
32311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * Insert a new entry between two known consecutive entries.
33311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff *
34311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * This is only for internal list manipulation where we know
35311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * the prev/next entries already!
36311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff */
37311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffstatic __inline__ void __list_add(struct list_head * new,
38311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff	struct list_head * prev,
39311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff	struct list_head * next)
40311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff{
41311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff	next->prev = new;
42311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff	new->next = next;
43311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff	new->prev = prev;
44311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff	prev->next = new;
45311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff}
46732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com
47311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff/*
48311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * Insert a new entry after the specified head..
49baf44ead8ad43d5c600b7f89420905a7397489fbopenvcdiff */
50baf44ead8ad43d5c600b7f89420905a7397489fbopenvcdiffstatic __inline__ void list_add(struct list_head *new, struct list_head *head)
51baf44ead8ad43d5c600b7f89420905a7397489fbopenvcdiff{
52baf44ead8ad43d5c600b7f89420905a7397489fbopenvcdiff	__list_add(new, head, head->next);
53baf44ead8ad43d5c600b7f89420905a7397489fbopenvcdiff}
54baf44ead8ad43d5c600b7f89420905a7397489fbopenvcdiff
55baf44ead8ad43d5c600b7f89420905a7397489fbopenvcdiff/*
56732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com * Insert a new entry at the tail
57baf44ead8ad43d5c600b7f89420905a7397489fbopenvcdiff */
58baf44ead8ad43d5c600b7f89420905a7397489fbopenvcdiffstatic __inline__ void list_add_tail(struct list_head *new, struct list_head *head)
59311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff{
60311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff	__list_add(new, head->prev, head);
61311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff}
62311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
63311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff/*
64311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * Delete a list entry by making the prev/next entries
65311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * point to each other.
66311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff *
67311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * This is only for internal list manipulation where we know
68311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * the prev/next entries already!
69311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff */
70311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffstatic __inline__ void __list_del(struct list_head * prev,
71311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff				  struct list_head * next)
72311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff{
73311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff	next->prev = prev;
74311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff	prev->next = next;
75311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff}
76311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
77311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffstatic __inline__ void list_del(struct list_head *entry)
78311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff{
79311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff	__list_del(entry->prev, entry->next);
80311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff}
81311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
82311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffstatic __inline__ int list_empty(struct list_head *head)
83311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff{
84311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff	return head->next == head;
85311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff}
86311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
87311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff/*
88311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff * Splice in "list" into "head"
89311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff */
90311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiffstatic __inline__ void list_splice(struct list_head *list, struct list_head *head)
91311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff{
92311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff	struct list_head *first = list->next;
93311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
94311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff	if (first != list) {
95311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff		struct list_head *last = list->prev;
96311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff		struct list_head *at = head->next;
97311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
98311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff		first->prev = head;
99311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff		head->next = first;
100311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff
101311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff		last->next = at;
102311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff		at->prev = last;
103311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff	}
104311c71486f5f6074e5ba62a7f4c5397c8700b868openvcdiff}
10528db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff
10628db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff#define list_entry(ptr, type, member) \
10728db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff	((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
10828db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff
10928db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff#define list_for_each(pos, head) \
11028db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff        for (pos = (head)->next; pos != (head); pos = pos->next)
11128db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff
112732fff248e662ec47aa27c124632f406f27b6c8dopenvcdiff@gmail.com#endif
11328db8079f707ebdf43ce62cdfd96eb39c8f889e0openvcdiff