commit 12a67279a06b4a5b518cda65b99afd22efa915ca
parent fc7d77be4729cd3b48db4e746e82c2dab343d003
Author: vaplv <vaplv@free.fr>
Date: Tue, 11 Oct 2016 11:12:38 +0200
Fix issues in the free-list implementation
Do not clean-up the next generated unique name when "clear" is invoked
onto the free-list; one can still own a free-list identifier with an old
name that must not match the future entries.
Fix the "clean/del" functions. On "clean" invocation, the list was
initialized as if it did not reserved any memory space. This lead to
unnecessary allocation on the next call of the "add" function. In
addition, the entry added just after the free-list clean-up was the last
entry of the free-list container while one can expect that it was the
first one. The same problems occur when the "del" function is invoked on
the first entry of the free-list, that is also its only one entry.
Diffstat:
2 files changed, 29 insertions(+), 7 deletions(-)
diff --git a/src/free_list.h b/src/free_list.h
@@ -182,9 +182,9 @@ FLIST_FUNC__(del)(struct FLIST_TYPE__* list, struct fid id)
}
/* Add the item to the single linked list of free items */
- item->fitem__.id = FID_NULL;
item->fitem__.next = list->head;
list->head = item->fitem__.id.index;
+ item->fitem__.id = FID_NULL;
}
}
@@ -195,14 +195,16 @@ FLIST_FUNC__(clear)(struct FLIST_TYPE__* list)
ASSERT(list);
FOR_EACH(iitem, 0, list->nitems) {
list->items[iitem].fitem__.next = iitem + 1;
- list->items[iitem].fitem__.next = iitem - 1;
+ list->items[iitem].fitem__.prev = iitem - 1;
list->items[iitem].fitem__.id.name = UINT32_MAX;
}
- if(list->nitems)
+ if(!list->nitems) {
+ list->head = UINT32_MAX;
+ } else {
+ list->head = 0;
list->items[list->nitems - 1].fitem__.next = UINT32_MAX;
-
- list->head = list->tail = UINT32_MAX;
- list->name_next = 0;
+ }
+ list->tail = UINT32_MAX;
}
static FINLINE struct fid
@@ -216,7 +218,7 @@ static FINLINE int
FLIST_FUNC__(is_empty)(struct FLIST_TYPE__* list)
{
ASSERT(list);
- return list->head == list->tail;
+ return list->tail == UINT32_MAX;
}
#undef FLIST_TYPE__
diff --git a/src/test_free_list.c b/src/test_free_list.c
@@ -46,8 +46,27 @@ main(int argc, char** argv)
CHECK(flist_object_get(&list, id[0]), NULL);
id[0] = flist_object_add(&list);
+ CHECK(id[0].index, 0);
CHECK(flist_object_is_empty(&list), 0);
flist_object_clear(&list);
+
+ id[0] = flist_object_add(&list);
+ id[1] = flist_object_add(&list);
+ CHECK(id[0].index, 0);
+ CHECK(id[1].index, 1);
+ flist_object_del(&list, id[0]);
+ CHECK(id[1].index, 1);
+ id[0] = flist_object_add(&list);
+ CHECK(id[0].index, 0);
+ CHECK(id[1].index, 1);
+ flist_object_del(&list, id[0]);
+ flist_object_del(&list, id[1]);
+ id[0] = flist_object_add(&list);
+ id[1] = flist_object_add(&list);
+ flist_object_clear(&list);
+ CHECK(id[0].index != id[1].index, 1);
+ CHECK(id[0].index <= 1, 1);
+ CHECK(id[1].index <= 1, 1);
CHECK(flist_object_is_empty(&list), 1);
FOR_EACH(i, 0, NB_OBJ / 2) {
@@ -56,6 +75,7 @@ main(int argc, char** argv)
CHECK(flist_object_hold(&list, id[i]), 1);
obj = flist_object_get(&list, id[i]);
tmp_id = object_id_get(obj);
+ CHECK(id[i].index, (unsigned)i);
CHECK(FID_EQ(tmp_id, id[i]), 1);
NCHECK(obj, NULL);
obj->i = 0xDECAF000 + (unsigned)i;