david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[list] Reduce overall code size by externalising many list functions

Typical saving is 10-20 bytes in each file using list functions.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown 2012-11-02 16:12:56 +00:00
parent f68b4069b1
commit 54a861a7bd
2 changed files with 215 additions and 122 deletions

84
src/core/list.c Normal file
View File

@ -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 );
}

View 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) )
/**