git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6701 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2014-02-11 13:00:24 +00:00
parent 4541bd732a
commit 7f3e0e57b2
5 changed files with 144 additions and 17 deletions

View File

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

View File

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

View File

@ -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;
}

View File

@ -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(&gtr1, MSG_OK);
chEvtSignalI(tp, 0x55);
chSchRescheduleS();
chSysUnlock();
chThdSleepMilliseconds(500);
chThdSleepMilliseconds(250);
}
}

View File

@ -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(&gtr1, 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
*
* <h2>Description</h2>
* Event flags functionality is tested.
*
* <h2>Conditions</h2>
* None.
*
* <h2>Test Steps</h2>
* - 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
};