rbheap: Fix rtems_rbheap_free()

Remove unused descriptor of merged free chunks from the free chain and
add them to the spare descriptors.

Close #2417.
This commit is contained in:
Sebastian Huber
2015-09-11 10:42:06 +02:00
parent 5e4714b032
commit 10c4636947
2 changed files with 21 additions and 21 deletions

View File

@@ -7,10 +7,10 @@
*/ */
/* /*
* Copyright (c) 2012 embedded brains GmbH. All rights reserved. * Copyright (c) 2012-2015 embedded brains GmbH. All rights reserved.
* *
* embedded brains GmbH * embedded brains GmbH
* Obere Lagerstr. 30 * Dornierstr. 4
* 82178 Puchheim * 82178 Puchheim
* Germany * Germany
* <rtems@embedded-brains.de> * <rtems@embedded-brains.de>
@@ -225,24 +225,17 @@ static rtems_rbheap_chunk *succ(const rtems_rbheap_chunk *chunk)
} }
static void check_and_merge( static void check_and_merge(
rtems_chain_control *free_chain, rtems_rbheap_control *control,
rtems_rbtree_control *chunk_tree,
rtems_rbheap_chunk *a, rtems_rbheap_chunk *a,
rtems_rbheap_chunk *b rtems_rbheap_chunk *b,
rtems_rbheap_chunk *c
) )
{ {
if (b != NULL_PAGE && rtems_rbheap_is_chunk_free(b)) { if (c != NULL_PAGE && rtems_rbheap_is_chunk_free(c)) {
if (b->begin < a->begin) {
rtems_rbheap_chunk *t = a;
a = b;
b = t;
}
a->size += b->size; a->size += b->size;
rtems_chain_extract_unprotected(&b->chain_node); rtems_chain_extract_unprotected(&b->chain_node);
add_to_chain(free_chain, b); rtems_rbheap_add_to_spare_descriptor_chain(control, b);
rtems_rbtree_extract(chunk_tree, &b->tree_node); rtems_rbtree_extract(&control->chunk_tree, &b->tree_node);
} }
} }
@@ -251,15 +244,17 @@ rtems_status_code rtems_rbheap_free(rtems_rbheap_control *control, void *ptr)
rtems_status_code sc = RTEMS_SUCCESSFUL; rtems_status_code sc = RTEMS_SUCCESSFUL;
if (ptr != NULL) { if (ptr != NULL) {
rtems_chain_control *free_chain = &control->free_chunk_chain; rtems_rbheap_chunk *chunk = find(&control->chunk_tree, (uintptr_t) ptr);
rtems_rbtree_control *chunk_tree = &control->chunk_tree;
rtems_rbheap_chunk *chunk = find(chunk_tree, (uintptr_t) ptr);
if (chunk != NULL_PAGE) { if (chunk != NULL_PAGE) {
if (!rtems_rbheap_is_chunk_free(chunk)) { if (!rtems_rbheap_is_chunk_free(chunk)) {
check_and_merge(free_chain, chunk_tree, chunk, succ(chunk)); rtems_rbheap_chunk *other;
add_to_chain(free_chain, chunk);
check_and_merge(free_chain, chunk_tree, chunk, pred(chunk)); add_to_chain(&control->free_chunk_chain, chunk);
other = succ(chunk);
check_and_merge(control, chunk, other, other);
other = pred(chunk);
check_and_merge(control, other, chunk, other);
} else { } else {
sc = RTEMS_INCORRECT_STATE; sc = RTEMS_INCORRECT_STATE;
} }

View File

@@ -170,6 +170,11 @@ static void test_chunk_tree(
.chunk_end = chunk_begin + chunk_count .chunk_end = chunk_begin + chunk_count
}; };
rtems_test_assert(
rtems_chain_node_count_unprotected(&control->spare_descriptor_chain)
== PAGE_COUNT - chunk_count
);
_RBTree_Iterate( _RBTree_Iterate(
&control->chunk_tree, &control->chunk_tree,
chunk_visitor, chunk_visitor,