From 7f3e0e57b2a13aa4797a8409e6e63671cb6d6993 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 11 Feb 2014 13:00:24 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6701 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/nil/NIL-STM32F303-DISCOVERY/main.c | 2 +- os/nil/include/nil.h | 8 +++ os/nil/src/nil.c | 37 ++++++++++- test/nil/test_root.c | 6 +- test/nil/test_sequence_002.c | 108 ++++++++++++++++++++++++++++--- 5 files changed, 144 insertions(+), 17 deletions(-) diff --git a/demos/nil/NIL-STM32F303-DISCOVERY/main.c b/demos/nil/NIL-STM32F303-DISCOVERY/main.c index 2b648ff29..b928874f3 100644 --- a/demos/nil/NIL-STM32F303-DISCOVERY/main.c +++ b/demos/nil/NIL-STM32F303-DISCOVERY/main.c @@ -111,7 +111,7 @@ THD_FUNCTION(Thread3, arg) { THD_TABLE_BEGIN THD_TABLE_ENTRY(waThread1, "blinker1", Thread1, NULL) THD_TABLE_ENTRY(waThread2, "blinker2", Thread2, NULL) - THD_TABLE_ENTRY(wa_test_support, "test_support", test_support, NULL) + THD_TABLE_ENTRY(wa_test_support, "test_support", test_support, (void *)&nil.threads[3]) THD_TABLE_ENTRY(waThread3, "tester", Thread3, NULL) THD_TABLE_END diff --git a/os/nil/include/nil.h b/os/nil/include/nil.h index 7ba088dac..161c79a6d 100644 --- a/os/nil/include/nil.h +++ b/os/nil/include/nil.h @@ -596,6 +596,13 @@ typedef struct { */ #define chSchIsRescRequiredI() ((bool)(nil.current != nil.next)) +/** + * @brief Returns a pointer to the current @p thread_t. + * + * @xclass + */ +#define chThdGetSelfX() nil.current + /** * @brief Delays the invoking thread for the specified number of seconds. * @note The specified time is rounded up to a value allowed by the real @@ -802,6 +809,7 @@ extern "C" { void chEvtSignal(thread_t *tp, eventmask_t mask); void chEvtSignalI(thread_t *tp, eventmask_t mask); eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t timeout); + eventmask_t chEvtWaitAnyTimeoutS(eventmask_t mask, systime_t timeout); #ifdef __cplusplus } #endif diff --git a/os/nil/src/nil.c b/os/nil/src/nil.c index 9141129cb..edd717600 100644 --- a/os/nil/src/nil.c +++ b/os/nil/src/nil.c @@ -489,7 +489,9 @@ msg_t chSemWaitTimeout(semaphore_t *sp, systime_t timeout) { msg_t msg; chSysLock(); + msg = chSemWaitTimeoutS(sp, timeout); + chSysUnlock(); return msg; } @@ -599,8 +601,10 @@ void chSemSignalI(semaphore_t *sp) { void chSemReset(semaphore_t *sp, cnt_t n) { chSysLock(); + chSemResetI(sp, n); chSchRescheduleS(); + chSysUnlock(); } @@ -654,8 +658,10 @@ void chSemResetI(semaphore_t *sp, cnt_t n) { void chEvtSignal(thread_t *tp, eventmask_t mask) { chSysLock(); + chEvtSignalI(tp, mask); chSchRescheduleS(); + chSysUnlock(); } @@ -697,11 +703,38 @@ void chEvtSignalI(thread_t *tp, eventmask_t mask) { * @api */ eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t timeout) { - thread_t *ctp = nil.current; eventmask_t m; chSysLock(); + m = chEvtWaitAnyTimeoutS(mask, timeout); + + chSysUnlock(); + return m; +} + +/** + * @brief Waits for any of the specified events. + * @details The function waits for any event among those specified in + * @p mask to become pending then the events are cleared and + * returned. + * + * @param[in] mask mask of the event flags that the function should wait + * for, @p ALL_EVENTS enables all the events + * @param[in] timeout the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @return The mask of the served and cleared events. + * @retval 0 if the operation has timed out. + * + * @sclass + */ +eventmask_t chEvtWaitAnyTimeoutS(eventmask_t mask, systime_t timeout) { + thread_t *ctp = nil.current; + eventmask_t m; + if ((m = (ctp->epmask & mask)) == 0) { if (TIME_IMMEDIATE == timeout) { chSysUnlock(); @@ -715,8 +748,6 @@ eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t timeout) { m = ctp->epmask & mask; } ctp->epmask &= ~m; - - chSysUnlock(); return m; } diff --git a/test/nil/test_root.c b/test/nil/test_root.c index 49c1d7862..a8efacba7 100644 --- a/test/nil/test_root.c +++ b/test/nil/test_root.c @@ -51,8 +51,7 @@ thread_reference_t gtr1; */ THD_WORKING_AREA(wa_test_support, 128); THD_FUNCTION(test_support, arg) { - - (void)arg; + thread_t *tp = (thread_t *)arg; /* Initializing global resources.*/ chSemObjectInit(&gsem1, 0); @@ -65,10 +64,11 @@ THD_FUNCTION(test_support, arg) { chSemSignalI(&gsem1); chSemResetI(&gsem2, 0); chThdResumeI(>r1, MSG_OK); + chEvtSignalI(tp, 0x55); chSchRescheduleS(); chSysUnlock(); - chThdSleepMilliseconds(500); + chThdSleepMilliseconds(250); } } diff --git a/test/nil/test_sequence_002.c b/test/nil/test_sequence_002.c index ddb6379ff..a687e7f0f 100644 --- a/test/nil/test_sequence_002.c +++ b/test/nil/test_sequence_002.c @@ -222,9 +222,9 @@ static void test_002_003_execute(void) { test_set_step(1); { time = chVTGetSystemTimeX(); - msg = chSemWaitTimeout(&sem1, 100); - test_assert_time_window(time + 100, - time + 100 + 1, + msg = chSemWaitTimeout(&sem1, MS2ST(1000)); + test_assert_time_window(time + MS2ST(1000), + time + MS2ST(1000) + 1, "out of time window"); test_assert_lock(chSemGetCounterI(&sem1) == 0, "wrong counter value"); @@ -237,9 +237,9 @@ static void test_002_003_execute(void) { test_set_step(2); { time = chVTGetSystemTimeX(); - msg = chSemWaitTimeout(&sem1, 100); - test_assert_time_window(time + 100, - time + 100 + 1, + msg = chSemWaitTimeout(&sem1, MS2ST(1000)); + test_assert_time_window(time + MS2ST(1000), + time + MS2ST(1000) + 1, "out of time window"); test_assert_lock(chSemGetCounterI(&sem1) == 0, "wrong counter value"); @@ -304,11 +304,11 @@ static void test_002_004_execute(void) { test_set_step(2); { time = chVTGetSystemTimeX(); - msg = chThdSuspendTimeoutS(>r1, 100); - test_assert_time_window(time + 100, - time + 100 + 1, + msg = chThdSuspendTimeoutS(&tr1, MS2ST(1000)); + test_assert_time_window(time + MS2ST(1000), + time + MS2ST(1000) + 1, "out of time window"); - test_assert(NULL == gtr1, + test_assert(NULL == tr1, "not NULL"); test_assert(MSG_TIMEOUT == msg, "wrong returned message"); @@ -321,6 +321,91 @@ static const testcase_t test_002_004 = { NULL, test_002_004_execute }; +#endif /* TRUE */ + +#if TRUE || defined(__DOXYGEN__) +/** + * @page test_002_005 Events functionality + * + *

Description

+ * Event flags functionality is tested. + * + *

Conditions

+ * None. + * + *

Test Steps

+ * - A set of event flags are set on the current thread then the + * function chVTGetSystemTimeX() is invoked, the function is supposed to + * return immediately because the event flags are already pending, + * after return the events mask is tested. + * - The pending event flags mask is cleared then the function + * chVTGetSystemTimeX() is invoked, after return the events + * mask is tested. The thread is signaled by another thread. + * - + * . The function chVTGetSystemTimeX() is invoked, no event can + * wakeup the thread, the function must return because timeout. + */ + +static void test_002_005_setup(void) { + + chSemObjectInit(&sem1, 0); +} + +static void test_002_005_execute(void) { + systime_t time; + eventmask_t events; + + /* A set of event flags are set on the current thread then the + function chVTGetSystemTimeX() is invoked, the function is supposed to + return immediately because the event flags are already pending, + after return the events mask is tested.*/ + test_set_step(1); + { + time = chVTGetSystemTimeX(); + chEvtSignalI(chThdGetSelfX(), 0x55); + events = chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(1000)); + test_assert((eventmask_t)0 != events, + "timed out"); + test_assert((eventmask_t)0x55 == events, + "wrong events mask"); + } + + /* The pending event flags mask is cleared then the function + chVTGetSystemTimeX() is invoked, after return the events + mask is tested. The thread is signaled by another thread.*/ + test_set_step(2); + { + time = chVTGetSystemTimeX(); + chThdGetSelfX()->epmask = 0; + events = chEvtWaitAnyTimeout(ALL_EVENTS, MS2ST(1000)); + test_assert((eventmask_t)0 != events, + "timed out"); + test_assert((eventmask_t)0x55 == events, + "wrong events mask"); + } + + /* The function chVTGetSystemTimeX() is invoked, no event can + wakeup the thread, the function must return because timeout.*/ + test_set_step(3); + { + chSysLock(); + time = chVTGetSystemTimeX(); + events = chEvtWaitAnyTimeoutS(0, MS2ST(1000)); + chSysUnlock(); + test_assert_time_window(time + MS2ST(1000), + time + MS2ST(1000) + 1, + "out of time window"); + test_assert((eventmask_t)0 == events, + "wrong events mask"); + } +} + +static const testcase_t test_002_005 = { + "events functionality", + test_002_005_setup, + NULL, + test_002_005_execute +}; #endif /* TRUE */ /**************************************************************************** @@ -342,6 +427,9 @@ const testcase_t * const test_sequence_002[] = { #endif #if TRUE || defined(__DOXYGEN__) &test_002_004, +#endif +#if TRUE || defined(__DOXYGEN__) + &test_002_005, #endif NULL }; -- cgit v1.2.3