From 3ae2e8ddb38615434dccd5a6462faae144633d27 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 26 Aug 2008 14:43:09 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@409 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- readme.txt | 6 ++- src/chmempools.c | 121 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/chpools.c | 121 ------------------------------------------------------- src/kernel.mk | 2 +- test/test.c | 6 +++ test/test.mk | 3 +- test/testmtx.c | 4 ++ test/testpools.c | 63 +++++++++++++++++++++++++++++ test/testpools.h | 25 ++++++++++++ 9 files changed, 226 insertions(+), 125 deletions(-) create mode 100644 src/chmempools.c delete mode 100644 src/chpools.c create mode 100644 test/testpools.c create mode 100644 test/testpools.h diff --git a/readme.txt b/readme.txt index a751fe1b0..9ef696309 100644 --- a/readme.txt +++ b/readme.txt @@ -77,11 +77,13 @@ Win32-MinGW - ChibiOS/RT simulator and demo into a WIN32 process, *** 0.7.0 *** - 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 it can also - handle application-defined objects. The allocator is, of course, thread-safe. + allocate kernel objects like Semaphores, Mutexes, Threads etc, of course it + is also possible to handle application-defined objects. The allocator is + thread-safe. - NEW: Kernel-provided sbrk() function, it is used internally by the Memory Pools but can also be used by the C runtime. There is also an option to meke the Memory Pools use an user-provided sbrk() function. +- Added a Memory Pools test case to the test suite. *** 0.6.10 *** - FIX: Fixed a case-sensitiveness error in lpc214x_ssp.c, it affected only diff --git a/src/chmempools.c b/src/chmempools.c new file mode 100644 index 000000000..5b714a73e --- /dev/null +++ b/src/chmempools.c @@ -0,0 +1,121 @@ +/* + 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 . +*/ + +/** + * @addtogroup MemoryPools + * @{ + */ + +#include + +#ifdef CH_USE_MEMPOOLS + +#ifndef CH_MEMPOOLS_PROVIDE_SBRK +#include +#else +/* + * Optional internal sbrk() implementation, this code requires the linker to + * provide two symbols: __heap_base__ and __heap_end__ that are the boundaries + * of the free RAM space. + */ +extern char __heap_base__; +extern char __heap_end__; +static char *current = &__heap_base__; + +void *sbrk(ptrdiff_t increment) { + char *cp; + + if (current + increment >= &__heap_end__) + return (void *)-1; + cp = current; + current += increment; + return cp; +} +#endif /* CH_MEMPOOLS_PROVIDE_SBRK */ + +/** + * Initializes a memory pool. + * @param mp pointer to a \p MemoryPool structure + * @param size the size of the objects contained in this memory pool + */ +void chPoolInit(MemoryPool *mp, size_t size) { + + chDbgAssert((mp != NULL) && (size >= sizeof(void *)), + "chpools.c, chPoolFree()"); + + mp->mp_next = NULL; + mp->mp_object_size = size; +} + +/** + * Allocates an object from a memory pool. + * @param mp pointer to a \p MemoryPool structure + * @param allow_growth if \p TRUE then the object is allocated by using + * \p sbrk() in case the memory pool is empty + * @return the pointer to the allocated object or \p NULL if the memory is + * exhausted + */ +void *chPoolAlloc(MemoryPool *mp, bool_t allow_growth) { + void *p; + + chDbgAssert(mp != NULL, "chpools.c, chPoolAlloc()"); + + chSysLock(); + + if (mp->mp_next == NULL) { + if (allow_growth) { + p = sbrk(mp->mp_object_size); + + chSysUnlock(); + if (p != (void *)-1) + return p; + } + return NULL; + } + p = mp->mp_next; + mp->mp_next = mp->mp_next->ph_next; + + chSysUnlock(); + return p; +} + +/** + * Releases (or adds) an object to a memory pool. + * @param mp pointer to a \p MemoryPool structure + * @param objp the pointer to the object to be released or added + * @note the object is assumed to be of the right size for the specified + * buffer. + */ +void chPoolFree(MemoryPool *mp, void *objp) { + struct pool_header *php = objp; + + chDbgAssert((mp != NULL) && (objp != NULL), + "chpools.c, chPoolFree()"); + + chSysLock(); + + php->ph_next = mp->mp_next; + mp->mp_next = php; + + chSysUnlock(); +} + +#endif /* CH_USE_MEMPOOLS */ + +/** @} */ diff --git a/src/chpools.c b/src/chpools.c deleted file mode 100644 index 5b714a73e..000000000 --- a/src/chpools.c +++ /dev/null @@ -1,121 +0,0 @@ -/* - 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 . -*/ - -/** - * @addtogroup MemoryPools - * @{ - */ - -#include - -#ifdef CH_USE_MEMPOOLS - -#ifndef CH_MEMPOOLS_PROVIDE_SBRK -#include -#else -/* - * Optional internal sbrk() implementation, this code requires the linker to - * provide two symbols: __heap_base__ and __heap_end__ that are the boundaries - * of the free RAM space. - */ -extern char __heap_base__; -extern char __heap_end__; -static char *current = &__heap_base__; - -void *sbrk(ptrdiff_t increment) { - char *cp; - - if (current + increment >= &__heap_end__) - return (void *)-1; - cp = current; - current += increment; - return cp; -} -#endif /* CH_MEMPOOLS_PROVIDE_SBRK */ - -/** - * Initializes a memory pool. - * @param mp pointer to a \p MemoryPool structure - * @param size the size of the objects contained in this memory pool - */ -void chPoolInit(MemoryPool *mp, size_t size) { - - chDbgAssert((mp != NULL) && (size >= sizeof(void *)), - "chpools.c, chPoolFree()"); - - mp->mp_next = NULL; - mp->mp_object_size = size; -} - -/** - * Allocates an object from a memory pool. - * @param mp pointer to a \p MemoryPool structure - * @param allow_growth if \p TRUE then the object is allocated by using - * \p sbrk() in case the memory pool is empty - * @return the pointer to the allocated object or \p NULL if the memory is - * exhausted - */ -void *chPoolAlloc(MemoryPool *mp, bool_t allow_growth) { - void *p; - - chDbgAssert(mp != NULL, "chpools.c, chPoolAlloc()"); - - chSysLock(); - - if (mp->mp_next == NULL) { - if (allow_growth) { - p = sbrk(mp->mp_object_size); - - chSysUnlock(); - if (p != (void *)-1) - return p; - } - return NULL; - } - p = mp->mp_next; - mp->mp_next = mp->mp_next->ph_next; - - chSysUnlock(); - return p; -} - -/** - * Releases (or adds) an object to a memory pool. - * @param mp pointer to a \p MemoryPool structure - * @param objp the pointer to the object to be released or added - * @note the object is assumed to be of the right size for the specified - * buffer. - */ -void chPoolFree(MemoryPool *mp, void *objp) { - struct pool_header *php = objp; - - chDbgAssert((mp != NULL) && (objp != NULL), - "chpools.c, chPoolFree()"); - - chSysLock(); - - php->ph_next = mp->mp_next; - mp->mp_next = php; - - chSysUnlock(); -} - -#endif /* CH_USE_MEMPOOLS */ - -/** @} */ diff --git a/src/kernel.mk b/src/kernel.mk index febd8fa9c..1aa60125b 100644 --- a/src/kernel.mk +++ b/src/kernel.mk @@ -6,4 +6,4 @@ KERNSRC = ../../src/chinit.c ../../src/chdebug.c \ ../../src/chsem.c ../../src/chmtx.c \ ../../src/chevents.c ../../src/chmsg.c \ ../../src/chsleep.c ../../src/chqueues.c \ - ../../src/chserial.c ../../src/chpools.c + ../../src/chserial.c ../../src/chmempools.c diff --git a/test/test.c b/test/test.c index 1a0b9a4ec..96bd43938 100644 --- a/test/test.c +++ b/test/test.c @@ -24,6 +24,7 @@ #include "testsem.h" #include "testmtx.h" #include "testmsg.h" +#include "testpools.h" #include "testbmk.h" /* @@ -34,10 +35,15 @@ static const struct testcase *tests[] = { &testrdy2, &testsem1, &testsem2, +#ifdef CH_USE_MUTEXES &testmtx1, &testmtx2, &testmtx3, +#endif &testmsg1, +#ifdef CH_USE_MEMPOOLS + &testpools1, +#endif &testbmk1, &testbmk2, &testbmk3, diff --git a/test/test.mk b/test/test.mk index ce890a855..73e6e1bc0 100644 --- a/test/test.mk +++ b/test/test.mk @@ -1,3 +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/testbmk.c + ../../test/testmtx.c ../../test/testmsg.c ../../test/testpools.c \ + ../../test/testbmk.c diff --git a/test/testmtx.c b/test/testmtx.c index 526a64ffa..2243b375f 100644 --- a/test/testmtx.c +++ b/test/testmtx.c @@ -21,6 +21,8 @@ #include "test.h" +#ifdef CH_USE_MUTEXES + #define ALLOWED_DELAY 5 static Mutex m1, m2; @@ -219,3 +221,5 @@ const struct testcase testmtx3 = { mtx3_teardown, mtx3_execute }; + +#endif /* CH_USE_MUTEXES */ diff --git a/test/testpools.c b/test/testpools.c new file mode 100644 index 000000000..a86eecedd --- /dev/null +++ b/test/testpools.c @@ -0,0 +1,63 @@ +/* + 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 . +*/ + +#include + +#include "test.h" + +#ifdef CH_USE_MEMPOOLS + +static MemoryPool mp1; + +static char *pools1_gettest(void) { + + return "Memory Pools, allocation and enqueuing test"; +} + +static void pools1_setup(void) { + + chPoolInit(&mp1, UserStackSize(THREADS_STACK_SIZE)); +} + +static void pools1_teardown(void) { +} + +static void pools1_execute(void) { + int i; + + /* Adding the WAs to the pool. */ + for (i = 0; i < 5; i++) + chPoolFree(&mp1, wa[i]); + + /* Empting the pool again. */ + for (i = 0; i < 5; i++) + test_assert(chPoolAlloc(&mp1, FALSE) != NULL, "pool list empty"); + + /* Now must be empty. */ + test_assert(chPoolAlloc(&mp1, FALSE) == NULL, "pool list not empty"); +} + +const struct testcase testpools1 = { + pools1_gettest, + pools1_setup, + pools1_teardown, + pools1_execute +}; + +#endif /* CH_USE_MEMPOOLS */ diff --git a/test/testpools.h b/test/testpools.h new file mode 100644 index 000000000..413d1eb76 --- /dev/null +++ b/test/testpools.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 . +*/ + +#ifndef _TESTPOOLS_H_ +#define _TESTPOOLS_H_ + +extern const struct testcase testpools1; + +#endif /* _TESTPOOLS_H_ */ -- cgit v1.2.3