From ba2ff06045c441a2be4ecd923d38e614db48f964 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Tue, 17 Oct 2017 07:46:38 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10841 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- test/oslib/source/test/oslib_test_root.c | 80 +--- test/oslib/source/test/oslib_test_root.h | 43 -- test/oslib/source/test/oslib_test_sequence_001.c | 565 ++++++++++------------- test/oslib/source/test/oslib_test_sequence_002.c | 345 +++++--------- test/oslib/source/test/oslib_test_sequence_003.c | 297 ++++++------ test/oslib/source/test/oslib_test_sequence_004.c | 279 ----------- test/oslib/source/test/oslib_test_sequence_004.h | 27 -- 7 files changed, 489 insertions(+), 1147 deletions(-) delete mode 100644 test/oslib/source/test/oslib_test_sequence_004.c delete mode 100644 test/oslib/source/test/oslib_test_sequence_004.h (limited to 'test/oslib/source') 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 * *

Description

- * This sequence tests the ChibiOS library functionalities related to - * binary semaphores. + * This sequence tests the ChibiOS libraryfunctionalities related to + * mailboxes. * *

Conditions

* This sequence is only executed if the following preprocessor condition * evaluates to true: - * - CH_CFG_USE_SEMAPHORES + * - CH_CFG_USE_MAILBOXES * . * *

Test Cases

* - @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 * *

Description

- * 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. * *

Test Steps

- * - [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 - * - *

Description

- * 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. - * - *

Test Steps

- * - [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 - * - *

Description

- * 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. - * - *

Test Steps

- * - [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 * *

Description

- * 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. * *

Test Steps

- * - [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 - * - *

Description

- * 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. - * - *

Test Steps

- * - [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 * *

Description

- * 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. * *

Test Steps

- * - [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 * *

Description

- * This sequence tests the ChibiOS libraryfunctionalities related to - * mailboxes. + * This sequence tests the ChibiOS library functionalities related to + * memory pools. * *

Conditions

* This sequence is only executed if the following preprocessor condition * evaluates to true: - * - CH_CFG_USE_MAILBOXES + * - CH_CFG_USE_MEMPOOLS * . * *

Test Cases

@@ -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 * *

Description

- * 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. * *

Test Steps

- * - [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 * *

Description

- * 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. + * + *

Conditions

+ * This test is only executed if the following preprocessor condition + * evaluates to true: + * - CH_CFG_USE_SEMAPHORES + * . * *

Test Steps

- * - [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 * *

Description

- * The mailbox API is tested for timeouts. + * The timeout features for the Guarded Memory Pools is tested. + * + *

Conditions

+ * This test is only executed if the following preprocessor condition + * evaluates to true: + * - CH_CFG_USE_SEMAPHORES + * . * *

Test Steps

- * - [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 * *

Description

* This sequence tests the ChibiOS library functionalities related to - * memory pools. + * memory heaps. * *

Conditions

* This sequence is only executed if the following preprocessor condition * evaluates to true: - * - CH_CFG_USE_MEMPOOLS + * - CH_CFG_USE_HEAP * . * *

Test Cases

* - @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 * *

Description

- * 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. * *

Test Steps

- * - [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 * *

Description

- * The memory pool functionality is tested by loading and emptying it, - * all conditions are tested. - * - *

Conditions

- * 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. * *

Test Steps

- * - [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 - * - *

Description

- * The timeout features for the Guarded Memory Pools is tested. - * - *

Conditions

- * This test is only executed if the following preprocessor condition - * evaluates to true: - * - CH_CFG_USE_SEMAPHORES - * . - * - *

Test Steps

- * - [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 - * - *

Description

- * This sequence tests the ChibiOS library functionalities related to - * memory heaps. - * - *

Conditions

- * This sequence is only executed if the following preprocessor condition - * evaluates to true: - * - CH_CFG_USE_HEAP - * . - * - *

Test Cases

- * - @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 - * - *

Description

- * 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. - * - *

Test Steps

- * - [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 - * - *

Description

- * The default heap is pre-allocated in the system. We test base - * functionality. - * - *

Test Steps

- * - [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 */ -- cgit v1.2.3