1 /* 2 * Copyright 2003-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved. 3 * Distributed under the terms of the MIT License. 4 */ 5 #ifndef KERNEL_LIST_H 6 #define KERNEL_LIST_H 7 8 9 #include <SupportDefs.h> 10 11 12 /* This header defines a doubly-linked list. It differentiates between a link 13 * and an item. 14 * A link is what is put into and removed from a list, an item is the whole 15 * object that contains the link. The item doesn't have to be begin with a 16 * link; the offset to the link structure is given to init_list_etc(), so that 17 * list_get_next/prev_item() will work correctly. 18 * Note, the offset value is only needed for the *_item() functions. If the 19 * offset is 0, list_link and item are identical - if you use init_list(), 20 * you don't have to care about the difference between a link and an item. 21 */ 22 23 24 // The use of offsetof() on non-PODs is invalid. Since many structs use 25 // templated members (i.e. DoublyLinkedList) which makes them non-PODs we 26 // can't use offsetof() anymore. This macro does the same, but requires an 27 // instance of the object in question. 28 #define offset_of_member(OBJECT, MEMBER) \ 29 ((size_t)((char*)&OBJECT.MEMBER - (char*)&OBJECT)) 30 31 32 typedef struct list_link list_link; 33 34 /* The object that is put into the list must begin with these 35 * fields, but it doesn't have to be this structure. 36 */ 37 38 struct list_link { 39 list_link *next; 40 list_link *prev; 41 }; 42 43 struct list { 44 list_link link; 45 int32 offset; 46 }; 47 48 49 #ifdef __cplusplus 50 extern "C" { 51 #endif 52 53 extern void list_init(struct list *list); 54 extern void list_init_etc(struct list *list, int32 offset); 55 extern void list_add_link_to_head(struct list *list, void *_link); 56 extern void list_add_link_to_tail(struct list *list, void *_link); 57 extern void list_remove_link(void *_link); 58 extern void *list_get_next_item(struct list *list, void *item); 59 extern void *list_get_prev_item(struct list *list, void *item); 60 extern void *list_get_last_item(struct list *list); 61 extern void list_add_item(struct list *list, void *item); 62 extern void list_remove_item(struct list *list, void *item); 63 extern void list_insert_item_before(struct list *list, void *before, void *item); 64 extern void *list_remove_head_item(struct list *list); 65 extern void *list_remove_tail_item(struct list *list); 66 extern void list_move_to_list(struct list *sourceList, struct list *targetList); 67 68 static inline bool 69 list_is_empty(struct list *list) 70 { 71 return list->link.next == (list_link *)list; 72 } 73 74 static inline void * 75 list_get_first_item(struct list *list) 76 { 77 return list_get_next_item(list, NULL); 78 } 79 80 #ifdef __cplusplus 81 } 82 #endif 83 84 #endif /* KERNEL_LIST_H */ 85