diff options
author | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2008-08-28 15:10:54 +0000 |
---|---|---|
committer | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2008-08-28 15:10:54 +0000 |
commit | 7ffd1d5e5b41393b518ad0a3b6e94056d9044e26 (patch) | |
tree | 90e9f89b83930f4c6331443d44d663642c20284d | |
parent | 7768c51b7b1ef0becc4090705a9bd2f14aa28d00 (diff) | |
download | ChibiOS-7ffd1d5e5b41393b518ad0a3b6e94056d9044e26.tar.gz ChibiOS-7ffd1d5e5b41393b518ad0a3b6e94056d9044e26.tar.bz2 ChibiOS-7ffd1d5e5b41393b518ad0a3b6e94056d9044e26.zip |
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@413 35acf78f-673a-0410-8e92-d51de3d6d3f4
-rw-r--r-- | readme.txt | 6 | ||||
-rw-r--r-- | src/chheap.c | 26 | ||||
-rw-r--r-- | src/chinit.c | 6 | ||||
-rw-r--r-- | src/include/heap.h | 1 | ||||
-rw-r--r-- | test/test.c | 4 | ||||
-rw-r--r-- | test/test.mk | 6 | ||||
-rw-r--r-- | test/testheap.c | 71 | ||||
-rw-r--r-- | test/testheap.h | 25 |
8 files changed, 137 insertions, 8 deletions
diff --git a/readme.txt b/readme.txt index 63b18bfc5..8b4c14fad 100644 --- a/readme.txt +++ b/readme.txt @@ -78,13 +78,13 @@ Win32-MinGW - ChibiOS/RT simulator and demo into a WIN32 process, - NEW: Memory Heap Allocator functionality added. The allocator implements a
first-fit strategy but there is an option that allow it to wrap the compiler
provided malloc() that may implement a different strategy. The heap
- allocator is entirely thread-safe and can use both a mutex or a semaphores
- as internal synchronization primitive.
+ allocator is thread-safe and can use both a mutex or a semaphores as
+ internal synchronization primitive.
- NEW: Memory Pools functionality added, this mechanism allows constant-time
allocation/freeing of constant-size objects. It can be used to dynamically
allocate kernel objects like Semaphores, Mutexes, Threads etc fully in real
time, of course it is also possible to manage application-defined objects.
- The pool allocator is entirely thread-safe.
+ The pool allocator is thread-safe.
It is worth remember that the kernel is still entirely static, it does not
use the allocation services internally, it is up to the application code
to use the allocators in order to use dynamic system objects.
diff --git a/src/chheap.c b/src/chheap.c index dbab1dbd5..0cda7f268 100644 --- a/src/chheap.c +++ b/src/chheap.c @@ -49,7 +49,7 @@ static struct { Mutex hmtx;
#elif defined(CH_USE_SEMAPHORES)
#define H_LOCK() chSemWait(&heap.hsem)
-#define H_UNLOCK() chMtxSignal(&heap.hsem)
+#define H_UNLOCK() chSemSignal(&heap.hsem)
Semaphore hsem;
#else
#error "The heap allocator requires mutexes or semaphores to be enabled"
@@ -181,6 +181,23 @@ void chHeapFree(void *p) { }
}
+/**
+ * Checks if the heap is non-empty and non-fragmented.
+ * @return \p TRUE if the condition is satisfied
+ * @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;
+
+ H_LOCK();
+
+ b = (heap.free.h_next != NULL) && (heap.free.h_next->h_next == NULL);
+
+ H_UNLOCK();
+ return b;
+}
+
#else /* CH_USE_MALLOC_HEAP */
#include <stdlib.h>
@@ -191,7 +208,7 @@ void chHeapFree(void *p) { static Mutex hmtx;
#elif defined(CH_USE_SEMAPHORES)
#define H_LOCK() chSemWait(&hsem)
-#define H_UNLOCK() chMtxSignal(&hsem)
+#define H_UNLOCK() chSemSignal(&hsem)
static Semaphore hsem;
#else
#error "The heap allocator requires mutexes or semaphores to be enabled"
@@ -226,6 +243,11 @@ void chHeapFree(void *p) { H_UNLOCK();
}
+bool_t chHeapNotFragmented(void) {
+
+ return FALSE;
+}
+
#endif /* CH_USE_MALLOC_HEAP */
#endif /* CH_USE_HEAP */
diff --git a/src/chinit.c b/src/chinit.c index 243ef2a97..5e6788693 100644 --- a/src/chinit.c +++ b/src/chinit.c @@ -40,6 +40,12 @@ void chSysInit(void) { #ifdef CH_USE_VIRTUAL_TIMERS chVTInit(); #endif +#ifdef CH_USE_HEAP + chHeapInit(); +#endif +#ifdef CH_USE_HEAP + chHeapInit(); +#endif /* * Now this instructions flow becomes the main thread. */ diff --git a/src/include/heap.h b/src/include/heap.h index 9619eba2f..d1aa83903 100644 --- a/src/include/heap.h +++ b/src/include/heap.h @@ -31,6 +31,7 @@ extern "C" { void chHeapInit(void);
void *chHeapAlloc(size_t size);
void chHeapFree(void *p);
+ bool_t chHeapNotFragmented(void);
#ifdef __cplusplus
}
#endif
diff --git a/test/test.c b/test/test.c index 96bd43938..5712f7bb2 100644 --- a/test/test.c +++ b/test/test.c @@ -24,6 +24,7 @@ #include "testsem.h"
#include "testmtx.h"
#include "testmsg.h"
+#include "testheap.h"
#include "testpools.h"
#include "testbmk.h"
@@ -41,6 +42,9 @@ static const struct testcase *tests[] = { &testmtx3,
#endif
&testmsg1,
+#ifdef CH_USE_HEAP
+ &testheap1,
+#endif
#ifdef CH_USE_MEMPOOLS
&testpools1,
#endif
diff --git a/test/test.mk b/test/test.mk index 73e6e1bc0..10b86d4eb 100644 --- a/test/test.mk +++ b/test/test.mk @@ -1,4 +1,4 @@ # List of all the ChibiOS/RT test files.
-TESTSRC = ../../test/test.c ../../test/testrdy.c ../../test/testsem.c \
- ../../test/testmtx.c ../../test/testmsg.c ../../test/testpools.c \
- ../../test/testbmk.c
+TESTSRC = ../../test/test.c ../../test/testrdy.c ../../test/testsem.c \
+ ../../test/testmtx.c ../../test/testmsg.c ../../test/testheap.c \
+ ../../test/testpools.c ../../test/testbmk.c
diff --git a/test/testheap.c b/test/testheap.c new file mode 100644 index 000000000..c719818f6 --- /dev/null +++ b/test/testheap.c @@ -0,0 +1,71 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <ch.h>
+
+#include "test.h"
+
+#ifdef CH_USE_HEAP
+
+#define SIZE 16
+
+static char *heap1_gettest(void) {
+
+ return "Heap, allocation and fragmentation test";
+}
+
+static void heap1_setup(void) {
+}
+
+static void heap1_teardown(void) {
+}
+
+static void heap1_execute(void) {
+ void *p1, *p2, *p3;
+
+ /* Test skipped if the heap is already fragmented. */
+ if (chHeapNotFragmented()) {
+ /* Same order */
+ p1 = chHeapAlloc(SIZE);
+ p2 = chHeapAlloc(SIZE);
+ p3 = chHeapAlloc(SIZE);
+ chHeapFree(p1); /* Does not merge */
+ chHeapFree(p2); /* Merges backward */
+ chHeapFree(p3); /* Merges both sides */
+ test_assert(chHeapNotFragmented(), "heap fragmented #1");
+
+ /* Reverse order */
+ p1 = chHeapAlloc(SIZE);
+ p2 = chHeapAlloc(SIZE);
+ p3 = chHeapAlloc(SIZE);
+ chHeapFree(p3); /* Merges forward */
+ chHeapFree(p2); /* Merges forward */
+ chHeapFree(p1); /* Merges forward */
+ test_assert(chHeapNotFragmented(), "heap fragmented #2");
+ }
+}
+
+const struct testcase testheap1 = {
+ heap1_gettest,
+ heap1_setup,
+ heap1_teardown,
+ heap1_execute
+};
+
+#endif /* CH_USE_HEAP */
diff --git a/test/testheap.h b/test/testheap.h new file mode 100644 index 000000000..4fc6d17ce --- /dev/null +++ b/test/testheap.h @@ -0,0 +1,25 @@ +/*
+ ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio.
+
+ This file is part of ChibiOS/RT.
+
+ ChibiOS/RT is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ ChibiOS/RT is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _TESTHEAP_H_
+#define _TESTHEAP_H_
+
+extern const struct testcase testheap1;
+
+#endif /* _TESTHEAP_H_ */
|