]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[list] Reduce overall code size by externalising many list functions
authorMichael Brown <mcb30@ipxe.org>
Fri, 2 Nov 2012 16:12:56 +0000 (16:12 +0000)
committerMichael Brown <mcb30@ipxe.org>
Fri, 2 Nov 2012 16:21:06 +0000 (16:21 +0000)
Typical saving is 10-20 bytes in each file using list functions.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/core/list.c [new file with mode: 0644]
src/include/ipxe/list.h

diff --git a/src/core/list.c b/src/core/list.c
new file mode 100644 (file)
index 0000000..77579d6
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301, USA.
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+/** @file
+ *
+ * Linked lists
+ *
+ */
+
+#include <ipxe/list.h>
+
+void extern_list_add ( struct list_head *new, struct list_head *head ) {
+       inline_list_add ( new, head );
+}
+
+void extern_list_add_tail ( struct list_head *new, struct list_head *head ) {
+       inline_list_add_tail ( new, head );
+}
+
+void extern_list_del ( struct list_head *list ) {
+       inline_list_del ( list );
+}
+
+int extern_list_empty ( const struct list_head *list ) {
+       return inline_list_empty ( list );
+}
+
+int extern_list_is_singular ( const struct list_head *list ) {
+       return inline_list_is_singular ( list );
+}
+
+int extern_list_is_last ( const struct list_head *list,
+                         const struct list_head *head ) {
+       return inline_list_is_last ( list, head );
+}
+
+void extern_list_cut_position ( struct list_head *new,
+                               struct list_head *list,
+                               struct list_head *entry ) {
+       inline_list_cut_position ( new, list, entry );
+}
+
+void extern_list_splice ( const struct list_head *list,
+                         struct list_head *entry ) {
+       inline_list_splice ( list, entry );
+}
+
+void extern_list_splice_tail ( const struct list_head *list,
+                              struct list_head *entry ) {
+       inline_list_splice_tail ( list, entry );
+}
+
+void extern_list_splice_init ( struct list_head *list,
+                              struct list_head *entry ) {
+       inline_list_splice_init ( list, entry );
+}
+
+void extern_list_splice_tail_init ( struct list_head *list,
+                                   struct list_head *entry ) {
+       inline_list_splice_tail_init ( list, entry );
+}
+
+int extern_list_contains ( struct list_head *entry,
+                          struct list_head *head ) {
+       return inline_list_contains ( entry, head );
+}
index b14a83d703761c1ca33577705e198ea18e57e136..0d0973077e88efc803f6b40dbe7f160e21172453 100644 (file)
@@ -42,9 +42,9 @@ struct list_head {
  *
  * @v list             List head
  */
-#define INIT_LIST_HEAD( list ) do {                    \
-       (list)->next = (list);                          \
-       (list)->prev = (list);                          \
+#define INIT_LIST_HEAD( list ) do {                            \
+       (list)->next = (list);                                  \
+       (list)->prev = (list);                                  \
        } while ( 0 )
 
 /**
@@ -52,43 +52,35 @@ struct list_head {
  *
  * @v list             List entry or head
  */
-#define list_check( list ) ( {                         \
-       assert ( (list) != NULL );                      \
-       assert ( (list)->prev != NULL );                \
-       assert ( (list)->next != NULL );                \
-       assert ( (list)->next->prev == (list) );        \
-       assert ( (list)->prev->next == (list) );        \
+#define list_check( list ) ( {                                 \
+       assert ( (list) != NULL );                              \
+       assert ( (list)->prev != NULL );                        \
+       assert ( (list)->next != NULL );                        \
+       assert ( (list)->next->prev == (list) );                \
+       assert ( (list)->prev->next == (list) );                \
        } )
 
-/**
- * Insert a list entry between two known consecutive entries
- *
- * @v new              New list entry
- * @v prev             Previous list entry
- * @v next             Next list entry
- */
-static inline void __list_add ( struct list_head *new,
-                               struct list_head *prev,
-                               struct list_head *next ) {
-       next->prev = new;
-       new->next = next;
-       new->prev = prev;
-       prev->next = new;
-}
-
 /**
  * Add a new entry to the head of a list
  *
  * @v new              New entry to be added
  * @v head             List head, or entry after which to add the new entry
  */
-static inline void list_add ( struct list_head *new, struct list_head *head ) {
-       __list_add ( new, head, head->next );
-}
-#define list_add( new, head ) do {                     \
-       list_check ( (head) );                          \
-       list_add ( (new), (head) );                     \
+#define list_add( new, head ) do {                             \
+       list_check ( (head) );                                  \
+       extern_list_add ( (new), (head) );                      \
        } while ( 0 )
+static inline void inline_list_add ( struct list_head *new,
+                                    struct list_head *head ) {
+       struct list_head *prev = head;
+       struct list_head *next = head->next;
+       next->prev = (new);
+       (new)->next = next;
+       (new)->prev = prev;
+       prev->next = (new);
+}
+extern void extern_list_add ( struct list_head *new,
+                             struct list_head *head );
 
 /**
  * Add a new entry to the tail of a list
@@ -96,26 +88,21 @@ static inline void list_add ( struct list_head *new, struct list_head *head ) {
  * @v new              New entry to be added
  * @v head             List head, or entry before which to add the new entry
  */
-static inline void list_add_tail ( struct list_head *new,
-                                  struct list_head *head ) {
-       __list_add ( new, head->prev, head );
-}
-#define list_add_tail( new, head ) do {                        \
-       list_check ( (head) );                          \
-       list_add_tail ( (new), (head) );                \
+#define list_add_tail( new, head ) do {                                \
+       list_check ( (head) );                                  \
+       extern_list_add_tail ( (new), (head) );                 \
        } while ( 0 )
-
-/**
- * Delete a list entry between two known consecutive entries
- *
- * @v prev             Previous list entry
- * @v next             Next list entry
- */
-static inline void __list_del ( struct list_head *prev,
-                               struct list_head *next ) {
-       next->prev = prev;
-       prev->next = next;
+static inline void inline_list_add_tail ( struct list_head *new,
+                                         struct list_head *head ) {
+       struct list_head *prev = head->prev;
+       struct list_head *next = head;
+       next->prev = (new);
+       (new)->next = next;
+       (new)->prev = prev;
+       prev->next = (new);
 }
+extern void extern_list_add_tail ( struct list_head *new,
+                                  struct list_head *head );
 
 /**
  * Delete an entry from a list
@@ -125,37 +112,43 @@ static inline void __list_del ( struct list_head *prev,
  * Note that list_empty() on entry does not return true after this;
  * the entry is in an undefined state.
  */
-static inline void list_del ( struct list_head *list ) {
-       __list_del ( list->prev, list->next );
-}
-#define list_del( list ) do {                          \
-       list_check ( (list) );                          \
-       list_del ( (list) );                            \
+#define list_del( list ) do {                                  \
+       list_check ( (list) );                                  \
+       inline_list_del ( (list) );                             \
        } while ( 0 )
+static inline void inline_list_del ( struct list_head *list ) {
+       struct list_head *next = (list)->next;
+       struct list_head *prev = (list)->prev;
+       next->prev = prev;
+       prev->next = next;
+}
+extern void extern_list_del ( struct list_head *list );
 
 /**
  * Test whether a list is empty
  *
  * @v list             List head
  */
-static inline int list_empty ( const struct list_head *list ) {
+#define list_empty( list ) ( {                                 \
+       list_check ( (list) );                                  \
+       inline_list_empty ( (list) ); } )
+static inline int inline_list_empty ( const struct list_head *list ) {
        return ( list->next == list );
 }
-#define list_empty( list ) ( {                         \
-       list_check ( (list) );                          \
-       list_empty ( (list) ); } )
+extern int extern_list_empty ( const struct list_head *list );
 
 /**
  * Test whether a list has just one entry
  *
  * @v list             List to test
  */
-static inline int list_is_singular ( const struct list_head *list ) {
+#define list_is_singular( list ) ( {                           \
+       list_check ( (list) );                                  \
+       inline_list_is_singular ( (list) ); } )
+static inline int inline_list_is_singular ( const struct list_head *list ) {
        return ( ( ! list_empty ( list ) ) && ( list->next == list->prev ) );
 }
-#define list_is_singular( list ) ( {                   \
-       list_check ( (list) );                          \
-       list_is_singular ( (list) ); } )
+extern int extern_list_is_singular ( const struct list_head *list );
 
 /**
  * Test whether an entry is the last entry in list
@@ -163,14 +156,16 @@ static inline int list_is_singular ( const struct list_head *list ) {
  * @v list             List entry to test
  * @v head             List head
  */
-static inline int list_is_last ( const struct list_head *list,
-                                const struct list_head *head ) {
+#define list_is_last( list, head ) ( {                         \
+       list_check ( (list) );                                  \
+       list_check ( (head) );                                  \
+       inline_list_is_last ( (list), (head) ); } )
+static inline int inline_list_is_last ( const struct list_head *list,
+                                       const struct list_head *head ) {
        return ( list->next == head );
 }
-#define list_is_last( list, head ) ( {                 \
-       list_check ( (list) );                          \
-       list_check ( (head) );                          \
-       list_is_last ( (list), (head) ); } )
+extern int extern_list_is_last ( const struct list_head *list,
+                                const struct list_head *head );
 
 /**
  * Cut a list into two
@@ -183,9 +178,16 @@ static inline int list_is_last ( const struct list_head *list,
  * @c new, which should be an empty list.  @c entry may be equal to @c
  * list, in which case no entries are moved.
  */
-static inline void list_cut_position ( struct list_head *new,
-                                      struct list_head *list,
-                                      struct list_head *entry ) {
+#define list_cut_position( new, list, entry ) do {             \
+       list_check ( (new) );                                   \
+       assert ( list_empty ( (new) ) );                        \
+       list_check ( (list) );                                  \
+       list_check ( (entry) );                                 \
+       extern_list_cut_position ( (new), (list), (entry) );    \
+       } while ( 0 )
+static inline void inline_list_cut_position ( struct list_head *new,
+                                             struct list_head *list,
+                                             struct list_head *entry ) {
        struct list_head *first = entry->next;
 
        if ( list != entry ) {
@@ -197,13 +199,9 @@ static inline void list_cut_position ( struct list_head *new,
                list->next->prev = list;
        }
 }
-#define list_cut_position( new, list, entry ) do {     \
-       list_check ( (new) );                           \
-       assert ( list_empty ( (new) ) );                \
-       list_check ( (list) );                          \
-       list_check ( (entry) );                         \
-       list_cut_position ( (new), (list), (entry) );   \
-       } while ( 0 )
+extern void extern_list_cut_position ( struct list_head *new,
+                                      struct list_head *list,
+                                      struct list_head *entry );
 
 /**
  * Move all entries from one list into another list
@@ -215,8 +213,13 @@ static inline void list_cut_position ( struct list_head *new,
  * list is left in an undefined state; use @c list_splice_init() if
  * you want @c list to become an empty list.
  */
-static inline void list_splice ( const struct list_head *list,
-                                struct list_head *entry ) {
+#define list_splice( list, entry ) do {                                \
+       list_check ( (list) );                                  \
+       list_check ( (entry) );                                 \
+       extern_list_splice ( (list), (entry) );                 \
+       } while ( 0 )
+static inline void inline_list_splice ( const struct list_head *list,
+                                       struct list_head *entry ) {
        struct list_head *first = list->next;
        struct list_head *last = list->prev;
 
@@ -227,11 +230,8 @@ static inline void list_splice ( const struct list_head *list,
                first->prev->next = first;
        }
 }
-#define list_splice( list, entry ) do {                        \
-       list_check ( (list) );                          \
-       list_check ( (entry) );                         \
-       list_splice ( (list), (entry) );                \
-       } while ( 0 )
+extern void extern_list_splice ( const struct list_head *list,
+                                struct list_head *entry );
 
 /**
  * Move all entries from one list into another list
@@ -243,8 +243,13 @@ static inline void list_splice ( const struct list_head *list,
  * list is left in an undefined state; use @c list_splice_tail_init() if
  * you want @c list to become an empty list.
  */
-static inline void list_splice_tail ( const struct list_head *list,
-                                     struct list_head *entry ) {
+#define list_splice_tail( list, entry ) do {                   \
+       list_check ( (list) );                                  \
+       list_check ( (entry) );                                 \
+       extern_list_splice_tail ( (list), (entry) );            \
+       } while ( 0 )
+static inline void inline_list_splice_tail ( const struct list_head *list,
+                                            struct list_head *entry ) {
        struct list_head *first = list->next;
        struct list_head *last = list->prev;
 
@@ -255,11 +260,8 @@ static inline void list_splice_tail ( const struct list_head *list,
                last->next->prev = last;
        }
 }
-#define list_splice_tail( list, entry ) do {           \
-       list_check ( (list) );                          \
-       list_check ( (entry) );                         \
-       list_splice_tail ( (list), (entry) );           \
-       } while ( 0 )
+extern void extern_list_splice_tail ( const struct list_head *list,
+                                     struct list_head *entry );
 
 /**
  * Move all entries from one list into another list and reinitialise empty list
@@ -269,16 +271,18 @@ static inline void list_splice_tail ( const struct list_head *list,
  *
  * All entries from @c list are inserted after @c entry.
  */
-static inline void list_splice_init ( struct list_head *list,
-                                     struct list_head *entry ) {
+#define list_splice_init( list, entry ) do {                   \
+       list_check ( (list) );                                  \
+       list_check ( (entry) );                                 \
+       extern_list_splice_init ( (list), (entry) );            \
+       } while ( 0 )
+static inline void inline_list_splice_init ( struct list_head *list,
+                                            struct list_head *entry ) {
        list_splice ( list, entry );
        INIT_LIST_HEAD ( list );
 }
-#define list_splice_init( list, entry ) do {                   \
-       list_check ( (list) );                          \
-       list_check ( (entry) );                         \
-       list_splice_init ( (list), (entry) );           \
-       } while ( 0 )
+extern void extern_list_splice_init ( struct list_head *list,
+                                     struct list_head *entry );
 
 /**
  * Move all entries from one list into another list and reinitialise empty list
@@ -288,16 +292,19 @@ static inline void list_splice_init ( struct list_head *list,
  *
  * All entries from @c list are inserted before @c entry.
  */
-static inline void list_splice_tail_init ( struct list_head *list,
-                                          struct list_head *entry ) {
+#define list_splice_tail_init( list, entry ) do {              \
+       list_check ( (list) );                                  \
+       list_check ( (entry) );                                 \
+       extern_list_splice_tail_init ( (list), (entry) );       \
+       } while ( 0 )
+
+static inline void inline_list_splice_tail_init ( struct list_head *list,
+                                                 struct list_head *entry ) {
        list_splice_tail ( list, entry );
        INIT_LIST_HEAD ( list );
 }
-#define list_splice_tail_init( list, entry ) do {      \
-       list_check ( (list) );                          \
-       list_check ( (entry) );                         \
-       list_splice_tail_init ( (list), (entry) );      \
-       } while ( 0 )
+extern void extern_list_splice_tail_init ( struct list_head *list,
+                                          struct list_head *entry );
 
 /**
  * Get the container of a list entry
@@ -307,8 +314,8 @@ static inline void list_splice_tail_init ( struct list_head *list,
  * @v member           Name of list field within containing type
  * @ret container      Containing object
  */
-#define list_entry( list, type, member ) ( {           \
-       list_check ( (list) );                          \
+#define list_entry( list, type, member ) ( {                   \
+       list_check ( (list) );                                  \
        container_of ( list, type, member ); } )
 
 /**
@@ -319,9 +326,9 @@ static inline void list_splice_tail_init ( struct list_head *list,
  * @v member           Name of list field within containing type
  * @ret first          First list entry, or NULL
  */
-#define list_first_entry( list, type, member )         \
-       ( list_empty ( (list) ) ?                       \
-         ( type * ) NULL :                             \
+#define list_first_entry( list, type, member )                 \
+       ( list_empty ( (list) ) ?                               \
+         ( type * ) NULL :                                     \
          list_entry ( (list)->next, type, member ) )
 
 /**
@@ -332,9 +339,9 @@ static inline void list_splice_tail_init ( struct list_head *list,
  * @v member           Name of list field within containing type
  * @ret first          First list entry, or NULL
  */
-#define list_last_entry( list, type, member )          \
-       ( list_empty ( (list) ) ?                       \
-         ( type * ) NULL :                             \
+#define list_last_entry( list, type, member )                  \
+       ( list_empty ( (list) ) ?                               \
+         ( type * ) NULL :                                     \
          list_entry ( (list)->prev, type, member ) )
 
 /**
@@ -424,8 +431,12 @@ static inline void list_splice_tail_init ( struct list_head *list,
  * @v head             List head
  * @ret present                List contains specified entry
  */
-static inline int list_contains ( struct list_head *entry,
-                                 struct list_head *head ) {
+#define list_contains( entry, head ) ( {                       \
+       list_check ( (head) );                                  \
+       list_check ( (entry) );                                 \
+       extern_list_contains ( (entry), (head) ); } )
+static inline int inline_list_contains ( struct list_head *entry,
+                                        struct list_head *head ) {
        struct list_head *tmp;
 
        list_for_each ( tmp, head ) {
@@ -434,10 +445,8 @@ static inline int list_contains ( struct list_head *entry,
        }
        return 0;
 }
-#define list_contains( entry, head ) ( {               \
-       list_check ( (head) );                          \
-       list_check ( (entry) );                         \
-       list_contains ( (entry), (head) ); } )
+extern int extern_list_contains ( struct list_head *entry,
+                                 struct list_head *head );
 
 /**
  * Test if list contains a specified entry
@@ -446,7 +455,7 @@ static inline int list_contains ( struct list_head *entry,
  * @v head             List head
  * @ret present                List contains specified entry
  */
-#define list_contains_entry( entry, head, member )     \
+#define list_contains_entry( entry, head, member )             \
        list_contains ( &(entry)->member, (head) )
 
 /**