Sfoglia il codice sorgente

First version, based on include/linux/list.h, stripped down to just

those functions we are likely to need.

Still need to come up with a way of getting the linker to create
static lists using this linking mechanism.
tags/v0.9.3
Michael Brown 19 anni fa
parent
commit
2558439ce4
1 ha cambiato i file con 155 aggiunte e 0 eliminazioni
  1. 155
    0
      src/include/gpxe/list.h

+ 155
- 0
src/include/gpxe/list.h Vedi File

@@ -0,0 +1,155 @@
1
+#ifndef _LIST_H
2
+#define _LIST_H
3
+
4
+/** @file
5
+ *
6
+ * Linked lists
7
+ *
8
+ * This linked list handling code is based on the Linux kernel's
9
+ * list.h.
10
+ */
11
+
12
+#include <stddef.h>
13
+
14
+/*
15
+ * These are non-NULL pointers that will result in page faults
16
+ * under normal circumstances, used to verify that nobody uses
17
+ * non-initialized list entries.
18
+ */
19
+#define LIST_POISON1 ( ( void * ) 0x00100100 )
20
+#define LIST_POISON2 ( ( void * ) 0x00200200 )
21
+
22
+/*
23
+ * Simple doubly linked list implementation.
24
+ *
25
+ * Some of the internal functions ("__xxx") are useful when
26
+ * manipulating whole lists rather than single entries, as
27
+ * sometimes we already know the next/prev entries and we can
28
+ * generate better code by using them directly rather than
29
+ * using the generic single-entry routines.
30
+ */
31
+
32
+struct list_head {
33
+	struct list_head *next;
34
+	struct list_head *prev;
35
+};
36
+
37
+#define LIST_HEAD_INIT( name ) { &(name), &(name) }
38
+
39
+#define LIST_HEAD( name ) \
40
+	struct list_head name = LIST_HEAD_INIT ( name )
41
+
42
+#define INIT_LIST_HEAD( ptr ) do { \
43
+	(ptr)->next = (ptr); (ptr)->prev = (ptr); \
44
+} while ( 0 )
45
+
46
+/*
47
+ * Insert a new entry between two known consecutive entries.
48
+ *
49
+ * This is only for internal list manipulation where we know
50
+ * the prev/next entries already!
51
+ */
52
+static inline void __list_add ( struct list_head *new,
53
+				struct list_head *prev,
54
+				struct list_head *next ) {
55
+	next->prev = new;
56
+	new->next = next;
57
+	new->prev = prev;
58
+	prev->next = new;
59
+}
60
+
61
+/**
62
+ * Add a new entry to the head of a list
63
+ *
64
+ * @v new	New entry to be added
65
+ * @v head	List head to add it after
66
+ *
67
+ * Insert a new entry after the specified head.  This is good for
68
+ * implementing stacks.
69
+ */
70
+static inline void list_add ( struct list_head *new, struct list_head *head ) {
71
+	__list_add ( new, head, head->next );
72
+}
73
+
74
+/**
75
+ * Add a new entry to the tail of a list
76
+ *
77
+ * @v new	New entry to be added
78
+ * @v head	List head to add it before
79
+ *
80
+ * Insert a new entry before the specified head.  This is useful for
81
+ * implementing queues.
82
+ */
83
+static inline void list_add_tail ( struct list_head *new,
84
+				   struct list_head *head ) {
85
+	__list_add ( new, head->prev, head );
86
+}
87
+
88
+/*
89
+ * Delete a list entry by making the prev/next entries
90
+ * point to each other.
91
+ *
92
+ * This is only for internal list manipulation where we know
93
+ * the prev/next entries already!
94
+ */
95
+static inline void __list_del ( struct list_head * prev,
96
+				struct list_head * next ) {
97
+	next->prev = prev;
98
+	prev->next = next;
99
+}
100
+
101
+/**
102
+ * Delete an entry from a list
103
+ *
104
+ * @v entry	Element to delete from the list
105
+ *
106
+ * Note that list_empty() on entry does not return true after this;
107
+ * the entry is in an undefined state.
108
+ */
109
+static inline void list_del ( struct list_head *entry ) {
110
+	__list_del ( entry->prev, entry->next );
111
+	entry->next = LIST_POISON1;
112
+	entry->prev = LIST_POISON2;
113
+}
114
+
115
+/**
116
+ * Test whether a list is empty
117
+ *
118
+ * @v head	List to test.
119
+ */
120
+static inline int list_empty ( const struct list_head *head ) {
121
+	return head->next == head;
122
+}
123
+
124
+/**
125
+ * Get the containing struct for this entry
126
+ *
127
+ * @v ptr	The struct list_head pointer
128
+ * @v type	The type of the struct this is embedded in
129
+ * @v member	The name of the list_struct within the struct
130
+ */
131
+#define list_entry( ptr, type, member ) \
132
+	container_of ( ptr, type, member )
133
+
134
+/**
135
+ * Iterate over a list
136
+ *
137
+ * @v pos	The &struct list_head to use as a loop counter
138
+ * @v head	The head for your list
139
+ */
140
+#define list_for_each( pos, head ) \
141
+	for ( pos = (head)->next; pos != (head); pos = pos->next )
142
+
143
+/**
144
+ * Iterate over entries in a list
145
+ *
146
+ * @v pos	The type * to use as a loop counter
147
+ * @v head	The head for your list
148
+ * @v member	The name of the list_struct within the struct
149
+ */
150
+#define list_for_each_entry( pos, head, member )			      \
151
+	for ( pos = list_entry ( (head)->next, typeof ( *pos ), member);      \
152
+	      &pos->member != (head);					      \
153
+	      pos = list_entry ( pos->member.next, typeof ( *pos ), member ) )
154
+
155
+#endif /* _LIST_H */

Loading…
Annulla
Salva