aboutsummaryrefslogtreecommitdiffstats
path: root/test
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2018-09-30 05:38:03 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2018-09-30 05:38:03 +0000
commit8fa2bcdad9edb41d01c9ccf1ebbbe135713bf9c0 (patch)
tree0810a1752b0312c1ce321281d4fa8a0225e16daf /test
parentf562ee4948dd1e2b9175dfa3f2a2c071023c6167 (diff)
downloadChibiOS-8fa2bcdad9edb41d01c9ccf1ebbbe135713bf9c0.tar.gz
ChibiOS-8fa2bcdad9edb41d01c9ccf1ebbbe135713bf9c0.tar.bz2
ChibiOS-8fa2bcdad9edb41d01c9ccf1ebbbe135713bf9c0.zip
Fixed small errors in pipes and pipes factory.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12307 110e8d01-0319-4d1e-a829-52ad28d1bb01
Diffstat (limited to 'test')
-rw-r--r--test/oslib/configuration.xml139
-rw-r--r--test/oslib/oslib_test.mk3
-rw-r--r--test/oslib/source/test/oslib_test_root.c10
-rw-r--r--test/oslib/source/test/oslib_test_root.h1
-rw-r--r--test/oslib/source/test/oslib_test_sequence_001.c2
-rw-r--r--test/oslib/source/test/oslib_test_sequence_002.c234
-rw-r--r--test/oslib/source/test/oslib_test_sequence_003.c299
-rw-r--r--test/oslib/source/test/oslib_test_sequence_004.c773
8 files changed, 490 insertions, 971 deletions
diff --git a/test/oslib/configuration.xml b/test/oslib/configuration.xml
index 7b3a6b47f..723f47727 100644
--- a/test/oslib/configuration.xml
+++ b/test/oslib/configuration.xml
@@ -53,7 +53,7 @@
<value>Mailboxes.</value>
</brief>
<description>
- <value>This sequence tests the ChibiOS libraryfunctionalities related to mailboxes.</value>
+ <value>This sequence tests the ChibiOS library functionalities related to mailboxes.</value>
</description>
<condition>
<value>CH_CFG_USE_MAILBOXES</value>
@@ -435,10 +435,144 @@ test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");]]></value>
<value>Internal Tests</value>
</type>
<brief>
+ <value>Pipes</value>
+ </brief>
+ <description>
+ <value>This sequence tests the ChibiOS library functionalities related to pipes.</value>
+ </description>
+ <condition>
+ <value>CH_CFG_USE_PIPES</value>
+ </condition>
+ <shared_code>
+ <value><![CDATA[#define PIPE_SIZE 16
+
+static uint8_t buffer[PIPE_SIZE];
+static PIPE_DECL(pipe1, buffer, PIPE_SIZE);
+
+static const uint8_t pipe_pattern[] = "0123456789ABCDEF";]]></value>
+ </shared_code>
+ <cases>
+ <case>
+ <brief>
+ <value>Filling and emptying a pipe, non blocking.</value>
+ </brief>
+ <description>
+ <value>The pipe functionality is tested by loading and emptying it, all conditions are tested.</value>
+ </description>
+ <condition>
+ <value>
+ </value>
+ </condition>
+ <various_code>
+ <setup_code>
+ <value><![CDATA[chPipeObjectInit(&pipe1, buffer, PIPE_SIZE);]]></value>
+ </setup_code>
+ <teardown_code>
+ <value/>
+ </teardown_code>
+ <local_variables>
+ <value><![CDATA[unsigned i;]]></value>
+ </local_variables>
+ </various_code>
+ <steps>
+ <step>
+ <description>
+ <value>Filling whole pipe.</value>
+ </description>
+ <tags>
+ <value></value>
+ </tags>
+ <code>
+ <value><![CDATA[msg_t msg;
+
+msg = chPipeWriteTimeout(&pipe1, pipe_pattern, PIPE_SIZE, TIME_IMMEDIATE);
+test_assert(msg == PIPE_SIZE, "wrong size");
+test_assert((pipe1.rdptr == pipe1.buffer) &&
+ (pipe1.wrptr == pipe1.buffer) &&
+ (pipe1.cnt == PIPE_SIZE),
+ "invalid pipe state");]]></value>
+ </code>
+ </step>
+ <step>
+ <description>
+ <value>Emptying pipe.</value>
+ </description>
+ <tags>
+ <value></value>
+ </tags>
+ <code>
+ <value><![CDATA[msg_t msg;
+uint8_t buf[PIPE_SIZE];
+
+msg = chPipeReadTimeout(&pipe1, buf, PIPE_SIZE, TIME_IMMEDIATE);
+test_assert(msg == PIPE_SIZE, "wrong size");
+test_assert((pipe1.rdptr == pipe1.buffer) &&
+ (pipe1.wrptr == pipe1.buffer) &&
+ (pipe1.cnt == PIPE_SIZE),
+ "invalid pipe state");]]></value>
+ </code>
+ </step>
+ <step>
+ <description>
+ <value>
+ </value>
+ </description>
+ <tags>
+ <value></value>
+ </tags>
+ <code>
+ <value><![CDATA[]]></value>
+ </code>
+ </step>
+ <step>
+ <description>
+ <value>
+ </value>
+ </description>
+ <tags>
+ <value></value>
+ </tags>
+ <code>
+ <value><![CDATA[]]></value>
+ </code>
+ </step>
+ <step>
+ <description>
+ <value>
+ </value>
+ </description>
+ <tags>
+ <value></value>
+ </tags>
+ <code>
+ <value><![CDATA[]]></value>
+ </code>
+ </step>
+ <step>
+ <description>
+ <value>
+ </value>
+ </description>
+ <tags>
+ <value></value>
+ </tags>
+ <code>
+ <value><![CDATA[]]></value>
+ </code>
+ </step>
+ </steps>
+ </case>
+ </cases>
+ </sequence>
+ <sequence>
+ <type index="0">
+ <value>Internal Tests</value>
+ </type>
+ <brief>
<value>Memory Pools.</value>
</brief>
<description>
- <value>This sequence tests the ChibiOS library functionalities related to memory pools.</value>
+ <value>This sequence tests the ChibiOS library functionalities related to memory pools.</value>
</description>
<condition>
<value>CH_CFG_USE_MEMPOOLS</value>
@@ -1681,6 +1815,7 @@ test_assert(dpp == NULL, "found");]]></value>
</case>
</cases>
</sequence>
+
</sequences>
</instance>
</instances>
diff --git a/test/oslib/oslib_test.mk b/test/oslib/oslib_test.mk
index f342719e1..d4d863f36 100644
--- a/test/oslib/oslib_test.mk
+++ b/test/oslib/oslib_test.mk
@@ -3,7 +3,8 @@ TESTSRC += ${CHIBIOS}/test/oslib/source/test/oslib_test_root.c \
${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_001.c \
${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_002.c \
${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_003.c \
- ${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_004.c
+ ${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_004.c \
+ ${CHIBIOS}/test/oslib/source/test/oslib_test_sequence_005.c
# Required include directories
TESTINC += ${CHIBIOS}/test/oslib/source/test
diff --git a/test/oslib/source/test/oslib_test_root.c b/test/oslib/source/test/oslib_test_root.c
index e222dcd06..9f65ccc68 100644
--- a/test/oslib/source/test/oslib_test_root.c
+++ b/test/oslib/source/test/oslib_test_root.c
@@ -25,6 +25,7 @@
* - @subpage oslib_test_sequence_002
* - @subpage oslib_test_sequence_003
* - @subpage oslib_test_sequence_004
+ * - @subpage oslib_test_sequence_005
* .
*/
@@ -49,15 +50,18 @@ const testsequence_t * const oslib_test_suite_array[] = {
#if (CH_CFG_USE_MAILBOXES) || defined(__DOXYGEN__)
&oslib_test_sequence_001,
#endif
-#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
+#if (CH_CFG_USE_PIPES) || defined(__DOXYGEN__)
&oslib_test_sequence_002,
#endif
-#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
+#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
&oslib_test_sequence_003,
#endif
-#if ((CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE)) || defined(__DOXYGEN__)
+#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
&oslib_test_sequence_004,
#endif
+#if ((CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE)) || defined(__DOXYGEN__)
+ &oslib_test_sequence_005,
+#endif
NULL
};
diff --git a/test/oslib/source/test/oslib_test_root.h b/test/oslib/source/test/oslib_test_root.h
index 760ccddc8..01b6eefe9 100644
--- a/test/oslib/source/test/oslib_test_root.h
+++ b/test/oslib/source/test/oslib_test_root.h
@@ -28,6 +28,7 @@
#include "oslib_test_sequence_002.h"
#include "oslib_test_sequence_003.h"
#include "oslib_test_sequence_004.h"
+#include "oslib_test_sequence_005.h"
#if !defined(__DOXYGEN__)
diff --git a/test/oslib/source/test/oslib_test_sequence_001.c b/test/oslib/source/test/oslib_test_sequence_001.c
index 74672a242..076efa102 100644
--- a/test/oslib/source/test/oslib_test_sequence_001.c
+++ b/test/oslib/source/test/oslib_test_sequence_001.c
@@ -26,7 +26,7 @@
* File: @ref oslib_test_sequence_001.c
*
* <h2>Description</h2>
- * This sequence tests the ChibiOS libraryfunctionalities related to
+ * This sequence tests the ChibiOS library functionalities related to
* mailboxes.
*
* <h2>Conditions</h2>
diff --git a/test/oslib/source/test/oslib_test_sequence_002.c b/test/oslib/source/test/oslib_test_sequence_002.c
index bd661ce13..406b4f21d 100644
--- a/test/oslib/source/test/oslib_test_sequence_002.c
+++ b/test/oslib/source/test/oslib_test_sequence_002.c
@@ -21,259 +21,121 @@
* @file oslib_test_sequence_002.c
* @brief Test Sequence 002 code.
*
- * @page oslib_test_sequence_002 [2] Memory Pools
+ * @page oslib_test_sequence_002 [2] Pipes
*
* File: @ref oslib_test_sequence_002.c
*
* <h2>Description</h2>
* This sequence tests the ChibiOS library functionalities related to
- * memory pools.
+ * pipes.
*
* <h2>Conditions</h2>
* This sequence is only executed if the following preprocessor condition
* evaluates to true:
- * - CH_CFG_USE_MEMPOOLS
+ * - CH_CFG_USE_PIPES
* .
*
* <h2>Test Cases</h2>
* - @subpage oslib_test_002_001
- * - @subpage oslib_test_002_002
- * - @subpage oslib_test_002_003
* .
*/
-#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
+#if (CH_CFG_USE_PIPES) || defined(__DOXYGEN__)
/****************************************************************************
* Shared code.
****************************************************************************/
-#define MEMORY_POOL_SIZE 4
+#define PIPE_SIZE 16
-static uint32_t objects[MEMORY_POOL_SIZE];
-static MEMORYPOOL_DECL(mp1, sizeof (uint32_t), PORT_NATURAL_ALIGN, NULL);
+static uint8_t buffer[PIPE_SIZE];
+static PIPE_DECL(pipe1, buffer, PIPE_SIZE);
-#if CH_CFG_USE_SEMAPHORES
-static GUARDEDMEMORYPOOL_DECL(gmp1, sizeof (uint32_t), PORT_NATURAL_ALIGN);
-#endif
-
-static void *null_provider(size_t size, unsigned align) {
-
- (void)size;
- (void)align;
-
- return NULL;
-}
+static const uint8_t pipe_pattern[] = "0123456789ABCDEF";
/****************************************************************************
* Test cases.
****************************************************************************/
/**
- * @page oslib_test_002_001 [2.1] Loading and emptying a memory pool
+ * @page oslib_test_002_001 [2.1] Loading and emptying a pipe, non blocking
*
* <h2>Description</h2>
- * The memory pool functionality is tested by loading and emptying it,
- * all conditions are tested.
+ * The pipe functionality is tested by loading and emptying it, all
+ * conditions are tested.
*
* <h2>Test Steps</h2>
- * - [2.1.1] Adding the objects to the pool using chPoolLoadArray().
- * - [2.1.2] Emptying the pool using chPoolAlloc().
- * - [2.1.3] Now must be empty.
- * - [2.1.4] Adding the objects to the pool using chPoolFree().
- * - [2.1.5] Emptying the pool using chPoolAlloc() again.
- * - [2.1.6] Now must be empty again.
- * - [2.1.7] Covering the case where a provider is unable to return
- * more memory.
+ * - [2.1.1] Filling whole pipe.
+ * - [2.1.2] Emptying pipe.
+ * - [2.1.3].
+ * - [2.1.4].
+ * - [2.1.5].
+ * - [2.1.6].
* .
*/
static void oslib_test_002_001_setup(void) {
- chPoolObjectInit(&mp1, sizeof (uint32_t), NULL);
+ chPipeObjectInit(&pipe1, buffer, PIPE_SIZE);
}
static void oslib_test_002_001_execute(void) {
unsigned i;
- /* [2.1.1] Adding the objects to the pool using chPoolLoadArray().*/
+ /* [2.1.1] Filling whole pipe.*/
test_set_step(1);
{
- chPoolLoadArray(&mp1, objects, MEMORY_POOL_SIZE);
+ msg_t msg;
+
+ msg = chPipeWriteTimeout(&pipe1, pipe_pattern, PIPE_SIZE, TIME_IMMEDIATE);
+ test_assert(msg == PIPE_SIZE, "wrong size");
+ test_assert((pipe1.rdptr == pipe1.buffer) &&
+ (pipe1.wrptr == pipe1.buffer) &&
+ (pipe1.cnt == PIPE_SIZE),
+ "invalid pipe state");
}
- /* [2.1.2] Emptying the pool using chPoolAlloc().*/
+ /* [2.1.2] Emptying pipe.*/
test_set_step(2);
{
- for (i = 0; i < MEMORY_POOL_SIZE; i++)
- test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
+ msg_t msg;
+ uint8_t buf[PIPE_SIZE];
+
+ msg = chPipeReadTimeout(&pipe1, buf, PIPE_SIZE, TIME_IMMEDIATE);
+ test_assert(msg == PIPE_SIZE, "wrong size");
+ test_assert((pipe1.rdptr == pipe1.buffer) &&
+ (pipe1.wrptr == pipe1.buffer) &&
+ (pipe1.cnt == 0),
+ "invalid pipe state");
}
- /* [2.1.3] Now must be empty.*/
+ /* [2.1.3].*/
test_set_step(3);
{
- test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
}
- /* [2.1.4] Adding the objects to the pool using chPoolFree().*/
+ /* [2.1.4].*/
test_set_step(4);
{
- for (i = 0; i < MEMORY_POOL_SIZE; i++)
- chPoolFree(&mp1, &objects[i]);
}
- /* [2.1.5] Emptying the pool using chPoolAlloc() again.*/
+ /* [2.1.5].*/
test_set_step(5);
{
- for (i = 0; i < MEMORY_POOL_SIZE; i++)
- test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
}
- /* [2.1.6] Now must be empty again.*/
+ /* [2.1.6].*/
test_set_step(6);
{
- test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
- }
-
- /* [2.1.7] Covering the case where a provider is unable to return
- more memory.*/
- test_set_step(7);
- {
- chPoolObjectInit(&mp1, sizeof (uint32_t), null_provider);
- test_assert(chPoolAlloc(&mp1) == NULL, "provider returned memory");
}
}
static const testcase_t oslib_test_002_001 = {
- "Loading and emptying a memory pool",
+ "Loading and emptying a pipe, non blocking",
oslib_test_002_001_setup,
NULL,
oslib_test_002_001_execute
};
-#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
-/**
- * @page oslib_test_002_002 [2.2] Loading and emptying a guarded memory pool without waiting
- *
- * <h2>Description</h2>
- * 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>
- * - [2.2.1] Adding the objects to the pool using
- * chGuardedPoolLoadArray().
- * - [2.2.2] Emptying the pool using chGuardedPoolAllocTimeout().
- * - [2.2.3] Now must be empty.
- * - [2.2.4] Adding the objects to the pool using chGuardedPoolFree().
- * - [2.2.5] Emptying the pool using chGuardedPoolAllocTimeout() again.
- * - [2.2.6] Now must be empty again.
- * .
- */
-
-static void oslib_test_002_002_setup(void) {
- chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
-}
-
-static void oslib_test_002_002_execute(void) {
- unsigned i;
-
- /* [2.2.1] Adding the objects to the pool using
- chGuardedPoolLoadArray().*/
- test_set_step(1);
- {
- chGuardedPoolLoadArray(&gmp1, objects, MEMORY_POOL_SIZE);
- }
-
- /* [2.2.2] Emptying the pool using chGuardedPoolAllocTimeout().*/
- test_set_step(2);
- {
- for (i = 0; i < MEMORY_POOL_SIZE; i++)
- test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
- }
-
- /* [2.2.3] Now must be empty.*/
- test_set_step(3);
- {
- test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
- }
-
- /* [2.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]);
- }
-
- /* [2.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");
- }
-
- /* [2.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 oslib_test_002_002 = {
- "Loading and emptying a guarded memory pool without waiting",
- oslib_test_002_002_setup,
- NULL,
- oslib_test_002_002_execute
-};
-#endif /* CH_CFG_USE_SEMAPHORES */
-
-#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
-/**
- * @page oslib_test_002_003 [2.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>
- * - [2.3.1] Trying to allocate with 100mS timeout, must fail because
- * the pool is empty.
- * .
- */
-
-static void oslib_test_002_003_setup(void) {
- chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
-}
-
-static void oslib_test_002_003_execute(void) {
-
- /* [2.3.1] Trying to allocate with 100mS timeout, must fail because
- the pool is empty.*/
- test_set_step(1);
- {
- test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_MS2I(100)) == NULL, "list not empty");
- }
-}
-
-static const testcase_t oslib_test_002_003 = {
- "Guarded Memory Pools timeout",
- oslib_test_002_003_setup,
- NULL,
- oslib_test_002_003_execute
-};
-#endif /* CH_CFG_USE_SEMAPHORES */
-
/****************************************************************************
* Exported data.
****************************************************************************/
@@ -283,21 +145,15 @@ static const testcase_t oslib_test_002_003 = {
*/
const testcase_t * const oslib_test_sequence_002_array[] = {
&oslib_test_002_001,
-#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
- &oslib_test_002_002,
-#endif
-#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
- &oslib_test_002_003,
-#endif
NULL
};
/**
- * @brief Memory Pools.
+ * @brief Pipes.
*/
const testsequence_t oslib_test_sequence_002 = {
- "Memory Pools",
+ "Pipes",
oslib_test_sequence_002_array
};
-#endif /* CH_CFG_USE_MEMPOOLS */
+#endif /* CH_CFG_USE_PIPES */
diff --git a/test/oslib/source/test/oslib_test_sequence_003.c b/test/oslib/source/test/oslib_test_sequence_003.c
index 9f623e9db..7bfd208e0 100644
--- a/test/oslib/source/test/oslib_test_sequence_003.c
+++ b/test/oslib/source/test/oslib_test_sequence_003.c
@@ -21,240 +21,258 @@
* @file oslib_test_sequence_003.c
* @brief Test Sequence 003 code.
*
- * @page oslib_test_sequence_003 [3] Memory Heaps
+ * @page oslib_test_sequence_003 [3] Memory Pools
*
* File: @ref oslib_test_sequence_003.c
*
* <h2>Description</h2>
* This sequence tests the ChibiOS library functionalities related to
- * memory heaps.
+ * memory 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 oslib_test_003_001
* - @subpage oslib_test_003_002
+ * - @subpage oslib_test_003_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 uint8_t test_heap_buffer[HEAP_SIZE];
+static uint32_t objects[MEMORY_POOL_SIZE];
+static MEMORYPOOL_DECL(mp1, sizeof (uint32_t), PORT_NATURAL_ALIGN, NULL);
+
+#if CH_CFG_USE_SEMAPHORES
+static GUARDEDMEMORYPOOL_DECL(gmp1, sizeof (uint32_t), PORT_NATURAL_ALIGN);
+#endif
+
+static void *null_provider(size_t size, unsigned align) {
+
+ (void)size;
+ (void)align;
+
+ return NULL;
+}
/****************************************************************************
* Test cases.
****************************************************************************/
/**
- * @page oslib_test_003_001 [3.1] Allocation and fragmentation
+ * @page oslib_test_003_001 [3.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>
- * - [3.1.1] Testing initial conditions, the heap must not be
- * fragmented and one free block present.
- * - [3.1.2] Trying to allocate an block bigger than available space,
- * an error is expected.
- * - [3.1.3] Single block allocation using chHeapAlloc() then the block
- * is freed using chHeapFree(), must not fail.
- * - [3.1.4] Using chHeapStatus() to assess the heap state. There must
- * be at least one free block of sufficient size.
- * - [3.1.5] Allocating then freeing in the same order.
- * - [3.1.6] Allocating then freeing in reverse order.
- * - [3.1.7] Small fragments handling. Checking the behavior when
- * allocating blocks with size not multiple of alignment unit.
- * - [3.1.8] Skipping a fragment, the first fragment in the list is too
- * small so the allocator must pick the second one.
- * - [3.1.9] Allocating the whole available space.
- * - [3.1.10] Testing final conditions. The heap geometry must be the
- * same than the one registered at beginning.
+ * - [3.1.1] Adding the objects to the pool using chPoolLoadArray().
+ * - [3.1.2] Emptying the pool using chPoolAlloc().
+ * - [3.1.3] Now must be empty.
+ * - [3.1.4] Adding the objects to the pool using chPoolFree().
+ * - [3.1.5] Emptying the pool using chPoolAlloc() again.
+ * - [3.1.6] Now must be empty again.
+ * - [3.1.7] Covering the case where a provider is unable to return
+ * more memory.
* .
*/
static void oslib_test_003_001_setup(void) {
- chHeapObjectInit(&test_heap, test_heap_buffer, sizeof(test_heap_buffer));
+ chPoolObjectInit(&mp1, sizeof (uint32_t), NULL);
}
static void oslib_test_003_001_execute(void) {
- void *p1, *p2, *p3;
- size_t n, sz;
+ unsigned i;
- /* [3.1.1] Testing initial conditions, the heap must not be
- fragmented and one free block present.*/
+ /* [3.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);
}
- /* [3.1.2] Trying to allocate an block bigger than available space,
- an error is expected.*/
+ /* [3.1.2] Emptying the pool using chPoolAlloc().*/
test_set_step(2);
{
- p1 = chHeapAlloc(&test_heap, sizeof test_heap_buffer * 2);
- test_assert(p1 == NULL, "allocation not failed");
+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
+ test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
}
- /* [3.1.3] Single block allocation using chHeapAlloc() then the block
- is freed using chHeapFree(), must not fail.*/
+ /* [3.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");
}
- /* [3.1.4] Using chHeapStatus() to assess the heap state. There must
- be at least one free block of sufficient size.*/
+ /* [3.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]);
}
- /* [3.1.5] Allocating then freeing in the same order.*/
+ /* [3.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");
}
- /* [3.1.6] Allocating then freeing in reverse order.*/
+ /* [3.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");
}
- /* [3.1.7] Small fragments handling. Checking the behavior when
- allocating blocks with size not multiple of alignment unit.*/
+ /* [3.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");
- }
-
- /* [3.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");
- }
-
- /* [3.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);
- }
-
- /* [3.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 oslib_test_003_001 = {
- "Allocation and fragmentation",
+ "Loading and emptying a memory pool",
oslib_test_003_001_setup,
NULL,
oslib_test_003_001_execute
};
+#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
/**
- * @page oslib_test_003_002 [3.2] Default Heap
+ * @page oslib_test_003_002 [3.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>
- * - [3.2.1] Single block allocation using chHeapAlloc() then the block
- * is freed using chHeapFree(), must not fail.
- * - [3.2.2] Testing allocation failure.
+ * - [3.2.1] Adding the objects to the pool using
+ * chGuardedPoolLoadArray().
+ * - [3.2.2] Emptying the pool using chGuardedPoolAllocTimeout().
+ * - [3.2.3] Now must be empty.
+ * - [3.2.4] Adding the objects to the pool using chGuardedPoolFree().
+ * - [3.2.5] Emptying the pool using chGuardedPoolAllocTimeout() again.
+ * - [3.2.6] Now must be empty again.
* .
*/
+static void oslib_test_003_002_setup(void) {
+ chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
+}
+
static void oslib_test_003_002_execute(void) {
- void *p1;
- size_t total_size, largest_size;
+ unsigned i;
- /* [3.2.1] Single block allocation using chHeapAlloc() then the block
- is freed using chHeapFree(), must not fail.*/
+ /* [3.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);
}
- /* [3.2.2] Testing allocation failure.*/
+ /* [3.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");
+ }
+
+ /* [3.2.3] Now must be empty.*/
+ test_set_step(3);
+ {
+ test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
+ }
+
+ /* [3.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]);
+ }
+
+ /* [3.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");
+ }
+
+ /* [3.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 oslib_test_003_002 = {
- "Default Heap",
- NULL,
+ "Loading and emptying a guarded memory pool without waiting",
+ oslib_test_003_002_setup,
NULL,
oslib_test_003_002_execute
};
+#endif /* CH_CFG_USE_SEMAPHORES */
+
+#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
+/**
+ * @page oslib_test_003_003 [3.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>
+ * - [3.3.1] Trying to allocate with 100mS timeout, must fail because
+ * the pool is empty.
+ * .
+ */
+
+static void oslib_test_003_003_setup(void) {
+ chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
+}
+
+static void oslib_test_003_003_execute(void) {
+
+ /* [3.3.1] Trying to allocate with 100mS timeout, must fail because
+ the pool is empty.*/
+ test_set_step(1);
+ {
+ test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_MS2I(100)) == NULL, "list not empty");
+ }
+}
+
+static const testcase_t oslib_test_003_003 = {
+ "Guarded Memory Pools timeout",
+ oslib_test_003_003_setup,
+ NULL,
+ oslib_test_003_003_execute
+};
+#endif /* CH_CFG_USE_SEMAPHORES */
/****************************************************************************
* Exported data.
@@ -265,16 +283,21 @@ static const testcase_t oslib_test_003_002 = {
*/
const testcase_t * const oslib_test_sequence_003_array[] = {
&oslib_test_003_001,
+#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
&oslib_test_003_002,
+#endif
+#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
+ &oslib_test_003_003,
+#endif
NULL
};
/**
- * @brief Memory Heaps.
+ * @brief Memory Pools.
*/
const testsequence_t oslib_test_sequence_003 = {
- "Memory Heaps",
+ "Memory Pools",
oslib_test_sequence_003_array
};
-#endif /* CH_CFG_USE_HEAP */
+#endif /* CH_CFG_USE_MEMPOOLS */
diff --git a/test/oslib/source/test/oslib_test_sequence_004.c b/test/oslib/source/test/oslib_test_sequence_004.c
index a053008d8..84b466a64 100644
--- a/test/oslib/source/test/oslib_test_sequence_004.c
+++ b/test/oslib/source/test/oslib_test_sequence_004.c
@@ -21,725 +21,240 @@
* @file oslib_test_sequence_004.c
* @brief Test Sequence 004 code.
*
- * @page oslib_test_sequence_004 [4] Objects Factory
+ * @page oslib_test_sequence_004 [4] Memory Heaps
*
* File: @ref oslib_test_sequence_004.c
*
* <h2>Description</h2>
* This sequence tests the ChibiOS library functionalities related to
- * the object factory.
+ * memory heaps.
*
* <h2>Conditions</h2>
* This sequence is only executed if the following preprocessor condition
* evaluates to true:
- * - (CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE)
+ * - CH_CFG_USE_HEAP
* .
*
* <h2>Test Cases</h2>
* - @subpage oslib_test_004_001
* - @subpage oslib_test_004_002
- * - @subpage oslib_test_004_003
- * - @subpage oslib_test_004_004
- * - @subpage oslib_test_004_005
- * - @subpage oslib_test_004_006
* .
*/
-#if ((CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE)) || defined(__DOXYGEN__)
+#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
/****************************************************************************
* Shared code.
****************************************************************************/
+#define ALLOC_SIZE 16
+#define HEAP_SIZE (ALLOC_SIZE * 8)
+
+static memory_heap_t test_heap;
+static uint8_t test_heap_buffer[HEAP_SIZE];
/****************************************************************************
* Test cases.
****************************************************************************/
-#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXYGEN__)
/**
- * @page oslib_test_004_001 [4.1] Objects Registry
+ * @page oslib_test_004_001 [4.1] Allocation and fragmentation
*
* <h2>Description</h2>
- * This test case verifies the static objects registry.
- *
- * <h2>Conditions</h2>
- * This test is only executed if the following preprocessor condition
- * evaluates to true:
- * - CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE
- * .
+ * 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.
*
* <h2>Test Steps</h2>
- * - [4.1.1] Retrieving a registered object by name, must not exist.
- * - [4.1.2] Registering an object, it must not exists, must succeed.
- * - [4.1.3] Registering an object with the same name, must fail.
- * - [4.1.4] Retrieving the registered object by name, must exist, then
- * increasing the reference counter, finally releasing both
- * references.
- * - [4.1.5] Releasing the first reference to the object, must not
- * trigger an assertion.
- * - [4.1.6] Retrieving the registered object by name again, must not
- * exist.
+ * - [4.1.1] Testing initial conditions, the heap must not be
+ * fragmented and one free block present.
+ * - [4.1.2] Trying to allocate an block bigger than available space,
+ * an error is expected.
+ * - [4.1.3] Single block allocation using chHeapAlloc() then the block
+ * is freed using chHeapFree(), must not fail.
+ * - [4.1.4] Using chHeapStatus() to assess the heap state. There must
+ * be at least one free block of sufficient size.
+ * - [4.1.5] Allocating then freeing in the same order.
+ * - [4.1.6] Allocating then freeing in reverse order.
+ * - [4.1.7] Small fragments handling. Checking the behavior when
+ * allocating blocks with size not multiple of alignment unit.
+ * - [4.1.8] Skipping a fragment, the first fragment in the list is too
+ * small so the allocator must pick the second one.
+ * - [4.1.9] Allocating the whole available space.
+ * - [4.1.10] Testing final conditions. The heap geometry must be the
+ * same than the one registered at beginning.
* .
*/
-static void oslib_test_004_001_teardown(void) {
- registered_object_t *rop;
-
- rop = chFactoryFindObject("myobj");
- if (rop != NULL) {
- while (rop->element.refs > 0U) {
- chFactoryReleaseObject(rop);
- }
- }
+static void oslib_test_004_001_setup(void) {
+ chHeapObjectInit(&test_heap, test_heap_buffer, sizeof(test_heap_buffer));
}
static void oslib_test_004_001_execute(void) {
- registered_object_t *rop;
+ void *p1, *p2, *p3;
+ size_t n, sz;
- /* [4.1.1] Retrieving a registered object by name, must not exist.*/
+ /* [4.1.1] Testing initial conditions, the heap must not be
+ fragmented and one free block present.*/
test_set_step(1);
{
- rop = chFactoryFindObject("myobj");
- test_assert(rop == NULL, "found");
+ test_assert(chHeapStatus(&test_heap, &sz, NULL) == 1, "heap fragmented");
}
- /* [4.1.2] Registering an object, it must not exists, must succeed.*/
+ /* [4.1.2] Trying to allocate an block bigger than available space,
+ an error is expected.*/
test_set_step(2);
{
- static uint32_t myobj = 0x55aa;
-
- rop = chFactoryRegisterObject("myobj", (void *)&myobj);
- test_assert(rop != NULL, "cannot register");
+ p1 = chHeapAlloc(&test_heap, sizeof test_heap_buffer * 2);
+ test_assert(p1 == NULL, "allocation not failed");
}
- /* [4.1.3] Registering an object with the same name, must fail.*/
+ /* [4.1.3] Single block allocation using chHeapAlloc() then the block
+ is freed using chHeapFree(), must not fail.*/
test_set_step(3);
{
- registered_object_t *rop1;
- static uint32_t myobj = 0x55aa;
-
- rop1 = chFactoryRegisterObject("myobj", (void *)&myobj);
- test_assert(rop1 == NULL, "can register");
+ p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
+ test_assert(p1 != NULL, "allocation failed");
+ chHeapFree(p1);
}
- /* [4.1.4] Retrieving the registered object by name, must exist, then
- increasing the reference counter, finally releasing both
- references.*/
+ /* [4.1.4] Using chHeapStatus() to assess the heap state. There must
+ be at least one free block of sufficient size.*/
test_set_step(4);
{
- registered_object_t *rop1, *rop2;
-
- rop1 = chFactoryFindObject("myobj");
- test_assert(rop1 != NULL, "not found");
- test_assert(*(uint32_t *)(rop1->objp) == 0x55aa, "object mismatch");
- test_assert(rop == rop1, "object reference mismatch");
- test_assert(rop1->element.refs == 2, "object reference mismatch");
-
- rop2 = (registered_object_t *)chFactoryDuplicateReference(&rop1->element);
- test_assert(rop1 == rop2, "object reference mismatch");
- test_assert(*(uint32_t *)(rop2->objp) == 0x55aa, "object mismatch");
- test_assert(rop2->element.refs == 3, "object reference mismatch");
-
- chFactoryReleaseObject(rop2);
- test_assert(rop1->element.refs == 2, "references mismatch");
+ size_t total_size, largest_size;
- chFactoryReleaseObject(rop1);
- test_assert(rop->element.refs == 1, "references mismatch");
+ 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");
}
- /* [4.1.5] Releasing the first reference to the object, must not
- trigger an assertion.*/
+ /* [4.1.5] Allocating then freeing in the same order.*/
test_set_step(5);
{
- chFactoryReleaseObject(rop);
+ 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");
}
- /* [4.1.6] Retrieving the registered object by name again, must not
- exist.*/
+ /* [4.1.6] Allocating then freeing in reverse order.*/
test_set_step(6);
{
- rop = chFactoryFindObject("myobj");
- test_assert(rop == NULL, "found");
- }
-}
-
-static const testcase_t oslib_test_004_001 = {
- "Objects Registry",
- NULL,
- oslib_test_004_001_teardown,
- oslib_test_004_001_execute
-};
-#endif /* CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE */
-
-#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXYGEN__)
-/**
- * @page oslib_test_004_002 [4.2] Dynamic Buffers Factory
- *
- * <h2>Description</h2>
- * This test case verifies the dynamic buffers factory.
- *
- * <h2>Conditions</h2>
- * This test is only executed if the following preprocessor condition
- * evaluates to true:
- * - CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE
- * .
- *
- * <h2>Test Steps</h2>
- * - [4.2.1] Retrieving a dynamic buffer by name, must not exist.
- * - [4.2.2] Creating a dynamic buffer it must not exists, must
- * succeed.
- * - [4.2.3] Creating a dynamic buffer with the same name, must fail.
- * - [4.2.4] Retrieving the dynamic buffer by name, must exist, then
- * increasing the reference counter, finally releasing both
- * references.
- * - [4.2.5] Releasing the first reference to the dynamic buffer, must
- * not trigger an assertion.
- * - [4.2.6] Retrieving the dynamic buffer by name again, must not
- * exist.
- * .
- */
-
-static void oslib_test_004_002_teardown(void) {
- dyn_buffer_t *dbp;
-
- dbp = chFactoryFindBuffer("mybuf");
- if (dbp != NULL) {
- while (dbp->element.refs > 0U) {
- chFactoryReleaseBuffer(dbp);
- }
- }
-}
-
-static void oslib_test_004_002_execute(void) {
- dyn_buffer_t *dbp;
-
- /* [4.2.1] Retrieving a dynamic buffer by name, must not exist.*/
- test_set_step(1);
- {
- dbp = chFactoryFindBuffer("mybuf");
- test_assert(dbp == NULL, "found");
- }
-
- /* [4.2.2] Creating a dynamic buffer it must not exists, must
- succeed.*/
- test_set_step(2);
- {
- dbp = chFactoryCreateBuffer("mybuf", 128U);
- test_assert(dbp != NULL, "cannot create");
- }
-
- /* [4.2.3] Creating a dynamic buffer with the same name, must fail.*/
- test_set_step(3);
- {
- dyn_buffer_t *dbp1;
-
- dbp1 = chFactoryCreateBuffer("mybuf", 128U);
- test_assert(dbp1 == NULL, "can create");
- }
-
- /* [4.2.4] Retrieving the dynamic buffer by name, must exist, then
- increasing the reference counter, finally releasing both
- references.*/
- test_set_step(4);
- {
- dyn_buffer_t *dbp1, *dbp2;
-
- dbp1 = chFactoryFindBuffer("mybuf");
- test_assert(dbp1 != NULL, "not found");
- test_assert(dbp == dbp1, "object reference mismatch");
- test_assert(dbp1->element.refs == 2, "object reference mismatch");
-
- dbp2 = (dyn_buffer_t *)chFactoryDuplicateReference(&dbp1->element);
- test_assert(dbp1 == dbp2, "object reference mismatch");
- test_assert(dbp2->element.refs == 3, "object reference mismatch");
-
- chFactoryReleaseBuffer(dbp2);
- test_assert(dbp1->element.refs == 2, "references mismatch");
-
- chFactoryReleaseBuffer(dbp1);
- test_assert(dbp->element.refs == 1, "references mismatch");
- }
-
- /* [4.2.5] Releasing the first reference to the dynamic buffer, must
- not trigger an assertion.*/
- test_set_step(5);
- {
- chFactoryReleaseBuffer(dbp);
- }
-
- /* [4.2.6] Retrieving the dynamic buffer by name again, must not
- exist.*/
- test_set_step(6);
- {
- dbp = chFactoryFindBuffer("mybuf");
- test_assert(dbp == NULL, "found");
- }
-}
-
-static const testcase_t oslib_test_004_002 = {
- "Dynamic Buffers Factory",
- NULL,
- oslib_test_004_002_teardown,
- oslib_test_004_002_execute
-};
-#endif /* CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE */
-
-#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
-/**
- * @page oslib_test_004_003 [4.3] Dynamic Semaphores Factory
- *
- * <h2>Description</h2>
- * This test case verifies the dynamic semaphores factory.
- *
- * <h2>Conditions</h2>
- * This test is only executed if the following preprocessor condition
- * evaluates to true:
- * - CH_CFG_FACTORY_SEMAPHORES == TRUE
- * .
- *
- * <h2>Test Steps</h2>
- * - [4.3.1] Retrieving a dynamic semaphore by name, must not exist.
- * - [4.3.2] Creating a dynamic semaphore it must not exists, must
- * succeed.
- * - [4.3.3] Creating a dynamic semaphore with the same name, must
- * fail.
- * - [4.3.4] Retrieving the dynamic semaphore by name, must exist, then
- * increasing the reference counter, finally releasing both
- * references.
- * - [4.3.5] Releasing the first reference to the dynamic semaphore
- * must not trigger an assertion.
- * - [4.3.6] Retrieving the dynamic semaphore by name again, must not
- * exist.
- * .
- */
-
-static void oslib_test_004_003_teardown(void) {
- dyn_semaphore_t *dsp;
-
- dsp = chFactoryFindSemaphore("mysem");
- if (dsp != NULL) {
- while (dsp->element.refs > 0U) {
- chFactoryReleaseSemaphore(dsp);
- }
- }
-}
-
-static void oslib_test_004_003_execute(void) {
- dyn_semaphore_t *dsp;
-
- /* [4.3.1] Retrieving a dynamic semaphore by name, must not exist.*/
- test_set_step(1);
- {
- dsp = chFactoryFindSemaphore("mysem");
- test_assert(dsp == NULL, "found");
- }
-
- /* [4.3.2] Creating a dynamic semaphore it must not exists, must
- succeed.*/
- test_set_step(2);
- {
- dsp = chFactoryCreateSemaphore("mysem", 0);
- test_assert(dsp != NULL, "cannot create");
- }
-
- /* [4.3.3] Creating a dynamic semaphore with the same name, must
- fail.*/
- test_set_step(3);
- {
- dyn_semaphore_t *dsp1;
-
- dsp1 = chFactoryCreateSemaphore("mysem", 0);
- test_assert(dsp1 == NULL, "can create");
- }
-
- /* [4.3.4] Retrieving the dynamic semaphore by name, must exist, then
- increasing the reference counter, finally releasing both
- references.*/
- test_set_step(4);
- {
- dyn_semaphore_t *dsp1, *dsp2;
-
- dsp1 = chFactoryFindSemaphore("mysem");
- test_assert(dsp1 != NULL, "not found");
- test_assert(dsp == dsp1, "object reference mismatch");
- test_assert(dsp1->element.refs == 2, "object reference mismatch");
-
- dsp2 = (dyn_semaphore_t *)chFactoryDuplicateReference(&dsp1->element);
- test_assert(dsp1 == dsp2, "object reference mismatch");
- test_assert(dsp2->element.refs == 3, "object reference mismatch");
-
- chFactoryReleaseSemaphore(dsp2);
- test_assert(dsp1->element.refs == 2, "references mismatch");
-
- chFactoryReleaseSemaphore(dsp1);
- test_assert(dsp->element.refs == 1, "references mismatch");
- }
-
- /* [4.3.5] Releasing the first reference to the dynamic semaphore
- must not trigger an assertion.*/
- test_set_step(5);
- {
- chFactoryReleaseSemaphore(dsp);
- }
-
- /* [4.3.6] Retrieving the dynamic semaphore by name again, must not
- exist.*/
- test_set_step(6);
- {
- dsp = chFactoryFindSemaphore("mysem");
- test_assert(dsp == NULL, "found");
- }
-}
-
-static const testcase_t oslib_test_004_003 = {
- "Dynamic Semaphores Factory",
- NULL,
- oslib_test_004_003_teardown,
- oslib_test_004_003_execute
-};
-#endif /* CH_CFG_FACTORY_SEMAPHORES == TRUE */
-
-#if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXYGEN__)
-/**
- * @page oslib_test_004_004 [4.4] Dynamic Mailboxes Factory
- *
- * <h2>Description</h2>
- * This test case verifies the dynamic mailboxes factory.
- *
- * <h2>Conditions</h2>
- * This test is only executed if the following preprocessor condition
- * evaluates to true:
- * - CH_CFG_FACTORY_MAILBOXES == TRUE
- * .
- *
- * <h2>Test Steps</h2>
- * - [4.4.1] Retrieving a dynamic mailbox by name, must not exist.
- * - [4.4.2] Creating a dynamic mailbox it must not exists, must
- * succeed.
- * - [4.4.3] Creating a dynamic mailbox with the same name, must fail.
- * - [4.4.4] Retrieving the dynamic mailbox by name, must exist, then
- * increasing the reference counter, finally releasing both
- * references.
- * - [4.4.5] Releasing the first reference to the dynamic mailbox must
- * not trigger an assertion.
- * - [4.4.6] Retrieving the dynamic mailbox by name again, must not
- * exist.
- * .
- */
-
-static void oslib_test_004_004_teardown(void) {
- dyn_mailbox_t *dmp;
-
- dmp = chFactoryFindMailbox("mymbx");
- if (dmp != NULL) {
- while (dmp->element.refs > 0U) {
- chFactoryReleaseMailbox(dmp);
- }
- }
-}
-
-static void oslib_test_004_004_execute(void) {
- dyn_mailbox_t *dmp;
-
- /* [4.4.1] Retrieving a dynamic mailbox by name, must not exist.*/
- test_set_step(1);
- {
- dmp = chFactoryFindMailbox("mymbx");
- test_assert(dmp == NULL, "found");
+ 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");
}
- /* [4.4.2] Creating a dynamic mailbox it must not exists, must
- succeed.*/
- test_set_step(2);
+ /* [4.1.7] Small fragments handling. Checking the behavior when
+ allocating blocks with size not multiple of alignment unit.*/
+ test_set_step(7);
{
- dmp = chFactoryCreateMailbox("mymbx", 16U);
- test_assert(dmp != NULL, "cannot create");
+ 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");
}
- /* [4.4.3] Creating a dynamic mailbox with the same name, must
- fail.*/
- test_set_step(3);
- {
- dyn_mailbox_t *dmp1;
-
- dmp1 = chFactoryCreateMailbox("mymbx", 16U);
- test_assert(dmp1 == NULL, "can create");
- }
-
- /* [4.4.4] Retrieving the dynamic mailbox by name, must exist, then
- increasing the reference counter, finally releasing both
- references.*/
- test_set_step(4);
+ /* [4.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);
{
- dyn_mailbox_t *dmp1, *dmp2;
-
- dmp1 = chFactoryFindMailbox("mymbx");
- test_assert(dmp1 != NULL, "not found");
- test_assert(dmp == dmp1, "object reference mismatch");
- test_assert(dmp1->element.refs == 2, "object reference mismatch");
-
- dmp2 = (dyn_mailbox_t *)chFactoryDuplicateReference(&dmp1->element);
- test_assert(dmp1 == dmp2, "object reference mismatch");
- test_assert(dmp2->element.refs == 3, "object reference mismatch");
-
- chFactoryReleaseMailbox(dmp2);
- test_assert(dmp1->element.refs == 2, "references mismatch");
-
- chFactoryReleaseMailbox(dmp1);
- test_assert(dmp->element.refs == 1, "references mismatch");
+ 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");
}
- /* [4.4.5] Releasing the first reference to the dynamic mailbox must
- not trigger an assertion.*/
- test_set_step(5);
+ /* [4.1.9] Allocating the whole available space.*/
+ test_set_step(9);
{
- chFactoryReleaseMailbox(dmp);
+ (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);
}
- /* [4.4.6] Retrieving the dynamic mailbox by name again, must not
- exist.*/
- test_set_step(6);
+ /* [4.1.10] Testing final conditions. The heap geometry must be the
+ same than the one registered at beginning.*/
+ test_set_step(10);
{
- dmp = chFactoryFindMailbox("mymbx");
- test_assert(dmp == NULL, "found");
+ test_assert(chHeapStatus(&test_heap, &n, NULL) == 1, "heap fragmented");
+ test_assert(n == sz, "size changed");
}
}
-static const testcase_t oslib_test_004_004 = {
- "Dynamic Mailboxes Factory",
+static const testcase_t oslib_test_004_001 = {
+ "Allocation and fragmentation",
+ oslib_test_004_001_setup,
NULL,
- oslib_test_004_004_teardown,
- oslib_test_004_004_execute
+ oslib_test_004_001_execute
};
-#endif /* CH_CFG_FACTORY_MAILBOXES == TRUE */
-#if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__)
/**
- * @page oslib_test_004_005 [4.5] Dynamic Objects FIFOs Factory
+ * @page oslib_test_004_002 [4.2] Default Heap
*
* <h2>Description</h2>
- * This test case verifies the dynamic objects FIFOs factory.
- *
- * <h2>Conditions</h2>
- * This test is only executed if the following preprocessor condition
- * evaluates to true:
- * - CH_CFG_FACTORY_OBJ_FIFOS == TRUE
- * .
+ * The default heap is pre-allocated in the system. We test base
+ * functionality.
*
* <h2>Test Steps</h2>
- * - [4.5.1] Retrieving a dynamic objects FIFO by name, must not exist.
- * - [4.5.2] Creating a dynamic objects FIFO it must not exists, must
- * succeed.
- * - [4.5.3] Creating a dynamic objects FIFO with the same name, must
- * fail.
- * - [4.5.4] Retrieving the dynamic objects FIFO by name, must exist,
- * then increasing the reference counter, finally releasing both
- * references.
- * - [4.5.5] Releasing the first reference to the dynamic objects FIFO
- * must not trigger an assertion.
- * - [4.5.6] Retrieving the dynamic objects FIFO by name again, must
- * not exist.
+ * - [4.2.1] Single block allocation using chHeapAlloc() then the block
+ * is freed using chHeapFree(), must not fail.
+ * - [4.2.2] Testing allocation failure.
* .
*/
-static void oslib_test_004_005_teardown(void) {
- dyn_objects_fifo_t *dofp;
-
- dofp = chFactoryFindObjectsFIFO("myfifo");
- if (dofp != NULL) {
- while (dofp->element.refs > 0U) {
- chFactoryReleaseObjectsFIFO(dofp);
- }
- }
-}
-
-static void oslib_test_004_005_execute(void) {
- dyn_objects_fifo_t *dofp;
+static void oslib_test_004_002_execute(void) {
+ void *p1;
+ size_t total_size, largest_size;
- /* [4.5.1] Retrieving a dynamic objects FIFO by name, must not
- exist.*/
+ /* [4.2.1] Single block allocation using chHeapAlloc() then the block
+ is freed using chHeapFree(), must not fail.*/
test_set_step(1);
{
- dofp = chFactoryFindObjectsFIFO("myfifo");
- test_assert(dofp == NULL, "found");
+ (void)chHeapStatus(NULL, &total_size, &largest_size);
+ p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
+ test_assert(p1 != NULL, "allocation failed");
+ chHeapFree(p1);
}
- /* [4.5.2] Creating a dynamic objects FIFO it must not exists, must
- succeed.*/
+ /* [4.2.2] Testing allocation failure.*/
test_set_step(2);
{
- dofp = chFactoryCreateObjectsFIFO("myfifo", 16U, 16U, PORT_NATURAL_ALIGN);
- test_assert(dofp != NULL, "cannot create");
- }
-
- /* [4.5.3] Creating a dynamic objects FIFO with the same name, must
- fail.*/
- test_set_step(3);
- {
- dyn_objects_fifo_t *dofp1;
-
- dofp1 = chFactoryCreateObjectsFIFO("myfifo", 16U, 16U, PORT_NATURAL_ALIGN);
- test_assert(dofp1 == NULL, "can create");
- }
-
- /* [4.5.4] Retrieving the dynamic objects FIFO by name, must exist,
- then increasing the reference counter, finally releasing both
- references.*/
- test_set_step(4);
- {
- dyn_objects_fifo_t *dofp1, *dofp2;
-
- dofp1 = chFactoryFindObjectsFIFO("myfifo");
- test_assert(dofp1 != NULL, "not found");
- test_assert(dofp == dofp1, "object reference mismatch");
- test_assert(dofp1->element.refs == 2, "object reference mismatch");
-
- dofp2 = (dyn_objects_fifo_t *)chFactoryDuplicateReference(&dofp1->element);
- test_assert(dofp1 == dofp2, "object reference mismatch");
- test_assert(dofp2->element.refs == 3, "object reference mismatch");
-
- chFactoryReleaseObjectsFIFO(dofp2);
- test_assert(dofp1->element.refs == 2, "references mismatch");
-
- chFactoryReleaseObjectsFIFO(dofp1);
- test_assert(dofp->element.refs == 1, "references mismatch");
- }
-
- /* [4.5.5] Releasing the first reference to the dynamic objects FIFO
- must not trigger an assertion.*/
- test_set_step(5);
- {
- chFactoryReleaseObjectsFIFO(dofp);
- }
-
- /* [4.5.6] Retrieving the dynamic objects FIFO by name again, must
- not exist.*/
- test_set_step(6);
- {
- dofp = chFactoryFindObjectsFIFO("myfifo");
- test_assert(dofp == NULL, "found");
+ p1 = chHeapAlloc(NULL, (size_t)-256);
+ test_assert(p1 == NULL, "allocation not failed");
}
}
-static const testcase_t oslib_test_004_005 = {
- "Dynamic Objects FIFOs Factory",
+static const testcase_t oslib_test_004_002 = {
+ "Default Heap",
NULL,
- oslib_test_004_005_teardown,
- oslib_test_004_005_execute
-};
-#endif /* CH_CFG_FACTORY_OBJ_FIFOS == TRUE */
-
-#if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXYGEN__)
-/**
- * @page oslib_test_004_006 [4.6] Dynamic Pipes Factory
- *
- * <h2>Description</h2>
- * This test case verifies the dynamic pipes factory.
- *
- * <h2>Conditions</h2>
- * This test is only executed if the following preprocessor condition
- * evaluates to true:
- * - CH_CFG_FACTORY_PIPES == TRUE
- * .
- *
- * <h2>Test Steps</h2>
- * - [4.6.1] Retrieving a dynamic pipe by name, must not exist.
- * - [4.6.2] Creating a dynamic pipe it must not exists, must succeed.
- * - [4.6.3] Creating a dynamic pipe with the same name, must fail.
- * - [4.6.4] Retrieving the dynamic pipe by name, must exist, then
- * increasing the reference counter, finally releasing both
- * references.
- * - [4.6.5] Releasing the first reference to the dynamic pipe must not
- * trigger an assertion.
- * - [4.6.6] Retrieving the dynamic pipe by name again, must not exist.
- * .
- */
-
-static void oslib_test_004_006_teardown(void) {
- dyn_pipe_t *dpp;
-
- dpp = chFactoryFindPipe("mypipe");
- if (dpp != NULL) {
- while (dpp->element.refs > 0U) {
- chFactoryReleasePipe(dpp);
- }
- }
-}
-
-static void oslib_test_004_006_execute(void) {
- dyn_pipe_t *dpp;
-
- /* [4.6.1] Retrieving a dynamic pipe by name, must not exist.*/
- test_set_step(1);
- {
- dpp = chFactoryFindPipe("mypipe");
- test_assert(dpp == NULL, "found");
- }
-
- /* [4.6.2] Creating a dynamic pipe it must not exists, must
- succeed.*/
- test_set_step(2);
- {
- dpp = chFactoryCreatePipe("mypipe", 16U);
- test_assert(dpp != NULL, "cannot create");
- }
-
- /* [4.6.3] Creating a dynamic pipe with the same name, must fail.*/
- test_set_step(3);
- {
- dyn_pipe_t *dpp1;
-
- dpp1 = chFactoryCreatePipe("mypipe", 16U);
- test_assert(dpp1 == NULL, "can create");
- }
-
- /* [4.6.4] Retrieving the dynamic pipe by name, must exist, then
- increasing the reference counter, finally releasing both
- references.*/
- test_set_step(4);
- {
- dyn_pipe_t *dpp1, *dpp2;
-
- dpp1 = chFactoryFindPipe("mypipe");
- test_assert(dpp1 != NULL, "not found");
- test_assert(dpp == dpp1, "object reference mismatch");
- test_assert(dpp1->element.refs == 2, "object reference mismatch");
-
- dpp2 = (dyn_pipe_t *)chFactoryDuplicateReference(&dpp1->element);
- test_assert(dpp1 == dpp2, "object reference mismatch");
- test_assert(dpp2->element.refs == 3, "object reference mismatch");
-
- chFactoryReleasePipe(dpp2);
- test_assert(dpp1->element.refs == 2, "references mismatch");
-
- chFactoryReleasePipe(dpp1);
- test_assert(dpp->element.refs == 1, "references mismatch");
- }
-
- /* [4.6.5] Releasing the first reference to the dynamic pipe must not
- trigger an assertion.*/
- test_set_step(5);
- {
- chFactoryReleasePipe(dpp);
- }
-
- /* [4.6.6] Retrieving the dynamic pipe by name again, must not
- exist.*/
- test_set_step(6);
- {
- dpp = chFactoryFindPipe("mypipe");
- test_assert(dpp == NULL, "found");
- }
-}
-
-static const testcase_t oslib_test_004_006 = {
- "Dynamic Pipes Factory",
NULL,
- oslib_test_004_006_teardown,
- oslib_test_004_006_execute
+ oslib_test_004_002_execute
};
-#endif /* CH_CFG_FACTORY_PIPES == TRUE */
/****************************************************************************
* Exported data.
@@ -749,33 +264,17 @@ static const testcase_t oslib_test_004_006 = {
* @brief Array of test cases.
*/
const testcase_t * const oslib_test_sequence_004_array[] = {
-#if (CH_CFG_FACTORY_OBJECTS_REGISTRY == TRUE) || defined(__DOXYGEN__)
&oslib_test_004_001,
-#endif
-#if (CH_CFG_FACTORY_GENERIC_BUFFERS == TRUE) || defined(__DOXYGEN__)
&oslib_test_004_002,
-#endif
-#if (CH_CFG_FACTORY_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
- &oslib_test_004_003,
-#endif
-#if (CH_CFG_FACTORY_MAILBOXES == TRUE) || defined(__DOXYGEN__)
- &oslib_test_004_004,
-#endif
-#if (CH_CFG_FACTORY_OBJ_FIFOS == TRUE) || defined(__DOXYGEN__)
- &oslib_test_004_005,
-#endif
-#if (CH_CFG_FACTORY_PIPES == TRUE) || defined(__DOXYGEN__)
- &oslib_test_004_006,
-#endif
NULL
};
/**
- * @brief Objects Factory.
+ * @brief Memory Heaps.
*/
const testsequence_t oslib_test_sequence_004 = {
- "Objects Factory",
+ "Memory Heaps",
oslib_test_sequence_004_array
};
-#endif /* (CH_CFG_USE_FACTORY == TRUE) && (CH_CFG_USE_MEMPOOLS == TRUE) && (CH_CFG_USE_HEAP == TRUE) */
+#endif /* CH_CFG_USE_HEAP */