From 7b1bf2a147db46f7bfd504cab01a2a941f01d022 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Fri, 1 Apr 2016 12:13:54 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@9194 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- test/rt/source/test/test_root.c | 7 +- test/rt/source/test/test_sequence_012.c | 506 ++++++++++++++++++++++++++++++++ 2 files changed, 511 insertions(+), 2 deletions(-) (limited to 'test/rt/source') diff --git a/test/rt/source/test/test_root.c b/test/rt/source/test/test_root.c index 2c19a388c..026fed32c 100644 --- a/test/rt/source/test/test_root.c +++ b/test/rt/source/test/test_root.c @@ -95,7 +95,7 @@ void * ROMCONST wa[5] = {test.wa.T0, test.wa.T1, test.wa.T2, * Sets a termination request in all the test-spawned threads. */ void test_terminate_threads(void) { - int i; + unsigned i; for (i = 0; i < MAX_THREADS; i++) if (threads[i]) @@ -106,7 +106,7 @@ void test_terminate_threads(void) { * Waits for the completion of all the test-spawned threads. */ void test_wait_threads(void) { - int i; + unsigned i; for (i = 0; i < MAX_THREADS; i++) if (threads[i] != NULL) { @@ -115,6 +115,9 @@ void test_wait_threads(void) { } } +/* + * Delays execution until next system time tick. + */ systime_t test_wait_tick(void) { chThdSleep(1); diff --git a/test/rt/source/test/test_sequence_012.c b/test/rt/source/test/test_sequence_012.c index 8dde2e82c..bdaef4c4a 100644 --- a/test/rt/source/test/test_sequence_012.c +++ b/test/rt/source/test/test_sequence_012.c @@ -38,6 +38,12 @@ * - @subpage test_012_004 * - @subpage test_012_005 * - @subpage test_012_006 + * - @subpage test_012_007 + * - @subpage test_012_008 + * - @subpage test_012_009 + * - @subpage test_012_010 + * - @subpage test_012_011 + * - @subpage test_012_012 * . */ @@ -52,6 +58,8 @@ static semaphore_t sem1; 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; @@ -99,6 +107,27 @@ static THD_FUNCTION(bmk_thread4, p) { msg = self->u.rdymsg; } while (msg == MSG_OK); chSysUnlock(); +} + +static THD_FUNCTION(bmk_thread7, p) { + + (void)p; + while (!chThdShouldTerminateX()) + chSemWait(&sem1); +} + +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()); } /**************************************************************************** @@ -492,6 +521,471 @@ static const testcase_t test_012_006 = { test_012_006_execute }; +#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__) +/** + * @page test_012_007 [12.7] Mass reschedule performance + * + *

Description

+ * Five threads are created and atomically rescheduled by resetting the + * semaphore where they are waiting on. The operation is performed into + * a continuous loop.
The performance is calculated by measuring + * the number of iterations after a second of continuous operations. + * + *

Conditions

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

Test Steps

+ * - [12.7.1] Five threads are created at higher priority that + * immediately enqueue on a semaphore. + * - [12.7.2] The semaphore is reset waking up the five threads. The + * operation is repeated continuously in a one-second time window. + * - [12.7.3] The five threads are terminated. + * - [12.7.4] The score is printed. + * . + */ + +static void test_012_007_setup(void) { + chSemObjectInit(&sem1, 0); +} + +static void test_012_007_execute(void) { + uint32_t n; + + /* [12.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); + } + + /* [12.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 + MS2ST(1000); + do { + chSemReset(&sem1, 0); + n++; + #if defined(SIMULATOR) + _sim_check_for_interrupts(); + #endif + } while (chVTIsSystemTimeWithinX(start, end)); + } + + /* [12.7.3] The five threads are terminated.*/ + test_set_step(3); + { + test_terminate_threads(); + chSemReset(&sem1, 0); + test_wait_threads(); + } + + /* [12.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 test_012_007 = { + "Mass reschedule performance", + test_012_007_setup, + NULL, + test_012_007_execute +}; +#endif /* CH_CFG_USE_SEMAPHORES */ + +/** + * @page test_012_008 [12.8] Round-Robin voluntary reschedule + * + *

Description

+ * Five threads are created at equal priority, each thread just + * increases a variable and yields.
The performance is calculated + * by measuring the number of iterations after a second of continuous + * operations. + * + *

Test Steps

+ * - [12.8.1] The five threads are created at lower priority. The + * threds have equal priority and start calling @p chThdYield() + * continuously. + * - [12.8.2] Waiting one second then terminating the 5 threads. + * - [12.8.3] The score is printed. + * . + */ + +static void test_012_008_execute(void) { + uint32_t n; + + /* [12.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); + } + + /* [12.8.2] Waiting one second then terminating the 5 threads.*/ + test_set_step(2); + { + chThdSleepSeconds(1); + test_terminate_threads(); + test_wait_threads(); + } + + /* [12.8.3] The score is printed.*/ + test_set_step(3); + { + test_print("--- Score : "); + test_printn(n); + test_println(" ctxswc/S"); + } +} + +static const testcase_t test_012_008 = { + "Round-Robin voluntary reschedule", + NULL, + NULL, + test_012_008_execute +}; + +/** + * @page test_012_009 [12.9] Virtual Timers set/reset performance + * + *

Description

+ * A virtual timer is set and immediately reset into a continuous + * loop.
The performance is calculated by measuring the number of + * iterations after a second of continuous operations. + * + *

Test Steps

+ * - [12.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. + * - [12.9.2] The score is printed. + * . + */ + +static void test_012_009_execute(void) { + static virtual_timer_t vt1, vt2; + uint32_t n; + + /* [12.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 + MS2ST(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)); + } + + /* [12.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 test_012_009 = { + "Virtual Timers set/reset performance", + NULL, + NULL, + test_012_009_execute +}; + +#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__) +/** + * @page test_012_010 [12.10] Semaphores wait/signal performance + * + *

Description

+ * A counting semaphore is taken/released into a continuous loop, no + * Context Switch happens because the counter is always non + * negative.
The performance is calculated by measuring the number + * of iterations after a second of continuous operations. + * + *

Conditions

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

Test Steps

+ * - [12.10.1] A semaphore is teken and released. The operation is + * repeated continuously in a one-second time window. + * - [12.10.2] The score is printed. + * . + */ + +static void test_012_010_setup(void) { + chSemObjectInit(&sem1, 1); +} + +static void test_012_010_execute(void) { + uint32_t n; + + /* [12.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 + MS2ST(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)); + } + + /* [12.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 test_012_010 = { + "Semaphores wait/signal performance", + test_012_010_setup, + NULL, + test_012_010_execute +}; +#endif /* CH_CFG_USE_SEMAPHORES */ + +#if (CH_CFG_USE_MUTEXES) || defined(__DOXYGEN__) +/** + * @page test_012_011 [12.11] Mutexes lock/unlock performance + * + *

Description

+ * A mutex is locked/unlocked into a continuous loop, no Context Switch + * happens because there are no other threads asking for the mutex.
+ * The performance is calculated by measuring the number of iterations + * after a second of continuous operations. + * + *

Conditions

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

Test Steps

+ * - [12.11.1] A mutex is locked and unlocked. The operation is + * repeated continuously in a one-second time window. + * - [12.11.2] The score is printed. + * . + */ + +static void test_012_011_setup(void) { + chMtxObjectInit(&mtx1); +} + +static void test_012_011_execute(void) { + uint32_t n; + + /* [12.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 + MS2ST(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)); + } + + /* [12.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 test_012_011 = { + "Mutexes lock/unlock performance", + test_012_011_setup, + NULL, + test_012_011_execute +}; +#endif /* CH_CFG_USE_MUTEXES */ + +/** + * @page test_012_012 [12.12] RAM Footprint + * + *

Description

+ * The memory size of the various kernel objects is printed. + * + *

Test Steps

+ * - [12.12.1] The size of the system area is printed. + * - [12.12.2] The size of a thread structure is printed. + * - [12.12.3] The size of a virtual timer structure is printed. + * - [12.12.4] The size of a semaphore structure is printed. + * - [12.12.5] The size of a mutex is printed. + * - [12.12.6] The size of a condition variable is printed. + * - [12.12.7] The size of an event source is printed. + * - [12.12.8] The size of an event listener is printed. + * - [12.12.9] The size of a mailbox is printed. + * . + */ + +static void test_012_012_execute(void) { + + /* [12.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"); + } + + /* [12.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"); + } + + /* [12.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"); + } + + /* [12.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 + } + + /* [12.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 + } + + /* [12.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 + } + + /* [12.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 + } + + /* [12.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 + } + + /* [12.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 test_012_012 = { + "RAM Footprint", + NULL, + NULL, + test_012_012_execute +}; + /**************************************************************************** * Exported data. ****************************************************************************/ @@ -512,5 +1006,17 @@ const testcase_t * const test_sequence_012[] = { &test_012_004, &test_012_005, &test_012_006, +#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__) + &test_012_007, +#endif + &test_012_008, + &test_012_009, +#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__) + &test_012_010, +#endif +#if (CH_CFG_USE_MUTEXES) || defined(__DOXYGEN__) + &test_012_011, +#endif + &test_012_012, NULL }; -- cgit v1.2.3