summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2015-09-11 10:42:06 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2015-09-11 11:28:13 +0200
commit10c4636947f13f89dcabfb0c7f0f4f4966d7c7fb (patch)
treebcd25d160904e76757209b0f2b84025f34b202a3
parentlibtests/rbheap01: Simplify (diff)
downloadrtems-10c4636947f13f89dcabfb0c7f0f4f4966d7c7fb.tar.bz2
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.
-rw-r--r--cpukit/sapi/src/rbheap.c37
-rw-r--r--testsuites/libtests/rbheap01/init.c5
2 files changed, 21 insertions, 21 deletions
diff --git a/cpukit/sapi/src/rbheap.c b/cpukit/sapi/src/rbheap.c
index 6ad451c23c..6fc2aef218 100644
--- a/cpukit/sapi/src/rbheap.c
+++ b/cpukit/sapi/src/rbheap.c
@@ -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
- * Obere Lagerstr. 30
+ * Dornierstr. 4
* 82178 Puchheim
* Germany
* <rtems@embedded-brains.de>
@@ -225,24 +225,17 @@ static rtems_rbheap_chunk *succ(const rtems_rbheap_chunk *chunk)
}
static void check_and_merge(
- rtems_chain_control *free_chain,
- rtems_rbtree_control *chunk_tree,
+ rtems_rbheap_control *control,
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 (b->begin < a->begin) {
- rtems_rbheap_chunk *t = a;
-
- a = b;
- b = t;
- }
-
+ if (c != NULL_PAGE && rtems_rbheap_is_chunk_free(c)) {
a->size += b->size;
rtems_chain_extract_unprotected(&b->chain_node);
- add_to_chain(free_chain, b);
- rtems_rbtree_extract(chunk_tree, &b->tree_node);
+ rtems_rbheap_add_to_spare_descriptor_chain(control, b);
+ 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;
if (ptr != NULL) {
- rtems_chain_control *free_chain = &control->free_chunk_chain;
- rtems_rbtree_control *chunk_tree = &control->chunk_tree;
- rtems_rbheap_chunk *chunk = find(chunk_tree, (uintptr_t) ptr);
+ rtems_rbheap_chunk *chunk = find(&control->chunk_tree, (uintptr_t) ptr);
if (chunk != NULL_PAGE) {
if (!rtems_rbheap_is_chunk_free(chunk)) {
- check_and_merge(free_chain, chunk_tree, chunk, succ(chunk));
- add_to_chain(free_chain, chunk);
- check_and_merge(free_chain, chunk_tree, chunk, pred(chunk));
+ rtems_rbheap_chunk *other;
+
+ 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 {
sc = RTEMS_INCORRECT_STATE;
}
diff --git a/testsuites/libtests/rbheap01/init.c b/testsuites/libtests/rbheap01/init.c
index 8388e97541..bc16d0ae23 100644
--- a/testsuites/libtests/rbheap01/init.c
+++ b/testsuites/libtests/rbheap01/init.c
@@ -170,6 +170,11 @@ static void test_chunk_tree(
.chunk_end = chunk_begin + chunk_count
};
+ rtems_test_assert(
+ rtems_chain_node_count_unprotected(&control->spare_descriptor_chain)
+ == PAGE_COUNT - chunk_count
+ );
+
_RBTree_Iterate(
&control->chunk_tree,
chunk_visitor,