aboutsummaryrefslogtreecommitdiffstats
path: root/test/oslib/source
diff options
context:
space:
mode:
Diffstat (limited to 'test/oslib/source')
-rw-r--r--test/oslib/source/test/oslib_test_root.c80
-rw-r--r--test/oslib/source/test/oslib_test_root.h43
-rw-r--r--test/oslib/source/test/oslib_test_sequence_001.c565
-rw-r--r--test/oslib/source/test/oslib_test_sequence_002.c345
-rw-r--r--test/oslib/source/test/oslib_test_sequence_003.c297
-rw-r--r--test/oslib/source/test/oslib_test_sequence_004.c279
-rw-r--r--test/oslib/source/test/oslib_test_sequence_004.h27
7 files changed, 489 insertions, 1147 deletions
diff --git a/test/oslib/source/test/oslib_test_root.c b/test/oslib/source/test/oslib_test_root.c
index 675595015..5c88edd75 100644
--- a/test/oslib/source/test/oslib_test_root.c
+++ b/test/oslib/source/test/oslib_test_root.c
@@ -24,7 +24,6 @@
* - @subpage oslib_test_sequence_001
* - @subpage oslib_test_sequence_002
* - @subpage oslib_test_sequence_003
- * - @subpage oslib_test_sequence_004
* .
*/
@@ -46,17 +45,14 @@
* @brief Array of test sequences.
*/
const testsequence_t * const oslib_test_suite_array[] = {
-#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
- &oslib_test_sequence_001,
-#endif
#if (CH_CFG_USE_MAILBOXES) || defined(__DOXYGEN__)
- &oslib_test_sequence_002,
+ &oslib_test_sequence_001,
#endif
#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
- &oslib_test_sequence_003,
+ &oslib_test_sequence_002,
#endif
#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
- &oslib_test_sequence_004,
+ &oslib_test_sequence_003,
#endif
NULL
};
@@ -73,74 +69,4 @@ const testsuite_t oslib_test_suite = {
/* Shared code. */
/*===========================================================================*/
-void test_print_port_info(void) {
-
-#ifdef PORT_COMPILER_NAME
- test_print("*** Compiler: ");
- test_println(PORT_COMPILER_NAME);
-#endif
- test_print("*** Architecture: ");
- test_println(PORT_ARCHITECTURE_NAME);
-#ifdef PORT_CORE_VARIANT_NAME
- test_print("*** Core Variant: ");
- test_println(PORT_CORE_VARIANT_NAME);
-#endif
-#ifdef PORT_INFO
- test_print("*** Port Info: ");
- test_println(PORT_INFO);
-#endif
-}
-
-/*
- * Global test buffer holding 5 working areas.
- */
-ALIGNED_VAR(PORT_WORKING_AREA_ALIGN) uint8_t test_buffer[WA_SIZE * 5];
-
-/*
- * Pointers to the spawned threads.
- */
-thread_t *threads[MAX_THREADS];
-
-/*
- * Pointers to the working areas.
- */
-void * ROMCONST wa[5] = {test_buffer + (WA_SIZE * 0),
- test_buffer + (WA_SIZE * 1),
- test_buffer + (WA_SIZE * 2),
- test_buffer + (WA_SIZE * 3),
- test_buffer + (WA_SIZE * 4)};
-
-/*
- * Sets a termination request in all the test-spawned threads.
- */
-void test_terminate_threads(void) {
- unsigned i;
-
- for (i = 0; i < MAX_THREADS; i++)
- if (threads[i])
- chThdTerminate(threads[i]);
-}
-
-/*
- * Waits for the completion of all the test-spawned threads.
- */
-void test_wait_threads(void) {
- unsigned i;
-
- for (i = 0; i < MAX_THREADS; i++)
- if (threads[i] != NULL) {
- chThdWait(threads[i]);
- threads[i] = NULL;
- }
-}
-
-/*
- * Delays execution until next system time tick.
- */
-systime_t test_wait_tick(void) {
-
- chThdSleep(1);
- return chVTGetSystemTime();
-}
-
#endif /* !defined(__DOXYGEN__) */
diff --git a/test/oslib/source/test/oslib_test_root.h b/test/oslib/source/test/oslib_test_root.h
index fe823f874..6fa8fe58e 100644
--- a/test/oslib/source/test/oslib_test_root.h
+++ b/test/oslib/source/test/oslib_test_root.h
@@ -27,7 +27,6 @@
#include "oslib_test_sequence_001.h"
#include "oslib_test_sequence_002.h"
#include "oslib_test_sequence_003.h"
-#include "oslib_test_sequence_004.h"
#if !defined(__DOXYGEN__)
@@ -48,48 +47,6 @@ extern "C" {
/* Shared definitions. */
/*===========================================================================*/
-#define TEST_SUITE_NAME "ChibiOS/RT Test Suite"
-
-/*
- * Allowed delay in timeout checks.
- */
-#define ALLOWED_DELAY TIME_MS2I(2)
-
-/*
- * Maximum number of test threads.
- */
-#define MAX_THREADS 5
-
-/*
- * Stack size of test threads.
- */
-#if defined(CH_ARCHITECTURE_AVR) || defined(CH_ARCHITECTURE_MSP430)
-#define THREADS_STACK_SIZE 48
-#elif defined(CH_ARCHITECTURE_STM8)
-#define THREADS_STACK_SIZE 64
-#elif defined(CH_ARCHITECTURE_SIMIA32)
-#define THREADS_STACK_SIZE 512
-#else
-#define THREADS_STACK_SIZE 128
-#endif
-
-/*
- * Working Area size of test threads.
- */
-#define WA_SIZE MEM_ALIGN_NEXT(THD_WORKING_AREA_SIZE(THREADS_STACK_SIZE), \
- PORT_WORKING_AREA_ALIGN)
-
-#define TEST_REPORT_HOOK_HEADER test_print_port_info();
-
-extern uint8_t test_buffer[WA_SIZE * 5];
-extern thread_t *threads[MAX_THREADS];
-extern void * ROMCONST wa[5];
-
-void test_print_port_info(void);
-void test_terminate_threads(void);
-void test_wait_threads(void);
-systime_t test_wait_tick(void);
-
#endif /* !defined(__DOXYGEN__) */
#endif /* OSLIB_TEST_ROOT_H */
diff --git a/test/oslib/source/test/oslib_test_sequence_001.c b/test/oslib/source/test/oslib_test_sequence_001.c
index 49264f5d5..e03831c8d 100644
--- a/test/oslib/source/test/oslib_test_sequence_001.c
+++ b/test/oslib/source/test/oslib_test_sequence_001.c
@@ -21,470 +21,374 @@
* @file oslib_test_sequence_001.c
* @brief Test Sequence 001 code.
*
- * @page oslib_test_sequence_001 [1] Binary Semaphores
+ * @page oslib_test_sequence_001 [1] Mailboxes
*
* File: @ref oslib_test_sequence_001.c
*
* <h2>Description</h2>
- * This sequence tests the ChibiOS library functionalities related to
- * binary semaphores.
+ * This sequence tests the ChibiOS libraryfunctionalities related to
+ * mailboxes.
*
* <h2>Conditions</h2>
* This sequence is only executed if the following preprocessor condition
* evaluates to true:
- * - CH_CFG_USE_SEMAPHORES
+ * - CH_CFG_USE_MAILBOXES
* .
*
* <h2>Test Cases</h2>
* - @subpage oslib_test_001_001
* - @subpage oslib_test_001_002
* - @subpage oslib_test_001_003
- * - @subpage oslib_test_001_004
- * - @subpage oslib_test_001_005
- * - @subpage oslib_test_001_006
* .
*/
-#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
+#if (CH_CFG_USE_MAILBOXES) || defined(__DOXYGEN__)
/****************************************************************************
* Shared code.
****************************************************************************/
-#include "ch.h"
+#define MB_SIZE 4
-static semaphore_t sem1;
-
-static THD_FUNCTION(thread1, p) {
-
- chSemWait(&sem1);
- test_emit_token(*(char *)p);
-}
-
-static THD_FUNCTION(thread2, p) {
-
- (void)p;
- chThdSleepMilliseconds(50);
- chSysLock();
- chSemSignalI(&sem1); /* For coverage reasons */
- chSchRescheduleS();
- chSysUnlock();
-}
-
-static THD_FUNCTION(thread3, p) {
-
- (void)p;
- chSemWait(&sem1);
- chSemSignal(&sem1);
-}
-
-static THD_FUNCTION(thread4, p) {
-
- chBSemSignal((binary_semaphore_t *)p);
-}
+static msg_t mb_buffer[MB_SIZE];
+static MAILBOX_DECL(mb1, mb_buffer, MB_SIZE);
/****************************************************************************
* Test cases.
****************************************************************************/
/**
- * @page oslib_test_001_001 [1.1] Semaphore primitives, no state change
+ * @page oslib_test_001_001 [1.1] Mailbox normal API, non-blocking tests
*
* <h2>Description</h2>
- * Wait, Signal and Reset primitives are tested. The testing thread
- * does not trigger a state change.
+ * The mailbox normal API is tested without triggering blocking
+ * conditions.
*
* <h2>Test Steps</h2>
- * - [1.1.1] The function chSemWait() is invoked, after return the
- * counter and the returned message are tested.
- * - [1.1.2] The function chSemSignal() is invoked, after return the
- * counter is tested.
- * - [1.1.3] The function chSemReset() is invoked, after return the
- * counter is tested.
+ * - [1.1.1] Testing the mailbox size.
+ * - [1.1.2] Resetting the mailbox, conditions are checked, no errors
+ * expected.
+ * - [1.1.3] Testing the behavior of API when the mailbox is in reset
+ * state then return in active state.
+ * - [1.1.4] Filling the mailbox using chMBPostTimeout() and
+ * chMBPostAheadTimeout() once, no errors expected.
+ * - [1.1.5] Testing intermediate conditions. Data pointers must be
+ * aligned, semaphore counters are checked.
+ * - [1.1.6] Emptying the mailbox using chMBFetchTimeout(), no errors
+ * expected.
+ * - [1.1.7] Posting and then fetching one more message, no errors
+ * expected.
+ * - [1.1.8] Testing final conditions. Data pointers must be aligned to
+ * buffer start, semaphore counters are checked.
* .
*/
static void oslib_test_001_001_setup(void) {
- chSemObjectInit(&sem1, 1);
+ chMBObjectInit(&mb1, mb_buffer, MB_SIZE);
}
static void oslib_test_001_001_teardown(void) {
- chSemReset(&sem1, 0);
+ chMBReset(&mb1);
}
static void oslib_test_001_001_execute(void) {
+ msg_t msg1, msg2;
+ unsigned i;
- /* [1.1.1] The function chSemWait() is invoked, after return the
- counter and the returned message are tested.*/
+ /* [1.1.1] Testing the mailbox size.*/
test_set_step(1);
{
- msg_t msg;
-
- msg = chSemWait(&sem1);
- test_assert_lock(chSemGetCounterI(&sem1) == 0, "wrong counter value");
- test_assert(MSG_OK == msg, "wrong returned message");
+ test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "wrong size");
}
- /* [1.1.2] The function chSemSignal() is invoked, after return the
- counter is tested.*/
+ /* [1.1.2] Resetting the mailbox, conditions are checked, no errors
+ expected.*/
test_set_step(2);
{
- chSemSignal(&sem1);
- test_assert_lock(chSemGetCounterI(&sem1) == 1, "wrong counter value");
+ chMBReset(&mb1);
+ test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
+ test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
+ test_assert_lock(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
+ test_assert_lock(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
}
- /* [1.1.3] The function chSemReset() is invoked, after return the
- counter is tested.*/
+ /* [1.1.3] Testing the behavior of API when the mailbox is in reset
+ state then return in active state.*/
test_set_step(3);
{
- chSemReset(&sem1, 2);
- test_assert_lock(chSemGetCounterI(&sem1) == 2, "wrong counter value");
+ msg1 = chMBPostTimeout(&mb1, (msg_t)0, TIME_INFINITE);
+ test_assert(msg1 == MSG_RESET, "not in reset state");
+ msg1 = chMBPostAheadTimeout(&mb1, (msg_t)0, TIME_INFINITE);
+ test_assert(msg1 == MSG_RESET, "not in reset state");
+ msg1 = chMBFetchTimeout(&mb1, &msg2, TIME_INFINITE);
+ test_assert(msg1 == MSG_RESET, "not in reset state");
+ chMBResumeX(&mb1);
}
-}
-
-static const testcase_t oslib_test_001_001 = {
- "Semaphore primitives, no state change",
- oslib_test_001_001_setup,
- oslib_test_001_001_teardown,
- oslib_test_001_001_execute
-};
-
-/**
- * @page oslib_test_001_002 [1.2] Semaphore enqueuing test
- *
- * <h2>Description</h2>
- * Five threads with randomized priorities are enqueued to a semaphore
- * then awakened one at time. The test expects that the threads reach
- * their goal in FIFO order or priority order depending on the @p
- * CH_CFG_USE_SEMAPHORES_PRIORITY configuration setting.
- *
- * <h2>Test Steps</h2>
- * - [1.2.1] Five threads are created with mixed priority levels (not
- * increasing nor decreasing). Threads enqueue on a semaphore
- * initialized to zero.
- * - [1.2.2] The semaphore is signaled 5 times. The thread activation
- * sequence is tested.
- * .
- */
-
-static void oslib_test_001_002_setup(void) {
- chSemObjectInit(&sem1, 0);
-}
-
-static void oslib_test_001_002_execute(void) {
- /* [1.2.1] Five threads are created with mixed priority levels (not
- increasing nor decreasing). Threads enqueue on a semaphore
- initialized to zero.*/
- test_set_step(1);
+ /* [1.1.4] Filling the mailbox using chMBPostTimeout() and
+ chMBPostAheadTimeout() once, no errors expected.*/
+ test_set_step(4);
{
- threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+5, thread1, "A");
- threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()+1, thread1, "B");
- threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()+3, thread1, "C");
- threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()+4, thread1, "D");
- threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()+2, thread1, "E");
+ for (i = 0; i < MB_SIZE - 1; i++) {
+ msg1 = chMBPostTimeout(&mb1, 'B' + i, TIME_INFINITE);
+ test_assert(msg1 == MSG_OK, "wrong wake-up message");
+ }
+ msg1 = chMBPostAheadTimeout(&mb1, 'A', TIME_INFINITE);
+ test_assert(msg1 == MSG_OK, "wrong wake-up message");
}
- /* [1.2.2] The semaphore is signaled 5 times. The thread activation
- sequence is tested.*/
- test_set_step(2);
+ /* [1.1.5] Testing intermediate conditions. Data pointers must be
+ aligned, semaphore counters are checked.*/
+ test_set_step(5);
{
- chSemSignal(&sem1);
- chSemSignal(&sem1);
- chSemSignal(&sem1);
- chSemSignal(&sem1);
- chSemSignal(&sem1);
- test_wait_threads();
-#if CH_CFG_USE_SEMAPHORES_PRIORITY
- test_assert_sequence("ADCEB", "invalid sequence");
-#else
- test_assert_sequence("ABCDE", "invalid sequence");
-#endif
+ test_assert_lock(chMBGetFreeCountI(&mb1) == 0, "still empty");
+ test_assert_lock(chMBGetUsedCountI(&mb1) == MB_SIZE, "not full");
+ test_assert_lock(mb1.rdptr == mb1.wrptr, "pointers not aligned");
}
-}
-
-static const testcase_t oslib_test_001_002 = {
- "Semaphore enqueuing test",
- oslib_test_001_002_setup,
- NULL,
- oslib_test_001_002_execute
-};
-
-/**
- * @page oslib_test_001_003 [1.3] Semaphore timeout test
- *
- * <h2>Description</h2>
- * The three possible semaphore waiting modes (do not wait, wait with
- * timeout, wait without timeout) are explored. The test expects that
- * the semaphore wait function returns the correct value in each of the
- * above scenario and that the semaphore structure status is correct
- * after each operation.
- *
- * <h2>Test Steps</h2>
- * - [1.3.1] Testing special case TIME_IMMEDIATE.
- * - [1.3.2] Testing non-timeout condition.
- * - [1.3.3] Testing timeout condition.
- * .
- */
-
-static void oslib_test_001_003_setup(void) {
- chSemObjectInit(&sem1, 0);
-}
-
-static void oslib_test_001_003_execute(void) {
- unsigned i;
- systime_t target_time;
- msg_t msg;
- /* [1.3.1] Testing special case TIME_IMMEDIATE.*/
- test_set_step(1);
+ /* [1.1.6] Emptying the mailbox using chMBFetchTimeout(), no errors
+ expected.*/
+ test_set_step(6);
{
- msg = chSemWaitTimeout(&sem1, TIME_IMMEDIATE);
- test_assert(msg == MSG_TIMEOUT, "wrong wake-up message");
- test_assert(queue_isempty(&sem1.queue), "queue not empty");
- test_assert(sem1.cnt == 0, "counter not zero");
+ for (i = 0; i < MB_SIZE; i++) {
+ msg1 = chMBFetchTimeout(&mb1, &msg2, TIME_INFINITE);
+ test_assert(msg1 == MSG_OK, "wrong wake-up message");
+ test_emit_token(msg2);
+ }
+ test_assert_sequence("ABCD", "wrong get sequence");
}
- /* [1.3.2] Testing non-timeout condition.*/
- test_set_step(2);
+ /* [1.1.7] Posting and then fetching one more message, no errors
+ expected.*/
+ test_set_step(7);
{
- threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX() - 1,
- thread2, 0);
- msg = chSemWaitTimeout(&sem1, TIME_MS2I(500));
- test_wait_threads();
- test_assert(msg == MSG_OK, "wrong wake-up message");
- test_assert(queue_isempty(&sem1.queue), "queue not empty");
- test_assert(sem1.cnt == 0, "counter not zero");
+ msg1 = chMBPostTimeout(&mb1, 'B' + i, TIME_INFINITE);
+ test_assert(msg1 == MSG_OK, "wrong wake-up message");
+ msg1 = chMBFetchTimeout(&mb1, &msg2, TIME_INFINITE);
+ test_assert(msg1 == MSG_OK, "wrong wake-up message");
}
- /* [1.3.3] Testing timeout condition.*/
- test_set_step(3);
+ /* [1.1.8] Testing final conditions. Data pointers must be aligned to
+ buffer start, semaphore counters are checked.*/
+ test_set_step(8);
{
- target_time = test_wait_tick() + TIME_MS2I(5 * 50);
- for (i = 0; i < 5; i++) {
- test_emit_token('A' + i);
- msg = chSemWaitTimeout(&sem1, TIME_MS2I(50));
- test_assert(msg == MSG_TIMEOUT, "wrong wake-up message");
- test_assert(queue_isempty(&sem1.queue), "queue not empty");
- test_assert(sem1.cnt == 0, "counter not zero");
- }
- test_assert_sequence("ABCDE", "invalid sequence");
- test_assert_time_window(target_time, target_time + ALLOWED_DELAY,
- "out of time window");
+ test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
+ test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
+ test_assert(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
+ test_assert(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
}
}
-static const testcase_t oslib_test_001_003 = {
- "Semaphore timeout test",
- oslib_test_001_003_setup,
- NULL,
- oslib_test_001_003_execute
+static const testcase_t oslib_test_001_001 = {
+ "Mailbox normal API, non-blocking tests",
+ oslib_test_001_001_setup,
+ oslib_test_001_001_teardown,
+ oslib_test_001_001_execute
};
/**
- * @page oslib_test_001_004 [1.4] Testing chSemAddCounterI() functionality
+ * @page oslib_test_001_002 [1.2] Mailbox I-Class API, non-blocking tests
*
* <h2>Description</h2>
- * The functon is tested by waking up a thread then the semaphore
- * counter value is tested.
+ * The mailbox I-Class API is tested without triggering blocking
+ * conditions.
*
* <h2>Test Steps</h2>
- * - [1.4.1] A thread is created, it goes to wait on the semaphore.
- * - [1.4.2] The semaphore counter is increased by two, it is then
- * tested to be one, the thread must have completed.
+ * - [1.2.1] Testing the mailbox size.
+ * - [1.2.2] Resetting the mailbox, conditions are checked, no errors
+ * expected. The mailbox is then returned in active state.
+ * - [1.2.3] Filling the mailbox using chMBPostI() and chMBPostAheadI()
+ * once, no errors expected.
+ * - [1.2.4] Testing intermediate conditions. Data pointers must be
+ * aligned, semaphore counters are checked.
+ * - [1.2.5] Emptying the mailbox using chMBFetchI(), no errors
+ * expected.
+ * - [1.2.6] Posting and then fetching one more message, no errors
+ * expected.
+ * - [1.2.7] Testing final conditions. Data pointers must be aligned to
+ * buffer start, semaphore counters are checked.
* .
*/
-static void oslib_test_001_004_setup(void) {
- chSemObjectInit(&sem1, 0);
+static void oslib_test_001_002_setup(void) {
+ chMBObjectInit(&mb1, mb_buffer, MB_SIZE);
}
-static void oslib_test_001_004_execute(void) {
+static void oslib_test_001_002_teardown(void) {
+ chMBReset(&mb1);
+}
- /* [1.4.1] A thread is created, it goes to wait on the semaphore.*/
+static void oslib_test_001_002_execute(void) {
+ msg_t msg1, msg2;
+ unsigned i;
+
+ /* [1.2.1] Testing the mailbox size.*/
test_set_step(1);
{
- threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, thread1, "A");
+ test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "wrong size");
}
- /* [1.4.2] The semaphore counter is increased by two, it is then
- tested to be one, the thread must have completed.*/
+ /* [1.2.2] Resetting the mailbox, conditions are checked, no errors
+ expected. The mailbox is then returned in active state.*/
test_set_step(2);
{
chSysLock();
- chSemAddCounterI(&sem1, 2);
- chSchRescheduleS();
+ chMBResetI(&mb1);
chSysUnlock();
- test_wait_threads();
- test_assert_lock(chSemGetCounterI(&sem1) == 1, "invalid counter");
- test_assert_sequence("A", "invalid sequence");
+ test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
+ test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
+ test_assert_lock(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
+ test_assert_lock(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
+ chMBResumeX(&mb1);
}
-}
-
-static const testcase_t oslib_test_001_004 = {
- "Testing chSemAddCounterI() functionality",
- oslib_test_001_004_setup,
- NULL,
- oslib_test_001_004_execute
-};
-
-/**
- * @page oslib_test_001_005 [1.5] Testing chSemWaitSignal() functionality
- *
- * <h2>Description</h2>
- * This test case explicitly addresses the @p chSemWaitSignal()
- * function. A thread is created that performs a wait and a signal
- * operations. The tester thread is awakened from an atomic wait/signal
- * operation. The test expects that the semaphore wait function returns
- * the correct value in each of the above scenario and that the
- * semaphore structure status is correct after each operation.
- *
- * <h2>Test Steps</h2>
- * - [1.5.1] An higher priority thread is created that performs
- * non-atomical wait and signal operations on a semaphore.
- * - [1.5.2] The function chSemSignalWait() is invoked by specifying
- * the same semaphore for the wait and signal phases. The counter
- * value must be one on exit.
- * - [1.5.3] The function chSemSignalWait() is invoked again by
- * specifying the same semaphore for the wait and signal phases. The
- * counter value must be one on exit.
- * .
- */
-
-static void oslib_test_001_005_setup(void) {
- chSemObjectInit(&sem1, 0);
-}
-static void oslib_test_001_005_teardown(void) {
- test_wait_threads();
-}
+ /* [1.2.3] Filling the mailbox using chMBPostI() and chMBPostAheadI()
+ once, no errors expected.*/
+ test_set_step(3);
+ {
+ for (i = 0; i < MB_SIZE - 1; i++) {
+ chSysLock();
+ msg1 = chMBPostI(&mb1, 'B' + i);
+ chSysUnlock();
+ test_assert(msg1 == MSG_OK, "wrong wake-up message");
+ }
+ chSysLock();
+ msg1 = chMBPostAheadI(&mb1, 'A');
+ chSysUnlock();
+ test_assert(msg1 == MSG_OK, "wrong wake-up message");
+ }
-static void oslib_test_001_005_execute(void) {
+ /* [1.2.4] Testing intermediate conditions. Data pointers must be
+ aligned, semaphore counters are checked.*/
+ test_set_step(4);
+ {
+ test_assert_lock(chMBGetFreeCountI(&mb1) == 0, "still empty");
+ test_assert_lock(chMBGetUsedCountI(&mb1) == MB_SIZE, "not full");
+ test_assert_lock(mb1.rdptr == mb1.wrptr, "pointers not aligned");
+ }
- /* [1.5.1] An higher priority thread is created that performs
- non-atomical wait and signal operations on a semaphore.*/
- test_set_step(1);
+ /* [1.2.5] Emptying the mailbox using chMBFetchI(), no errors
+ expected.*/
+ test_set_step(5);
{
- threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, thread3, 0);
+ for (i = 0; i < MB_SIZE; i++) {
+ chSysLock();
+ msg1 = chMBFetchI(&mb1, &msg2);
+ chSysUnlock();
+ test_assert(msg1 == MSG_OK, "wrong wake-up message");
+ test_emit_token(msg2);
+ }
+ test_assert_sequence("ABCD", "wrong get sequence");
}
- /* [1.5.2] The function chSemSignalWait() is invoked by specifying
- the same semaphore for the wait and signal phases. The counter
- value must be one on exit.*/
- test_set_step(2);
+ /* [1.2.6] Posting and then fetching one more message, no errors
+ expected.*/
+ test_set_step(6);
{
- chSemSignalWait(&sem1, &sem1);
- test_assert(queue_isempty(&sem1.queue), "queue not empty");
- test_assert(sem1.cnt == 0, "counter not zero");
+ msg1 = chMBPostTimeout(&mb1, 'B' + i, TIME_INFINITE);
+ test_assert(msg1 == MSG_OK, "wrong wake-up message");
+ msg1 = chMBFetchTimeout(&mb1, &msg2, TIME_INFINITE);
+ test_assert(msg1 == MSG_OK, "wrong wake-up message");
}
- /* [1.5.3] The function chSemSignalWait() is invoked again by
- specifying the same semaphore for the wait and signal phases. The
- counter value must be one on exit.*/
- test_set_step(3);
+ /* [1.2.7] Testing final conditions. Data pointers must be aligned to
+ buffer start, semaphore counters are checked.*/
+ test_set_step(7);
{
- chSemSignalWait(&sem1, &sem1);
- test_assert(queue_isempty(&sem1.queue), "queue not empty");
- test_assert(sem1.cnt == 0, "counter not zero");
+ test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
+ test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
+ test_assert(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
+ test_assert(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
}
}
-static const testcase_t oslib_test_001_005 = {
- "Testing chSemWaitSignal() functionality",
- oslib_test_001_005_setup,
- oslib_test_001_005_teardown,
- oslib_test_001_005_execute
+static const testcase_t oslib_test_001_002 = {
+ "Mailbox I-Class API, non-blocking tests",
+ oslib_test_001_002_setup,
+ oslib_test_001_002_teardown,
+ oslib_test_001_002_execute
};
/**
- * @page oslib_test_001_006 [1.6] Testing Binary Semaphores special case
+ * @page oslib_test_001_003 [1.3] Mailbox timeouts
*
* <h2>Description</h2>
- * This test case tests the binary semaphores functionality. The test
- * both checks the binary semaphore status and the expected status of
- * the underlying counting semaphore.
+ * The mailbox API is tested for timeouts.
*
* <h2>Test Steps</h2>
- * - [1.6.1] Creating a binary semaphore in "taken" state, the state is
- * checked.
- * - [1.6.2] Resetting the binary semaphore in "taken" state, the state
- * must not change.
- * - [1.6.3] Starting a signaler thread at a lower priority.
- * - [1.6.4] Waiting for the binary semaphore to be signaled, the
- * semaphore is expected to be taken.
- * - [1.6.5] Signaling the binary semaphore, checking the binary
- * semaphore state to be "not taken" and the underlying counter
- * semaphore counter to be one.
- * - [1.6.6] Signaling the binary semaphore again, the internal state
- * must not change from "not taken".
+ * - [1.3.1] Filling the mailbox.
+ * - [1.3.2] Testing chMBPostTimeout(), chMBPostI(),
+ * chMBPostAheadTimeout() and chMBPostAheadI() timeout.
+ * - [1.3.3] Resetting the mailbox. The mailbox is then returned in
+ * active state.
+ * - [1.3.4] Testing chMBFetchTimeout() and chMBFetchI() timeout.
* .
*/
-static void oslib_test_001_006_teardown(void) {
- test_wait_threads();
+static void oslib_test_001_003_setup(void) {
+ chMBObjectInit(&mb1, mb_buffer, MB_SIZE);
+}
+
+static void oslib_test_001_003_teardown(void) {
+ chMBReset(&mb1);
}
-static void oslib_test_001_006_execute(void) {
- binary_semaphore_t bsem;
- msg_t msg;
+static void oslib_test_001_003_execute(void) {
+ msg_t msg1, msg2;
+ unsigned i;
- /* [1.6.1] Creating a binary semaphore in "taken" state, the state is
- checked.*/
+ /* [1.3.1] Filling the mailbox.*/
test_set_step(1);
{
- chBSemObjectInit(&bsem, true);
- test_assert_lock(chBSemGetStateI(&bsem) == true, "not taken");
+ for (i = 0; i < MB_SIZE; i++) {
+ msg1 = chMBPostTimeout(&mb1, 'B' + i, TIME_INFINITE);
+ test_assert(msg1 == MSG_OK, "wrong wake-up message");
+ }
}
- /* [1.6.2] Resetting the binary semaphore in "taken" state, the state
- must not change.*/
+ /* [1.3.2] Testing chMBPostTimeout(), chMBPostI(),
+ chMBPostAheadTimeout() and chMBPostAheadI() timeout.*/
test_set_step(2);
{
- chBSemReset(&bsem, true);
- test_assert_lock(chBSemGetStateI(&bsem) == true, "not taken");
+ msg1 = chMBPostTimeout(&mb1, 'X', 1);
+ test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
+ chSysLock();
+ msg1 = chMBPostI(&mb1, 'X');
+ chSysUnlock();
+ test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
+ msg1 = chMBPostAheadTimeout(&mb1, 'X', 1);
+ test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
+ chSysLock();
+ msg1 = chMBPostAheadI(&mb1, 'X');
+ chSysUnlock();
+ test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
}
- /* [1.6.3] Starting a signaler thread at a lower priority.*/
+ /* [1.3.3] Resetting the mailbox. The mailbox is then returned in
+ active state.*/
test_set_step(3);
{
- threads[0] = chThdCreateStatic(wa[0], WA_SIZE,
- chThdGetPriorityX()-1, thread4, &bsem);
+ chMBReset(&mb1);
+ chMBResumeX(&mb1);
}
- /* [1.6.4] Waiting for the binary semaphore to be signaled, the
- semaphore is expected to be taken.*/
+ /* [1.3.4] Testing chMBFetchTimeout() and chMBFetchI() timeout.*/
test_set_step(4);
{
- msg = chBSemWait(&bsem);
- test_assert_lock(chBSemGetStateI(&bsem) == true, "not taken");
- test_assert(msg == MSG_OK, "unexpected message");
- }
-
- /* [1.6.5] Signaling the binary semaphore, checking the binary
- semaphore state to be "not taken" and the underlying counter
- semaphore counter to be one.*/
- test_set_step(5);
- {
- chBSemSignal(&bsem);
- test_assert_lock(chBSemGetStateI(&bsem) ==false, "still taken");
- test_assert_lock(chSemGetCounterI(&bsem.sem) == 1, "unexpected counter");
- }
-
- /* [1.6.6] Signaling the binary semaphore again, the internal state
- must not change from "not taken".*/
- test_set_step(6);
- {
- chBSemSignal(&bsem);
- test_assert_lock(chBSemGetStateI(&bsem) == false, "taken");
- test_assert_lock(chSemGetCounterI(&bsem.sem) == 1, "unexpected counter");
+ msg1 = chMBFetchTimeout(&mb1, &msg2, 1);
+ test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
+ chSysLock();
+ msg1 = chMBFetchI(&mb1, &msg2);
+ chSysUnlock();
+ test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
}
}
-static const testcase_t oslib_test_001_006 = {
- "Testing Binary Semaphores special case",
- NULL,
- oslib_test_001_006_teardown,
- oslib_test_001_006_execute
+static const testcase_t oslib_test_001_003 = {
+ "Mailbox timeouts",
+ oslib_test_001_003_setup,
+ oslib_test_001_003_teardown,
+ oslib_test_001_003_execute
};
/****************************************************************************
@@ -498,18 +402,15 @@ const testcase_t * const oslib_test_sequence_001_array[] = {
&oslib_test_001_001,
&oslib_test_001_002,
&oslib_test_001_003,
- &oslib_test_001_004,
- &oslib_test_001_005,
- &oslib_test_001_006,
NULL
};
/**
- * @brief Binary Semaphores.
+ * @brief Mailboxes.
*/
const testsequence_t oslib_test_sequence_001 = {
NULL,
oslib_test_sequence_001_array
};
-#endif /* CH_CFG_USE_SEMAPHORES */
+#endif /* CH_CFG_USE_MAILBOXES */
diff --git a/test/oslib/source/test/oslib_test_sequence_002.c b/test/oslib/source/test/oslib_test_sequence_002.c
index 5b4f10859..75c9d8a1d 100644
--- a/test/oslib/source/test/oslib_test_sequence_002.c
+++ b/test/oslib/source/test/oslib_test_sequence_002.c
@@ -21,18 +21,18 @@
* @file oslib_test_sequence_002.c
* @brief Test Sequence 002 code.
*
- * @page oslib_test_sequence_002 [2] Mailboxes
+ * @page oslib_test_sequence_002 [2] Memory Pools
*
* File: @ref oslib_test_sequence_002.c
*
* <h2>Description</h2>
- * This sequence tests the ChibiOS libraryfunctionalities related to
- * mailboxes.
+ * This sequence tests the ChibiOS library functionalities related to
+ * memory pools.
*
* <h2>Conditions</h2>
* This sequence is only executed if the following preprocessor condition
* evaluates to true:
- * - CH_CFG_USE_MAILBOXES
+ * - CH_CFG_USE_MEMPOOLS
* .
*
* <h2>Test Cases</h2>
@@ -42,354 +42,237 @@
* .
*/
-#if (CH_CFG_USE_MAILBOXES) || defined(__DOXYGEN__)
+#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
/****************************************************************************
* Shared code.
****************************************************************************/
-#define MB_SIZE 4
+#define MEMORY_POOL_SIZE 4
-static msg_t mb_buffer[MB_SIZE];
-static MAILBOX_DECL(mb1, mb_buffer, MB_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_002_001 [2.1] Mailbox normal API, non-blocking tests
+ * @page oslib_test_002_001 [2.1] Loading and emptying a memory pool
*
* <h2>Description</h2>
- * The mailbox normal API is tested without triggering blocking
- * conditions.
+ * The memory pool functionality is tested by loading and emptying it,
+ * all conditions are tested.
*
* <h2>Test Steps</h2>
- * - [2.1.1] Testing the mailbox size.
- * - [2.1.2] Resetting the mailbox, conditions are checked, no errors
- * expected.
- * - [2.1.3] Testing the behavior of API when the mailbox is in reset
- * state then return in active state.
- * - [2.1.4] Filling the mailbox using chMBPostTimeout() and
- * chMBPostAheadTimeout() once, no errors expected.
- * - [2.1.5] Testing intermediate conditions. Data pointers must be
- * aligned, semaphore counters are checked.
- * - [2.1.6] Emptying the mailbox using chMBFetchTimeout(), no errors
- * expected.
- * - [2.1.7] Posting and then fetching one more message, no errors
- * expected.
- * - [2.1.8] Testing final conditions. Data pointers must be aligned to
- * buffer start, semaphore counters are checked.
+ * - [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.
* .
*/
static void oslib_test_002_001_setup(void) {
- chMBObjectInit(&mb1, mb_buffer, MB_SIZE);
-}
-
-static void oslib_test_002_001_teardown(void) {
- chMBReset(&mb1);
+ chPoolObjectInit(&mp1, sizeof (uint32_t), NULL);
}
static void oslib_test_002_001_execute(void) {
- msg_t msg1, msg2;
unsigned i;
- /* [2.1.1] Testing the mailbox size.*/
+ /* [2.1.1] Adding the objects to the pool using chPoolLoadArray().*/
test_set_step(1);
{
- test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "wrong size");
+ chPoolLoadArray(&mp1, objects, MEMORY_POOL_SIZE);
}
- /* [2.1.2] Resetting the mailbox, conditions are checked, no errors
- expected.*/
+ /* [2.1.2] Emptying the pool using chPoolAlloc().*/
test_set_step(2);
{
- chMBReset(&mb1);
- test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
- test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
- test_assert_lock(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
- test_assert_lock(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
+ test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
}
- /* [2.1.3] Testing the behavior of API when the mailbox is in reset
- state then return in active state.*/
+ /* [2.1.3] Now must be empty.*/
test_set_step(3);
{
- msg1 = chMBPostTimeout(&mb1, (msg_t)0, TIME_INFINITE);
- test_assert(msg1 == MSG_RESET, "not in reset state");
- msg1 = chMBPostAheadTimeout(&mb1, (msg_t)0, TIME_INFINITE);
- test_assert(msg1 == MSG_RESET, "not in reset state");
- msg1 = chMBFetchTimeout(&mb1, &msg2, TIME_INFINITE);
- test_assert(msg1 == MSG_RESET, "not in reset state");
- chMBResumeX(&mb1);
+ test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
}
- /* [2.1.4] Filling the mailbox using chMBPostTimeout() and
- chMBPostAheadTimeout() once, no errors expected.*/
+ /* [2.1.4] Adding the objects to the pool using chPoolFree().*/
test_set_step(4);
{
- for (i = 0; i < MB_SIZE - 1; i++) {
- msg1 = chMBPostTimeout(&mb1, 'B' + i, TIME_INFINITE);
- test_assert(msg1 == MSG_OK, "wrong wake-up message");
- }
- msg1 = chMBPostAheadTimeout(&mb1, 'A', TIME_INFINITE);
- test_assert(msg1 == MSG_OK, "wrong wake-up message");
+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
+ chPoolFree(&mp1, &objects[i]);
}
- /* [2.1.5] Testing intermediate conditions. Data pointers must be
- aligned, semaphore counters are checked.*/
+ /* [2.1.5] Emptying the pool using chPoolAlloc() again.*/
test_set_step(5);
{
- test_assert_lock(chMBGetFreeCountI(&mb1) == 0, "still empty");
- test_assert_lock(chMBGetUsedCountI(&mb1) == MB_SIZE, "not full");
- test_assert_lock(mb1.rdptr == mb1.wrptr, "pointers not aligned");
+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
+ test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
}
- /* [2.1.6] Emptying the mailbox using chMBFetchTimeout(), no errors
- expected.*/
+ /* [2.1.6] Now must be empty again.*/
test_set_step(6);
{
- for (i = 0; i < MB_SIZE; i++) {
- msg1 = chMBFetchTimeout(&mb1, &msg2, TIME_INFINITE);
- test_assert(msg1 == MSG_OK, "wrong wake-up message");
- test_emit_token(msg2);
- }
- test_assert_sequence("ABCD", "wrong get sequence");
+ test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
}
- /* [2.1.7] Posting and then fetching one more message, no errors
- expected.*/
+ /* [2.1.7] Covering the case where a provider is unable to return
+ more memory.*/
test_set_step(7);
{
- msg1 = chMBPostTimeout(&mb1, 'B' + i, TIME_INFINITE);
- test_assert(msg1 == MSG_OK, "wrong wake-up message");
- msg1 = chMBFetchTimeout(&mb1, &msg2, TIME_INFINITE);
- test_assert(msg1 == MSG_OK, "wrong wake-up message");
- }
-
- /* [2.1.8] Testing final conditions. Data pointers must be aligned to
- buffer start, semaphore counters are checked.*/
- test_set_step(8);
- {
- test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
- test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
- test_assert(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
- test_assert(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
+ chPoolObjectInit(&mp1, sizeof (uint32_t), null_provider);
+ test_assert(chPoolAlloc(&mp1) == NULL, "provider returned memory");
}
}
static const testcase_t oslib_test_002_001 = {
- "Mailbox normal API, non-blocking tests",
+ "Loading and emptying a memory pool",
oslib_test_002_001_setup,
- oslib_test_002_001_teardown,
+ NULL,
oslib_test_002_001_execute
};
+#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
/**
- * @page oslib_test_002_002 [2.2] Mailbox I-Class API, non-blocking tests
+ * @page oslib_test_002_002 [2.2] Loading and emptying a guarded memory pool without waiting
*
* <h2>Description</h2>
- * The mailbox I-Class API is tested without triggering blocking
- * conditions.
+ * 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] Testing the mailbox size.
- * - [2.2.2] Resetting the mailbox, conditions are checked, no errors
- * expected. The mailbox is then returned in active state.
- * - [2.2.3] Filling the mailbox using chMBPostI() and chMBPostAheadI()
- * once, no errors expected.
- * - [2.2.4] Testing intermediate conditions. Data pointers must be
- * aligned, semaphore counters are checked.
- * - [2.2.5] Emptying the mailbox using chMBFetchI(), no errors
- * expected.
- * - [2.2.6] Posting and then fetching one more message, no errors
- * expected.
- * - [2.2.7] Testing final conditions. Data pointers must be aligned to
- * buffer start, semaphore counters are checked.
+ * - [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) {
- chMBObjectInit(&mb1, mb_buffer, MB_SIZE);
-}
-
-static void oslib_test_002_002_teardown(void) {
- chMBReset(&mb1);
+ chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
}
static void oslib_test_002_002_execute(void) {
- msg_t msg1, msg2;
unsigned i;
- /* [2.2.1] Testing the mailbox size.*/
+ /* [2.2.1] Adding the objects to the pool using
+ chGuardedPoolLoadArray().*/
test_set_step(1);
{
- test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "wrong size");
+ chGuardedPoolLoadArray(&gmp1, objects, MEMORY_POOL_SIZE);
}
- /* [2.2.2] Resetting the mailbox, conditions are checked, no errors
- expected. The mailbox is then returned in active state.*/
+ /* [2.2.2] Emptying the pool using chGuardedPoolAllocTimeout().*/
test_set_step(2);
{
- chSysLock();
- chMBResetI(&mb1);
- chSysUnlock();
- test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
- test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
- test_assert_lock(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
- test_assert_lock(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
- chMBResumeX(&mb1);
+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
+ test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
}
- /* [2.2.3] Filling the mailbox using chMBPostI() and chMBPostAheadI()
- once, no errors expected.*/
+ /* [2.2.3] Now must be empty.*/
test_set_step(3);
{
- for (i = 0; i < MB_SIZE - 1; i++) {
- chSysLock();
- msg1 = chMBPostI(&mb1, 'B' + i);
- chSysUnlock();
- test_assert(msg1 == MSG_OK, "wrong wake-up message");
- }
- chSysLock();
- msg1 = chMBPostAheadI(&mb1, 'A');
- chSysUnlock();
- test_assert(msg1 == MSG_OK, "wrong wake-up message");
+ test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
}
- /* [2.2.4] Testing intermediate conditions. Data pointers must be
- aligned, semaphore counters are checked.*/
+ /* [2.2.4] Adding the objects to the pool using
+ chGuardedPoolFree().*/
test_set_step(4);
{
- test_assert_lock(chMBGetFreeCountI(&mb1) == 0, "still empty");
- test_assert_lock(chMBGetUsedCountI(&mb1) == MB_SIZE, "not full");
- test_assert_lock(mb1.rdptr == mb1.wrptr, "pointers not aligned");
+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
+ chGuardedPoolFree(&gmp1, &objects[i]);
}
- /* [2.2.5] Emptying the mailbox using chMBFetchI(), no errors
- expected.*/
+ /* [2.2.5] Emptying the pool using chGuardedPoolAllocTimeout()
+ again.*/
test_set_step(5);
{
- for (i = 0; i < MB_SIZE; i++) {
- chSysLock();
- msg1 = chMBFetchI(&mb1, &msg2);
- chSysUnlock();
- test_assert(msg1 == MSG_OK, "wrong wake-up message");
- test_emit_token(msg2);
- }
- test_assert_sequence("ABCD", "wrong get sequence");
+ for (i = 0; i < MEMORY_POOL_SIZE; i++)
+ test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
}
- /* [2.2.6] Posting and then fetching one more message, no errors
- expected.*/
+ /* [2.2.6] Now must be empty again.*/
test_set_step(6);
{
- msg1 = chMBPostTimeout(&mb1, 'B' + i, TIME_INFINITE);
- test_assert(msg1 == MSG_OK, "wrong wake-up message");
- msg1 = chMBFetchTimeout(&mb1, &msg2, TIME_INFINITE);
- test_assert(msg1 == MSG_OK, "wrong wake-up message");
- }
-
- /* [2.2.7] Testing final conditions. Data pointers must be aligned to
- buffer start, semaphore counters are checked.*/
- test_set_step(7);
- {
- test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "not empty");
- test_assert_lock(chMBGetUsedCountI(&mb1) == 0, "still full");
- test_assert(mb1.buffer == mb1.wrptr, "write pointer not aligned to base");
- test_assert(mb1.buffer == mb1.rdptr, "read pointer not aligned to base");
+ test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
}
}
static const testcase_t oslib_test_002_002 = {
- "Mailbox I-Class API, non-blocking tests",
+ "Loading and emptying a guarded memory pool without waiting",
oslib_test_002_002_setup,
- oslib_test_002_002_teardown,
+ 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] Mailbox timeouts
+ * @page oslib_test_002_003 [2.3] Guarded Memory Pools timeout
*
* <h2>Description</h2>
- * The mailbox API is tested for timeouts.
+ * 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] Filling the mailbox.
- * - [2.3.2] Testing chMBPostTimeout(), chMBPostI(),
- * chMBPostAheadTimeout() and chMBPostAheadI() timeout.
- * - [2.3.3] Resetting the mailbox. The mailbox is then returned in
- * active state.
- * - [2.3.4] Testing chMBFetchTimeout() and chMBFetchI() timeout.
+ * - [2.3.1] Trying to allocate with 100mS timeout, must fail because
+ * the pool is empty.
* .
*/
static void oslib_test_002_003_setup(void) {
- chMBObjectInit(&mb1, mb_buffer, MB_SIZE);
-}
-
-static void oslib_test_002_003_teardown(void) {
- chMBReset(&mb1);
+ chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
}
static void oslib_test_002_003_execute(void) {
- msg_t msg1, msg2;
- unsigned i;
- /* [2.3.1] Filling the mailbox.*/
+ /* [2.3.1] Trying to allocate with 100mS timeout, must fail because
+ the pool is empty.*/
test_set_step(1);
{
- for (i = 0; i < MB_SIZE; i++) {
- msg1 = chMBPostTimeout(&mb1, 'B' + i, TIME_INFINITE);
- test_assert(msg1 == MSG_OK, "wrong wake-up message");
- }
- }
-
- /* [2.3.2] Testing chMBPostTimeout(), chMBPostI(),
- chMBPostAheadTimeout() and chMBPostAheadI() timeout.*/
- test_set_step(2);
- {
- msg1 = chMBPostTimeout(&mb1, 'X', 1);
- test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
- chSysLock();
- msg1 = chMBPostI(&mb1, 'X');
- chSysUnlock();
- test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
- msg1 = chMBPostAheadTimeout(&mb1, 'X', 1);
- test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
- chSysLock();
- msg1 = chMBPostAheadI(&mb1, 'X');
- chSysUnlock();
- test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
- }
-
- /* [2.3.3] Resetting the mailbox. The mailbox is then returned in
- active state.*/
- test_set_step(3);
- {
- chMBReset(&mb1);
- chMBResumeX(&mb1);
- }
-
- /* [2.3.4] Testing chMBFetchTimeout() and chMBFetchI() timeout.*/
- test_set_step(4);
- {
- msg1 = chMBFetchTimeout(&mb1, &msg2, 1);
- test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
- chSysLock();
- msg1 = chMBFetchI(&mb1, &msg2);
- chSysUnlock();
- test_assert(msg1 == MSG_TIMEOUT, "wrong wake-up message");
+ test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_MS2I(100)) == NULL, "list not empty");
}
}
static const testcase_t oslib_test_002_003 = {
- "Mailbox timeouts",
+ "Guarded Memory Pools timeout",
oslib_test_002_003_setup,
- oslib_test_002_003_teardown,
+ NULL,
oslib_test_002_003_execute
};
+#endif /* CH_CFG_USE_SEMAPHORES */
/****************************************************************************
* Exported data.
@@ -400,17 +283,21 @@ 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 Mailboxes.
+ * @brief Memory Pools.
*/
const testsequence_t oslib_test_sequence_002 = {
NULL,
oslib_test_sequence_002_array
};
-#endif /* CH_CFG_USE_MAILBOXES */
+#endif /* CH_CFG_USE_MEMPOOLS */
diff --git a/test/oslib/source/test/oslib_test_sequence_003.c b/test/oslib/source/test/oslib_test_sequence_003.c
index c103873ac..806cd2706 100644
--- a/test/oslib/source/test/oslib_test_sequence_003.c
+++ b/test/oslib/source/test/oslib_test_sequence_003.c
@@ -21,258 +21,240 @@
* @file oslib_test_sequence_003.c
* @brief Test Sequence 003 code.
*
- * @page oslib_test_sequence_003 [3] Memory Pools
+ * @page oslib_test_sequence_003 [3] Memory Heaps
*
* File: @ref oslib_test_sequence_003.c
*
* <h2>Description</h2>
* This sequence tests the ChibiOS library functionalities related to
- * memory pools.
+ * memory heaps.
*
* <h2>Conditions</h2>
* This sequence is only executed if the following preprocessor condition
* evaluates to true:
- * - CH_CFG_USE_MEMPOOLS
+ * - CH_CFG_USE_HEAP
* .
*
* <h2>Test Cases</h2>
* - @subpage oslib_test_003_001
* - @subpage oslib_test_003_002
- * - @subpage oslib_test_003_003
* .
*/
-#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
+#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
/****************************************************************************
* Shared code.
****************************************************************************/
-#define MEMORY_POOL_SIZE 4
+#define ALLOC_SIZE 16
+#define HEAP_SIZE (ALLOC_SIZE * 8)
-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;
-}
+static memory_heap_t test_heap;
+static uint8_t test_heap_buffer[HEAP_SIZE];
/****************************************************************************
* Test cases.
****************************************************************************/
/**
- * @page oslib_test_003_001 [3.1] Loading and emptying a memory pool
+ * @page oslib_test_003_001 [3.1] Allocation and fragmentation
*
* <h2>Description</h2>
- * The memory pool functionality is tested by loading and emptying it,
- * all conditions are tested.
+ * 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>
- * - [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.
+ * - [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.
* .
*/
static void oslib_test_003_001_setup(void) {
- chPoolObjectInit(&mp1, sizeof (uint32_t), NULL);
+ chHeapObjectInit(&test_heap, test_heap_buffer, sizeof(test_heap_buffer));
}
static void oslib_test_003_001_execute(void) {
- unsigned i;
+ void *p1, *p2, *p3;
+ size_t n, sz;
- /* [3.1.1] Adding the objects to the pool using chPoolLoadArray().*/
+ /* [3.1.1] Testing initial conditions, the heap must not be
+ fragmented and one free block present.*/
test_set_step(1);
{
- chPoolLoadArray(&mp1, objects, MEMORY_POOL_SIZE);
+ test_assert(chHeapStatus(&test_heap, &sz, NULL) == 1, "heap fragmented");
}
- /* [3.1.2] Emptying the pool using chPoolAlloc().*/
+ /* [3.1.2] Trying to allocate an block bigger than available space,
+ an error is expected.*/
test_set_step(2);
{
- for (i = 0; i < MEMORY_POOL_SIZE; i++)
- test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
+ p1 = chHeapAlloc(&test_heap, sizeof test_heap_buffer * 2);
+ test_assert(p1 == NULL, "allocation not failed");
}
- /* [3.1.3] Now must be empty.*/
+ /* [3.1.3] Single block allocation using chHeapAlloc() then the block
+ is freed using chHeapFree(), must not fail.*/
test_set_step(3);
{
- test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
+ p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
+ test_assert(p1 != NULL, "allocation failed");
+ chHeapFree(p1);
}
- /* [3.1.4] Adding the objects to the pool using chPoolFree().*/
+ /* [3.1.4] Using chHeapStatus() to assess the heap state. There must
+ be at least one free block of sufficient size.*/
test_set_step(4);
{
- for (i = 0; i < MEMORY_POOL_SIZE; i++)
- chPoolFree(&mp1, &objects[i]);
+ 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");
}
- /* [3.1.5] Emptying the pool using chPoolAlloc() again.*/
+ /* [3.1.5] Allocating then freeing in the same order.*/
test_set_step(5);
{
- for (i = 0; i < MEMORY_POOL_SIZE; i++)
- test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
+ 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");
}
- /* [3.1.6] Now must be empty again.*/
+ /* [3.1.6] Allocating then freeing in reverse order.*/
test_set_step(6);
{
- test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
+ 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");
}
- /* [3.1.7] Covering the case where a provider is unable to return
- more memory.*/
+ /* [3.1.7] Small fragments handling. Checking the behavior when
+ allocating blocks with size not multiple of alignment unit.*/
test_set_step(7);
{
- chPoolObjectInit(&mp1, sizeof (uint32_t), null_provider);
- test_assert(chPoolAlloc(&mp1) == NULL, "provider returned memory");
+ 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");
}
}
static const testcase_t oslib_test_003_001 = {
- "Loading and emptying a memory pool",
+ "Allocation and fragmentation",
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] Loading and emptying a guarded memory pool without waiting
+ * @page oslib_test_003_002 [3.2] Default Heap
*
* <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
- * .
+ * The default heap is pre-allocated in the system. We test base
+ * functionality.
*
* <h2>Test Steps</h2>
- * - [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.
+ * - [3.2.1] Single block allocation using chHeapAlloc() then the block
+ * is freed using chHeapFree(), must not fail.
+ * - [3.2.2] Testing allocation failure.
* .
*/
-static void oslib_test_003_002_setup(void) {
- chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
-}
-
static void oslib_test_003_002_execute(void) {
- unsigned i;
+ void *p1;
+ size_t total_size, largest_size;
- /* [3.2.1] Adding the objects to the pool using
- chGuardedPoolLoadArray().*/
+ /* [3.2.1] Single block allocation using chHeapAlloc() then the block
+ is freed using chHeapFree(), must not fail.*/
test_set_step(1);
{
- chGuardedPoolLoadArray(&gmp1, objects, MEMORY_POOL_SIZE);
+ (void)chHeapStatus(NULL, &total_size, &largest_size);
+ p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
+ test_assert(p1 != NULL, "allocation failed");
+ chHeapFree(p1);
}
- /* [3.2.2] Emptying the pool using chGuardedPoolAllocTimeout().*/
+ /* [3.2.2] Testing allocation failure.*/
test_set_step(2);
{
- 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");
+ p1 = chHeapAlloc(NULL, (size_t)-256);
+ test_assert(p1 == NULL, "allocation not failed");
}
}
static const testcase_t oslib_test_003_002 = {
- "Loading and emptying a guarded memory pool without waiting",
- oslib_test_003_002_setup,
+ "Default Heap",
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
+ oslib_test_003_002_execute
};
-#endif /* CH_CFG_USE_SEMAPHORES */
/****************************************************************************
* Exported data.
@@ -283,21 +265,16 @@ static const testcase_t oslib_test_003_003 = {
*/
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 Pools.
+ * @brief Memory Heaps.
*/
const testsequence_t oslib_test_sequence_003 = {
NULL,
oslib_test_sequence_003_array
};
-#endif /* CH_CFG_USE_MEMPOOLS */
+#endif /* CH_CFG_USE_HEAP */
diff --git a/test/oslib/source/test/oslib_test_sequence_004.c b/test/oslib/source/test/oslib_test_sequence_004.c
deleted file mode 100644
index cceae6958..000000000
--- a/test/oslib/source/test/oslib_test_sequence_004.c
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-#include "hal.h"
-#include "oslib_test_root.h"
-
-/**
- * @file oslib_test_sequence_004.c
- * @brief Test Sequence 004 code.
- *
- * @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
- * memory heaps.
- *
- * <h2>Conditions</h2>
- * This sequence is only executed if the following preprocessor condition
- * evaluates to true:
- * - CH_CFG_USE_HEAP
- * .
- *
- * <h2>Test Cases</h2>
- * - @subpage oslib_test_004_001
- * - @subpage oslib_test_004_002
- * .
- */
-
-#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
-
-/****************************************************************************
- * Shared code.
- ****************************************************************************/
-
-#define ALLOC_SIZE 16
-#define HEAP_SIZE (ALLOC_SIZE * 8)
-
-memory_heap_t test_heap;
-
-/****************************************************************************
- * Test cases.
- ****************************************************************************/
-
-/**
- * @page oslib_test_004_001 [4.1] Allocation and fragmentation
- *
- * <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.
- *
- * <h2>Test Steps</h2>
- * - [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_setup(void) {
- chHeapObjectInit(&test_heap, test_buffer, sizeof(test_buffer));
-}
-
-static void oslib_test_004_001_execute(void) {
- void *p1, *p2, *p3;
- size_t n, sz;
-
- /* [4.1.1] Testing initial conditions, the heap must not be
- fragmented and one free block present.*/
- test_set_step(1);
- {
- test_assert(chHeapStatus(&test_heap, &sz, NULL) == 1, "heap fragmented");
- }
-
- /* [4.1.2] Trying to allocate an block bigger than available space,
- an error is expected.*/
- test_set_step(2);
- {
- p1 = chHeapAlloc(&test_heap, sizeof test_buffer * 2);
- test_assert(p1 == NULL, "allocation not failed");
- }
-
- /* [4.1.3] Single block allocation using chHeapAlloc() then the block
- is freed using chHeapFree(), must not fail.*/
- test_set_step(3);
- {
- p1 = chHeapAlloc(&test_heap, ALLOC_SIZE);
- test_assert(p1 != NULL, "allocation failed");
- chHeapFree(p1);
- }
-
- /* [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);
- {
- 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");
- }
-
- /* [4.1.5] Allocating then freeing in the same order.*/
- 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");
- }
-
- /* [4.1.6] Allocating then freeing in reverse order.*/
- 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");
- }
-
- /* [4.1.7] Small fragments handling. Checking the behavior when
- allocating blocks with size not multiple of alignment unit.*/
- 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");
- }
-
- /* [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);
- {
- 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.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);
- }
-
- /* [4.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");
- }
-}
-
-static const testcase_t oslib_test_004_001 = {
- "Allocation and fragmentation",
- oslib_test_004_001_setup,
- NULL,
- oslib_test_004_001_execute
-};
-
-/**
- * @page oslib_test_004_002 [4.2] Default Heap
- *
- * <h2>Description</h2>
- * The default heap is pre-allocated in the system. We test base
- * functionality.
- *
- * <h2>Test Steps</h2>
- * - [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_002_execute(void) {
- void *p1;
- size_t total_size, largest_size;
-
- /* [4.2.1] Single block allocation using chHeapAlloc() then the block
- is freed using chHeapFree(), must not fail.*/
- 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);
- }
-
- /* [4.2.2] Testing allocation failure.*/
- test_set_step(2);
- {
- p1 = chHeapAlloc(NULL, (size_t)-256);
- test_assert(p1 == NULL, "allocation not failed");
- }
-}
-
-static const testcase_t oslib_test_004_002 = {
- "Default Heap",
- NULL,
- NULL,
- oslib_test_004_002_execute
-};
-
-/****************************************************************************
- * Exported data.
- ****************************************************************************/
-
-/**
- * @brief Array of test cases.
- */
-const testcase_t * const oslib_test_sequence_004_array[] = {
- &oslib_test_004_001,
- &oslib_test_004_002,
- NULL
-};
-
-/**
- * @brief Memory Heaps.
- */
-const testsequence_t oslib_test_sequence_004 = {
- NULL,
- oslib_test_sequence_004_array
-};
-
-#endif /* CH_CFG_USE_HEAP */
diff --git a/test/oslib/source/test/oslib_test_sequence_004.h b/test/oslib/source/test/oslib_test_sequence_004.h
deleted file mode 100644
index c301863f2..000000000
--- a/test/oslib/source/test/oslib_test_sequence_004.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- ChibiOS - Copyright (C) 2006..2017 Giovanni Di Sirio
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-*/
-
-/**
- * @file oslib_test_sequence_004.h
- * @brief Test Sequence 004 header.
- */
-
-#ifndef OSLIB_TEST_SEQUENCE_004_H
-#define OSLIB_TEST_SEQUENCE_004_H
-
-extern const testsequence_t oslib_test_sequence_004;
-
-#endif /* OSLIB_TEST_SEQUENCE_004_H */