commit 50ca94e819c603cf483d2af98dd9c5bbb5f3b140
parent c72250ab04b1663d31a285068e12655414bf24fc
Author: vaplv <vaplv@free.fr>
Date: Tue, 26 Nov 2013 17:24:51 +0100
Begin the implementation of a free_list
Diffstat:
| A | src/free_list.h | | | 85 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 85 insertions(+), 0 deletions(-)
diff --git a/src/free_list.h b/src/free_list.h
@@ -0,0 +1,85 @@
+#ifndef FREE_LIST_H
+#define FREE_LIST_H
+
+#ifndef FREE_ITEM_TYPE
+ #error Missing arguments
+#endif
+
+struct free_id {
+ uint32_t index; /* Index into the free list */
+ uint32_t name; /* Unique id that identifies this item */
+};
+
+#define FREE_ITEM \
+ struct { \
+ struct free_id id; \
+ uint32_t next; \
+ } free_item__
+
+struct free_list {
+ uint32_t head;
+ uint32_t name_next;
+ FREE_ITEM_TYPE* items;
+ uint32_t nitems;
+};
+
+static FINLINE void
+free_list_init(struct free_list* list)
+{
+ ASSERT(list);
+ list->head = UINT32_MAX;
+ list->name_next = 0;
+ list->items = NULL;
+ list->nitems = 0;
+}
+
+static FINLINE bool
+free_list_hold(struct free_list* list, struct free_id* id)
+{
+ ASSERT(list && id);
+ return list->items[id->index].free_item__.id.name == id->name;
+}
+
+static FINLINE FREE_ITEM*
+free_list_get(struct free_list* list, struct free_id* id)
+{
+ ASSERT(list && id);
+ if(free_list_hold(list, id)) {
+ return list->mem[id->index];
+ } else {
+ return NULL;
+ }
+}
+
+static FINLINE struct free_id
+free_list_add(struct free_list* list)
+{
+ struct free_id id;
+ ASSERT(list);
+
+ id.name = list.name_next++;
+ if(list.head != UINT32_MAX) {
+ id.index = list.head;
+ list.head = list.items[list.head].free_item__.next;
+ } else {
+ FREE_ITEM item;
+ memset(&item, 0, sizeof(FREE_ITEM));
+ id.index = list->nitems;
+ item.free_item__.id = id;
+ list.items = MEM_REALLOC(list.items, nitems * 2 * sizeof(FREE_ITEM_TYPE));
+ }
+ return id;
+}
+
+static FINLINE void
+free_list_del(struct free_list* list, struct free_id* id)
+{
+ ASSERT(list && id);
+ FREE_ITEM* item = free_list_get(list, id);
+ item->free_item__.id.name = UINT32_MAX;
+ item->free_item__.next = list->head;
+ list->head = item->free_item__.id.index;
+}
+
+#endif /* FREE_LIST_H */
+