aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/chheap.c30
-rw-r--r--src/include/heap.h2
-rw-r--r--test/testheap.c19
3 files changed, 39 insertions, 12 deletions
diff --git a/src/chheap.c b/src/chheap.c
index faa3cc42f..3069d5be6 100644
--- a/src/chheap.c
+++ b/src/chheap.c
@@ -184,20 +184,32 @@ void chHeapFree(void *p) {
}
/**
- * Checks if the heap is non-empty and non-fragmented.
- * @return \p TRUE if the condition is satisfied
+ * Determines the heap status.
+ * @sizep pointer to a variable that will receive the total fragmented free
+ * space
+ * @return the number of fragments in the heap
* @note This function is meant to be used in the test suite, it should not be
* really useful for the application code.
*/
-bool_t chHeapNotFragmented(void) {
- bool_t b;
+size_t chHeapStatus(size_t *sizep) {
+ struct header *qp;
+ size_t n, sz;
H_LOCK();
- b = (heap.free.h_next != NULL) && (heap.free.h_next->h_next == NULL);
+ sz = 0;
+ for (n = 0, qp = &heap.free; qp->h_next; n++, qp = qp->h_next)
+ sz += qp->h_next->h_size;
+ if (sizep)
+ *sizep = sz;
+
+// if ((heap.free.h_next != NULL) && (heap.free.h_next->h_next == NULL))
+// n = heap.free.h_next->h_size;
+// else
+// n = 0;
H_UNLOCK();
- return b;
+ return n;
}
#else /* CH_USE_MALLOC_HEAP */
@@ -245,9 +257,11 @@ void chHeapFree(void *p) {
H_UNLOCK();
}
-bool_t chHeapNotFragmented(void) {
+size_t chHeapStatus(size_t *sizep) {
- return FALSE;
+ if (sizep)
+ *sizep = 0;
+ return 0;
}
#endif /* CH_USE_MALLOC_HEAP */
diff --git a/src/include/heap.h b/src/include/heap.h
index d1aa83903..b303fde1a 100644
--- a/src/include/heap.h
+++ b/src/include/heap.h
@@ -31,7 +31,7 @@ extern "C" {
void chHeapInit(void);
void *chHeapAlloc(size_t size);
void chHeapFree(void *p);
- bool_t chHeapNotFragmented(void);
+ size_t chHeapStatus(size_t *sizep);
#ifdef __cplusplus
}
#endif
diff --git a/test/testheap.c b/test/testheap.c
index c719818f6..775902dd3 100644
--- a/test/testheap.c
+++ b/test/testheap.c
@@ -38,9 +38,15 @@ static void heap1_teardown(void) {
static void heap1_execute(void) {
void *p1, *p2, *p3;
+ size_t n, sz;
/* Test skipped if the heap is already fragmented. */
- if (chHeapNotFragmented()) {
+
+ if ((n = chHeapStatus(&sz)) == 1) {
+ test_print("--- Size : ");
+ test_printn(sz);
+ test_println(" bytes, not fragmented");
+
/* Same order */
p1 = chHeapAlloc(SIZE);
p2 = chHeapAlloc(SIZE);
@@ -48,7 +54,7 @@ static void heap1_execute(void) {
chHeapFree(p1); /* Does not merge */
chHeapFree(p2); /* Merges backward */
chHeapFree(p3); /* Merges both sides */
- test_assert(chHeapNotFragmented(), "heap fragmented #1");
+ test_assert(chHeapStatus(&n) == 1, "heap fragmented #1");
/* Reverse order */
p1 = chHeapAlloc(SIZE);
@@ -57,7 +63,14 @@ static void heap1_execute(void) {
chHeapFree(p3); /* Merges forward */
chHeapFree(p2); /* Merges forward */
chHeapFree(p1); /* Merges forward */
- test_assert(chHeapNotFragmented(), "heap fragmented #2");
+ test_assert(chHeapStatus(&n) == 1, "heap fragmented #2");
+
+ test_assert(n == sz, "heap size changed");
+ }
+ else {
+ test_print("--- Size : ");
+ test_printn(sz);
+ test_println(" bytes, fragmented, test skipped");
}
}