list.h

Go to the documentation of this file.
00001 #ifndef _GPXE_LIST_H
00002 #define _GPXE_LIST_H
00003 
00004 /** @file
00005  *
00006  * Linked lists
00007  *
00008  * This linked list handling code is based on the Linux kernel's
00009  * list.h.
00010  */
00011 
00012 FILE_LICENCE ( GPL2_ONLY );
00013 
00014 #include <stddef.h>
00015 #include <assert.h>
00016 
00017 /*
00018  * Simple doubly linked list implementation.
00019  *
00020  * Some of the internal functions ("__xxx") are useful when
00021  * manipulating whole lists rather than single entries, as
00022  * sometimes we already know the next/prev entries and we can
00023  * generate better code by using them directly rather than
00024  * using the generic single-entry routines.
00025  */
00026 
00027 struct list_head {
00028         struct list_head *next;
00029         struct list_head *prev;
00030 };
00031 
00032 #define LIST_HEAD_INIT( name ) { &(name), &(name) }
00033 
00034 #define LIST_HEAD( name ) \
00035         struct list_head name = LIST_HEAD_INIT ( name )
00036 
00037 #define INIT_LIST_HEAD( ptr ) do { \
00038         (ptr)->next = (ptr); (ptr)->prev = (ptr); \
00039 } while ( 0 )
00040 
00041 /*
00042  * Insert a new entry between two known consecutive entries.
00043  *
00044  * This is only for internal list manipulation where we know
00045  * the prev/next entries already!
00046  */
00047 static inline void __list_add ( struct list_head *new,
00048                                 struct list_head *prev,
00049                                 struct list_head *next ) {
00050         next->prev = new;
00051         new->next = next;
00052         new->prev = prev;
00053         prev->next = new;
00054 }
00055 
00056 /**
00057  * Add a new entry to the head of a list
00058  *
00059  * @v new       New entry to be added
00060  * @v head      List head to add it after
00061  *
00062  * Insert a new entry after the specified head.  This is good for
00063  * implementing stacks.
00064  */
00065 static inline void list_add ( struct list_head *new, struct list_head *head ) {
00066         __list_add ( new, head, head->next );
00067 }
00068 #define list_add( new, head ) do {                      \
00069         assert ( (head)->next->prev == (head) );        \
00070         assert ( (head)->prev->next == (head) );        \
00071         list_add ( (new), (head) );                     \
00072         } while ( 0 )
00073 
00074 /**
00075  * Add a new entry to the tail of a list
00076  *
00077  * @v new       New entry to be added
00078  * @v head      List head to add it before
00079  *
00080  * Insert a new entry before the specified head.  This is useful for
00081  * implementing queues.
00082  */
00083 static inline void list_add_tail ( struct list_head *new,
00084                                    struct list_head *head ) {
00085         __list_add ( new, head->prev, head );
00086 }
00087 #define list_add_tail( new, head ) do {                 \
00088         assert ( (head)->next->prev == (head) );        \
00089         assert ( (head)->prev->next == (head) );        \
00090         list_add_tail ( (new), (head) );                \
00091         } while ( 0 )
00092 
00093 /*
00094  * Delete a list entry by making the prev/next entries
00095  * point to each other.
00096  *
00097  * This is only for internal list manipulation where we know
00098  * the prev/next entries already!
00099  */
00100 static inline void __list_del ( struct list_head * prev,
00101                                 struct list_head * next ) {
00102         next->prev = prev;
00103         prev->next = next;
00104 }
00105 
00106 /**
00107  * Delete an entry from a list
00108  *
00109  * @v entry     Element to delete from the list
00110  *
00111  * Note that list_empty() on entry does not return true after this;
00112  * the entry is in an undefined state.
00113  */
00114 static inline void list_del ( struct list_head *entry ) {
00115         __list_del ( entry->prev, entry->next );
00116 }
00117 #define list_del( entry ) do {                          \
00118         assert ( (entry)->prev != NULL );               \
00119         assert ( (entry)->next != NULL );               \
00120         assert ( (entry)->next->prev == (entry) );      \
00121         assert ( (entry)->prev->next == (entry) );      \
00122         list_del ( (entry) );                           \
00123         } while ( 0 )
00124 
00125 /**
00126  * Test whether a list is empty
00127  *
00128  * @v head      List to test.
00129  */
00130 static inline int list_empty ( const struct list_head *head ) {
00131         return head->next == head;
00132 }
00133 
00134 /**
00135  * Get the containing struct for this entry
00136  *
00137  * @v ptr       The struct list_head pointer
00138  * @v type      The type of the struct this is embedded in
00139  * @v member    The name of the list_struct within the struct
00140  */
00141 #define list_entry( ptr, type, member ) \
00142         container_of ( ptr, type, member )
00143 
00144 /**
00145  * Iterate over a list
00146  *
00147  * @v pos       The &struct list_head to use as a loop counter
00148  * @v head      The head for your list
00149  */
00150 #define list_for_each( pos, head ) \
00151         for ( pos = (head)->next; pos != (head); pos = pos->next )
00152 
00153 /**
00154  * Iterate over entries in a list
00155  *
00156  * @v pos       The type * to use as a loop counter
00157  * @v head      The head for your list
00158  * @v member    The name of the list_struct within the struct
00159  */
00160 #define list_for_each_entry( pos, head, member )                              \
00161         for ( pos = list_entry ( (head)->next, typeof ( *pos ), member );     \
00162               &pos->member != (head);                                         \
00163               pos = list_entry ( pos->member.next, typeof ( *pos ), member ) )
00164 
00165 /**
00166  * Iterate over entries in a list, safe against deletion of entries
00167  *
00168  * @v pos       The type * to use as a loop counter
00169  * @v tmp       Another type * to use for temporary storage
00170  * @v head      The head for your list
00171  * @v member    The name of the list_struct within the struct
00172  */
00173 #define list_for_each_entry_safe( pos, tmp, head, member )                    \
00174         for ( pos = list_entry ( (head)->next, typeof ( *pos ), member ),     \
00175               tmp = list_entry ( pos->member.next, typeof ( *tmp ), member ); \
00176               &pos->member != (head);                                         \
00177               pos = tmp,                                                      \
00178               tmp = list_entry ( tmp->member.next, typeof ( *tmp ), member ) )
00179 
00180 #endif /* _GPXE_LIST_H */

Generated on Tue Apr 6 20:01:08 2010 for gPXE by  doxygen 1.5.7.1