Benchmarks added to Nil test suite.
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@12654 110e8d01-0319-4d1e-a829-52ad28d1bb01
This commit is contained in:
parent
d6fa7fed19
commit
14b7df7ccc
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
# Compiler options here.
|
# Compiler options here.
|
||||||
ifeq ($(USE_OPT),)
|
ifeq ($(USE_OPT),)
|
||||||
USE_OPT = -O0 -ggdb -fomit-frame-pointer -falign-functions=16
|
USE_OPT = -O2 -ggdb -fomit-frame-pointer -falign-functions=16
|
||||||
endif
|
endif
|
||||||
|
|
||||||
# C specific options here (added to USE_OPT).
|
# C specific options here (added to USE_OPT).
|
||||||
|
|
|
@ -284,21 +284,21 @@
|
||||||
*
|
*
|
||||||
* @note The default is @p FALSE.
|
* @note The default is @p FALSE.
|
||||||
*/
|
*/
|
||||||
#define CH_DBG_SYSTEM_STATE_CHECK TRUE
|
#define CH_DBG_SYSTEM_STATE_CHECK FALSE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Debug option, parameters checks.
|
* @brief Debug option, parameters checks.
|
||||||
*
|
*
|
||||||
* @note The default is @p FALSE.
|
* @note The default is @p FALSE.
|
||||||
*/
|
*/
|
||||||
#define CH_DBG_ENABLE_CHECKS TRUE
|
#define CH_DBG_ENABLE_CHECKS FALSE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief System assertions.
|
* @brief System assertions.
|
||||||
*
|
*
|
||||||
* @note The default is @p FALSE.
|
* @note The default is @p FALSE.
|
||||||
*/
|
*/
|
||||||
#define CH_DBG_ENABLE_ASSERTS TRUE
|
#define CH_DBG_ENABLE_ASSERTS FALSE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Stack check.
|
* @brief Stack check.
|
||||||
|
|
|
@ -1049,6 +1049,29 @@ struct nil_system {
|
||||||
port_unlock_from_isr(); \
|
port_unlock_from_isr(); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Puts the current thread to sleep into the specified state.
|
||||||
|
*
|
||||||
|
* @param[in] newstate the new thread state or a semaphore pointer
|
||||||
|
* @return The wakeup message.
|
||||||
|
*
|
||||||
|
* @sclass
|
||||||
|
*/
|
||||||
|
#define chSchGoSleepS(newstate) chSchGoSleepTimeoutS(newstate, TIME_INFINITE)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Wakes up a thread.
|
||||||
|
*
|
||||||
|
* @param[in] ntp the thread to be made ready
|
||||||
|
* @param[in] msg the wakeup message
|
||||||
|
*
|
||||||
|
* @sclass
|
||||||
|
*/
|
||||||
|
#define chSchWakeupS(ntp, msg) do { \
|
||||||
|
chSchReadyI(ntp, msg); \
|
||||||
|
chSchRescheduleS(); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Evaluates if a reschedule is required.
|
* @brief Evaluates if a reschedule is required.
|
||||||
*
|
*
|
||||||
|
@ -1203,6 +1226,22 @@ struct nil_system {
|
||||||
#define chVTTimeElapsedSinceX(start) \
|
#define chVTTimeElapsedSinceX(start) \
|
||||||
chTimeDiffX((start), chVTGetSystemTimeX())
|
chTimeDiffX((start), chVTGetSystemTimeX())
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Checks if the current system time is within the specified time
|
||||||
|
* window.
|
||||||
|
* @note When start==end then the function returns always true because the
|
||||||
|
* whole time range is specified.
|
||||||
|
*
|
||||||
|
* @param[in] start the start of the time window (inclusive)
|
||||||
|
* @param[in] end the end of the time window (non inclusive)
|
||||||
|
* @retval true current time within the specified time window.
|
||||||
|
* @retval false current time not within the specified time window.
|
||||||
|
*
|
||||||
|
* @xclass
|
||||||
|
*/
|
||||||
|
#define chVTIsSystemTimeWithinX(start, end) \
|
||||||
|
chTimeIsInRangeX(chVTGetSystemTimeX(), start, end)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Adds an interval to a system time returning a system time.
|
* @brief Adds an interval to a system time returning a system time.
|
||||||
*
|
*
|
||||||
|
|
|
@ -655,7 +655,7 @@ void chSchRescheduleS(void) {
|
||||||
* timeout specification.
|
* timeout specification.
|
||||||
* @details The thread goes into a sleeping state, if it is not awakened
|
* @details The thread goes into a sleeping state, if it is not awakened
|
||||||
* explicitly within the specified system time then it is forcibly
|
* explicitly within the specified system time then it is forcibly
|
||||||
* awakened with a @p NIL_MSG_TMO low level message.
|
* awakened with a @p MSG_TIMEOUT low level message.
|
||||||
*
|
*
|
||||||
* @param[in] newstate the new thread state or a semaphore pointer
|
* @param[in] newstate the new thread state or a semaphore pointer
|
||||||
* @param[in] timeout the number of ticks before the operation timeouts.
|
* @param[in] timeout the number of ticks before the operation timeouts.
|
||||||
|
@ -663,7 +663,7 @@ void chSchRescheduleS(void) {
|
||||||
* - @a TIME_INFINITE no timeout.
|
* - @a TIME_INFINITE no timeout.
|
||||||
* .
|
* .
|
||||||
* @return The wakeup message.
|
* @return The wakeup message.
|
||||||
* @retval NIL_MSG_TMO if a timeout occurred.
|
* @retval MSG_TIMEOUT if a timeout occurred.
|
||||||
*
|
*
|
||||||
* @sclass
|
* @sclass
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -45,10 +45,13 @@
|
||||||
*/
|
*/
|
||||||
#define ALLOWED_DELAY TIME_MS2I(2)
|
#define ALLOWED_DELAY TIME_MS2I(2)
|
||||||
|
|
||||||
|
extern THD_WORKING_AREA(wa_common, 128);
|
||||||
systime_t test_wait_tick(void);]]></value>
|
systime_t test_wait_tick(void);]]></value>
|
||||||
</global_definitions>
|
</global_definitions>
|
||||||
<global_code>
|
<global_code>
|
||||||
<value><![CDATA[/*
|
<value><![CDATA[THD_WORKING_AREA(wa_common, 128);
|
||||||
|
|
||||||
|
/*
|
||||||
* Delays execution until next system time tick.
|
* Delays execution until next system time tick.
|
||||||
*/
|
*/
|
||||||
systime_t test_wait_tick(void) {
|
systime_t test_wait_tick(void) {
|
||||||
|
@ -449,7 +452,6 @@ static semaphore_t sem1, sem2;
|
||||||
/*
|
/*
|
||||||
* Signaler thread.
|
* Signaler thread.
|
||||||
*/
|
*/
|
||||||
static THD_WORKING_AREA(wa_signaler, 128);
|
|
||||||
static THD_FUNCTION(signaler, arg) {
|
static THD_FUNCTION(signaler, arg) {
|
||||||
|
|
||||||
(void)arg;
|
(void)arg;
|
||||||
|
@ -550,8 +552,8 @@ test_assert_lock(chSemGetCounterI(&sem1) == 2, "wrong counter value");]]></value
|
||||||
<value><![CDATA[thread_config_t tc = {
|
<value><![CDATA[thread_config_t tc = {
|
||||||
chThdGetPriorityX() - 1,
|
chThdGetPriorityX() - 1,
|
||||||
"signaler",
|
"signaler",
|
||||||
wa_signaler,
|
wa_common,
|
||||||
THD_WORKING_AREA_END(wa_signaler),
|
THD_WORKING_AREA_END(wa_common),
|
||||||
signaler,
|
signaler,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
@ -680,7 +682,6 @@ static thread_reference_t tr1;
|
||||||
/*
|
/*
|
||||||
* Resumer thread.
|
* Resumer thread.
|
||||||
*/
|
*/
|
||||||
static THD_WORKING_AREA(wa_resumer, 128);
|
|
||||||
static THD_FUNCTION(resumer, arg) {
|
static THD_FUNCTION(resumer, arg) {
|
||||||
|
|
||||||
(void)arg;
|
(void)arg;
|
||||||
|
@ -711,8 +712,8 @@ static THD_FUNCTION(resumer, arg) {
|
||||||
<value><![CDATA[thread_config_t tc = {
|
<value><![CDATA[thread_config_t tc = {
|
||||||
chThdGetPriorityX() - 1,
|
chThdGetPriorityX() - 1,
|
||||||
"resumer",
|
"resumer",
|
||||||
wa_resumer,
|
wa_common,
|
||||||
THD_WORKING_AREA_END(wa_resumer),
|
THD_WORKING_AREA_END(wa_common),
|
||||||
resumer,
|
resumer,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
@ -793,7 +794,6 @@ static ROMCONST evhandler_t evhndl[] = {h1, h2, h3};
|
||||||
/*
|
/*
|
||||||
* Direct events thread.
|
* Direct events thread.
|
||||||
*/
|
*/
|
||||||
static THD_WORKING_AREA(wa_evtthd1, 128);
|
|
||||||
static THD_FUNCTION(evtthd1, p) {
|
static THD_FUNCTION(evtthd1, p) {
|
||||||
|
|
||||||
chThdSleepMilliseconds(50);
|
chThdSleepMilliseconds(50);
|
||||||
|
@ -803,7 +803,6 @@ static THD_FUNCTION(evtthd1, p) {
|
||||||
/*
|
/*
|
||||||
* Broadcaster thread.
|
* Broadcaster thread.
|
||||||
*/
|
*/
|
||||||
static THD_WORKING_AREA(wa_evtthd2, 128);
|
|
||||||
static THD_FUNCTION(evtthd2, p) {
|
static THD_FUNCTION(evtthd2, p) {
|
||||||
|
|
||||||
(void)p;
|
(void)p;
|
||||||
|
@ -987,8 +986,8 @@ test_assert(m == 0, "stuck event");]]></value>
|
||||||
thread_config_t tc = {
|
thread_config_t tc = {
|
||||||
chThdGetPriorityX() + 1,
|
chThdGetPriorityX() + 1,
|
||||||
"event1",
|
"event1",
|
||||||
wa_evtthd1,
|
wa_common,
|
||||||
THD_WORKING_AREA_END(wa_evtthd1),
|
THD_WORKING_AREA_END(wa_common),
|
||||||
evtthd1,
|
evtthd1,
|
||||||
chThdGetSelfX()
|
chThdGetSelfX()
|
||||||
};
|
};
|
||||||
|
@ -1076,8 +1075,8 @@ test_assert(m == 0, "stuck event");]]></value>
|
||||||
thread_config_t tc = {
|
thread_config_t tc = {
|
||||||
chThdGetPriorityX() + 1,
|
chThdGetPriorityX() + 1,
|
||||||
"event1",
|
"event1",
|
||||||
wa_evtthd1,
|
wa_common,
|
||||||
THD_WORKING_AREA_END(wa_evtthd1),
|
THD_WORKING_AREA_END(wa_common),
|
||||||
evtthd1,
|
evtthd1,
|
||||||
chThdGetSelfX()
|
chThdGetSelfX()
|
||||||
};
|
};
|
||||||
|
@ -1176,8 +1175,8 @@ test_assert(m == 0, "stuck event");]]></value>
|
||||||
thread_config_t tc = {
|
thread_config_t tc = {
|
||||||
chThdGetPriorityX() + 1,
|
chThdGetPriorityX() + 1,
|
||||||
"event1",
|
"event1",
|
||||||
wa_evtthd1,
|
wa_common,
|
||||||
THD_WORKING_AREA_END(wa_evtthd1),
|
THD_WORKING_AREA_END(wa_common),
|
||||||
evtthd1,
|
evtthd1,
|
||||||
chThdGetSelfX()
|
chThdGetSelfX()
|
||||||
};
|
};
|
||||||
|
@ -1311,8 +1310,8 @@ chEvtRegisterMask(&es2, &el2, 4);]]></value>
|
||||||
thread_config_t tc = {
|
thread_config_t tc = {
|
||||||
chThdGetPriorityX() + 1,
|
chThdGetPriorityX() + 1,
|
||||||
"event2",
|
"event2",
|
||||||
wa_evtthd2,
|
wa_common,
|
||||||
THD_WORKING_AREA_END(wa_evtthd2),
|
THD_WORKING_AREA_END(wa_common),
|
||||||
evtthd2,
|
evtthd2,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
@ -1371,7 +1370,6 @@ test_assert(!chEvtIsListeningI(&es2), "stuck listener");]]></value>
|
||||||
<value><![CDATA[/*
|
<value><![CDATA[/*
|
||||||
* Messager thread.
|
* Messager thread.
|
||||||
*/
|
*/
|
||||||
static THD_WORKING_AREA(wa_messager, 128);
|
|
||||||
static THD_FUNCTION(messager, p) {
|
static THD_FUNCTION(messager, p) {
|
||||||
|
|
||||||
chMsgSend(p, 'A');
|
chMsgSend(p, 'A');
|
||||||
|
@ -1416,8 +1414,8 @@ msg_t msg;]]></value>
|
||||||
<value><![CDATA[thread_config_t tc = {
|
<value><![CDATA[thread_config_t tc = {
|
||||||
chThdGetPriorityX() - 1,
|
chThdGetPriorityX() - 1,
|
||||||
"messager",
|
"messager",
|
||||||
wa_messager,
|
wa_common,
|
||||||
THD_WORKING_AREA_END(wa_messager),
|
THD_WORKING_AREA_END(wa_common),
|
||||||
messager,
|
messager,
|
||||||
chThdGetSelfX()
|
chThdGetSelfX()
|
||||||
};
|
};
|
||||||
|
@ -1448,6 +1446,624 @@ test_assert_sequence("ABCD", "invalid sequence");]]></value>
|
||||||
</case>
|
</case>
|
||||||
</cases>
|
</cases>
|
||||||
</sequence>
|
</sequence>
|
||||||
|
<sequence>
|
||||||
|
<type index="2">
|
||||||
|
<value>Benchmarks</value>
|
||||||
|
</type>
|
||||||
|
<brief>
|
||||||
|
<value>Benchmarks.</value>
|
||||||
|
</brief>
|
||||||
|
<description>
|
||||||
|
<value>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.</value>
|
||||||
|
</description>
|
||||||
|
<condition>
|
||||||
|
<value />
|
||||||
|
</condition>
|
||||||
|
<shared_code>
|
||||||
|
<value><![CDATA[#if CH_CFG_USE_SEMAPHORES || defined(__DOXYGEN__)
|
||||||
|
static semaphore_t sem1;
|
||||||
|
#endif
|
||||||
|
#if CH_CFG_USE_MUTEXES || defined(__DOXYGEN__)
|
||||||
|
static mutex_t mtx1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#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 = chTimeAddX(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(NIL_STATE_SUSPENDED);
|
||||||
|
msg = self->u1.msg;
|
||||||
|
} while (msg == MSG_OK);
|
||||||
|
chSysUnlock();
|
||||||
|
}]]></value>
|
||||||
|
</shared_code>
|
||||||
|
<cases>
|
||||||
|
<case>
|
||||||
|
<brief>
|
||||||
|
<value>Messages performance #1.</value>
|
||||||
|
</brief>
|
||||||
|
<description>
|
||||||
|
<value>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.</value>
|
||||||
|
</description>
|
||||||
|
<condition>
|
||||||
|
<value>CH_CFG_USE_MESSAGES</value>
|
||||||
|
</condition>
|
||||||
|
<various_code>
|
||||||
|
<setup_code>
|
||||||
|
<value />
|
||||||
|
</setup_code>
|
||||||
|
<teardown_code>
|
||||||
|
<value />
|
||||||
|
</teardown_code>
|
||||||
|
<local_variables>
|
||||||
|
<value><![CDATA[uint32_t n;
|
||||||
|
thread_t *tp;]]></value>
|
||||||
|
</local_variables>
|
||||||
|
</various_code>
|
||||||
|
<steps>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>The messenger thread is started at a lower priority than the current thread.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value />
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[thread_config_t tc = {
|
||||||
|
chThdGetPriorityX() + 1,
|
||||||
|
"messenger",
|
||||||
|
wa_common,
|
||||||
|
THD_WORKING_AREA_END(wa_common),
|
||||||
|
bmk_thread1,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
tp = chThdCreate(&tc);]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>The number of messages exchanged is counted in a one second time window.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value />
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[n = msg_loop_test(tp);
|
||||||
|
chThdWait(tp);]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>Score is printed.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value />
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[test_print("--- Score : ");
|
||||||
|
test_printn(n);
|
||||||
|
test_print(" msgs/S, ");
|
||||||
|
test_printn(n << 1);
|
||||||
|
test_println(" ctxswc/S");]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
</steps>
|
||||||
|
</case>
|
||||||
|
<case>
|
||||||
|
<brief>
|
||||||
|
<value>Messages performance #2.</value>
|
||||||
|
</brief>
|
||||||
|
<description>
|
||||||
|
<value>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.</value>
|
||||||
|
</description>
|
||||||
|
<condition>
|
||||||
|
<value>CH_CFG_USE_MESSAGES</value>
|
||||||
|
</condition>
|
||||||
|
<various_code>
|
||||||
|
<setup_code>
|
||||||
|
<value />
|
||||||
|
</setup_code>
|
||||||
|
<teardown_code>
|
||||||
|
<value />
|
||||||
|
</teardown_code>
|
||||||
|
<local_variables>
|
||||||
|
<value><![CDATA[uint32_t n;
|
||||||
|
thread_t *tp;]]></value>
|
||||||
|
</local_variables>
|
||||||
|
</various_code>
|
||||||
|
<steps>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>The messenger thread is started at an higher priority than the current thread.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value />
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[thread_config_t tc = {
|
||||||
|
chThdGetPriorityX() - 1,
|
||||||
|
"messenger",
|
||||||
|
wa_common,
|
||||||
|
THD_WORKING_AREA_END(wa_common),
|
||||||
|
bmk_thread1,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
tp = chThdCreate(&tc);]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>The number of messages exchanged is counted in a one second time window.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value />
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[n = msg_loop_test(tp);
|
||||||
|
chThdWait(tp);]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>Score is printed.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value />
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[test_print("--- Score : ");
|
||||||
|
test_printn(n);
|
||||||
|
test_print(" msgs/S, ");
|
||||||
|
test_printn(n << 1);
|
||||||
|
test_println(" ctxswc/S");]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
</steps>
|
||||||
|
</case>
|
||||||
|
<case>
|
||||||
|
<brief>
|
||||||
|
<value>Context Switch performance.</value>
|
||||||
|
</brief>
|
||||||
|
<description>
|
||||||
|
<value>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.</value>
|
||||||
|
</description>
|
||||||
|
<condition>
|
||||||
|
<value />
|
||||||
|
</condition>
|
||||||
|
<various_code>
|
||||||
|
<setup_code>
|
||||||
|
<value />
|
||||||
|
</setup_code>
|
||||||
|
<teardown_code>
|
||||||
|
<value />
|
||||||
|
</teardown_code>
|
||||||
|
<local_variables>
|
||||||
|
<value><![CDATA[thread_t *tp;
|
||||||
|
uint32_t n;]]></value>
|
||||||
|
</local_variables>
|
||||||
|
</various_code>
|
||||||
|
<steps>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>Starting the target thread at an higher priority level.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value />
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[thread_config_t tc = {
|
||||||
|
chThdGetPriorityX() - 1,
|
||||||
|
"messenger",
|
||||||
|
wa_common,
|
||||||
|
THD_WORKING_AREA_END(wa_common),
|
||||||
|
bmk_thread4,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
tp = chThdCreate(&tc);]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>Waking up the thread as fast as possible in a one second time window.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value />
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[systime_t start, end;
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
start = test_wait_tick();
|
||||||
|
end = chTimeAddX(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;
|
||||||
|
} while (chVTIsSystemTimeWithinX(start, end));]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>Stopping the target thread.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value />
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[chSysLock();
|
||||||
|
chSchWakeupS(tp, MSG_TIMEOUT);
|
||||||
|
chSysUnlock();
|
||||||
|
chThdWait(tp);]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>Score is printed.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value />
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[test_print("--- Score : ");
|
||||||
|
test_printn(n * 2);
|
||||||
|
test_println(" ctxswc/S");]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
</steps>
|
||||||
|
</case>
|
||||||
|
<case>
|
||||||
|
<brief>
|
||||||
|
<value>Threads performance, full cycle.</value>
|
||||||
|
</brief>
|
||||||
|
<description>
|
||||||
|
<value>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.</value>
|
||||||
|
</description>
|
||||||
|
<condition>
|
||||||
|
<value />
|
||||||
|
</condition>
|
||||||
|
<various_code>
|
||||||
|
<setup_code>
|
||||||
|
<value />
|
||||||
|
</setup_code>
|
||||||
|
<teardown_code>
|
||||||
|
<value />
|
||||||
|
</teardown_code>
|
||||||
|
<local_variables>
|
||||||
|
<value><![CDATA[uint32_t n;]]></value>
|
||||||
|
</local_variables>
|
||||||
|
</various_code>
|
||||||
|
<steps>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>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.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value />
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[systime_t start, end;
|
||||||
|
thread_config_t tc = {
|
||||||
|
chThdGetPriorityX() + 1,
|
||||||
|
"messenger",
|
||||||
|
wa_common,
|
||||||
|
THD_WORKING_AREA_END(wa_common),
|
||||||
|
bmk_thread3,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
start = test_wait_tick();
|
||||||
|
end = chTimeAddX(start, TIME_MS2I(1000));
|
||||||
|
do {
|
||||||
|
chThdWait(chThdCreate(&tc));
|
||||||
|
n++;
|
||||||
|
} while (chVTIsSystemTimeWithinX(start, end));]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>Score is printed.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value />
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[test_print("--- Score : ");
|
||||||
|
test_printn(n);
|
||||||
|
test_println(" threads/S");]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
</steps>
|
||||||
|
</case>
|
||||||
|
<case>
|
||||||
|
<brief>
|
||||||
|
<value>Threads performance, create/exit only.</value>
|
||||||
|
</brief>
|
||||||
|
<description>
|
||||||
|
<value>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.</value>
|
||||||
|
</description>
|
||||||
|
<condition>
|
||||||
|
<value />
|
||||||
|
</condition>
|
||||||
|
<various_code>
|
||||||
|
<setup_code>
|
||||||
|
<value />
|
||||||
|
</setup_code>
|
||||||
|
<teardown_code>
|
||||||
|
<value />
|
||||||
|
</teardown_code>
|
||||||
|
<local_variables>
|
||||||
|
<value><![CDATA[uint32_t n;]]></value>
|
||||||
|
</local_variables>
|
||||||
|
</various_code>
|
||||||
|
<steps>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>A thread is created at an higher priority level and let terminate immediately. The operation is repeated continuously in a one-second time window.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value />
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[systime_t start, end;
|
||||||
|
thread_config_t tc = {
|
||||||
|
chThdGetPriorityX() - 1,
|
||||||
|
"messenger",
|
||||||
|
wa_common,
|
||||||
|
THD_WORKING_AREA_END(wa_common),
|
||||||
|
bmk_thread3,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
start = test_wait_tick();
|
||||||
|
end = chTimeAddX(start, TIME_MS2I(1000));
|
||||||
|
do {
|
||||||
|
chThdWait(chThdCreate(&tc));
|
||||||
|
n++;
|
||||||
|
} while (chVTIsSystemTimeWithinX(start, end));]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>Score is printed.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value />
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[test_print("--- Score : ");
|
||||||
|
test_printn(n);
|
||||||
|
test_println(" threads/S");]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
</steps>
|
||||||
|
</case>
|
||||||
|
<case>
|
||||||
|
<brief>
|
||||||
|
<value>Semaphores wait/signal performance</value>
|
||||||
|
</brief>
|
||||||
|
<description>
|
||||||
|
<value>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.</value>
|
||||||
|
</description>
|
||||||
|
<condition>
|
||||||
|
<value>CH_CFG_USE_SEMAPHORES</value>
|
||||||
|
</condition>
|
||||||
|
<various_code>
|
||||||
|
<setup_code>
|
||||||
|
<value><![CDATA[chSemObjectInit(&sem1, 1);]]></value>
|
||||||
|
</setup_code>
|
||||||
|
<teardown_code>
|
||||||
|
<value />
|
||||||
|
</teardown_code>
|
||||||
|
<local_variables>
|
||||||
|
<value><![CDATA[uint32_t n;]]></value>
|
||||||
|
</local_variables>
|
||||||
|
</various_code>
|
||||||
|
<steps>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>A semaphore is teken and released. The operation is repeated continuously in a one-second time window.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value />
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[systime_t start, end;
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
start = test_wait_tick();
|
||||||
|
end = chTimeAddX(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));]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>The score is printed.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value />
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[test_print("--- Score : ");
|
||||||
|
test_printn(n * 4);
|
||||||
|
test_println(" wait+signal/S");]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
</steps>
|
||||||
|
</case>
|
||||||
|
<case>
|
||||||
|
<brief>
|
||||||
|
<value>RAM Footprint.</value>
|
||||||
|
</brief>
|
||||||
|
<description>
|
||||||
|
<value>The memory size of the various kernel objects is printed.</value>
|
||||||
|
</description>
|
||||||
|
<condition>
|
||||||
|
<value />
|
||||||
|
</condition>
|
||||||
|
<various_code>
|
||||||
|
<setup_code>
|
||||||
|
<value />
|
||||||
|
</setup_code>
|
||||||
|
<teardown_code>
|
||||||
|
<value />
|
||||||
|
</teardown_code>
|
||||||
|
<local_variables>
|
||||||
|
<value />
|
||||||
|
</local_variables>
|
||||||
|
</various_code>
|
||||||
|
<steps>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>The size of the system area is printed.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value />
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[test_print("--- System: ");
|
||||||
|
test_printn(sizeof(nil_system_t));
|
||||||
|
test_println(" bytes");]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>The size of a thread structure is printed.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value />
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[test_print("--- Thread: ");
|
||||||
|
test_printn(sizeof(thread_t));
|
||||||
|
test_println(" bytes");]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>The size of a semaphore structure is printed.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value />
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[#if CH_CFG_USE_SEMAPHORES || defined(__DOXYGEN__)
|
||||||
|
test_print("--- Semaph: ");
|
||||||
|
test_printn(sizeof(semaphore_t));
|
||||||
|
test_println(" bytes");
|
||||||
|
#endif]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>The size of an event source is printed.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value />
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[#if CH_CFG_USE_EVENTS || defined(__DOXYGEN__)
|
||||||
|
test_print("--- EventS: ");
|
||||||
|
test_printn(sizeof(event_source_t));
|
||||||
|
test_println(" bytes");
|
||||||
|
#endif]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>The size of an event listener is printed.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value />
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[#if CH_CFG_USE_EVENTS || defined(__DOXYGEN__)
|
||||||
|
test_print("--- EventL: ");
|
||||||
|
test_printn(sizeof(event_listener_t));
|
||||||
|
test_println(" bytes");
|
||||||
|
#endif]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
<step>
|
||||||
|
<description>
|
||||||
|
<value>The size of a mailbox is printed.</value>
|
||||||
|
</description>
|
||||||
|
<tags>
|
||||||
|
<value />
|
||||||
|
</tags>
|
||||||
|
<code>
|
||||||
|
<value><![CDATA[#if CH_CFG_USE_MAILBOXES || defined(__DOXYGEN__)
|
||||||
|
test_print("--- MailB.: ");
|
||||||
|
test_printn(sizeof(mailbox_t));
|
||||||
|
test_println(" bytes");
|
||||||
|
#endif]]></value>
|
||||||
|
</code>
|
||||||
|
</step>
|
||||||
|
</steps>
|
||||||
|
</case>
|
||||||
|
</cases>
|
||||||
|
</sequence>
|
||||||
</sequences>
|
</sequences>
|
||||||
</instance>
|
</instance>
|
||||||
</instances>
|
</instances>
|
||||||
|
|
|
@ -5,7 +5,8 @@ TESTSRC += ${CHIBIOS}/test/nil/source/test/nil_test_root.c \
|
||||||
${CHIBIOS}/test/nil/source/test/nil_test_sequence_003.c \
|
${CHIBIOS}/test/nil/source/test/nil_test_sequence_003.c \
|
||||||
${CHIBIOS}/test/nil/source/test/nil_test_sequence_004.c \
|
${CHIBIOS}/test/nil/source/test/nil_test_sequence_004.c \
|
||||||
${CHIBIOS}/test/nil/source/test/nil_test_sequence_005.c \
|
${CHIBIOS}/test/nil/source/test/nil_test_sequence_005.c \
|
||||||
${CHIBIOS}/test/nil/source/test/nil_test_sequence_006.c
|
${CHIBIOS}/test/nil/source/test/nil_test_sequence_006.c \
|
||||||
|
${CHIBIOS}/test/nil/source/test/nil_test_sequence_007.c
|
||||||
|
|
||||||
# Required include directories
|
# Required include directories
|
||||||
TESTINC += ${CHIBIOS}/test/nil/source/test
|
TESTINC += ${CHIBIOS}/test/nil/source/test
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
* - @subpage nil_test_sequence_004
|
* - @subpage nil_test_sequence_004
|
||||||
* - @subpage nil_test_sequence_005
|
* - @subpage nil_test_sequence_005
|
||||||
* - @subpage nil_test_sequence_006
|
* - @subpage nil_test_sequence_006
|
||||||
|
* - @subpage nil_test_sequence_007
|
||||||
* .
|
* .
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -60,6 +61,7 @@ const testsequence_t * const nil_test_suite_array[] = {
|
||||||
#if (CH_CFG_USE_MESSAGES) || defined(__DOXYGEN__)
|
#if (CH_CFG_USE_MESSAGES) || defined(__DOXYGEN__)
|
||||||
&nil_test_sequence_006,
|
&nil_test_sequence_006,
|
||||||
#endif
|
#endif
|
||||||
|
&nil_test_sequence_007,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -75,6 +77,8 @@ const testsuite_t nil_test_suite = {
|
||||||
/* Shared code. */
|
/* Shared code. */
|
||||||
/*===========================================================================*/
|
/*===========================================================================*/
|
||||||
|
|
||||||
|
THD_WORKING_AREA(wa_common, 128);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Delays execution until next system time tick.
|
* Delays execution until next system time tick.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "nil_test_sequence_004.h"
|
#include "nil_test_sequence_004.h"
|
||||||
#include "nil_test_sequence_005.h"
|
#include "nil_test_sequence_005.h"
|
||||||
#include "nil_test_sequence_006.h"
|
#include "nil_test_sequence_006.h"
|
||||||
|
#include "nil_test_sequence_007.h"
|
||||||
|
|
||||||
#if !defined(__DOXYGEN__)
|
#if !defined(__DOXYGEN__)
|
||||||
|
|
||||||
|
@ -57,6 +58,7 @@ extern "C" {
|
||||||
*/
|
*/
|
||||||
#define ALLOWED_DELAY TIME_MS2I(2)
|
#define ALLOWED_DELAY TIME_MS2I(2)
|
||||||
|
|
||||||
|
extern THD_WORKING_AREA(wa_common, 128);
|
||||||
systime_t test_wait_tick(void);
|
systime_t test_wait_tick(void);
|
||||||
|
|
||||||
#endif /* !defined(__DOXYGEN__) */
|
#endif /* !defined(__DOXYGEN__) */
|
||||||
|
|
|
@ -57,7 +57,6 @@ static semaphore_t sem1, sem2;
|
||||||
/*
|
/*
|
||||||
* Signaler thread.
|
* Signaler thread.
|
||||||
*/
|
*/
|
||||||
static THD_WORKING_AREA(wa_signaler, 128);
|
|
||||||
static THD_FUNCTION(signaler, arg) {
|
static THD_FUNCTION(signaler, arg) {
|
||||||
|
|
||||||
(void)arg;
|
(void)arg;
|
||||||
|
@ -166,8 +165,8 @@ static void nil_test_003_002_setup(void) {
|
||||||
thread_config_t tc = {
|
thread_config_t tc = {
|
||||||
chThdGetPriorityX() - 1,
|
chThdGetPriorityX() - 1,
|
||||||
"signaler",
|
"signaler",
|
||||||
wa_signaler,
|
wa_common,
|
||||||
THD_WORKING_AREA_END(wa_signaler),
|
THD_WORKING_AREA_END(wa_common),
|
||||||
signaler,
|
signaler,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
|
@ -45,7 +45,6 @@ static thread_reference_t tr1;
|
||||||
/*
|
/*
|
||||||
* Resumer thread.
|
* Resumer thread.
|
||||||
*/
|
*/
|
||||||
static THD_WORKING_AREA(wa_resumer, 128);
|
|
||||||
static THD_FUNCTION(resumer, arg) {
|
static THD_FUNCTION(resumer, arg) {
|
||||||
|
|
||||||
(void)arg;
|
(void)arg;
|
||||||
|
@ -85,8 +84,8 @@ static void nil_test_004_001_setup(void) {
|
||||||
thread_config_t tc = {
|
thread_config_t tc = {
|
||||||
chThdGetPriorityX() - 1,
|
chThdGetPriorityX() - 1,
|
||||||
"resumer",
|
"resumer",
|
||||||
wa_resumer,
|
wa_common,
|
||||||
THD_WORKING_AREA_END(wa_resumer),
|
THD_WORKING_AREA_END(wa_common),
|
||||||
resumer,
|
resumer,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
|
@ -62,7 +62,6 @@ static ROMCONST evhandler_t evhndl[] = {h1, h2, h3};
|
||||||
/*
|
/*
|
||||||
* Direct events thread.
|
* Direct events thread.
|
||||||
*/
|
*/
|
||||||
static THD_WORKING_AREA(wa_evtthd1, 128);
|
|
||||||
static THD_FUNCTION(evtthd1, p) {
|
static THD_FUNCTION(evtthd1, p) {
|
||||||
|
|
||||||
chThdSleepMilliseconds(50);
|
chThdSleepMilliseconds(50);
|
||||||
|
@ -72,7 +71,6 @@ static THD_FUNCTION(evtthd1, p) {
|
||||||
/*
|
/*
|
||||||
* Broadcaster thread.
|
* Broadcaster thread.
|
||||||
*/
|
*/
|
||||||
static THD_WORKING_AREA(wa_evtthd2, 128);
|
|
||||||
static THD_FUNCTION(evtthd2, p) {
|
static THD_FUNCTION(evtthd2, p) {
|
||||||
|
|
||||||
(void)p;
|
(void)p;
|
||||||
|
@ -238,8 +236,8 @@ static void nil_test_005_003_execute(void) {
|
||||||
thread_config_t tc = {
|
thread_config_t tc = {
|
||||||
chThdGetPriorityX() + 1,
|
chThdGetPriorityX() + 1,
|
||||||
"event1",
|
"event1",
|
||||||
wa_evtthd1,
|
wa_common,
|
||||||
THD_WORKING_AREA_END(wa_evtthd1),
|
THD_WORKING_AREA_END(wa_common),
|
||||||
evtthd1,
|
evtthd1,
|
||||||
chThdGetSelfX()
|
chThdGetSelfX()
|
||||||
};
|
};
|
||||||
|
@ -320,8 +318,8 @@ static void nil_test_005_004_execute(void) {
|
||||||
thread_config_t tc = {
|
thread_config_t tc = {
|
||||||
chThdGetPriorityX() + 1,
|
chThdGetPriorityX() + 1,
|
||||||
"event1",
|
"event1",
|
||||||
wa_evtthd1,
|
wa_common,
|
||||||
THD_WORKING_AREA_END(wa_evtthd1),
|
THD_WORKING_AREA_END(wa_common),
|
||||||
evtthd1,
|
evtthd1,
|
||||||
chThdGetSelfX()
|
chThdGetSelfX()
|
||||||
};
|
};
|
||||||
|
@ -409,8 +407,8 @@ static void nil_test_005_005_execute(void) {
|
||||||
thread_config_t tc = {
|
thread_config_t tc = {
|
||||||
chThdGetPriorityX() + 1,
|
chThdGetPriorityX() + 1,
|
||||||
"event1",
|
"event1",
|
||||||
wa_evtthd1,
|
wa_common,
|
||||||
THD_WORKING_AREA_END(wa_evtthd1),
|
THD_WORKING_AREA_END(wa_common),
|
||||||
evtthd1,
|
evtthd1,
|
||||||
chThdGetSelfX()
|
chThdGetSelfX()
|
||||||
};
|
};
|
||||||
|
@ -542,8 +540,8 @@ static void nil_test_005_007_execute(void) {
|
||||||
thread_config_t tc = {
|
thread_config_t tc = {
|
||||||
chThdGetPriorityX() + 1,
|
chThdGetPriorityX() + 1,
|
||||||
"event2",
|
"event2",
|
||||||
wa_evtthd2,
|
wa_common,
|
||||||
THD_WORKING_AREA_END(wa_evtthd2),
|
THD_WORKING_AREA_END(wa_common),
|
||||||
evtthd2,
|
evtthd2,
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
|
@ -49,7 +49,6 @@
|
||||||
/*
|
/*
|
||||||
* Messager thread.
|
* Messager thread.
|
||||||
*/
|
*/
|
||||||
static THD_WORKING_AREA(wa_messager, 128);
|
|
||||||
static THD_FUNCTION(messager, p) {
|
static THD_FUNCTION(messager, p) {
|
||||||
|
|
||||||
chMsgSend(p, 'A');
|
chMsgSend(p, 'A');
|
||||||
|
@ -86,8 +85,8 @@ static void nil_test_006_001_execute(void) {
|
||||||
thread_config_t tc = {
|
thread_config_t tc = {
|
||||||
chThdGetPriorityX() - 1,
|
chThdGetPriorityX() - 1,
|
||||||
"messager",
|
"messager",
|
||||||
wa_messager,
|
wa_common,
|
||||||
THD_WORKING_AREA_END(wa_messager),
|
THD_WORKING_AREA_END(wa_common),
|
||||||
messager,
|
messager,
|
||||||
chThdGetSelfX()
|
chThdGetSelfX()
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,640 @@
|
||||||
|
/*
|
||||||
|
ChibiOS - Copyright (C) 2006..2018 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 "nil_test_root.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file nil_test_sequence_007.c
|
||||||
|
* @brief Test Sequence 007 code.
|
||||||
|
*
|
||||||
|
* @page nil_test_sequence_007 [7] Benchmarks
|
||||||
|
*
|
||||||
|
* File: @ref nil_test_sequence_007.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 nil_test_007_001
|
||||||
|
* - @subpage nil_test_007_002
|
||||||
|
* - @subpage nil_test_007_003
|
||||||
|
* - @subpage nil_test_007_004
|
||||||
|
* - @subpage nil_test_007_005
|
||||||
|
* - @subpage nil_test_007_006
|
||||||
|
* - @subpage nil_test_007_007
|
||||||
|
* .
|
||||||
|
*/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* 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
|
||||||
|
|
||||||
|
#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 = chTimeAddX(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(NIL_STATE_SUSPENDED);
|
||||||
|
msg = self->u1.msg;
|
||||||
|
} while (msg == MSG_OK);
|
||||||
|
chSysUnlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Test cases.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
#if (CH_CFG_USE_MESSAGES) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @page nil_test_007_001 [7.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>
|
||||||
|
* - [7.1.1] The messenger thread is started at a lower priority than
|
||||||
|
* the current thread.
|
||||||
|
* - [7.1.2] The number of messages exchanged is counted in a one
|
||||||
|
* second time window.
|
||||||
|
* - [7.1.3] Score is printed.
|
||||||
|
* .
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void nil_test_007_001_execute(void) {
|
||||||
|
uint32_t n;
|
||||||
|
thread_t *tp;
|
||||||
|
|
||||||
|
/* [7.1.1] The messenger thread is started at a lower priority than
|
||||||
|
the current thread.*/
|
||||||
|
test_set_step(1);
|
||||||
|
{
|
||||||
|
thread_config_t tc = {
|
||||||
|
chThdGetPriorityX() + 1,
|
||||||
|
"messenger",
|
||||||
|
wa_common,
|
||||||
|
THD_WORKING_AREA_END(wa_common),
|
||||||
|
bmk_thread1,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
tp = chThdCreate(&tc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [7.1.2] The number of messages exchanged is counted in a one
|
||||||
|
second time window.*/
|
||||||
|
test_set_step(2);
|
||||||
|
{
|
||||||
|
n = msg_loop_test(tp);
|
||||||
|
chThdWait(tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [7.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 nil_test_007_001 = {
|
||||||
|
"Messages performance #1",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
nil_test_007_001_execute
|
||||||
|
};
|
||||||
|
#endif /* CH_CFG_USE_MESSAGES */
|
||||||
|
|
||||||
|
#if (CH_CFG_USE_MESSAGES) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @page nil_test_007_002 [7.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>
|
||||||
|
* - [7.2.1] The messenger thread is started at an higher priority than
|
||||||
|
* the current thread.
|
||||||
|
* - [7.2.2] The number of messages exchanged is counted in a one
|
||||||
|
* second time window.
|
||||||
|
* - [7.2.3] Score is printed.
|
||||||
|
* .
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void nil_test_007_002_execute(void) {
|
||||||
|
uint32_t n;
|
||||||
|
thread_t *tp;
|
||||||
|
|
||||||
|
/* [7.2.1] The messenger thread is started at an higher priority than
|
||||||
|
the current thread.*/
|
||||||
|
test_set_step(1);
|
||||||
|
{
|
||||||
|
thread_config_t tc = {
|
||||||
|
chThdGetPriorityX() - 1,
|
||||||
|
"messenger",
|
||||||
|
wa_common,
|
||||||
|
THD_WORKING_AREA_END(wa_common),
|
||||||
|
bmk_thread1,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
tp = chThdCreate(&tc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [7.2.2] The number of messages exchanged is counted in a one
|
||||||
|
second time window.*/
|
||||||
|
test_set_step(2);
|
||||||
|
{
|
||||||
|
n = msg_loop_test(tp);
|
||||||
|
chThdWait(tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [7.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 nil_test_007_002 = {
|
||||||
|
"Messages performance #2",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
nil_test_007_002_execute
|
||||||
|
};
|
||||||
|
#endif /* CH_CFG_USE_MESSAGES */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page nil_test_007_003 [7.3] 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>
|
||||||
|
* - [7.3.1] Starting the target thread at an higher priority level.
|
||||||
|
* - [7.3.2] Waking up the thread as fast as possible in a one second
|
||||||
|
* time window.
|
||||||
|
* - [7.3.3] Stopping the target thread.
|
||||||
|
* - [7.3.4] Score is printed.
|
||||||
|
* .
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void nil_test_007_003_execute(void) {
|
||||||
|
thread_t *tp;
|
||||||
|
uint32_t n;
|
||||||
|
|
||||||
|
/* [7.3.1] Starting the target thread at an higher priority level.*/
|
||||||
|
test_set_step(1);
|
||||||
|
{
|
||||||
|
thread_config_t tc = {
|
||||||
|
chThdGetPriorityX() - 1,
|
||||||
|
"messenger",
|
||||||
|
wa_common,
|
||||||
|
THD_WORKING_AREA_END(wa_common),
|
||||||
|
bmk_thread4,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
tp = chThdCreate(&tc);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [7.3.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 = chTimeAddX(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;
|
||||||
|
} while (chVTIsSystemTimeWithinX(start, end));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [7.3.3] Stopping the target thread.*/
|
||||||
|
test_set_step(3);
|
||||||
|
{
|
||||||
|
chSysLock();
|
||||||
|
chSchWakeupS(tp, MSG_TIMEOUT);
|
||||||
|
chSysUnlock();
|
||||||
|
chThdWait(tp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [7.3.4] Score is printed.*/
|
||||||
|
test_set_step(4);
|
||||||
|
{
|
||||||
|
test_print("--- Score : ");
|
||||||
|
test_printn(n * 2);
|
||||||
|
test_println(" ctxswc/S");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const testcase_t nil_test_007_003 = {
|
||||||
|
"Context Switch performance",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
nil_test_007_003_execute
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page nil_test_007_004 [7.4] 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>
|
||||||
|
* - [7.4.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.
|
||||||
|
* - [7.4.2] Score is printed.
|
||||||
|
* .
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void nil_test_007_004_execute(void) {
|
||||||
|
uint32_t n;
|
||||||
|
|
||||||
|
/* [7.4.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);
|
||||||
|
{
|
||||||
|
systime_t start, end;
|
||||||
|
thread_config_t tc = {
|
||||||
|
chThdGetPriorityX() + 1,
|
||||||
|
"messenger",
|
||||||
|
wa_common,
|
||||||
|
THD_WORKING_AREA_END(wa_common),
|
||||||
|
bmk_thread3,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
start = test_wait_tick();
|
||||||
|
end = chTimeAddX(start, TIME_MS2I(1000));
|
||||||
|
do {
|
||||||
|
chThdWait(chThdCreate(&tc));
|
||||||
|
n++;
|
||||||
|
} while (chVTIsSystemTimeWithinX(start, end));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [7.4.2] Score is printed.*/
|
||||||
|
test_set_step(2);
|
||||||
|
{
|
||||||
|
test_print("--- Score : ");
|
||||||
|
test_printn(n);
|
||||||
|
test_println(" threads/S");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const testcase_t nil_test_007_004 = {
|
||||||
|
"Threads performance, full cycle",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
nil_test_007_004_execute
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page nil_test_007_005 [7.5] 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>
|
||||||
|
* - [7.5.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.
|
||||||
|
* - [7.5.2] Score is printed.
|
||||||
|
* .
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void nil_test_007_005_execute(void) {
|
||||||
|
uint32_t n;
|
||||||
|
|
||||||
|
/* [7.5.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);
|
||||||
|
{
|
||||||
|
systime_t start, end;
|
||||||
|
thread_config_t tc = {
|
||||||
|
chThdGetPriorityX() - 1,
|
||||||
|
"messenger",
|
||||||
|
wa_common,
|
||||||
|
THD_WORKING_AREA_END(wa_common),
|
||||||
|
bmk_thread3,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
start = test_wait_tick();
|
||||||
|
end = chTimeAddX(start, TIME_MS2I(1000));
|
||||||
|
do {
|
||||||
|
chThdWait(chThdCreate(&tc));
|
||||||
|
n++;
|
||||||
|
} while (chVTIsSystemTimeWithinX(start, end));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [7.5.2] Score is printed.*/
|
||||||
|
test_set_step(2);
|
||||||
|
{
|
||||||
|
test_print("--- Score : ");
|
||||||
|
test_printn(n);
|
||||||
|
test_println(" threads/S");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const testcase_t nil_test_007_005 = {
|
||||||
|
"Threads performance, create/exit only",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
nil_test_007_005_execute
|
||||||
|
};
|
||||||
|
|
||||||
|
#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
|
||||||
|
/**
|
||||||
|
* @page nil_test_007_006 [7.6] 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>
|
||||||
|
* - [7.6.1] A semaphore is teken and released. The operation is
|
||||||
|
* repeated continuously in a one-second time window.
|
||||||
|
* - [7.6.2] The score is printed.
|
||||||
|
* .
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void nil_test_007_006_setup(void) {
|
||||||
|
chSemObjectInit(&sem1, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void nil_test_007_006_execute(void) {
|
||||||
|
uint32_t n;
|
||||||
|
|
||||||
|
/* [7.6.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 = chTimeAddX(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));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [7.6.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 nil_test_007_006 = {
|
||||||
|
"Semaphores wait/signal performance",
|
||||||
|
nil_test_007_006_setup,
|
||||||
|
NULL,
|
||||||
|
nil_test_007_006_execute
|
||||||
|
};
|
||||||
|
#endif /* CH_CFG_USE_SEMAPHORES */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @page nil_test_007_007 [7.7] RAM Footprint
|
||||||
|
*
|
||||||
|
* <h2>Description</h2>
|
||||||
|
* The memory size of the various kernel objects is printed.
|
||||||
|
*
|
||||||
|
* <h2>Test Steps</h2>
|
||||||
|
* - [7.7.1] The size of the system area is printed.
|
||||||
|
* - [7.7.2] The size of a thread structure is printed.
|
||||||
|
* - [7.7.3] The size of a semaphore structure is printed.
|
||||||
|
* - [7.7.4] The size of an event source is printed.
|
||||||
|
* - [7.7.5] The size of an event listener is printed.
|
||||||
|
* - [7.7.6] The size of a mailbox is printed.
|
||||||
|
* .
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void nil_test_007_007_execute(void) {
|
||||||
|
|
||||||
|
/* [7.7.1] The size of the system area is printed.*/
|
||||||
|
test_set_step(1);
|
||||||
|
{
|
||||||
|
test_print("--- System: ");
|
||||||
|
test_printn(sizeof(nil_system_t));
|
||||||
|
test_println(" bytes");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [7.7.2] The size of a thread structure is printed.*/
|
||||||
|
test_set_step(2);
|
||||||
|
{
|
||||||
|
test_print("--- Thread: ");
|
||||||
|
test_printn(sizeof(thread_t));
|
||||||
|
test_println(" bytes");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [7.7.3] The size of a semaphore structure is printed.*/
|
||||||
|
test_set_step(3);
|
||||||
|
{
|
||||||
|
#if CH_CFG_USE_SEMAPHORES || defined(__DOXYGEN__)
|
||||||
|
test_print("--- Semaph: ");
|
||||||
|
test_printn(sizeof(semaphore_t));
|
||||||
|
test_println(" bytes");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [7.7.4] The size of an event source is printed.*/
|
||||||
|
test_set_step(4);
|
||||||
|
{
|
||||||
|
#if CH_CFG_USE_EVENTS || defined(__DOXYGEN__)
|
||||||
|
test_print("--- EventS: ");
|
||||||
|
test_printn(sizeof(event_source_t));
|
||||||
|
test_println(" bytes");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [7.7.5] The size of an event listener is printed.*/
|
||||||
|
test_set_step(5);
|
||||||
|
{
|
||||||
|
#if CH_CFG_USE_EVENTS || defined(__DOXYGEN__)
|
||||||
|
test_print("--- EventL: ");
|
||||||
|
test_printn(sizeof(event_listener_t));
|
||||||
|
test_println(" bytes");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/* [7.7.6] The size of a mailbox is printed.*/
|
||||||
|
test_set_step(6);
|
||||||
|
{
|
||||||
|
#if CH_CFG_USE_MAILBOXES || defined(__DOXYGEN__)
|
||||||
|
test_print("--- MailB.: ");
|
||||||
|
test_printn(sizeof(mailbox_t));
|
||||||
|
test_println(" bytes");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const testcase_t nil_test_007_007 = {
|
||||||
|
"RAM Footprint",
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
nil_test_007_007_execute
|
||||||
|
};
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Exported data.
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Array of test cases.
|
||||||
|
*/
|
||||||
|
const testcase_t * const nil_test_sequence_007_array[] = {
|
||||||
|
#if (CH_CFG_USE_MESSAGES) || defined(__DOXYGEN__)
|
||||||
|
&nil_test_007_001,
|
||||||
|
#endif
|
||||||
|
#if (CH_CFG_USE_MESSAGES) || defined(__DOXYGEN__)
|
||||||
|
&nil_test_007_002,
|
||||||
|
#endif
|
||||||
|
&nil_test_007_003,
|
||||||
|
&nil_test_007_004,
|
||||||
|
&nil_test_007_005,
|
||||||
|
#if (CH_CFG_USE_SEMAPHORES) || defined(__DOXYGEN__)
|
||||||
|
&nil_test_007_006,
|
||||||
|
#endif
|
||||||
|
&nil_test_007_007,
|
||||||
|
NULL
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Benchmarks.
|
||||||
|
*/
|
||||||
|
const testsequence_t nil_test_sequence_007 = {
|
||||||
|
"Benchmarks",
|
||||||
|
nil_test_sequence_007_array
|
||||||
|
};
|
|
@ -0,0 +1,27 @@
|
||||||
|
/*
|
||||||
|
ChibiOS - Copyright (C) 2006..2018 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 nil_test_sequence_007.h
|
||||||
|
* @brief Test Sequence 007 header.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef NIL_TEST_SEQUENCE_007_H
|
||||||
|
#define NIL_TEST_SEQUENCE_007_H
|
||||||
|
|
||||||
|
extern const testsequence_t nil_test_sequence_007;
|
||||||
|
|
||||||
|
#endif /* NIL_TEST_SEQUENCE_007_H */
|
Loading…
Reference in New Issue