/* * Copyright (c) 2004-2010 Alex Pankratov. All rights reserved. * * Hierarchical memory allocator, 1.2.1 * http://swapped.cc/halloc */ /* * The program is distributed under terms of BSD license. * You can obtain the copy of the license by visiting: * * http://www.opensource.org/licenses/bsd-license.php */ #ifndef _LIBP_HLIST_H_ #define _LIBP_HLIST_H_ #include #include "macros.h" /* static_inline */ /* * weak double-linked list w/ tail sentinel */ typedef struct hlist_head hlist_head_t; typedef struct hlist_item hlist_item_t; /* * */ struct hlist_head { hlist_item_t * next; }; struct hlist_item { hlist_item_t * next; hlist_item_t ** prev; }; /* * shared tail sentinel */ struct hlist_item hlist_null; /* * */ #define __hlist_init(h) { &hlist_null } #define __hlist_init_item(i) { &hlist_null, &(i).next } static_inline void hlist_init(hlist_head_t * h); static_inline void hlist_init_item(hlist_item_t * i); /* static_inline void hlist_purge(hlist_head_t * h); */ /* static_inline bool_t hlist_empty(const hlist_head_t * h); */ /* static_inline hlist_item_t * hlist_head(const hlist_head_t * h); */ /* static_inline hlist_item_t * hlist_next(const hlist_item_t * i); */ /* static_inline hlist_item_t * hlist_prev(const hlist_item_t * i, const hlist_head_t * h); */ static_inline void hlist_add(hlist_head_t * h, hlist_item_t * i); /* static_inline void hlist_add_prev(hlist_item_t * l, hlist_item_t * i); */ /* static_inline void hlist_add_next(hlist_item_t * l, hlist_item_t * i); */ static_inline void hlist_del(hlist_item_t * i); static_inline void hlist_relink(hlist_item_t * i); static_inline void hlist_relink_head(hlist_head_t * h); #define hlist_for_each(i, h) \ for (i = (h)->next; i != &hlist_null; i = i->next) #define hlist_for_each_safe(i, tmp, h) \ for (i = (h)->next, tmp = i->next; \ i!= &hlist_null; \ i = tmp, tmp = i->next) /* * static */ static_inline void hlist_init(hlist_head_t * h) { assert(h); h->next = &hlist_null; } static_inline void hlist_init_item(hlist_item_t * i) { assert(i); i->prev = &i->next; i->next = &hlist_null; } static_inline void hlist_add(hlist_head_t * h, hlist_item_t * i) { hlist_item_t * next; assert(h && i); next = i->next = h->next; next->prev = &i->next; h->next = i; i->prev = &h->next; } static_inline void hlist_del(hlist_item_t * i) { hlist_item_t * next; assert(i); next = i->next; next->prev = i->prev; *i->prev = next; hlist_init_item(i); } static_inline void hlist_relink(hlist_item_t * i) { assert(i); *i->prev = i; i->next->prev = &i->next; } static_inline void hlist_relink_head(hlist_head_t * h) { assert(h); h->next->prev = &h->next; } #endif