{
/* All blocks remaining in the greylist now are unreachable so free them */
splaytree_destroy(heap->greylist);
+ heap->greylist = NULL;
/* Now iterate over the sub heaps and make sure the full/available lists are correct */
for (unsigned int i = 0; i < NUM_HEAP_STACKS; i++) {
- segment_t* prev = NULL;
- segment_t* curr = heap->heaps[i].full;
+ segment_t* avail = heap->heaps[i].available;
+ segment_t* full = NULL;
+ segment_t* curr = heap->heaps[i].full;
while(curr != NULL) {
- if (segment_empty(curr)) {
- segment_t* deadite = curr;
- if (NULL != prev) {
- prev->next = curr->next;
- curr = curr->next;
- }
- deadite->next = NULL;
- segment_destroy(deadite);
- } else if (!segment_full(curr)) {
- if (NULL != prev) {
- prev->next = curr->next;
- curr = curr->next;
- }
- curr->next = heap->heaps[i].available;
- heap->heaps[i].available = curr;
+ segment_t* seg = curr;
+ curr = curr->next;
+ if (segment_full(seg)) {
+ seg->next = full;
+ full = seg;
+ } else if (segment_empty(seg)) {
+ seg->next = NULL;
+ segment_destroy(seg);
} else {
- prev = curr;
- curr = curr->next;
+ seg->next = avail;
+ avail = seg;
}
}
- segment_destroy(heap->heaps[i].available);
+ heap->heaps[i].available = avail;
+ heap->heaps[i].full = full;
}
}
CHECK(blocks != heap->blocks);
heap_destroy(heap);
}
+
+ TEST(Verify_finish_collection_moves_segments_from_the_full_list_to_the_available_list_when_some_blocks_are_reclaimed) {
+ heap_t* heap = heap_create();
+ segment_t* seg = segment_create(2, NULL);
+ seg->blockmap[0] = 42;
+ splaytree_t* blocks = heap->blocks;
+ heap->heaps[1].full = seg;
+ heap_start_collection(heap);
+ heap_finish_collection(heap);
+ CHECK(blocks != heap->blocks);
+ CHECK(heap->heaps[1].available == seg);
+ CHECK(heap->heaps[1].full == NULL);
+ heap_destroy(heap);
+ }
+
+ TEST(Verify_finish_collection_moves_segments_from_the_full_list_to_the_available_list_when_some_blocks_are_reclaimed) {
+ heap_t* heap = heap_create();
+ segment_t* seg2 = segment_create(2, NULL);
+ segment_t* seg1 = segment_create(2, seg2);
+ seg1->blockmap[0] = 0;
+ seg2->blockmap[0] = 42;
+ splaytree_t* blocks = heap->blocks;
+ heap->heaps[1].full = seg1;
+ heap_start_collection(heap);
+ heap_finish_collection(heap);
+ CHECK(blocks != heap->blocks);
+ CHECK(heap->heaps[1].available == seg2);
+ CHECK(heap->heaps[1].full == seg1);
+ heap_destroy(heap);
+ }
+
+ TEST(Verify_finish_collection_frees_empty_segments_in_the_full_list) {
+ heap_t* heap = heap_create();
+ segment_t* seg = segment_create(2, NULL);
+ splaytree_t* blocks = heap->blocks;
+ heap->heaps[1].full = seg;
+ heap_start_collection(heap);
+ heap_finish_collection(heap);
+ CHECK(blocks != heap->blocks);
+ CHECK(heap->heaps[1].available == NULL);
+ CHECK(heap->heaps[1].full == NULL);
+ heap_destroy(heap);
+ }
+
+ TEST(Verify_finish_collection_frees_empty_segments_in_the_full_list) {
+ heap_t* heap = heap_create();
+ segment_t* seg2 = segment_create(2, NULL);
+ segment_t* seg1 = segment_create(2, seg2);
+ seg1->blockmap[0] = 0;
+ splaytree_t* blocks = heap->blocks;
+ heap->heaps[1].full = seg1;
+ heap_start_collection(heap);
+ heap_finish_collection(heap);
+ CHECK(blocks != heap->blocks);
+ CHECK(heap->heaps[1].available == NULL);
+ CHECK(heap->heaps[1].full == seg1);
+ heap_destroy(heap);
+ }
+
+ TEST(Verify_finish_collection_does_nothing_when_full_list_contains_only_full_segments) {
+ heap_t* heap = heap_create();
+ segment_t* seg = segment_create(2, NULL);
+ seg->blockmap[0] = 0;
+ splaytree_t* blocks = heap->blocks;
+ heap->heaps[1].full = seg;
+ heap_start_collection(heap);
+ heap_finish_collection(heap);
+ CHECK(blocks != heap->blocks);
+ CHECK(heap->heaps[1].available == NULL);
+ CHECK(heap->heaps[1].full == seg);
+ heap_destroy(heap);
+ }
}