00001 #ifndef __LIB_KERNEL_LIST_H 00002 #define __LIB_KERNEL_LIST_H 00003 00004 /* Doubly linked list. 00005 00006 This implementation of a doubly linked list does not require 00007 use of dynamically allocated memory. Instead, each structure 00008 that is a potential list element must embed a struct list_elem 00009 member. All of the list functions operate on these `struct 00010 list_elem's. The list_entry macro allows conversion from a 00011 struct list_elem back to a structure object that contains it. 00012 00013 For example, suppose there is a needed for a list of `struct 00014 foo'. `struct foo' should contain a `struct list_elem' 00015 member, like so: 00016 00017 struct foo 00018 { 00019 struct list_elem elem; 00020 int bar; 00021 ...other members... 00022 }; 00023 00024 Then a list of `struct foo' can be be declared and initialized 00025 like so: 00026 00027 struct list foo_list; 00028 00029 list_init (&foo_list); 00030 00031 Iteration is a typical situation where it is necessary to 00032 convert from a struct list_elem back to its enclosing 00033 structure. Here's an example using foo_list: 00034 00035 struct list_elem *e; 00036 00037 for (e = list_begin (&foo_list); e != list_end (&foo_list); 00038 e = list_next (e)) 00039 { 00040 struct foo *f = list_entry (e, struct foo, elem); 00041 ...do something with f... 00042 } 00043 00044 You can find real examples of list usage throughout the 00045 source; for example, malloc.c, palloc.c, and thread.c in the 00046 threads directory all use lists. 00047 00048 The interface for this list is inspired by the list<> template 00049 in the C++ STL. If you're familiar with list<>, you should 00050 find this easy to use. However, it should be emphasized that 00051 these lists do *no* type checking and can't do much other 00052 correctness checking. If you screw up, it will bite you. 00053 00054 Glossary of list terms: 00055 00056 - "front": The first element in a list. Undefined in an 00057 empty list. Returned by list_front(). 00058 00059 - "back": The last element in a list. Undefined in an empty 00060 list. Returned by list_back(). 00061 00062 - "tail": The element figuratively just after the last 00063 element of a list. Well defined even in an empty list. 00064 Returned by list_end(). Used as the end sentinel for an 00065 iteration from front to back. 00066 00067 - "beginning": In a non-empty list, the front. In an empty 00068 list, the tail. Returned by list_begin(). Used as the 00069 starting point for an iteration from front to back. 00070 00071 - "head": The element figuratively just before the first 00072 element of a list. Well defined even in an empty list. 00073 Returned by list_rend(). Used as the end sentinel for an 00074 iteration from back to front. 00075 00076 - "reverse beginning": In a non-empty list, the back. In an 00077 empty list, the head. Returned by list_rbegin(). Used as 00078 the starting point for an iteration from back to front. 00079 00080 - "interior element": An element that is not the head or 00081 tail, that is, a real list element. An empty list does 00082 not have any interior elements. 00083 */ 00084 00085 #include <stdbool.h> 00086 #include <stddef.h> 00087 #include <stdint.h> 00088 00089 /* List element. */ 00090 struct list_elem 00091 { 00092 struct list_elem *prev; /* Previous list element. */ 00093 struct list_elem *next; /* Next list element. */ 00094 }; 00095 00096 /* List. */ 00097 struct list 00098 { 00099 struct list_elem head; /* List head. */ 00100 struct list_elem tail; /* List tail. */ 00101 }; 00102 00103 /* Converts pointer to list element LIST_ELEM into a pointer to 00104 the structure that LIST_ELEM is embedded inside. Supply the 00105 name of the outer structure STRUCT and the member name MEMBER 00106 of the list element. See the big comment at the top of the 00107 file for an example. */ 00108 #define list_entry(LIST_ELEM, STRUCT, MEMBER) \ 00109 ((STRUCT *) ((uint8_t *) &(LIST_ELEM)->next \ 00110 - offsetof (STRUCT, MEMBER.next))) 00111 00112 /* List initialization. 00113 00114 A list may be initialized by calling list_init(): 00115 00116 struct list my_list; 00117 list_init (&my_list); 00118 00119 or with an initializer using LIST_INITIALIZER: 00120 00121 struct list my_list = LIST_INITIALIZER (my_list); */ 00122 #define LIST_INITIALIZER(NAME) { { NULL, &(NAME).tail }, \ 00123 { &(NAME).head, NULL } } 00124 00125 void list_init (struct list *); 00126 00127 /* List traversal. */ 00128 struct list_elem *list_begin (struct list *); 00129 struct list_elem *list_next (struct list_elem *); 00130 struct list_elem *list_end (struct list *); 00131 00132 struct list_elem *list_rbegin (struct list *); 00133 struct list_elem *list_prev (struct list_elem *); 00134 struct list_elem *list_rend (struct list *); 00135 00136 struct list_elem *list_head (struct list *); 00137 struct list_elem *list_tail (struct list *); 00138 00139 /* List insertion. */ 00140 void list_insert (struct list_elem *, struct list_elem *); 00141 void list_splice (struct list_elem *before, 00142 struct list_elem *first, struct list_elem *last); 00143 void list_push_front (struct list *, struct list_elem *); 00144 void list_push_back (struct list *, struct list_elem *); 00145 00146 /* List removal. */ 00147 struct list_elem *list_remove (struct list_elem *); 00148 struct list_elem *list_pop_front (struct list *); 00149 struct list_elem *list_pop_back (struct list *); 00150 00151 /* List elements. */ 00152 struct list_elem *list_front (struct list *); 00153 struct list_elem *list_back (struct list *); 00154 00155 /* List properties. */ 00156 size_t list_size (struct list *); 00157 bool list_empty (struct list *); 00158 00159 /* Miscellaneous. */ 00160 void list_reverse (struct list *); 00161 00162 /* Compares the value of two list elements A and B, given 00163 auxiliary data AUX. Returns true if A is less than B, or 00164 false if A is greater than or equal to B. */ 00165 typedef bool list_less_func (const struct list_elem *a, 00166 const struct list_elem *b, 00167 void *aux); 00168 00169 /* Operations on lists with ordered elements. */ 00170 void list_sort (struct list *, 00171 list_less_func *, void *aux); 00172 void list_insert_ordered (struct list *, struct list_elem *, 00173 list_less_func *, void *aux); 00174 void list_unique (struct list *, struct list *duplicates, 00175 list_less_func *, void *aux); 00176 00177 /* Max and min. */ 00178 struct list_elem *list_max (struct list *, list_less_func *, void *aux); 00179 struct list_elem *list_min (struct list *, list_less_func *, void *aux); 00180 00181 #endif /* lib/kernel/list.h */