aboutsummaryrefslogtreecommitdiffstats
path: root/test/rt/source
diff options
context:
space:
mode:
authorGiovanni Di Sirio <gdisirio@gmail.com>2017-10-17 07:46:38 +0000
committerGiovanni Di Sirio <gdisirio@gmail.com>2017-10-17 07:46:38 +0000
commitba2ff06045c441a2be4ecd923d38e614db48f964 (patch)
treeccbb16452507ef332c8aeabd2785bb2498853b8c /test/rt/source
parenta202724feaf68aaf44986e2bc336de0008bb2c64 (diff)
downloadChibiOS-ba2ff06045c441a2be4ecd923d38e614db48f964.tar.gz
ChibiOS-ba2ff06045c441a2be4ecd923d38e614db48f964.tar.bz2
ChibiOS-ba2ff06045c441a2be4ecd923d38e614db48f964.zip
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@10841 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'test/rt/source')
-rw-r--r--test/rt/source/test/rt_test_root.c14
-rw-r--r--test/rt/source/test/rt_test_root.h5
-rw-r--r--test/rt/source/test/rt_test_sequence_005.c4
-rw-r--r--test/rt/source/test/rt_test_sequence_009.c385
-rw-r--r--test/rt/source/test/rt_test_sequence_010.c974
-rw-r--r--test/rt/source/test/rt_test_sequence_011.c279
-rw-r--r--test/rt/source/test/rt_test_sequence_011.h27
-rw-r--r--test/rt/source/test/rt_test_sequence_012.c291
-rw-r--r--test/rt/source/test/rt_test_sequence_012.h27
-rw-r--r--test/rt/source/test/rt_test_sequence_013.c1038
-rw-r--r--test/rt/source/test/rt_test_sequence_013.h27
11 files changed, 987 insertions, 2084 deletions
diff --git a/test/rt/source/test/rt_test_root.c b/test/rt/source/test/rt_test_root.c
index d5bb0c426..37deb5f29 100644
--- a/test/rt/source/test/rt_test_root.c
+++ b/test/rt/source/test/rt_test_root.c
@@ -31,9 +31,6 @@
* - @subpage rt_test_sequence_008
* - @subpage rt_test_sequence_009
* - @subpage rt_test_sequence_010
- * - @subpage rt_test_sequence_011
- * - @subpage rt_test_sequence_012
- * - @subpage rt_test_sequence_013
* .
*/
@@ -71,19 +68,10 @@ const testsequence_t * const rt_test_suite_array[] = {
#if (CH_CFG_USE_EVENTS) || defined(__DOXYGEN__)
&rt_test_sequence_008,
#endif
-#if (CH_CFG_USE_MAILBOXES) || defined(__DOXYGEN__)
+#if (CH_CFG_USE_DYNAMIC) || defined(__DOXYGEN__)
&rt_test_sequence_009,
#endif
-#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
&rt_test_sequence_010,
-#endif
-#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
- &rt_test_sequence_011,
-#endif
-#if (CH_CFG_USE_DYNAMIC) || defined(__DOXYGEN__)
- &rt_test_sequence_012,
-#endif
- &rt_test_sequence_013,
NULL
};
diff --git a/test/rt/source/test/rt_test_root.h b/test/rt/source/test/rt_test_root.h
index c06c699c5..4bdacf5eb 100644
--- a/test/rt/source/test/rt_test_root.h
+++ b/test/rt/source/test/rt_test_root.h
@@ -34,9 +34,6 @@
#include "rt_test_sequence_008.h"
#include "rt_test_sequence_009.h"
#include "rt_test_sequence_010.h"
-#include "rt_test_sequence_011.h"
-#include "rt_test_sequence_012.h"
-#include "rt_test_sequence_013.h"
#if !defined(__DOXYGEN__)
@@ -57,8 +54,6 @@ extern "C" {
/* Shared definitions. */
/*===========================================================================*/
-#define TEST_SUITE_NAME "ChibiOS/RT Test Suite"
-
/*
* Allowed delay in timeout checks.
*/
diff --git a/test/rt/source/test/rt_test_sequence_005.c b/test/rt/source/test/rt_test_sequence_005.c
index 6b461c926..29127092b 100644
--- a/test/rt/source/test/rt_test_sequence_005.c
+++ b/test/rt/source/test/rt_test_sequence_005.c
@@ -21,7 +21,7 @@
* @file rt_test_sequence_005.c
* @brief Test Sequence 005 code.
*
- * @page rt_test_sequence_005 [5] Counter and Binary Semaphores
+ * @page rt_test_sequence_005 [5] Counter Semaphores
*
* File: @ref rt_test_sequence_005.c
*
@@ -505,7 +505,7 @@ const testcase_t * const rt_test_sequence_005_array[] = {
};
/**
- * @brief Counter and Binary Semaphores.
+ * @brief Counter Semaphores.
*/
const testsequence_t rt_test_sequence_005 = {
NULL,
diff --git a/test/rt/source/test/rt_test_sequence_009.c b/test/rt/source/test/rt_test_sequence_009.c
index 4e738186b..47843184e 100644
--- a/test/rt/source/test/rt_test_sequence_009.c
+++ b/test/rt/source/test/rt_test_sequence_009.c
@@ -21,375 +21,247 @@
* @file rt_test_sequence_009.c
* @brief Test Sequence 009 code.
*
- * @page rt_test_sequence_009 [9] Mailboxes
+ * @page rt_test_sequence_009 [9] Dynamic threads
*
* File: @ref rt_test_sequence_009.c
*
* <h2>Description</h2>
- * This sequence tests the ChibiOS/RT functionalities related to
- * mailboxes.
+ * This module implements the test sequence for the dynamic thread
+ * creation APIs.
*
* <h2>Conditions</h2>
* This sequence is only executed if the following preprocessor condition
* evaluates to true:
- * - CH_CFG_USE_MAILBOXES
+ * - CH_CFG_USE_DYNAMIC
* .
*
* <h2>Test Cases</h2>
* - @subpage rt_test_009_001
* - @subpage rt_test_009_002
- * - @subpage rt_test_009_003
* .
*/
-#if (CH_CFG_USE_MAILBOXES) || defined(__DOXYGEN__)
+#if (CH_CFG_USE_DYNAMIC) || defined(__DOXYGEN__)
/****************************************************************************
* Shared code.
****************************************************************************/
-#define MB_SIZE 4
+#if CH_CFG_USE_HEAP
+static memory_heap_t heap1;
+#endif
+#if CH_CFG_USE_MEMPOOLS
+static memory_pool_t mp1;
+#endif
-static msg_t mb_buffer[MB_SIZE];
-static MAILBOX_DECL(mb1, mb_buffer, MB_SIZE);
+static THD_FUNCTION(dyn_thread1, p) {
+
+ test_emit_token(*(char *)p);
+}
/****************************************************************************
* Test cases.
****************************************************************************/
+#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
/**
- * @page rt_test_009_001 [9.1] Mailbox normal API, non-blocking tests
+ * @page rt_test_009_001 [9.1] Threads creation from Memory Heap
*
* <h2>Description</h2>
- * The mailbox normal API is tested without triggering blocking
- * conditions.
+ * Two threads are started by allocating the memory from the Memory
+ * Heap then a third thread is started with a huge stack
+ * requirement.<br> The test expects the first two threads to
+ * successfully start and the third one to fail.
+ *
+ * <h2>Conditions</h2>
+ * This test is only executed if the following preprocessor condition
+ * evaluates to true:
+ * - CH_CFG_USE_HEAP
+ * .
*
* <h2>Test Steps</h2>
- * - [9.1.1] Testing the mailbox size.
- * - [9.1.2] Resetting the mailbox, conditions are checked, no errors
- * expected.
- * - [9.1.3] Testing the behavior of API when the mailbox is in reset
- * state then return in active state.
- * - [9.1.4] Filling the mailbox using chMBPostTimeout() and
- * chMBPostAheadTimeout() once, no errors expected.
- * - [9.1.5] Testing intermediate conditions. Data pointers must be
- * aligned, semaphore counters are checked.
- * - [9.1.6] Emptying the mailbox using chMBFetchTimeout(), no errors
- * expected.
- * - [9.1.7] Posting and then fetching one more message, no errors
- * expected.
- * - [9.1.8] Testing final conditions. Data pointers must be aligned to
- * buffer start, semaphore counters are checked.
+ * - [9.1.1] Getting base priority for threads.
+ * - [9.1.2] Getting heap info before the test.
+ * - [9.1.3] Creating thread 1, it is expected to succeed.
+ * - [9.1.4] Creating thread 2, it is expected to succeed.
+ * - [9.1.5] Creating thread 3, it is expected to fail.
+ * - [9.1.6] Letting threads execute then checking the start order and
+ * freeing memory.
+ * - [9.1.7] Getting heap info again for verification.
* .
*/
static void rt_test_009_001_setup(void) {
- chMBObjectInit(&mb1, mb_buffer, MB_SIZE);
-}
-
-static void rt_test_009_001_teardown(void) {
- chMBReset(&mb1);
+ chHeapObjectInit(&heap1, test_buffer, sizeof test_buffer);
}
static void rt_test_009_001_execute(void) {
- msg_t msg1, msg2;
- unsigned i;
+ size_t n1, total1, largest1;
+ size_t n2, total2, largest2;
+ tprio_t prio;
- /* [9.1.1] Testing the mailbox size.*/
+ /* [9.1.1] Getting base priority for threads.*/
test_set_step(1);
{
- test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "wrong size");
+ prio = chThdGetPriorityX();
}
- /* [9.1.2] Resetting the mailbox, conditions are checked, no errors
- expected.*/
+ /* [9.1.2] Getting heap info before the test.*/
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");
+ n1 = chHeapStatus(&heap1, &total1, &largest1);
+ test_assert(n1 == 1, "heap fragmented");
}
- /* [9.1.3] Testing the behavior of API when the mailbox is in reset
- state then return in active state.*/
+ /* [9.1.3] Creating thread 1, it is expected to succeed.*/
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);
+ threads[0] = chThdCreateFromHeap(&heap1,
+ THD_WORKING_AREA_SIZE(THREADS_STACK_SIZE),
+ "dyn1",
+ prio-1, dyn_thread1, "A");
+ test_assert(threads[0] != NULL, "thread creation failed");
}
- /* [9.1.4] Filling the mailbox using chMBPostTimeout() and
- chMBPostAheadTimeout() once, no errors expected.*/
+ /* [9.1.4] Creating thread 2, it is expected to succeed.*/
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");
+ threads[1] = chThdCreateFromHeap(&heap1,
+ THD_WORKING_AREA_SIZE(THREADS_STACK_SIZE),
+ "dyn2",
+ prio-2, dyn_thread1, "B");
+ test_assert(threads[1] != NULL, "thread creation failed");
}
- /* [9.1.5] Testing intermediate conditions. Data pointers must be
- aligned, semaphore counters are checked.*/
+ /* [9.1.5] Creating thread 3, it is expected to fail.*/
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");
+ threads[2] = chThdCreateFromHeap(&heap1,
+ THD_WORKING_AREA_SIZE(THREADS_STACK_SIZE * 1024),
+ "dyn3",
+ prio-3, dyn_thread1, "C");
+ test_assert(threads[2] == NULL, "thread creation not failed");
}
- /* [9.1.6] Emptying the mailbox using chMBFetchTimeout(), no errors
- expected.*/
+ /* [9.1.6] Letting threads execute then checking the start order and
+ freeing memory.*/
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_wait_threads();
+ test_assert_sequence("AB", "invalid sequence");
}
- /* [9.1.7] Posting and then fetching one more message, no errors
- expected.*/
+ /* [9.1.7] Getting heap info again for verification.*/
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");
- }
-
- /* [9.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");
+ n2 = chHeapStatus(&heap1, &total2, &largest2);
+ test_assert(n1 == n2, "fragmentation changed");
+ test_assert(total1 == total2, "total free space changed");
+ test_assert(largest1 == largest2, "largest fragment size changed");
}
}
static const testcase_t rt_test_009_001 = {
- "Mailbox normal API, non-blocking tests",
+ "Threads creation from Memory Heap",
rt_test_009_001_setup,
- rt_test_009_001_teardown,
+ NULL,
rt_test_009_001_execute
};
+#endif /* CH_CFG_USE_HEAP */
+#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
/**
- * @page rt_test_009_002 [9.2] Mailbox I-Class API, non-blocking tests
+ * @page rt_test_009_002 [9.2] Threads creation from Memory Pool
*
* <h2>Description</h2>
- * The mailbox I-Class API is tested without triggering blocking
- * conditions.
+ * Five thread creation are attempted from a pool containing only four
+ * elements.<br> The test expects the first four threads to
+ * successfully start and the last one to fail.
+ *
+ * <h2>Conditions</h2>
+ * This test is only executed if the following preprocessor condition
+ * evaluates to true:
+ * - CH_CFG_USE_MEMPOOLS
+ * .
*
* <h2>Test Steps</h2>
- * - [9.2.1] Testing the mailbox size.
- * - [9.2.2] Resetting the mailbox, conditions are checked, no errors
- * expected. The mailbox is then returned in active state.
- * - [9.2.3] Filling the mailbox using chMBPostI() and chMBPostAheadI()
- * once, no errors expected.
- * - [9.2.4] Testing intermediate conditions. Data pointers must be
- * aligned, semaphore counters are checked.
- * - [9.2.5] Emptying the mailbox using chMBFetchI(), no errors
- * expected.
- * - [9.2.6] Posting and then fetching one more message, no errors
- * expected.
- * - [9.2.7] Testing final conditions. Data pointers must be aligned to
- * buffer start, semaphore counters are checked.
+ * - [9.2.1] Adding four working areas to the pool.
+ * - [9.2.2] Getting base priority for threads.
+ * - [9.2.3] Creating the five threads.
+ * - [9.2.4] Testing that only the fifth thread creation failed.
+ * - [9.2.5] Letting them run, free the memory then checking the
+ * execution sequence.
+ * - [9.2.6] Testing that the pool contains four elements again.
* .
*/
static void rt_test_009_002_setup(void) {
- chMBObjectInit(&mb1, mb_buffer, MB_SIZE);
-}
-
-static void rt_test_009_002_teardown(void) {
- chMBReset(&mb1);
+ chPoolObjectInit(&mp1, THD_WORKING_AREA_SIZE(THREADS_STACK_SIZE), NULL);
}
static void rt_test_009_002_execute(void) {
- msg_t msg1, msg2;
unsigned i;
+ tprio_t prio;
- /* [9.2.1] Testing the mailbox size.*/
+ /* [9.2.1] Adding four working areas to the pool.*/
test_set_step(1);
{
- test_assert_lock(chMBGetFreeCountI(&mb1) == MB_SIZE, "wrong size");
+ for (i = 0; i < 4; i++)
+ chPoolFree(&mp1, wa[i]);
}
- /* [9.2.2] Resetting the mailbox, conditions are checked, no errors
- expected. The mailbox is then returned in active state.*/
+ /* [9.2.2] Getting base priority for threads.*/
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);
+ prio = chThdGetPriorityX();
}
- /* [9.2.3] Filling the mailbox using chMBPostI() and chMBPostAheadI()
- once, no errors expected.*/
+ /* [9.2.3] Creating the five threads.*/
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");
+ threads[0] = chThdCreateFromMemoryPool(&mp1, "dyn1", prio-1, dyn_thread1, "A");
+ threads[1] = chThdCreateFromMemoryPool(&mp1, "dyn2", prio-2, dyn_thread1, "B");
+ threads[2] = chThdCreateFromMemoryPool(&mp1, "dyn3", prio-3, dyn_thread1, "C");
+ threads[3] = chThdCreateFromMemoryPool(&mp1, "dyn4", prio-4, dyn_thread1, "D");
+ threads[4] = chThdCreateFromMemoryPool(&mp1, "dyn5", prio-5, dyn_thread1, "E");
}
- /* [9.2.4] Testing intermediate conditions. Data pointers must be
- aligned, semaphore counters are checked.*/
+ /* [9.2.4] Testing that only the fifth thread creation failed.*/
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");
+ test_assert((threads[0] != NULL) &&
+ (threads[1] != NULL) &&
+ (threads[2] != NULL) &&
+ (threads[3] != NULL),
+ "thread creation failed");
+ test_assert(threads[4] == NULL,
+ "thread creation not failed");
}
- /* [9.2.5] Emptying the mailbox using chMBFetchI(), no errors
- expected.*/
+ /* [9.2.5] Letting them run, free the memory then checking the
+ execution sequence.*/
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");
+ test_wait_threads();
+ test_assert_sequence("ABCD", "invalid sequence");
}
- /* [9.2.6] Posting and then fetching one more message, no errors
- expected.*/
+ /* [9.2.6] Testing that the pool contains four elements 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");
- }
-
- /* [9.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");
+ for (i = 0; i < 4; i++)
+ test_assert(chPoolAlloc(&mp1) != NULL, "pool list empty");
+ test_assert(chPoolAlloc(&mp1) == NULL, "pool list not empty");
}
}
static const testcase_t rt_test_009_002 = {
- "Mailbox I-Class API, non-blocking tests",
+ "Threads creation from Memory Pool",
rt_test_009_002_setup,
- rt_test_009_002_teardown,
+ NULL,
rt_test_009_002_execute
};
-
-/**
- * @page rt_test_009_003 [9.3] Mailbox timeouts
- *
- * <h2>Description</h2>
- * The mailbox API is tested for timeouts.
- *
- * <h2>Test Steps</h2>
- * - [9.3.1] Filling the mailbox.
- * - [9.3.2] Testing chMBPostTimeout(), chMBPostI(),
- * chMBPostAheadTimeout() and chMBPostAheadI() timeout.
- * - [9.3.3] Resetting the mailbox. The mailbox is then returned in
- * active state.
- * - [9.3.4] Testing chMBFetchTimeout() and chMBFetchI() timeout.
- * .
- */
-
-static void rt_test_009_003_setup(void) {
- chMBObjectInit(&mb1, mb_buffer, MB_SIZE);
-}
-
-static void rt_test_009_003_teardown(void) {
- chMBReset(&mb1);
-}
-
-static void rt_test_009_003_execute(void) {
- msg_t msg1, msg2;
- unsigned i;
-
- /* [9.3.1] Filling the mailbox.*/
- 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");
- }
- }
-
- /* [9.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");
- }
-
- /* [9.3.3] Resetting the mailbox. The mailbox is then returned in
- active state.*/
- test_set_step(3);
- {
- chMBReset(&mb1);
- chMBResumeX(&mb1);
- }
-
- /* [9.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");
- }
-}
-
-static const testcase_t rt_test_009_003 = {
- "Mailbox timeouts",
- rt_test_009_003_setup,
- rt_test_009_003_teardown,
- rt_test_009_003_execute
-};
+#endif /* CH_CFG_USE_MEMPOOLS */
/****************************************************************************
* Exported data.
@@ -399,18 +271,21 @@ static const testcase_t rt_test_009_003 = {
* @brief Array of test cases.
*/
const testcase_t * const rt_test_sequence_009_array[] = {
+#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
&rt_test_009_001,
+#endif
+#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
&rt_test_009_002,
- &rt_test_009_003,
+#endif
NULL
};
/**
- * @brief Mailboxes.
+ * @brief Dynamic threads.
*/
const testsequence_t rt_test_sequence_009 = {
NULL,
rt_test_sequence_009_array
};
-#endif /* CH_CFG_USE_MAILBOXES */
+#endif /* CH_CFG_USE_DYNAMIC */
diff --git a/test/rt/source/test/rt_test_sequence_010.c b/test/rt/source/test/rt_test_sequence_010.c
index d21946ef8..4a9d365f0 100644
--- a/test/rt/source/test/rt_test_sequence_010.c
+++ b/test/rt/source/test/rt_test_sequence_010.c
@@ -21,142 +21,523 @@
* @file rt_test_sequence_010.c
* @brief Test Sequence 010 code.
*
- * @page rt_test_sequence_010 [10] Memory Pools
+ * @page rt_test_sequence_010 [10] Benchmarks
*
* File: @ref rt_test_sequence_010.c
*
* <h2>Description</h2>
- * This sequence tests the ChibiOS/RT functionalities related to memory
- * pools.
- *
- * <h2>Conditions</h2>
- * This sequence is only executed if the following preprocessor condition
- * evaluates to true:
- * - CH_CFG_USE_MEMPOOLS
- * .
+ * This module implements a series of system benchmarks. The benchmarks
+ * are useful as a stress test and as a reference when comparing
+ * ChibiOS/RT with similar systems.<br> Objective of the test sequence
+ * is to provide a performance index for the most critical system
+ * subsystems. The performance numbers allow to discover performance
+ * regressions between successive ChibiOS/RT releases.
*
* <h2>Test Cases</h2>
* - @subpage rt_test_010_001
* - @subpage rt_test_010_002
* - @subpage rt_test_010_003
+ * - @subpage rt_test_010_004
+ * - @subpage rt_test_010_005
+ * - @subpage rt_test_010_006
+ * - @subpage rt_test_010_007
+ * - @subpage rt_test_010_008
+ * - @subpage rt_test_010_009
+ * - @subpage rt_test_010_010
+ * - @subpage rt_test_010_011
+ * - @subpage rt_test_010_012
* .
*/
-#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
-
/****************************************************************************
* Shared code.
****************************************************************************/
-#define MEMORY_POOL_SIZE 4
+#if CH_CFG_USE_SEMAPHORES || defined(__DOXYGEN__)
+static semaphore_t sem1;
+#endif
+#if CH_CFG_USE_MUTEXES || defined(__DOXYGEN__)
+static mutex_t mtx1;
+#endif
-static uint32_t objects[MEMORY_POOL_SIZE];
-static MEMORYPOOL_DECL(mp1, sizeof (uint32_t), PORT_NATURAL_ALIGN, NULL);
+static void tmo(void *param) {(void)param;}
-#if CH_CFG_USE_SEMAPHORES
-static GUARDEDMEMORYPOOL_DECL(gmp1, sizeof (uint32_t), PORT_NATURAL_ALIGN);
+#if CH_CFG_USE_MESSAGES
+static THD_FUNCTION(bmk_thread1, p) {
+ thread_t *tp;
+ msg_t msg;
+
+ (void)p;
+ do {
+ tp = chMsgWait();
+ msg = chMsgGet(tp);
+ chMsgRelease(tp, msg);
+ } while (msg);
+}
+
+NOINLINE static unsigned int msg_loop_test(thread_t *tp) {
+ systime_t start, end;
+
+ uint32_t n = 0;
+ start = test_wait_tick();
+ end = start + TIME_MS2I(1000);
+ do {
+ (void)chMsgSend(tp, 1);
+ n++;
+#if defined(SIMULATOR)
+ _sim_check_for_interrupts();
+#endif
+ } while (chVTIsSystemTimeWithinX(start, end));
+ (void)chMsgSend(tp, 0);
+ return n;
+}
#endif
-static void *null_provider(size_t size, unsigned align) {
+static THD_FUNCTION(bmk_thread3, p) {
+
+ chThdExit((msg_t)p);
+}
+
+static THD_FUNCTION(bmk_thread4, p) {
+ msg_t msg;
+ thread_t *self = chThdGetSelfX();
+
+ (void)p;
+ chSysLock();
+ do {
+ chSchGoSleepS(CH_STATE_SUSPENDED);
+ msg = self->u.rdymsg;
+ } while (msg == MSG_OK);
+ chSysUnlock();
+}
+
+#if CH_CFG_USE_SEMAPHORES
+static THD_FUNCTION(bmk_thread7, p) {
+
+ (void)p;
+ while (!chThdShouldTerminateX())
+ chSemWait(&sem1);
+}
+#endif
- (void)size;
- (void)align;
+static THD_FUNCTION(bmk_thread8, p) {
- return NULL;
+ do {
+ chThdYield();
+ chThdYield();
+ chThdYield();
+ chThdYield();
+ (*(uint32_t *)p) += 4;
+#if defined(SIMULATOR)
+ _sim_check_for_interrupts();
+#endif
+ } while(!chThdShouldTerminateX());
}
/****************************************************************************
* Test cases.
****************************************************************************/
+#if (CH_CFG_USE_MESSAGES) || defined(__DOXYGEN__)
/**
- * @page rt_test_010_001 [10.1] Loading and emptying a memory pool
+ * @page rt_test_010_001 [10.1] Messages performance #1
*
* <h2>Description</h2>
- * The memory pool functionality is tested by loading and emptying it,
- * all conditions are tested.
+ * A message server thread is created with a lower priority than the
+ * client thread, the messages throughput per second is measured and
+ * the result printed on the output log.
+ *
+ * <h2>Conditions</h2>
+ * This test is only executed if the following preprocessor condition
+ * evaluates to true:
+ * - CH_CFG_USE_MESSAGES
+ * .
*
* <h2>Test Steps</h2>
- * - [10.1.1] Adding the objects to the pool using chPoolLoadArray().
- * - [10.1.2] Emptying the pool using chPoolAlloc().
- * - [10.1.3] Now must be empty.
- * - [10.1.4] Adding the objects to the pool using chPoolFree().
- * - [10.1.5] Emptying the pool using chPoolAlloc() again.
- * - [10.1.6] Now must be empty again.
- * - [10.1.7] Covering the case where a provider is unable to return
- * more memory.
+ * - [10.1.1] The messenger thread is started at a lower priority than
+ * the current thread.
+ * - [10.1.2] The number of messages exchanged is counted in a one
+ * second time window.
+ * - [10.1.3] Score is printed.
* .
*/
-static void rt_test_010_001_setup(void) {
- chPoolObjectInit(&mp1, sizeof (uint32_t), NULL);
+static void rt_test_010_001_execute(void) {
+ uint32_t n;
+
+ /* [10.1.1] The messenger thread is started at a lower priority than
+ the current thread.*/
+ test_set_step(1);
+ {
+ threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-1, bmk_thread1, NULL);
+ }
+
+ /* [10.1.2] The number of messages exchanged is counted in a one
+ second time window.*/
+ test_set_step(2);
+ {
+ n = msg_loop_test(threads[0]);
+ test_wait_threads();
+ }
+
+ /* [10.1.3] Score is printed.*/
+ test_set_step(3);
+ {
+ test_print("--- Score : ");
+ test_printn(n);
+ test_print(" msgs/S, ");
+ test_printn(n << 1);
+ test_println(" ctxswc/S");
+ }
}
-static void rt_test_010_001_execute(void) {
- unsigned i;
+static const testcase_t rt_test_010_001 = {
+ "Messages performance #1",
+ NULL,
+ NULL,
+ rt_test_010_001_execute
+};
+#endif /* CH_CFG_USE_MESSAGES */
+
+#if (CH_CFG_USE_MESSAGES) || defined(__DOXYGEN__)
+/**
+ * @page rt_test_010_002 [10.2] Messages performance #2
+ *
+ * <h2>Description</h2>
+ * A message server thread is created with an higher priority than the
+ * client thread, the messages throughput per second is measured and
+ * the result printed on the output log.
+ *
+ * <h2>Conditions</h2>
+ * This test is only executed if the following preprocessor condition
+ * evaluates to true:
+ * - CH_CFG_USE_MESSAGES
+ * .
+ *
+ * <h2>Test Steps</h2>
+ * - [10.2.1] The messenger thread is started at an higher priority
+ * than the current thread.
+ * - [10.2.2] The number of messages exchanged is counted in a one
+ * second time window.
+ * - [10.2.3] Score is printed.
+ * .
+ */
+
+static void rt_test_010_002_execute(void) {
+ uint32_t n;
+
+ /* [10.2.1] The messenger thread is started at an higher priority
+ than the current thread.*/
+ test_set_step(1);
+ {
+ threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, bmk_thread1, NULL);
+ }
+
+ /* [10.2.2] The number of messages exchanged is counted in a one
+ second time window.*/
+ test_set_step(2);
+ {
+ n = msg_loop_test(threads[0]);
+ test_wait_threads();
+ }
+
+ /* [10.2.3] Score is printed.*/
+ test_set_step(3);
+ {
+ test_print("--- Score : ");
+ test_printn(n);
+ test_print(" msgs/S, ");
+ test_printn(n << 1);
+ test_println(" ctxswc/S");
+ }
+}
+
+static const testcase_t rt_test_010_002 = {
+ "Messages performance #2",
+ NULL,
+ NULL,
+ rt_test_010_002_execute
+};
+#endif /* CH_CFG_USE_MESSAGES */
- /* [10.1.1] Adding the objects to the pool using chPoolLoadArray().*/
+#if (CH_CFG_USE_MESSAGES) || defined(__DOXYGEN__)
+/**
+ * @page rt_test_010_003 [10.3] Messages performance #3
+ *
+ * <h2>Description</h2>
+ * A message server thread is created with an higher priority than the
+ * client thread, four lower priority threads crowd the ready list, the
+ * messages throughput per second is measured while the ready list and
+ * the result printed on the output log.
+ *
+ * <h2>Conditions</h2>
+ * This test is only executed if the following preprocessor condition
+ * evaluates to true:
+ * - CH_CFG_USE_MESSAGES
+ * .
+ *
+ * <h2>Test Steps</h2>
+ * - [10.3.1] The messenger thread is started at an higher priority
+ * than the current thread.
+ * - [10.3.2] Four threads are started at a lower priority than the
+ * current thread.
+ * - [10.3.3] The number of messages exchanged is counted in a one
+ * second time window.
+ * - [10.3.4] Score is printed.
+ * .
+ */
+
+static void rt_test_010_003_execute(void) {
+ uint32_t n;
+
+ /* [10.3.1] The messenger thread is started at an higher priority
+ than the current thread.*/
test_set_step(1);
{
- chPoolLoadArray(&mp1, objects, MEMORY_POOL_SIZE);
+ threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, bmk_thread1, NULL);
}
- /* [10.1.2] Emptying the pool using chPoolAlloc().*/
+ /* [10.3.2] Four threads are started at a lower priority than the
+ current thread.*/
test_set_step(2);
{
- for (i = 0; i < MEMORY_POOL_SIZE; i++)
- test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
+ threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-2, bmk_thread3, NULL);
+ threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-3, bmk_thread3, NULL);
+ threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-4, bmk_thread3, NULL);
+ threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-5, bmk_thread3, NULL);
}
- /* [10.1.3] Now must be empty.*/
+ /* [10.3.3] The number of messages exchanged is counted in a one
+ second time window.*/
test_set_step(3);
{
- test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
+ n = msg_loop_test(threads[0]);
+ test_wait_threads();
}
- /* [10.1.4] Adding the objects to the pool using chPoolFree().*/
+ /* [10.3.4] Score is printed.*/
test_set_step(4);
{
- for (i = 0; i < MEMORY_POOL_SIZE; i++)
- chPoolFree(&mp1, &objects[i]);
+ test_print("--- Score : ");
+ test_printn(n);
+ test_print(" msgs/S, ");
+ test_printn(n << 1);
+ test_println(" ctxswc/S");
}
+}
- /* [10.1.5] Emptying the pool using chPoolAlloc() again.*/
- test_set_step(5);
+static const testcase_t rt_test_010_003 = {
+ "Messages performance #3",
+ NULL,
+ NULL,
+ rt_test_010_003_execute
+};
+#endif /* CH_CFG_USE_MESSAGES */
+
+/**
+ * @page rt_test_010_004 [10.4] Context Switch performance
+ *
+ * <h2>Description</h2>
+ * A thread is created that just performs a @p chSchGoSleepS() into a
+ * loop, the thread is awakened as fast is possible by the tester
+ * thread.<br> The Context Switch performance is calculated by
+ * measuring the number of iterations after a second of continuous
+ * operations.
+ *
+ * <h2>Test Steps</h2>
+ * - [10.4.1] Starting the target thread at an higher priority level.
+ * - [10.4.2] Waking up the thread as fast as possible in a one second
+ * time window.
+ * - [10.4.3] Stopping the target thread.
+ * - [10.4.4] Score is printed.
+ * .
+ */
+
+static void rt_test_010_004_execute(void) {
+ thread_t *tp;
+ uint32_t n;
+
+ /* [10.4.1] Starting the target thread at an higher priority level.*/
+ test_set_step(1);
{
- for (i = 0; i < MEMORY_POOL_SIZE; i++)
- test_assert(chPoolAlloc(&mp1) != NULL, "list empty");
+ tp = threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1,
+ bmk_thread4, NULL);
}
- /* [10.1.6] Now must be empty again.*/
- test_set_step(6);
+ /* [10.4.2] Waking up the thread as fast as possible in a one second
+ time window.*/
+ test_set_step(2);
{
- test_assert(chPoolAlloc(&mp1) == NULL, "list not empty");
+ systime_t start, end;
+
+ n = 0;
+ start = test_wait_tick();
+ end = start + TIME_MS2I(1000);
+ do {
+ chSysLock();
+ chSchWakeupS(tp, MSG_OK);
+ chSchWakeupS(tp, MSG_OK);
+ chSchWakeupS(tp, MSG_OK);
+ chSchWakeupS(tp, MSG_OK);
+ chSysUnlock();
+ n += 4;
+#if defined(SIMULATOR)
+ _sim_check_for_interrupts();
+#endif
+ } while (chVTIsSystemTimeWithinX(start, end));
}
- /* [10.1.7] Covering the case where a provider is unable to return
- more memory.*/
- test_set_step(7);
+ /* [10.4.3] Stopping the target thread.*/
+ test_set_step(3);
{
- chPoolObjectInit(&mp1, sizeof (uint32_t), null_provider);
- test_assert(chPoolAlloc(&mp1) == NULL, "provider returned memory");
+ chSysLock();
+ chSchWakeupS(tp, MSG_TIMEOUT);
+ chSysUnlock();
+ test_wait_threads();
+ }
+
+ /* [10.4.4] Score is printed.*/
+ test_set_step(4);
+ {
+ test_print("--- Score : ");
+ test_printn(n * 2);
+ test_println(" ctxswc/S");
}
}
-static const testcase_t rt_test_010_001 = {
- "Loading and emptying a memory pool",
- rt_test_010_001_setup,
+static const testcase_t rt_test_010_004 = {
+ "Context Switch performance",
NULL,
- rt_test_010_001_execute
+ NULL,
+ rt_test_010_004_execute
+};
+
+/**
+ * @page rt_test_010_005 [10.5] Threads performance, full cycle
+ *
+ * <h2>Description</h2>
+ * Threads are continuously created and terminated into a loop. A full
+ * chThdCreateStatic() / @p chThdExit() / @p chThdWait() cycle is
+ * performed in each iteration.<br> The performance is calculated by
+ * measuring the number of iterations after a second of continuous
+ * operations.
+ *
+ * <h2>Test Steps</h2>
+ * - [10.5.1] A thread is created at a lower priority level and its
+ * termination detected using @p chThdWait(). The operation is
+ * repeated continuously in a one-second time window.
+ * - [10.5.2] Score is printed.
+ * .
+ */
+
+static void rt_test_010_005_execute(void) {
+ uint32_t n;
+ tprio_t prio = chThdGetPriorityX() - 1;
+ systime_t start, end;
+
+ /* [10.5.1] A thread is created at a lower priority level and its
+ termination detected using @p chThdWait(). The operation is
+ repeated continuously in a one-second time window.*/
+ test_set_step(1);
+ {
+ n = 0;
+ start = test_wait_tick();
+ end = start + TIME_MS2I(1000);
+ do {
+ chThdWait(chThdCreateStatic(wa[0], WA_SIZE, prio, bmk_thread3, NULL));
+ n++;
+#if defined(SIMULATOR)
+ _sim_check_for_interrupts();
+#endif
+ } while (chVTIsSystemTimeWithinX(start, end));
+ }
+
+ /* [10.5.2] Score is printed.*/
+ test_set_step(2);
+ {
+ test_print("--- Score : ");
+ test_printn(n);
+ test_println(" threads/S");
+ }
+}
+
+static const testcase_t rt_test_010_005 = {
+ "Threads performance, full cycle",
+ NULL,
+ NULL,
+ rt_test_010_005_execute
+};
+
+/**
+ * @page rt_test_010_006 [10.6] Threads performance, create/exit only
+ *
+ * <h2>Description</h2>
+ * Threads are continuously created and terminated into a loop. A
+ * partial @p chThdCreateStatic() / @p chThdExit() cycle is performed
+ * in each iteration, the @p chThdWait() is not necessary because the
+ * thread is created at an higher priority so there is no need to wait
+ * for it to terminate.<br> The performance is calculated by measuring
+ * the number of iterations after a second of continuous operations.
+ *
+ * <h2>Test Steps</h2>
+ * - [10.6.1] A thread is created at an higher priority level and let
+ * terminate immediately. The operation is repeated continuously in a
+ * one-second time window.
+ * - [10.6.2] Score is printed.
+ * .
+ */
+
+static void rt_test_010_006_execute(void) {
+ uint32_t n;
+ tprio_t prio = chThdGetPriorityX() + 1;
+ systime_t start, end;
+
+ /* [10.6.1] A thread is created at an higher priority level and let
+ terminate immediately. The operation is repeated continuously in a
+ one-second time window.*/
+ test_set_step(1);
+ {
+ n = 0;
+ start = test_wait_tick();
+ end = start + TIME_MS2I(1000);
+ do {
+#if CH_CFG_USE_REGISTRY
+ chThdRelease(chThdCreateStatic(wa[0], WA_SIZE, prio, bmk_thread3, NULL));
+#else
+ chThdCreateStatic(wa[0], WA_SIZE, prio, bmk_thread3, NULL);
+#endif
+ n++;
+#if defined(SIMULATOR)
+ _sim_check_for_interrupts();
+#endif
+ } while (chVTIsSystemTimeWithinX(start, end));
+ }
+
+ /* [10.6.2] Score is printed.*/
+ test_set_step(2);
+ {
+ test_print("--- Score : ");
+ test_printn(n);
+ test_println(" threads/S");
+ }
+}
+
+static const testcase_t rt_test_010_006 = {
+ "Threads performance, create/exit only",
+ NULL,
+ NULL,
+ rt_test_010_006_execute
};
#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
/**
- * @page rt_test_010_002 [10.2] Loading and emptying a guarded memory pool without waiting
+ * @page rt_test_010_007 [10.7] Mass reschedule performance
*
* <h2>Description</h2>
- * The memory pool functionality is tested by loading and emptying it,
- * all conditions are tested.
+ * Five threads are created and atomically rescheduled by resetting the
+ * semaphore where they are waiting on. The operation is performed into
+ * a continuous loop.<br> The performance is calculated by measuring
+ * the number of iterations after a second of continuous operations.
*
* <h2>Conditions</h2>
* This test is only executed if the following preprocessor condition
@@ -165,81 +546,206 @@ static const testcase_t rt_test_010_001 = {
* .
*
* <h2>Test Steps</h2>
- * - [10.2.1] Adding the objects to the pool using
- * chGuardedPoolLoadArray().
- * - [10.2.2] Emptying the pool using chGuardedPoolAllocTimeout().
- * - [10.2.3] Now must be empty.
- * - [10.2.4] Adding the objects to the pool using chGuardedPoolFree().
- * - [10.2.5] Emptying the pool using chGuardedPoolAllocTimeout()
- * again.
- * - [10.2.6] Now must be empty again.
+ * - [10.7.1] Five threads are created at higher priority that
+ * immediately enqueue on a semaphore.
+ * - [10.7.2] The semaphore is reset waking up the five threads. The
+ * operation is repeated continuously in a one-second time window.
+ * - [10.7.3] The five threads are terminated.
+ * - [10.7.4] The score is printed.
* .
*/
-static void rt_test_010_002_setup(void) {
- chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
+static void rt_test_010_007_setup(void) {
+ chSemObjectInit(&sem1, 0);
}
-static void rt_test_010_002_execute(void) {
- unsigned i;
+static void rt_test_010_007_execute(void) {
+ uint32_t n;
- /* [10.2.1] Adding the objects to the pool using
- chGuardedPoolLoadArray().*/
+ /* [10.7.1] Five threads are created at higher priority that
+ immediately enqueue on a semaphore.*/
test_set_step(1);
{
- chGuardedPoolLoadArray(&gmp1, objects, MEMORY_POOL_SIZE);
+ threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+5, bmk_thread7, NULL);
+ threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()+4, bmk_thread7, NULL);
+ threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()+3, bmk_thread7, NULL);
+ threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()+2, bmk_thread7, NULL);
+ threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()+1, bmk_thread7, NULL);
}
- /* [10.2.2] Emptying the pool using chGuardedPoolAllocTimeout().*/
+ /* [10.7.2] The semaphore is reset waking up the five threads. The
+ operation is repeated continuously in a one-second time window.*/
test_set_step(2);
{
- for (i = 0; i < MEMORY_POOL_SIZE; i++)
- test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
+ systime_t start, end;
+
+ n = 0;
+ start = test_wait_tick();
+ end = start + TIME_MS2I(1000);
+ do {
+ chSemReset(&sem1, 0);
+ n++;
+#if defined(SIMULATOR)
+ _sim_check_for_interrupts();
+#endif
+ } while (chVTIsSystemTimeWithinX(start, end));
}
- /* [10.2.3] Now must be empty.*/
+ /* [10.7.3] The five threads are terminated.*/
test_set_step(3);
{
- test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
+ test_terminate_threads();
+ chSemReset(&sem1, 0);
+ test_wait_threads();
}
- /* [10.2.4] Adding the objects to the pool using
- chGuardedPoolFree().*/
+ /* [10.7.4] The score is printed.*/
test_set_step(4);
{
- for (i = 0; i < MEMORY_POOL_SIZE; i++)
- chGuardedPoolFree(&gmp1, &objects[i]);
+ test_print("--- Score : ");
+ test_printn(n);
+ test_print(" reschedules/S, ");
+ test_printn(n * 6);
+ test_println(" ctxswc/S");
}
+}
- /* [10.2.5] Emptying the pool using chGuardedPoolAllocTimeout()
- again.*/
- test_set_step(5);
+static const testcase_t rt_test_010_007 = {
+ "Mass reschedule performance",
+ rt_test_010_007_setup,
+ NULL,
+ rt_test_010_007_execute
+};
+#endif /* CH_CFG_USE_SEMAPHORES */
+
+/**
+ * @page rt_test_010_008 [10.8] Round-Robin voluntary reschedule
+ *
+ * <h2>Description</h2>
+ * Five threads are created at equal priority, each thread just
+ * increases a variable and yields.<br> The performance is calculated
+ * by measuring the number of iterations after a second of continuous
+ * operations.
+ *
+ * <h2>Test Steps</h2>
+ * - [10.8.1] The five threads are created at lower priority. The
+ * threds have equal priority and start calling @p chThdYield()
+ * continuously.
+ * - [10.8.2] Waiting one second then terminating the 5 threads.
+ * - [10.8.3] The score is printed.
+ * .
+ */
+
+static void rt_test_010_008_execute(void) {
+ uint32_t n;
+
+ /* [10.8.1] The five threads are created at lower priority. The
+ threds have equal priority and start calling @p chThdYield()
+ continuously.*/
+ test_set_step(1);
{
- for (i = 0; i < MEMORY_POOL_SIZE; i++)
- test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) != NULL, "list empty");
+ n = 0;
+ test_wait_tick();threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
+
+ threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
+ threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
+ threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
+ threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
}
- /* [10.2.6] Now must be empty again.*/
- test_set_step(6);
+ /* [10.8.2] Waiting one second then terminating the 5 threads.*/
+ test_set_step(2);
{
- test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_IMMEDIATE) == NULL, "list not empty");
+ chThdSleepSeconds(1);
+ test_terminate_threads();
+ test_wait_threads();
+ }
+
+ /* [10.8.3] The score is printed.*/
+ test_set_step(3);
+ {
+ test_print("--- Score : ");
+ test_printn(n);
+ test_println(" ctxswc/S");
}
}
-static const testcase_t rt_test_010_002 = {
- "Loading and emptying a guarded memory pool without waiting",
- rt_test_010_002_setup,
+static const testcase_t rt_test_010_008 = {
+ "Round-Robin voluntary reschedule",
NULL,
- rt_test_010_002_execute
+ NULL,
+ rt_test_010_008_execute
+};
+
+/**
+ * @page rt_test_010_009 [10.9] Virtual Timers set/reset performance
+ *
+ * <h2>Description</h2>
+ * A virtual timer is set and immediately reset into a continuous
+ * loop.<br> The performance is calculated by measuring the number of
+ * iterations after a second of continuous operations.
+ *
+ * <h2>Test Steps</h2>
+ * - [10.9.1] Two timers are set then reset without waiting for their
+ * counter to elapse. The operation is repeated continuously in a
+ * one-second time window.
+ * - [10.9.2] The score is printed.
+ * .
+ */
+
+static void rt_test_010_009_execute(void) {
+ static virtual_timer_t vt1, vt2;
+ uint32_t n;
+
+ /* [10.9.1] Two timers are set then reset without waiting for their
+ counter to elapse. The operation is repeated continuously in a
+ one-second time window.*/
+ test_set_step(1);
+ {
+ systime_t start, end;
+
+ n = 0;
+ start = test_wait_tick();
+ end = start + TIME_MS2I(1000);
+ do {
+ chSysLock();
+ chVTDoSetI(&vt1, 1, tmo, NULL);
+ chVTDoSetI(&vt2, 10000, tmo, NULL);
+ chVTDoResetI(&vt1);
+ chVTDoResetI(&vt2);
+ chSysUnlock();
+ n++;
+#if defined(SIMULATOR)
+ _sim_check_for_interrupts();
+#endif
+ } while (chVTIsSystemTimeWithinX(start, end));
+ }
+
+ /* [10.9.2] The score is printed.*/
+ test_set_step(2);
+ {
+ test_print("--- Score : ");
+ test_printn(n * 2);
+ test_println(" timers/S");
+ }
+}
+
+static const testcase_t rt_test_010_009 = {
+ "Virtual Timers set/reset performance",
+ NULL,
+ NULL,
+ rt_test_010_009_execute
};
-#endif /* CH_CFG_USE_SEMAPHORES */
#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
/**
- * @page rt_test_010_003 [10.3] Guarded Memory Pools timeout
+ * @page rt_test_010_010 [10.10] Semaphores wait/signal performance
*
* <h2>Description</h2>
- * The timeout features for the Guarded Memory Pools is tested.
+ * A counting semaphore is taken/released into a continuous loop, no
+ * Context Switch happens because the counter is always non
+ * negative.<br> The performance is calculated by measuring the number
+ * of iterations after a second of continuous operations.
*
* <h2>Conditions</h2>
* This test is only executed if the following preprocessor condition
@@ -248,33 +754,246 @@ static const testcase_t rt_test_010_002 = {
* .
*
* <h2>Test Steps</h2>
- * - [10.3.1] Trying to allocate with 100mS timeout, must fail because
- * the pool is empty.
+ * - [10.10.1] A semaphore is teken and released. The operation is
+ * repeated continuously in a one-second time window.
+ * - [10.10.2] The score is printed.
* .
*/
-static void rt_test_010_003_setup(void) {
- chGuardedPoolObjectInit(&gmp1, sizeof (uint32_t));
+static void rt_test_010_010_setup(void) {
+ chSemObjectInit(&sem1, 1);
}
-static void rt_test_010_003_execute(void) {
+static void rt_test_010_010_execute(void) {
+ uint32_t n;
- /* [10.3.1] Trying to allocate with 100mS timeout, must fail because
- the pool is empty.*/
+ /* [10.10.1] A semaphore is teken and released. The operation is
+ repeated continuously in a one-second time window.*/
test_set_step(1);
{
- test_assert(chGuardedPoolAllocTimeout(&gmp1, TIME_MS2I(100)) == NULL, "list not empty");
+ systime_t start, end;
+
+ n = 0;
+ start = test_wait_tick();
+ end = start + TIME_MS2I(1000);
+ do {
+ chSemWait(&sem1);
+ chSemSignal(&sem1);
+ chSemWait(&sem1);
+ chSemSignal(&sem1);
+ chSemWait(&sem1);
+ chSemSignal(&sem1);
+ chSemWait(&sem1);
+ chSemSignal(&sem1);
+ n++;
+#if defined(SIMULATOR)
+ _sim_check_for_interrupts();
+#endif
+ } while (chVTIsSystemTimeWithinX(start, end));
+ }
+
+ /* [10.10.2] The score is printed.*/
+ test_set_step(2);
+ {
+ test_print("--- Score : ");
+ test_printn(n * 4);
+ test_println(" wait+signal/S");
}
}
-static const testcase_t rt_test_010_003 = {
- "Guarded Memory Pools timeout",
- rt_test_010_003_setup,
+static const testcase_t rt_test_010_010 = {
+ "Semaphores wait/signal performance",
+ rt_test_010_010_setup,
NULL,
- rt_test_010_003_execute
+ rt_test_010_010_execute
};
#endif /* CH_CFG_USE_SEMAPHORES */
+#if (CH_CFG_USE_MUTEXES) || defined(__DOXYGEN__)
+/**
+ * @page rt_test_010_011 [10.11] Mutexes lock/unlock performance
+ *
+ * <h2>Description</h2>
+ * A mutex is locked/unlocked into a continuous loop, no Context Switch
+ * happens because there are no other threads asking for the mutex.<br>
+ * The performance is calculated by measuring the number of iterations
+ * after a second of continuous operations.
+ *
+ * <h2>Conditions</h2>
+ * This test is only executed if the following preprocessor condition
+ * evaluates to true:
+ * - CH_CFG_USE_MUTEXES
+ * .
+ *
+ * <h2>Test Steps</h2>
+ * - [10.11.1] A mutex is locked and unlocked. The operation is
+ * repeated continuously in a one-second time window.
+ * - [10.11.2] The score is printed.
+ * .
+ */
+
+static void rt_test_010_011_setup(void) {
+ chMtxObjectInit(&mtx1);
+}
+
+static void rt_test_010_011_execute(void) {
+ uint32_t n;
+
+ /* [10.11.1] A mutex is locked and unlocked. The operation is
+ repeated continuously in a one-second time window.*/
+ test_set_step(1);
+ {
+ systime_t start, end;
+
+ n = 0;
+ start = test_wait_tick();
+ end = start + TIME_MS2I(1000);
+ do {
+ chMtxLock(&mtx1);
+ chMtxUnlock(&mtx1);
+ chMtxLock(&mtx1);
+ chMtxUnlock(&mtx1);
+ chMtxLock(&mtx1);
+ chMtxUnlock(&mtx1);
+ chMtxLock(&mtx1);
+ chMtxUnlock(&mtx1);
+ n++;
+#if defined(SIMULATOR)
+ _sim_check_for_interrupts();
+#endif
+ } while (chVTIsSystemTimeWithinX(start, end));
+ }
+
+ /* [10.11.2] The score is printed.*/
+ test_set_step(2);
+ {
+ test_print("--- Score : ");
+ test_printn(n * 4);
+ test_println(" lock+unlock/S");
+ }
+}
+
+static const testcase_t rt_test_010_011 = {
+ "Mutexes lock/unlock performance",
+ rt_test_010_011_setup,
+ NULL,
+ rt_test_010_011_execute
+};
+#endif /* CH_CFG_USE_MUTEXES */
+
+/**
+ * @page rt_test_010_012 [10.12] RAM Footprint
+ *
+ * <h2>Description</h2>
+ * The memory size of the various kernel objects is printed.
+ *
+ * <h2>Test Steps</h2>
+ * - [10.12.1] The size of the system area is printed.
+ * - [10.12.2] The size of a thread structure is printed.
+ * - [10.12.3] The size of a virtual timer structure is printed.
+ * - [10.12.4] The size of a semaphore structure is printed.
+ * - [10.12.5] The size of a mutex is printed.
+ * - [10.12.6] The size of a condition variable is printed.
+ * - [10.12.7] The size of an event source is printed.
+ * - [10.12.8] The size of an event listener is printed.
+ * - [10.12.9] The size of a mailbox is printed.
+ * .
+ */
+
+static void rt_test_010_012_execute(void) {
+
+ /* [10.12.1] The size of the system area is printed.*/
+ test_set_step(1);
+ {
+ test_print("--- System: ");
+ test_printn(sizeof(ch_system_t));
+ test_println(" bytes");
+ }
+
+ /* [10.12.2] The size of a thread structure is printed.*/
+ test_set_step(2);
+ {
+ test_print("--- Thread: ");
+ test_printn(sizeof(thread_t));
+ test_println(" bytes");
+ }
+
+ /* [10.12.3] The size of a virtual timer structure is printed.*/
+ test_set_step(3);
+ {
+ test_print("--- Timer : ");
+ test_printn(sizeof(virtual_timer_t));
+ test_println(" bytes");
+ }
+
+ /* [10.12.4] The size of a semaphore structure is printed.*/
+ test_set_step(4);
+ {
+#if CH_CFG_USE_SEMAPHORES || defined(__DOXYGEN__)
+ test_print("--- Semaph: ");
+ test_printn(sizeof(semaphore_t));
+ test_println(" bytes");
+#endif
+ }
+
+ /* [10.12.5] The size of a mutex is printed.*/
+ test_set_step(5);
+ {
+#if CH_CFG_USE_MUTEXES || defined(__DOXYGEN__)
+ test_print("--- Mutex : ");
+ test_printn(sizeof(mutex_t));
+ test_println(" bytes");
+#endif
+ }
+
+ /* [10.12.6] The size of a condition variable is printed.*/
+ test_set_step(6);
+ {
+#if CH_CFG_USE_CONDVARS || defined(__DOXYGEN__)
+ test_print("--- CondV.: ");
+ test_printn(sizeof(condition_variable_t));
+ test_println(" bytes");
+#endif
+ }
+
+ /* [10.12.7] The size of an event source is printed.*/
+ test_set_step(7);
+ {
+#if CH_CFG_USE_EVENTS || defined(__DOXYGEN__)
+ test_print("--- EventS: ");
+ test_printn(sizeof(event_source_t));
+ test_println(" bytes");
+#endif
+ }
+
+ /* [10.12.8] The size of an event listener is printed.*/
+ test_set_step(8);
+ {
+#if CH_CFG_USE_EVENTS || defined(__DOXYGEN__)
+ test_print("--- EventL: ");
+ test_printn(sizeof(event_listener_t));
+ test_println(" bytes");
+#endif
+ }
+
+ /* [10.12.9] The size of a mailbox is printed.*/
+ test_set_step(9);
+ {
+#if CH_CFG_USE_MAILBOXES || defined(__DOXYGEN__)
+ test_print("--- MailB.: ");
+ test_printn(sizeof(mailbox_t));
+ test_println(" bytes");
+#endif
+ }
+}
+
+static const testcase_t rt_test_010_012 = {
+ "RAM Footprint",
+ NULL,
+ NULL,
+ rt_test_010_012_execute
+};
+
/****************************************************************************
* Exported data.
****************************************************************************/
@@ -283,22 +1002,37 @@ static const testcase_t rt_test_010_003 = {
* @brief Array of test cases.
*/
const testcase_t * const rt_test_sequence_010_array[] = {
+#if (CH_CFG_USE_MESSAGES) || defined(__DOXYGEN__)
&rt_test_010_001,
-#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
+#endif
+#if (CH_CFG_USE_MESSAGES) || defined(__DOXYGEN__)
&rt_test_010_002,
#endif
-#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
+#if (CH_CFG_USE_MESSAGES) || defined(__DOXYGEN__)
&rt_test_010_003,
#endif
+ &rt_test_010_004,
+ &rt_test_010_005,
+ &rt_test_010_006,
+#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
+ &rt_test_010_007,
+#endif
+ &rt_test_010_008,
+ &rt_test_010_009,
+#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
+ &rt_test_010_010,
+#endif
+#if (CH_CFG_USE_MUTEXES) || defined(__DOXYGEN__)
+ &rt_test_010_011,
+#endif
+ &rt_test_010_012,
NULL
};
/**
- * @brief Memory Pools.
+ * @brief Benchmarks.
*/
const testsequence_t rt_test_sequence_010 = {
NULL,
rt_test_sequence_010_array
};
-
-#endif /* CH_CFG_USE_MEMPOOLS */
diff --git a/test/rt/source/test/rt_test_sequence_011.c b/test/rt/source/test/rt_test_sequence_011.c
deleted file mode 100644
index ca8a1a706..000000000
--- a/test/rt/source/test/rt_test_sequence_011.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 "rt_test_root.h"
-
-/**
- * @file rt_test_sequence_011.c
- * @brief Test Sequence 011 code.
- *
- * @page rt_test_sequence_011 [11] Memory Heaps
- *
- * File: @ref rt_test_sequence_011.c
- *
- * <h2>Description</h2>
- * This sequence tests the ChibiOS/RT 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 rt_test_011_001
- * - @subpage rt_test_011_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 rt_test_011_001 [11.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>
- * - [11.1.1] Testing initial conditions, the heap must not be
- * fragmented and one free block present.
- * - [11.1.2] Trying to allocate an block bigger than available space,
- * an error is expected.
- * - [11.1.3] Single block allocation using chHeapAlloc() then the
- * block is freed using chHeapFree(), must not fail.
- * - [11.1.4] Using chHeapStatus() to assess the heap state. There must
- * be at least one free block of sufficient size.
- * - [11.1.5] Allocating then freeing in the same order.
- * - [11.1.6] Allocating then freeing in reverse order.
- * - [11.1.7] Small fragments handling. Checking the behavior when
- * allocating blocks with size not multiple of alignment unit.
- * - [11.1.8] Skipping a fragment, the first fragment in the list is
- * too small so the allocator must pick the second one.
- * - [11.1.9] Allocating the whole available space.
- * - [11.1.10] Testing final conditions. The heap geometry must be the
- * same than the one registered at beginning.
- * .
- */
-
-static void rt_test_011_001_setup(void) {
- chHeapObjectInit(&test_heap, test_buffer, sizeof(test_buffer));
-}
-
-static void rt_test_011_001_execute(void) {
- void *p1, *p2, *p3;
- size_t n, sz;
-
- /* [11.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");
- }
-
- /* [11.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");
- }
-
- /* [11.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);
- }
-
- /* [11.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");
- }
-
- /* [11.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");
- }
-
- /* [11.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");
- }
-
- /* [11.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");
- }
-
- /* [11.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");
- }
-
- /* [11.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);
- }
-
- /* [11.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 rt_test_011_001 = {
- "Allocation and fragmentation",
- rt_test_011_001_setup,
- NULL,
- rt_test_011_001_execute
-};
-
-/**
- * @page rt_test_011_002 [11.2] Default Heap
- *
- * <h2>Description</h2>
- * The default heap is pre-allocated in the system. We test base
- * functionality.
- *
- * <h2>Test Steps</h2>
- * - [11.2.1] Single block allocation using chHeapAlloc() then the
- * block is freed using chHeapFree(), must not fail.
- * - [11.2.2] Testing allocation failure.
- * .
- */
-
-static void rt_test_011_002_execute(void) {
- void *p1;
- size_t total_size, largest_size;
-
- /* [11.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);
- }
-
- /* [11.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 rt_test_011_002 = {
- "Default Heap",
- NULL,
- NULL,
- rt_test_011_002_execute
-};
-
-/****************************************************************************
- * Exported data.
- ****************************************************************************/
-
-/**
- * @brief Array of test cases.
- */
-const testcase_t * const rt_test_sequence_011_array[] = {
- &rt_test_011_001,
- &rt_test_011_002,
- NULL
-};
-
-/**
- * @brief Memory Heaps.
- */
-const testsequence_t rt_test_sequence_011 = {
- NULL,
- rt_test_sequence_011_array
-};
-
-#endif /* CH_CFG_USE_HEAP */
diff --git a/test/rt/source/test/rt_test_sequence_011.h b/test/rt/source/test/rt_test_sequence_011.h
deleted file mode 100644
index 36a60968e..000000000
--- a/test/rt/source/test/rt_test_sequence_011.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 rt_test_sequence_011.h
- * @brief Test Sequence 011 header.
- */
-
-#ifndef RT_TEST_SEQUENCE_011_H
-#define RT_TEST_SEQUENCE_011_H
-
-extern const testsequence_t rt_test_sequence_011;
-
-#endif /* RT_TEST_SEQUENCE_011_H */
diff --git a/test/rt/source/test/rt_test_sequence_012.c b/test/rt/source/test/rt_test_sequence_012.c
deleted file mode 100644
index 06f0fe8cf..000000000
--- a/test/rt/source/test/rt_test_sequence_012.c
+++ /dev/null
@@ -1,291 +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 "rt_test_root.h"
-
-/**
- * @file rt_test_sequence_012.c
- * @brief Test Sequence 012 code.
- *
- * @page rt_test_sequence_012 [12] Dynamic threads
- *
- * File: @ref rt_test_sequence_012.c
- *
- * <h2>Description</h2>
- * This module implements the test sequence for the dynamic thread
- * creation APIs.
- *
- * <h2>Conditions</h2>
- * This sequence is only executed if the following preprocessor condition
- * evaluates to true:
- * - CH_CFG_USE_DYNAMIC
- * .
- *
- * <h2>Test Cases</h2>
- * - @subpage rt_test_012_001
- * - @subpage rt_test_012_002
- * .
- */
-
-#if (CH_CFG_USE_DYNAMIC) || defined(__DOXYGEN__)
-
-/****************************************************************************
- * Shared code.
- ****************************************************************************/
-
-#if CH_CFG_USE_HEAP
-static memory_heap_t heap1;
-#endif
-#if CH_CFG_USE_MEMPOOLS
-static memory_pool_t mp1;
-#endif
-
-static THD_FUNCTION(dyn_thread1, p) {
-
- test_emit_token(*(char *)p);
-}
-
-/****************************************************************************
- * Test cases.
- ****************************************************************************/
-
-#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
-/**
- * @page rt_test_012_001 [12.1] Threads creation from Memory Heap
- *
- * <h2>Description</h2>
- * Two threads are started by allocating the memory from the Memory
- * Heap then a third thread is started with a huge stack
- * requirement.<br> The test expects the first two threads to
- * successfully start and the third one to fail.
- *
- * <h2>Conditions</h2>
- * This test is only executed if the following preprocessor condition
- * evaluates to true:
- * - CH_CFG_USE_HEAP
- * .
- *
- * <h2>Test Steps</h2>
- * - [12.1.1] Getting base priority for threads.
- * - [12.1.2] Getting heap info before the test.
- * - [12.1.3] Creating thread 1, it is expected to succeed.
- * - [12.1.4] Creating thread 2, it is expected to succeed.
- * - [12.1.5] Creating thread 3, it is expected to fail.
- * - [12.1.6] Letting threads execute then checking the start order and
- * freeing memory.
- * - [12.1.7] Getting heap info again for verification.
- * .
- */
-
-static void rt_test_012_001_setup(void) {
- chHeapObjectInit(&heap1, test_buffer, sizeof test_buffer);
-}
-
-static void rt_test_012_001_execute(void) {
- size_t n1, total1, largest1;
- size_t n2, total2, largest2;
- tprio_t prio;
-
- /* [12.1.1] Getting base priority for threads.*/
- test_set_step(1);
- {
- prio = chThdGetPriorityX();
- }
-
- /* [12.1.2] Getting heap info before the test.*/
- test_set_step(2);
- {
- n1 = chHeapStatus(&heap1, &total1, &largest1);
- test_assert(n1 == 1, "heap fragmented");
- }
-
- /* [12.1.3] Creating thread 1, it is expected to succeed.*/
- test_set_step(3);
- {
- threads[0] = chThdCreateFromHeap(&heap1,
- THD_WORKING_AREA_SIZE(THREADS_STACK_SIZE),
- "dyn1",
- prio-1, dyn_thread1, "A");
- test_assert(threads[0] != NULL, "thread creation failed");
- }
-
- /* [12.1.4] Creating thread 2, it is expected to succeed.*/
- test_set_step(4);
- {
- threads[1] = chThdCreateFromHeap(&heap1,
- THD_WORKING_AREA_SIZE(THREADS_STACK_SIZE),
- "dyn2",
- prio-2, dyn_thread1, "B");
- test_assert(threads[1] != NULL, "thread creation failed");
- }
-
- /* [12.1.5] Creating thread 3, it is expected to fail.*/
- test_set_step(5);
- {
- threads[2] = chThdCreateFromHeap(&heap1,
- THD_WORKING_AREA_SIZE(THREADS_STACK_SIZE * 1024),
- "dyn3",
- prio-3, dyn_thread1, "C");
- test_assert(threads[2] == NULL, "thread creation not failed");
- }
-
- /* [12.1.6] Letting threads execute then checking the start order and
- freeing memory.*/
- test_set_step(6);
- {
- test_wait_threads();
- test_assert_sequence("AB", "invalid sequence");
- }
-
- /* [12.1.7] Getting heap info again for verification.*/
- test_set_step(7);
- {
- n2 = chHeapStatus(&heap1, &total2, &largest2);
- test_assert(n1 == n2, "fragmentation changed");
- test_assert(total1 == total2, "total free space changed");
- test_assert(largest1 == largest2, "largest fragment size changed");
- }
-}
-
-static const testcase_t rt_test_012_001 = {
- "Threads creation from Memory Heap",
- rt_test_012_001_setup,
- NULL,
- rt_test_012_001_execute
-};
-#endif /* CH_CFG_USE_HEAP */
-
-#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
-/**
- * @page rt_test_012_002 [12.2] Threads creation from Memory Pool
- *
- * <h2>Description</h2>
- * Five thread creation are attempted from a pool containing only four
- * elements.<br> The test expects the first four threads to
- * successfully start and the last one to fail.
- *
- * <h2>Conditions</h2>
- * This test is only executed if the following preprocessor condition
- * evaluates to true:
- * - CH_CFG_USE_MEMPOOLS
- * .
- *
- * <h2>Test Steps</h2>
- * - [12.2.1] Adding four working areas to the pool.
- * - [12.2.2] Getting base priority for threads.
- * - [12.2.3] Creating the five threads.
- * - [12.2.4] Testing that only the fifth thread creation failed.
- * - [12.2.5] Letting them run, free the memory then checking the
- * execution sequence.
- * - [12.2.6] Testing that the pool contains four elements again.
- * .
- */
-
-static void rt_test_012_002_setup(void) {
- chPoolObjectInit(&mp1, THD_WORKING_AREA_SIZE(THREADS_STACK_SIZE), NULL);
-}
-
-static void rt_test_012_002_execute(void) {
- unsigned i;
- tprio_t prio;
-
- /* [12.2.1] Adding four working areas to the pool.*/
- test_set_step(1);
- {
- for (i = 0; i < 4; i++)
- chPoolFree(&mp1, wa[i]);
- }
-
- /* [12.2.2] Getting base priority for threads.*/
- test_set_step(2);
- {
- prio = chThdGetPriorityX();
- }
-
- /* [12.2.3] Creating the five threads.*/
- test_set_step(3);
- {
- threads[0] = chThdCreateFromMemoryPool(&mp1, "dyn1", prio-1, dyn_thread1, "A");
- threads[1] = chThdCreateFromMemoryPool(&mp1, "dyn2", prio-2, dyn_thread1, "B");
- threads[2] = chThdCreateFromMemoryPool(&mp1, "dyn3", prio-3, dyn_thread1, "C");
- threads[3] = chThdCreateFromMemoryPool(&mp1, "dyn4", prio-4, dyn_thread1, "D");
- threads[4] = chThdCreateFromMemoryPool(&mp1, "dyn5", prio-5, dyn_thread1, "E");
- }
-
- /* [12.2.4] Testing that only the fifth thread creation failed.*/
- test_set_step(4);
- {
- test_assert((threads[0] != NULL) &&
- (threads[1] != NULL) &&
- (threads[2] != NULL) &&
- (threads[3] != NULL),
- "thread creation failed");
- test_assert(threads[4] == NULL,
- "thread creation not failed");
- }
-
- /* [12.2.5] Letting them run, free the memory then checking the
- execution sequence.*/
- test_set_step(5);
- {
- test_wait_threads();
- test_assert_sequence("ABCD", "invalid sequence");
- }
-
- /* [12.2.6] Testing that the pool contains four elements again.*/
- test_set_step(6);
- {
- for (i = 0; i < 4; i++)
- test_assert(chPoolAlloc(&mp1) != NULL, "pool list empty");
- test_assert(chPoolAlloc(&mp1) == NULL, "pool list not empty");
- }
-}
-
-static const testcase_t rt_test_012_002 = {
- "Threads creation from Memory Pool",
- rt_test_012_002_setup,
- NULL,
- rt_test_012_002_execute
-};
-#endif /* CH_CFG_USE_MEMPOOLS */
-
-/****************************************************************************
- * Exported data.
- ****************************************************************************/
-
-/**
- * @brief Array of test cases.
- */
-const testcase_t * const rt_test_sequence_012_array[] = {
-#if (CH_CFG_USE_HEAP) || defined(__DOXYGEN__)
- &rt_test_012_001,
-#endif
-#if (CH_CFG_USE_MEMPOOLS) || defined(__DOXYGEN__)
- &rt_test_012_002,
-#endif
- NULL
-};
-
-/**
- * @brief Dynamic threads.
- */
-const testsequence_t rt_test_sequence_012 = {
- NULL,
- rt_test_sequence_012_array
-};
-
-#endif /* CH_CFG_USE_DYNAMIC */
diff --git a/test/rt/source/test/rt_test_sequence_012.h b/test/rt/source/test/rt_test_sequence_012.h
deleted file mode 100644
index 3adee9c66..000000000
--- a/test/rt/source/test/rt_test_sequence_012.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 rt_test_sequence_012.h
- * @brief Test Sequence 012 header.
- */
-
-#ifndef RT_TEST_SEQUENCE_012_H
-#define RT_TEST_SEQUENCE_012_H
-
-extern const testsequence_t rt_test_sequence_012;
-
-#endif /* RT_TEST_SEQUENCE_012_H */
diff --git a/test/rt/source/test/rt_test_sequence_013.c b/test/rt/source/test/rt_test_sequence_013.c
deleted file mode 100644
index 70b80ba88..000000000
--- a/test/rt/source/test/rt_test_sequence_013.c
+++ /dev/null
@@ -1,1038 +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 "rt_test_root.h"
-
-/**
- * @file rt_test_sequence_013.c
- * @brief Test Sequence 013 code.
- *
- * @page rt_test_sequence_013 [13] Benchmarks
- *
- * File: @ref rt_test_sequence_013.c
- *
- * <h2>Description</h2>
- * This module implements a series of system benchmarks. The benchmarks
- * are useful as a stress test and as a reference when comparing
- * ChibiOS/RT with similar systems.<br> Objective of the test sequence
- * is to provide a performance index for the most critical system
- * subsystems. The performance numbers allow to discover performance
- * regressions between successive ChibiOS/RT releases.
- *
- * <h2>Test Cases</h2>
- * - @subpage rt_test_013_001
- * - @subpage rt_test_013_002
- * - @subpage rt_test_013_003
- * - @subpage rt_test_013_004
- * - @subpage rt_test_013_005
- * - @subpage rt_test_013_006
- * - @subpage rt_test_013_007
- * - @subpage rt_test_013_008
- * - @subpage rt_test_013_009
- * - @subpage rt_test_013_010
- * - @subpage rt_test_013_011
- * - @subpage rt_test_013_012
- * .
- */
-
-/****************************************************************************
- * Shared code.
- ****************************************************************************/
-
-#if CH_CFG_USE_SEMAPHORES || defined(__DOXYGEN__)
-static semaphore_t sem1;
-#endif
-#if CH_CFG_USE_MUTEXES || defined(__DOXYGEN__)
-static mutex_t mtx1;
-#endif
-
-static void tmo(void *param) {(void)param;}
-
-#if CH_CFG_USE_MESSAGES
-static THD_FUNCTION(bmk_thread1, p) {
- thread_t *tp;
- msg_t msg;
-
- (void)p;
- do {
- tp = chMsgWait();
- msg = chMsgGet(tp);
- chMsgRelease(tp, msg);
- } while (msg);
-}
-
-NOINLINE static unsigned int msg_loop_test(thread_t *tp) {
- systime_t start, end;
-
- uint32_t n = 0;
- start = test_wait_tick();
- end = start + TIME_MS2I(1000);
- do {
- (void)chMsgSend(tp, 1);
- n++;
-#if defined(SIMULATOR)
- _sim_check_for_interrupts();
-#endif
- } while (chVTIsSystemTimeWithinX(start, end));
- (void)chMsgSend(tp, 0);
- return n;
-}
-#endif
-
-static THD_FUNCTION(bmk_thread3, p) {
-
- chThdExit((msg_t)p);
-}
-
-static THD_FUNCTION(bmk_thread4, p) {
- msg_t msg;
- thread_t *self = chThdGetSelfX();
-
- (void)p;
- chSysLock();
- do {
- chSchGoSleepS(CH_STATE_SUSPENDED);
- msg = self->u.rdymsg;
- } while (msg == MSG_OK);
- chSysUnlock();
-}
-
-#if CH_CFG_USE_SEMAPHORES
-static THD_FUNCTION(bmk_thread7, p) {
-
- (void)p;
- while (!chThdShouldTerminateX())
- chSemWait(&sem1);
-}
-#endif
-
-static THD_FUNCTION(bmk_thread8, p) {
-
- do {
- chThdYield();
- chThdYield();
- chThdYield();
- chThdYield();
- (*(uint32_t *)p) += 4;
-#if defined(SIMULATOR)
- _sim_check_for_interrupts();
-#endif
- } while(!chThdShouldTerminateX());
-}
-
-/****************************************************************************
- * Test cases.
- ****************************************************************************/
-
-#if (CH_CFG_USE_MESSAGES) || defined(__DOXYGEN__)
-/**
- * @page rt_test_013_001 [13.1] Messages performance #1
- *
- * <h2>Description</h2>
- * A message server thread is created with a lower priority than the
- * client thread, the messages throughput per second is measured and
- * the result printed on the output log.
- *
- * <h2>Conditions</h2>
- * This test is only executed if the following preprocessor condition
- * evaluates to true:
- * - CH_CFG_USE_MESSAGES
- * .
- *
- * <h2>Test Steps</h2>
- * - [13.1.1] The messenger thread is started at a lower priority than
- * the current thread.
- * - [13.1.2] The number of messages exchanged is counted in a one
- * second time window.
- * - [13.1.3] Score is printed.
- * .
- */
-
-static void rt_test_013_001_execute(void) {
- uint32_t n;
-
- /* [13.1.1] The messenger thread is started at a lower priority than
- the current thread.*/
- test_set_step(1);
- {
- threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-1, bmk_thread1, NULL);
- }
-
- /* [13.1.2] The number of messages exchanged is counted in a one
- second time window.*/
- test_set_step(2);
- {
- n = msg_loop_test(threads[0]);
- test_wait_threads();
- }
-
- /* [13.1.3] Score is printed.*/
- test_set_step(3);
- {
- test_print("--- Score : ");
- test_printn(n);
- test_print(" msgs/S, ");
- test_printn(n << 1);
- test_println(" ctxswc/S");
- }
-}
-
-static const testcase_t rt_test_013_001 = {
- "Messages performance #1",
- NULL,
- NULL,
- rt_test_013_001_execute
-};
-#endif /* CH_CFG_USE_MESSAGES */
-
-#if (CH_CFG_USE_MESSAGES) || defined(__DOXYGEN__)
-/**
- * @page rt_test_013_002 [13.2] Messages performance #2
- *
- * <h2>Description</h2>
- * A message server thread is created with an higher priority than the
- * client thread, the messages throughput per second is measured and
- * the result printed on the output log.
- *
- * <h2>Conditions</h2>
- * This test is only executed if the following preprocessor condition
- * evaluates to true:
- * - CH_CFG_USE_MESSAGES
- * .
- *
- * <h2>Test Steps</h2>
- * - [13.2.1] The messenger thread is started at an higher priority
- * than the current thread.
- * - [13.2.2] The number of messages exchanged is counted in a one
- * second time window.
- * - [13.2.3] Score is printed.
- * .
- */
-
-static void rt_test_013_002_execute(void) {
- uint32_t n;
-
- /* [13.2.1] The messenger thread is started at an higher priority
- than the current thread.*/
- test_set_step(1);
- {
- threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, bmk_thread1, NULL);
- }
-
- /* [13.2.2] The number of messages exchanged is counted in a one
- second time window.*/
- test_set_step(2);
- {
- n = msg_loop_test(threads[0]);
- test_wait_threads();
- }
-
- /* [13.2.3] Score is printed.*/
- test_set_step(3);
- {
- test_print("--- Score : ");
- test_printn(n);
- test_print(" msgs/S, ");
- test_printn(n << 1);
- test_println(" ctxswc/S");
- }
-}
-
-static const testcase_t rt_test_013_002 = {
- "Messages performance #2",
- NULL,
- NULL,
- rt_test_013_002_execute
-};
-#endif /* CH_CFG_USE_MESSAGES */
-
-#if (CH_CFG_USE_MESSAGES) || defined(__DOXYGEN__)
-/**
- * @page rt_test_013_003 [13.3] Messages performance #3
- *
- * <h2>Description</h2>
- * A message server thread is created with an higher priority than the
- * client thread, four lower priority threads crowd the ready list, the
- * messages throughput per second is measured while the ready list and
- * the result printed on the output log.
- *
- * <h2>Conditions</h2>
- * This test is only executed if the following preprocessor condition
- * evaluates to true:
- * - CH_CFG_USE_MESSAGES
- * .
- *
- * <h2>Test Steps</h2>
- * - [13.3.1] The messenger thread is started at an higher priority
- * than the current thread.
- * - [13.3.2] Four threads are started at a lower priority than the
- * current thread.
- * - [13.3.3] The number of messages exchanged is counted in a one
- * second time window.
- * - [13.3.4] Score is printed.
- * .
- */
-
-static void rt_test_013_003_execute(void) {
- uint32_t n;
-
- /* [13.3.1] The messenger thread is started at an higher priority
- than the current thread.*/
- test_set_step(1);
- {
- threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1, bmk_thread1, NULL);
- }
-
- /* [13.3.2] Four threads are started at a lower priority than the
- current thread.*/
- test_set_step(2);
- {
- threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-2, bmk_thread3, NULL);
- threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-3, bmk_thread3, NULL);
- threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-4, bmk_thread3, NULL);
- threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-5, bmk_thread3, NULL);
- }
-
- /* [13.3.3] The number of messages exchanged is counted in a one
- second time window.*/
- test_set_step(3);
- {
- n = msg_loop_test(threads[0]);
- test_wait_threads();
- }
-
- /* [13.3.4] Score is printed.*/
- test_set_step(4);
- {
- test_print("--- Score : ");
- test_printn(n);
- test_print(" msgs/S, ");
- test_printn(n << 1);
- test_println(" ctxswc/S");
- }
-}
-
-static const testcase_t rt_test_013_003 = {
- "Messages performance #3",
- NULL,
- NULL,
- rt_test_013_003_execute
-};
-#endif /* CH_CFG_USE_MESSAGES */
-
-/**
- * @page rt_test_013_004 [13.4] Context Switch performance
- *
- * <h2>Description</h2>
- * A thread is created that just performs a @p chSchGoSleepS() into a
- * loop, the thread is awakened as fast is possible by the tester
- * thread.<br> The Context Switch performance is calculated by
- * measuring the number of iterations after a second of continuous
- * operations.
- *
- * <h2>Test Steps</h2>
- * - [13.4.1] Starting the target thread at an higher priority level.
- * - [13.4.2] Waking up the thread as fast as possible in a one second
- * time window.
- * - [13.4.3] Stopping the target thread.
- * - [13.4.4] Score is printed.
- * .
- */
-
-static void rt_test_013_004_execute(void) {
- thread_t *tp;
- uint32_t n;
-
- /* [13.4.1] Starting the target thread at an higher priority level.*/
- test_set_step(1);
- {
- tp = threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+1,
- bmk_thread4, NULL);
- }
-
- /* [13.4.2] Waking up the thread as fast as possible in a one second
- time window.*/
- test_set_step(2);
- {
- systime_t start, end;
-
- n = 0;
- start = test_wait_tick();
- end = start + TIME_MS2I(1000);
- do {
- chSysLock();
- chSchWakeupS(tp, MSG_OK);
- chSchWakeupS(tp, MSG_OK);
- chSchWakeupS(tp, MSG_OK);
- chSchWakeupS(tp, MSG_OK);
- chSysUnlock();
- n += 4;
-#if defined(SIMULATOR)
- _sim_check_for_interrupts();
-#endif
- } while (chVTIsSystemTimeWithinX(start, end));
- }
-
- /* [13.4.3] Stopping the target thread.*/
- test_set_step(3);
- {
- chSysLock();
- chSchWakeupS(tp, MSG_TIMEOUT);
- chSysUnlock();
- test_wait_threads();
- }
-
- /* [13.4.4] Score is printed.*/
- test_set_step(4);
- {
- test_print("--- Score : ");
- test_printn(n * 2);
- test_println(" ctxswc/S");
- }
-}
-
-static const testcase_t rt_test_013_004 = {
- "Context Switch performance",
- NULL,
- NULL,
- rt_test_013_004_execute
-};
-
-/**
- * @page rt_test_013_005 [13.5] Threads performance, full cycle
- *
- * <h2>Description</h2>
- * Threads are continuously created and terminated into a loop. A full
- * chThdCreateStatic() / @p chThdExit() / @p chThdWait() cycle is
- * performed in each iteration.<br> The performance is calculated by
- * measuring the number of iterations after a second of continuous
- * operations.
- *
- * <h2>Test Steps</h2>
- * - [13.5.1] A thread is created at a lower priority level and its
- * termination detected using @p chThdWait(). The operation is
- * repeated continuously in a one-second time window.
- * - [13.5.2] Score is printed.
- * .
- */
-
-static void rt_test_013_005_execute(void) {
- uint32_t n;
- tprio_t prio = chThdGetPriorityX() - 1;
- systime_t start, end;
-
- /* [13.5.1] A thread is created at a lower priority level and its
- termination detected using @p chThdWait(). The operation is
- repeated continuously in a one-second time window.*/
- test_set_step(1);
- {
- n = 0;
- start = test_wait_tick();
- end = start + TIME_MS2I(1000);
- do {
- chThdWait(chThdCreateStatic(wa[0], WA_SIZE, prio, bmk_thread3, NULL));
- n++;
-#if defined(SIMULATOR)
- _sim_check_for_interrupts();
-#endif
- } while (chVTIsSystemTimeWithinX(start, end));
- }
-
- /* [13.5.2] Score is printed.*/
- test_set_step(2);
- {
- test_print("--- Score : ");
- test_printn(n);
- test_println(" threads/S");
- }
-}
-
-static const testcase_t rt_test_013_005 = {
- "Threads performance, full cycle",
- NULL,
- NULL,
- rt_test_013_005_execute
-};
-
-/**
- * @page rt_test_013_006 [13.6] Threads performance, create/exit only
- *
- * <h2>Description</h2>
- * Threads are continuously created and terminated into a loop. A
- * partial @p chThdCreateStatic() / @p chThdExit() cycle is performed
- * in each iteration, the @p chThdWait() is not necessary because the
- * thread is created at an higher priority so there is no need to wait
- * for it to terminate.<br> The performance is calculated by measuring
- * the number of iterations after a second of continuous operations.
- *
- * <h2>Test Steps</h2>
- * - [13.6.1] A thread is created at an higher priority level and let
- * terminate immediately. The operation is repeated continuously in a
- * one-second time window.
- * - [13.6.2] Score is printed.
- * .
- */
-
-static void rt_test_013_006_execute(void) {
- uint32_t n;
- tprio_t prio = chThdGetPriorityX() + 1;
- systime_t start, end;
-
- /* [13.6.1] A thread is created at an higher priority level and let
- terminate immediately. The operation is repeated continuously in a
- one-second time window.*/
- test_set_step(1);
- {
- n = 0;
- start = test_wait_tick();
- end = start + TIME_MS2I(1000);
- do {
-#if CH_CFG_USE_REGISTRY
- chThdRelease(chThdCreateStatic(wa[0], WA_SIZE, prio, bmk_thread3, NULL));
-#else
- chThdCreateStatic(wa[0], WA_SIZE, prio, bmk_thread3, NULL);
-#endif
- n++;
-#if defined(SIMULATOR)
- _sim_check_for_interrupts();
-#endif
- } while (chVTIsSystemTimeWithinX(start, end));
- }
-
- /* [13.6.2] Score is printed.*/
- test_set_step(2);
- {
- test_print("--- Score : ");
- test_printn(n);
- test_println(" threads/S");
- }
-}
-
-static const testcase_t rt_test_013_006 = {
- "Threads performance, create/exit only",
- NULL,
- NULL,
- rt_test_013_006_execute
-};
-
-#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
-/**
- * @page rt_test_013_007 [13.7] Mass reschedule performance
- *
- * <h2>Description</h2>
- * Five threads are created and atomically rescheduled by resetting the
- * semaphore where they are waiting on. The operation is performed into
- * a continuous loop.<br> The performance is calculated by measuring
- * the number of iterations after a second of continuous operations.
- *
- * <h2>Conditions</h2>
- * This test is only executed if the following preprocessor condition
- * evaluates to true:
- * - CH_CFG_USE_SEMAPHORES
- * .
- *
- * <h2>Test Steps</h2>
- * - [13.7.1] Five threads are created at higher priority that
- * immediately enqueue on a semaphore.
- * - [13.7.2] The semaphore is reset waking up the five threads. The
- * operation is repeated continuously in a one-second time window.
- * - [13.7.3] The five threads are terminated.
- * - [13.7.4] The score is printed.
- * .
- */
-
-static void rt_test_013_007_setup(void) {
- chSemObjectInit(&sem1, 0);
-}
-
-static void rt_test_013_007_execute(void) {
- uint32_t n;
-
- /* [13.7.1] Five threads are created at higher priority that
- immediately enqueue on a semaphore.*/
- test_set_step(1);
- {
- threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()+5, bmk_thread7, NULL);
- threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()+4, bmk_thread7, NULL);
- threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()+3, bmk_thread7, NULL);
- threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()+2, bmk_thread7, NULL);
- threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()+1, bmk_thread7, NULL);
- }
-
- /* [13.7.2] The semaphore is reset waking up the five threads. The
- operation is repeated continuously in a one-second time window.*/
- test_set_step(2);
- {
- systime_t start, end;
-
- n = 0;
- start = test_wait_tick();
- end = start + TIME_MS2I(1000);
- do {
- chSemReset(&sem1, 0);
- n++;
-#if defined(SIMULATOR)
- _sim_check_for_interrupts();
-#endif
- } while (chVTIsSystemTimeWithinX(start, end));
- }
-
- /* [13.7.3] The five threads are terminated.*/
- test_set_step(3);
- {
- test_terminate_threads();
- chSemReset(&sem1, 0);
- test_wait_threads();
- }
-
- /* [13.7.4] The score is printed.*/
- test_set_step(4);
- {
- test_print("--- Score : ");
- test_printn(n);
- test_print(" reschedules/S, ");
- test_printn(n * 6);
- test_println(" ctxswc/S");
- }
-}
-
-static const testcase_t rt_test_013_007 = {
- "Mass reschedule performance",
- rt_test_013_007_setup,
- NULL,
- rt_test_013_007_execute
-};
-#endif /* CH_CFG_USE_SEMAPHORES */
-
-/**
- * @page rt_test_013_008 [13.8] Round-Robin voluntary reschedule
- *
- * <h2>Description</h2>
- * Five threads are created at equal priority, each thread just
- * increases a variable and yields.<br> The performance is calculated
- * by measuring the number of iterations after a second of continuous
- * operations.
- *
- * <h2>Test Steps</h2>
- * - [13.8.1] The five threads are created at lower priority. The
- * threds have equal priority and start calling @p chThdYield()
- * continuously.
- * - [13.8.2] Waiting one second then terminating the 5 threads.
- * - [13.8.3] The score is printed.
- * .
- */
-
-static void rt_test_013_008_execute(void) {
- uint32_t n;
-
- /* [13.8.1] The five threads are created at lower priority. The
- threds have equal priority and start calling @p chThdYield()
- continuously.*/
- test_set_step(1);
- {
- n = 0;
- test_wait_tick();threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
-
- threads[1] = chThdCreateStatic(wa[1], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
- threads[2] = chThdCreateStatic(wa[2], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
- threads[3] = chThdCreateStatic(wa[3], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
- threads[4] = chThdCreateStatic(wa[4], WA_SIZE, chThdGetPriorityX()-1, bmk_thread8, (void *)&n);
- }
-
- /* [13.8.2] Waiting one second then terminating the 5 threads.*/
- test_set_step(2);
- {
- chThdSleepSeconds(1);
- test_terminate_threads();
- test_wait_threads();
- }
-
- /* [13.8.3] The score is printed.*/
- test_set_step(3);
- {
- test_print("--- Score : ");
- test_printn(n);
- test_println(" ctxswc/S");
- }
-}
-
-static const testcase_t rt_test_013_008 = {
- "Round-Robin voluntary reschedule",
- NULL,
- NULL,
- rt_test_013_008_execute
-};
-
-/**
- * @page rt_test_013_009 [13.9] Virtual Timers set/reset performance
- *
- * <h2>Description</h2>
- * A virtual timer is set and immediately reset into a continuous
- * loop.<br> The performance is calculated by measuring the number of
- * iterations after a second of continuous operations.
- *
- * <h2>Test Steps</h2>
- * - [13.9.1] Two timers are set then reset without waiting for their
- * counter to elapse. The operation is repeated continuously in a
- * one-second time window.
- * - [13.9.2] The score is printed.
- * .
- */
-
-static void rt_test_013_009_execute(void) {
- static virtual_timer_t vt1, vt2;
- uint32_t n;
-
- /* [13.9.1] Two timers are set then reset without waiting for their
- counter to elapse. The operation is repeated continuously in a
- one-second time window.*/
- test_set_step(1);
- {
- systime_t start, end;
-
- n = 0;
- start = test_wait_tick();
- end = start + TIME_MS2I(1000);
- do {
- chSysLock();
- chVTDoSetI(&vt1, 1, tmo, NULL);
- chVTDoSetI(&vt2, 10000, tmo, NULL);
- chVTDoResetI(&vt1);
- chVTDoResetI(&vt2);
- chSysUnlock();
- n++;
-#if defined(SIMULATOR)
- _sim_check_for_interrupts();
-#endif
- } while (chVTIsSystemTimeWithinX(start, end));
- }
-
- /* [13.9.2] The score is printed.*/
- test_set_step(2);
- {
- test_print("--- Score : ");
- test_printn(n * 2);
- test_println(" timers/S");
- }
-}
-
-static const testcase_t rt_test_013_009 = {
- "Virtual Timers set/reset performance",
- NULL,
- NULL,
- rt_test_013_009_execute
-};
-
-#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
-/**
- * @page rt_test_013_010 [13.10] Semaphores wait/signal performance
- *
- * <h2>Description</h2>
- * A counting semaphore is taken/released into a continuous loop, no
- * Context Switch happens because the counter is always non
- * negative.<br> The performance is calculated by measuring the number
- * of iterations after a second of continuous operations.
- *
- * <h2>Conditions</h2>
- * This test is only executed if the following preprocessor condition
- * evaluates to true:
- * - CH_CFG_USE_SEMAPHORES
- * .
- *
- * <h2>Test Steps</h2>
- * - [13.10.1] A semaphore is teken and released. The operation is
- * repeated continuously in a one-second time window.
- * - [13.10.2] The score is printed.
- * .
- */
-
-static void rt_test_013_010_setup(void) {
- chSemObjectInit(&sem1, 1);
-}
-
-static void rt_test_013_010_execute(void) {
- uint32_t n;
-
- /* [13.10.1] A semaphore is teken and released. The operation is
- repeated continuously in a one-second time window.*/
- test_set_step(1);
- {
- systime_t start, end;
-
- n = 0;
- start = test_wait_tick();
- end = start + TIME_MS2I(1000);
- do {
- chSemWait(&sem1);
- chSemSignal(&sem1);
- chSemWait(&sem1);
- chSemSignal(&sem1);
- chSemWait(&sem1);
- chSemSignal(&sem1);
- chSemWait(&sem1);
- chSemSignal(&sem1);
- n++;
-#if defined(SIMULATOR)
- _sim_check_for_interrupts();
-#endif
- } while (chVTIsSystemTimeWithinX(start, end));
- }
-
- /* [13.10.2] The score is printed.*/
- test_set_step(2);
- {
- test_print("--- Score : ");
- test_printn(n * 4);
- test_println(" wait+signal/S");
- }
-}
-
-static const testcase_t rt_test_013_010 = {
- "Semaphores wait/signal performance",
- rt_test_013_010_setup,
- NULL,
- rt_test_013_010_execute
-};
-#endif /* CH_CFG_USE_SEMAPHORES */
-
-#if (CH_CFG_USE_MUTEXES) || defined(__DOXYGEN__)
-/**
- * @page rt_test_013_011 [13.11] Mutexes lock/unlock performance
- *
- * <h2>Description</h2>
- * A mutex is locked/unlocked into a continuous loop, no Context Switch
- * happens because there are no other threads asking for the mutex.<br>
- * The performance is calculated by measuring the number of iterations
- * after a second of continuous operations.
- *
- * <h2>Conditions</h2>
- * This test is only executed if the following preprocessor condition
- * evaluates to true:
- * - CH_CFG_USE_MUTEXES
- * .
- *
- * <h2>Test Steps</h2>
- * - [13.11.1] A mutex is locked and unlocked. The operation is
- * repeated continuously in a one-second time window.
- * - [13.11.2] The score is printed.
- * .
- */
-
-static void rt_test_013_011_setup(void) {
- chMtxObjectInit(&mtx1);
-}
-
-static void rt_test_013_011_execute(void) {
- uint32_t n;
-
- /* [13.11.1] A mutex is locked and unlocked. The operation is
- repeated continuously in a one-second time window.*/
- test_set_step(1);
- {
- systime_t start, end;
-
- n = 0;
- start = test_wait_tick();
- end = start + TIME_MS2I(1000);
- do {
- chMtxLock(&mtx1);
- chMtxUnlock(&mtx1);
- chMtxLock(&mtx1);
- chMtxUnlock(&mtx1);
- chMtxLock(&mtx1);
- chMtxUnlock(&mtx1);
- chMtxLock(&mtx1);
- chMtxUnlock(&mtx1);
- n++;
-#if defined(SIMULATOR)
- _sim_check_for_interrupts();
-#endif
- } while (chVTIsSystemTimeWithinX(start, end));
- }
-
- /* [13.11.2] The score is printed.*/
- test_set_step(2);
- {
- test_print("--- Score : ");
- test_printn(n * 4);
- test_println(" lock+unlock/S");
- }
-}
-
-static const testcase_t rt_test_013_011 = {
- "Mutexes lock/unlock performance",
- rt_test_013_011_setup,
- NULL,
- rt_test_013_011_execute
-};
-#endif /* CH_CFG_USE_MUTEXES */
-
-/**
- * @page rt_test_013_012 [13.12] RAM Footprint
- *
- * <h2>Description</h2>
- * The memory size of the various kernel objects is printed.
- *
- * <h2>Test Steps</h2>
- * - [13.12.1] The size of the system area is printed.
- * - [13.12.2] The size of a thread structure is printed.
- * - [13.12.3] The size of a virtual timer structure is printed.
- * - [13.12.4] The size of a semaphore structure is printed.
- * - [13.12.5] The size of a mutex is printed.
- * - [13.12.6] The size of a condition variable is printed.
- * - [13.12.7] The size of an event source is printed.
- * - [13.12.8] The size of an event listener is printed.
- * - [13.12.9] The size of a mailbox is printed.
- * .
- */
-
-static void rt_test_013_012_execute(void) {
-
- /* [13.12.1] The size of the system area is printed.*/
- test_set_step(1);
- {
- test_print("--- System: ");
- test_printn(sizeof(ch_system_t));
- test_println(" bytes");
- }
-
- /* [13.12.2] The size of a thread structure is printed.*/
- test_set_step(2);
- {
- test_print("--- Thread: ");
- test_printn(sizeof(thread_t));
- test_println(" bytes");
- }
-
- /* [13.12.3] The size of a virtual timer structure is printed.*/
- test_set_step(3);
- {
- test_print("--- Timer : ");
- test_printn(sizeof(virtual_timer_t));
- test_println(" bytes");
- }
-
- /* [13.12.4] The size of a semaphore structure is printed.*/
- test_set_step(4);
- {
-#if CH_CFG_USE_SEMAPHORES || defined(__DOXYGEN__)
- test_print("--- Semaph: ");
- test_printn(sizeof(semaphore_t));
- test_println(" bytes");
-#endif
- }
-
- /* [13.12.5] The size of a mutex is printed.*/
- test_set_step(5);
- {
-#if CH_CFG_USE_MUTEXES || defined(__DOXYGEN__)
- test_print("--- Mutex : ");
- test_printn(sizeof(mutex_t));
- test_println(" bytes");
-#endif
- }
-
- /* [13.12.6] The size of a condition variable is printed.*/
- test_set_step(6);
- {
-#if CH_CFG_USE_CONDVARS || defined(__DOXYGEN__)
- test_print("--- CondV.: ");
- test_printn(sizeof(condition_variable_t));
- test_println(" bytes");
-#endif
- }
-
- /* [13.12.7] The size of an event source is printed.*/
- test_set_step(7);
- {
-#if CH_CFG_USE_EVENTS || defined(__DOXYGEN__)
- test_print("--- EventS: ");
- test_printn(sizeof(event_source_t));
- test_println(" bytes");
-#endif
- }
-
- /* [13.12.8] The size of an event listener is printed.*/
- test_set_step(8);
- {
-#if CH_CFG_USE_EVENTS || defined(__DOXYGEN__)
- test_print("--- EventL: ");
- test_printn(sizeof(event_listener_t));
- test_println(" bytes");
-#endif
- }
-
- /* [13.12.9] The size of a mailbox is printed.*/
- test_set_step(9);
- {
-#if CH_CFG_USE_MAILBOXES || defined(__DOXYGEN__)
- test_print("--- MailB.: ");
- test_printn(sizeof(mailbox_t));
- test_println(" bytes");
-#endif
- }
-}
-
-static const testcase_t rt_test_013_012 = {
- "RAM Footprint",
- NULL,
- NULL,
- rt_test_013_012_execute
-};
-
-/****************************************************************************
- * Exported data.
- ****************************************************************************/
-
-/**
- * @brief Array of test cases.
- */
-const testcase_t * const rt_test_sequence_013_array[] = {
-#if (CH_CFG_USE_MESSAGES) || defined(__DOXYGEN__)
- &rt_test_013_001,
-#endif
-#if (CH_CFG_USE_MESSAGES) || defined(__DOXYGEN__)
- &rt_test_013_002,
-#endif
-#if (CH_CFG_USE_MESSAGES) || defined(__DOXYGEN__)
- &rt_test_013_003,
-#endif
- &rt_test_013_004,
- &rt_test_013_005,
- &rt_test_013_006,
-#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
- &rt_test_013_007,
-#endif
- &rt_test_013_008,
- &rt_test_013_009,
-#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
- &rt_test_013_010,
-#endif
-#if (CH_CFG_USE_MUTEXES) || defined(__DOXYGEN__)
- &rt_test_013_011,
-#endif
- &rt_test_013_012,
- NULL
-};
-
-/**
- * @brief Benchmarks.
- */
-const testsequence_t rt_test_sequence_013 = {
- NULL,
- rt_test_sequence_013_array
-};
diff --git a/test/rt/source/test/rt_test_sequence_013.h b/test/rt/source/test/rt_test_sequence_013.h
deleted file mode 100644
index c4b3b512b..000000000
--- a/test/rt/source/test/rt_test_sequence_013.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 rt_test_sequence_013.h
- * @brief Test Sequence 013 header.
- */
-
-#ifndef RT_TEST_SEQUENCE_013_H
-#define RT_TEST_SEQUENCE_013_H
-
-extern const testsequence_t rt_test_sequence_013;
-
-#endif /* RT_TEST_SEQUENCE_013_H */