diff options
Diffstat (limited to 'test/rt/source/test/test_sequence_009.c')
-rw-r--r-- | test/rt/source/test/test_sequence_009.c | 294 |
1 files changed, 157 insertions, 137 deletions
diff --git a/test/rt/source/test/test_sequence_009.c b/test/rt/source/test/test_sequence_009.c index b980b828e..63e9f2da2 100644 --- a/test/rt/source/test/test_sequence_009.c +++ b/test/rt/source/test/test_sequence_009.c @@ -19,252 +19,272 @@ #include "test_root.h"
/**
- * @page test_sequence_009 [9] Memory Heaps
+ * @page test_sequence_009 [9] Memory Pools
*
* File: @ref test_sequence_009.c
*
* <h2>Description</h2>
* This sequence tests the ChibiOS/RT functionalities related to memory
- * heaps.
+ * pools.
*
* <h2>Conditions</h2>
* This sequence is only executed if the following preprocessor condition
* evaluates to true:
- * - CH_CFG_USE_HEAP
+ * - CH_CFG_USE_MEMPOOLS
* .
*
* <h2>Test Cases</h2>
* - @subpage test_009_001
* - @subpage test_009_002
+ * - @subpage test_009_003
* .
*/
-#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
+#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
/****************************************************************************
* Shared code.
****************************************************************************/
-#define ALLOC_SIZE 16 -#define HEAP_SIZE (ALLOC_SIZE * 8) +#define MEMORY_POOL_SIZE 4 -static memory_heap_t test_heap; -static CH_HEAP_AREA(myheap, HEAP_SIZE);
+static uint32_t objects[MEMORY_POOL_SIZE]; +static MEMORYPOOL_DECL(mp1, sizeof (uint32_t), NULL); +static GUARDEDMEMORYPOOL_DECL(gmp1, sizeof (uint32_t)); + +static void *null_provider(size_t size, unsigned align) { + + (void)size; + (void)align; + + return NULL; +}
/****************************************************************************
* Test cases.
****************************************************************************/
/**
- * @page test_009_001 [9.1] Allocation and fragmentation
+ * @page test_009_001 [9.1] Loading and emptying a memory pool
*
* <h2>Description</h2>
- * Series of allocations/deallocations are performed in carefully
- * designed sequences in order to stimulate all the possible code paths
- * inside the allocator. The test expects to find the heap back to the
- * initial status after each sequence.
+ * The memory pool functionality is tested by loading and emptying it,
+ * all conditions are tested.
*
* <h2>Test Steps</h2>
- * - [9.1.1] Testing initial conditions, the heap must not be
- * fragmented and one free block present.
- * - [9.1.2] Trying to allocate an block bigger than available space,
- * an error is expected.
- * - [9.1.3] Single block allocation using chHeapAlloc() then the block
- * is freed using chHeapFree(), must not fail.
- * - [9.1.4] Using chHeapStatus() to assess the heap state. There must
- * be at least one free block of sufficient size.
- * - [9.1.5] Allocating then freeing in the same order.
- * - [9.1.6] Allocating then freeing in reverse order.
- * - [9.1.7] Small fragments handling. Checking the behavior when
- * allocating blocks with size not multiple of alignment unit.
- * - [9.1.8] Skipping a fragment, the first fragment in the list is too
- * small so the allocator must pick the second one.
- * - [9.1.9] Allocating the whole available space.
- * - [9.1.10] Testing final conditions. The heap geometry must be the
- * same than the one registered at beginning.
+ * - [9.1.1] Adding the objects to the pool using chPoolLoadArray().
+ * - [9.1.2] Emptying the pool using chPoolAlloc().
+ * - [9.1.3] Now must be empty.
+ * - [9.1.4] Adding the objects to the pool using chPoolFree().
+ * - [9.1.5] Emptying the pool using chPoolAlloc() again.
+ * - [9.1.6] Now must be empty again.
+ * - [9.1.7] Covering the case where a provider is unable to return
+ * more memory.
* .
*/
static void test_009_001_setup(void) {
- chHeapObjectInit(&test_heap, myheap, sizeof(myheap));
+ chPoolObjectInit(&mp1, sizeof (uint32_t), NULL);
}
static void test_009_001_execute(void) {
- void *p1, *p2, *p3;
- size_t n, sz;
+ unsigned i;
- /* [9.1.1] Testing initial conditions, the heap must not be
- fragmented and one free block present.*/
+ /* [9.1.1] Adding the objects to the pool using chPoolLoadArray().*/
test_set_step(1);
{
- test_assert(chHeapStatus(&test_heap, &sz, NULL) == 1, "heap fragmented");
+ chPoolLoadArray(&mp1, objects, MEMORY_POOL_SIZE);
}
- /* [9.1.2] Trying to allocate an block bigger than available space,
- an error is expected.*/
+ /* [9.1.2] Emptying the pool using chPoolAlloc().*/
test_set_step(2);
{
- p1 = chHeapAlloc(&test_heap, HEAP_SIZE * 2);
- test_assert(p1 == NULL, "allocation not failed");
+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
+ test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
}
- /* [9.1.3] Single block allocation using chHeapAlloc() then the block
- is freed using chHeapFree(), must not fail.*/
+ /* [9.1.3] Now must be empty.*/
test_set_step(3);
{
- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- test_assert(p1 != NULL, "allocation failed");
- chHeapFree(p1);
+ test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
}
- /* [9.1.4] Using chHeapStatus() to assess the heap state. There must
- be at least one free block of sufficient size.*/
+ /* [9.1.4] Adding the objects to the pool using chPoolFree().*/
test_set_step(4);
{
- size_t total_size, largest_size;
-
- n = chHeapStatus(&test_heap, &total_size, &largest_size);
- test_assert(n == 1, "missing free block");
- test_assert(total_size >= ALLOC_SIZE, "unexpected heap state");
- test_assert(total_size == largest_size, "unexpected heap state");
+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
+ chPoolFree(&mp1, &objects[i]);
}
- /* [9.1.5] Allocating then freeing in the same order.*/
+ /* [9.1.5] Emptying the pool using chPoolAlloc() again.*/
test_set_step(5);
{
- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- p3 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- chHeapFree(p1); /* Does not merge.*/
- chHeapFree(p2); /* Merges backward.*/
- chHeapFree(p3); /* Merges both sides.*/
- test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
+ test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
}
- /* [9.1.6] Allocating then freeing in reverse order.*/
+ /* [9.1.6] Now must be empty again.*/
test_set_step(6);
{
- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- p3 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- chHeapFree(p3); /* Merges forward.*/
- chHeapFree(p2); /* Merges forward.*/
- chHeapFree(p1); /* Merges forward.*/
- test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
+ test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
}
- /* [9.1.7] Small fragments handling. Checking the behavior when
- allocating blocks with size not multiple of alignment unit.*/
+ /* [9.1.7] Covering the case where a provider is unable to return
+ more memory.*/
test_set_step(7);
{
- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE + 1);
- p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- chHeapFree(p1);
- test_assert(chHeapStatus(&test_heap, &n, NULL) == 2, "invalid state");
- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- /* Note, the first situation happens when the alignment size is smaller
- than the header size, the second in the other cases.*/
- test_assert((chHeapStatus(&test_heap, &n, NULL) == 1) ||
- (chHeapStatus(&test_heap, &n, NULL) == 2), "heap fragmented");
- chHeapFree(p2);
- chHeapFree(p1);
- test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
- }
-
- /* [9.1.8] Skipping a fragment, the first fragment in the list is too
- small so the allocator must pick the second one.*/
- test_set_step(8);
- {
- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- p2 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- chHeapFree(p1);
- test_assert( chHeapStatus(&test_heap, &n, NULL) == 2, "invalid state");
- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE * 2); /* Skips first fragment.*/
- chHeapFree(p1);
- chHeapFree(p2);
- test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
- }
-
- /* [9.1.9] Allocating the whole available space.*/
- test_set_step(9);
- {
- (void)chHeapStatus(&test_heap, &n, NULL);
- p1 = chHeapAlloc(&test_heap, n);
- test_assert(p1 != NULL, "allocation failed");
- test_assert(chHeapStatus(&test_heap, NULL, NULL) == 0, "not empty");
- chHeapFree(p1);
- }
-
- /* [9.1.10] Testing final conditions. The heap geometry must be the
- same than the one registered at beginning.*/
- test_set_step(10);
- {
- test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
- test_assert(n == sz, "size changed");
+ chPoolObjectInit(&mp1, sizeof (uint32_t), null_provider);
+ test_assert(chPoolAlloc(&mp1) == NULL, "provider returned memory");
}
}
static const testcase_t test_009_001 = {
- "Allocation and fragmentation",
+ "Loading and emptying a memory pool",
test_009_001_setup,
NULL,
test_009_001_execute
};
+#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
/**
- * @page test_009_002 [9.2] Default Heap
+ * @page test_009_002 [9.2] Loading and emptying a guarded memory pool without waiting
*
* <h2>Description</h2>
- * The default heap is pre-allocated in the system. We test base
- * functionality.
+ * The memory pool functionality is tested by loading and emptying it,
+ * all conditions are tested.
+ *
+ * <h2>Conditions</h2>
+ * This test is only executed if the following preprocessor condition
+ * evaluates to true:
+ * - CH_CFG_USE_SEMAPHORES
+ * .
*
* <h2>Test Steps</h2>
- * - [9.2.1] Single block allocation using chHeapAlloc() then the block
- * is freed using chHeapFree(), must not fail.
- * - [9.2.2] Testing allocation failure.
+ * - [9.2.1] Adding the objects to the pool using
+ * chGuardedPoolLoadArray().
+ * - [9.2.2] Emptying the pool using chGuardedPoolAllocTimeout().
+ * - [9.2.3] Now must be empty.
+ * - [9.2.4] Adding the objects to the pool using chGuardedPoolFree().
+ * - [9.2.5] Emptying the pool using chGuardedPoolAllocTimeout() again.
+ * - [9.2.6] Now must be empty again.
* .
*/
+static void test_009_002_setup(void) {
+ chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
+}
+
static void test_009_002_execute(void) {
- void *p1;
- size_t total_size, largest_size;
+ unsigned i;
- /* [9.2.1] Single block allocation using chHeapAlloc() then the block
- is freed using chHeapFree(), must not fail.*/
+ /* [9.2.1] Adding the objects to the pool using
+ chGuardedPoolLoadArray().*/
test_set_step(1);
{
- (void)chHeapStatus(NULL, &total_size, &largest_size);
- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- test_assert(p1 != NULL, "allocation failed");
- chHeapFree(p1);
+ chGuardedPoolLoadArray(&gmp1, objects, MEMORY_POOL_SIZE);
}
- /* [9.2.2] Testing allocation failure.*/
+ /* [9.2.2] Emptying the pool using chGuardedPoolAllocTimeout().*/
test_set_step(2);
{
- p1 = chHeapAlloc(NULL, (size_t)-256);
- test_assert(p1 == NULL, "allocation not failed");
+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
+ test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
+ }
+
+ /* [9.2.3] Now must be empty.*/
+ test_set_step(3);
+ {
+ test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
+ }
+
+ /* [9.2.4] Adding the objects to the pool using
+ chGuardedPoolFree().*/
+ test_set_step(4);
+ {
+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
+ chGuardedPoolFree(&gmp1, &objects[i]);
+ }
+
+ /* [9.2.5] Emptying the pool using chGuardedPoolAllocTimeout()
+ again.*/
+ test_set_step(5);
+ {
+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
+ test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
+ }
+
+ /* [9.2.6] Now must be empty again.*/
+ test_set_step(6);
+ {
+ test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
}
}
static const testcase_t test_009_002 = {
- "Default Heap",
- NULL,
+ "Loading and emptying a guarded memory pool without waiting",
+ test_009_002_setup,
NULL,
test_009_002_execute
};
+#endif /* CH_CFG_USE_SEMAPHORES */
+
+#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
+/**
+ * @page test_009_003 [9.3] Guarded Memory Pools timeout
+ *
+ * <h2>Description</h2>
+ * The timeout features for the Guarded Memory Pools is tested.
+ *
+ * <h2>Conditions</h2>
+ * This test is only executed if the following preprocessor condition
+ * evaluates to true:
+ * - CH_CFG_USE_SEMAPHORES
+ * .
+ *
+ * <h2>Test Steps</h2>
+ * - [9.3.1] Trying to allocate with 100mS timeout, must fail because
+ * the pool is empty.
+ * .
+ */
+
+static void test_009_003_setup(void) {
+ chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
+}
+
+static void test_009_003_execute(void) {
+
+ /* [9.3.1] Trying to allocate with 100mS timeout, must fail because
+ the pool is empty.*/
+ test_set_step(1);
+ {
+ test_assert(chGuardedPoolAllocTimeout(&gmp1, MS2ST(100)) == NULL, "list not empty");
+ }
+}
+
+static const testcase_t test_009_003 = {
+ "Guarded Memory Pools timeout",
+ test_009_003_setup,
+ NULL,
+ test_009_003_execute
+};
+#endif /* CH_CFG_USE_SEMAPHORES */
/****************************************************************************
* Exported data.
****************************************************************************/
/**
- * @brief Memory Heaps.
+ * @brief Memory Pools.
*/
const testcase_t * const test_sequence_009[] = {
&test_009_001,
+#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
&test_009_002,
+#endif
+#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
+ &test_009_003,
+#endif
NULL
};
-#endif /* CH_CFG_USE_HEAP */
+#endif /* CH_CFG_USE_MEMPOOLS */
|