From 067171ec9f0e8b5f488ceddf7cf11d1c1f0867e1 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 1 Sep 2013 08:19:24 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6237 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/nil/src/nil.c | 598 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 598 insertions(+) create mode 100644 os/nil/src/nil.c (limited to 'os/nil/src/nil.c') diff --git a/os/nil/src/nil.c b/os/nil/src/nil.c new file mode 100644 index 000000000..da75ce1a9 --- /dev/null +++ b/os/nil/src/nil.c @@ -0,0 +1,598 @@ +/* + Nil RTOS - Copyright (C) 2012 Giovanni Di Sirio. + + This file is part of Nil RTOS. + + Nil RTOS is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + Nil RTOS is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file nil.c + * @brief Nil RTOS main source file. + * + * @defgroup nil + * @details Nil RTOS services. + * @{ + */ + +#include "nil.h" + +/*===========================================================================*/ +/* Module local definitions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported variables. */ +/*===========================================================================*/ + +/** + * @brief System data structures. + */ +nil_system_t nil; + +/*===========================================================================*/ +/* Module local variables. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module local functions. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module interrupt handlers. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module exported functions. */ +/*===========================================================================*/ + +/** + * @brief Initializes the kernel. + * @details Initializes the kernel structures, the current instructions flow + * becomes the idle thread upon return. The idle thread must not + * invoke any kernel primitive able to change state to not runnable. + * + * @special + */ +void nilSysInit(void) { + thread_ref_t tr; + const thread_config_t *tcp; + + /* Port layer initialization.*/ + port_init(); + + /* Iterates through the list of defined threads.*/ + for (tr = &nil.threads[0], tcp = nil_thd_configs; + tr < &nil.threads[NIL_CFG_NUM_THREADS]; + tr++, tcp++) { + tr->state = NIL_THD_READY; + tr->timeout = 0; + + /* Port dependent thread initialization.*/ + SETUP_CONTEXT(tr, tcp->wap, tcp->size, tcp->funcp, tcp->arg); + + /* Initialization hook.*/ +#if defined(NIL_CFG_THREAD_EXT_INIT_HOOK) + NIL_CFG_THREAD_EXT_INIT_HOOK(tr); +#endif + } + + /* Runs the highest priority thread, the current one becomes the null + thread.*/ + nil.current = nil.next = nil.threads; + port_switch(nil.threads, &nil.threads[NIL_CFG_NUM_THREADS]); + + /* Interrupts enabled for the idle thread.*/ + nilSysEnable(); +} + +/** + * @brief Time management handler. + * @note This handler has to be invoked by a periodic ISR in order to + * reschedule the waiting threads. + * + * @iclass + */ +void nilSysTimerHandlerI(void) { + +#if NIL_CFG_TIMEDELTA == 0 + thread_ref_t tr = &nil.threads[0]; + nil.systime++; + do { + /* Is the thread in a wait state with timeout?.*/ + if (tr->timeout > 0) { + + nilDbgAssert(!NIL_THD_IS_READY(tr), + "nilSysTimerHandlerI(), #1", "is ready"); + + /* Did the timer reach zero?*/ + if (--tr->timeout == 0) { + /* Timeout on semaphores requires a special handling because the + semaphore counter must be incremented.*/ + if (NIL_THD_IS_WTSEM(tr)) + tr->u1.semp->cnt++; + else if (NIL_THD_IS_SUSP(tr)) + tr->u1.trp = NULL; + nilSchReadyI(tr, NIL_MSG_TMO); + } + } + /* Lock released in order to give a preemption chance on those + architectures supporting IRQ preemption.*/ + nilSysUnlockFromISR(); + tr++; + nilSysLockFromISR(); + } while (tr < &nil.threads[NIL_CFG_NUM_THREADS]); +#else + thread_ref_t tr = &nil.threads[0]; + systime_t next = 0; + + nilDbgAssert(nil.nexttime == port_timer_get_alarm(), + "nilSysTimerHandlerI(), #1", "time mismatch"); + + do { + /* Is the thread in a wait state with timeout?.*/ + if (tr->timeout > 0) { + + nilDbgAssert(!NIL_THD_IS_READY(tr), + "nilSysTimerHandlerI(), #2", "is ready"); + nilDbgAssert(tr->timeout >= nil.nexttime - nil.lasttime, + "nilSysTimerHandlerI(), #3", "skipped one"); + + tr->timeout -= nil.nexttime - nil.lasttime; + if (tr->timeout == 0) { + /* Timeout on semaphores requires a special handling because the + semaphore counter must be incremented.*/ + if (NIL_THD_IS_WTSEM(tr)) + tr->u1.semp->cnt++; + else if (NIL_THD_IS_SUSP(tr)) + tr->u1.trp = NULL; + nilSchReadyI(tr, NIL_MSG_TMO); + } + else { + if (tr->timeout <= next - 1) + next = tr->timeout; + } + } + /* Lock released in order to give a preemption chance on those + architectures supporting IRQ preemption.*/ + nilSysUnlockFromISR(); + tr++; + nilSysLockFromISR(); + } while (tr < &nil.threads[NIL_CFG_NUM_THREADS]); + nil.lasttime = nil.nexttime; + if (next > 0) { + nil.nexttime += next; + port_timer_set_alarm(nil.nexttime); + } + else { + /* No tick event needed.*/ + port_timer_stop_alarm(); + } +#endif +} + +/** + * @brief Makes the specified thread ready for execution. + * + * @param[in] tr reference to the @p thread_t object + * @param[in] msg the wakeup message + * + * @return The same reference passed as parameter. + */ +thread_ref_t nilSchReadyI(thread_ref_t tr, msg_t msg) { + + nilDbgAssert((tr >= nil.threads) && + (tr < &nil.threads[NIL_CFG_NUM_THREADS]), + "nilSchReadyI(), #1", "pointer out of range"); + nilDbgAssert(!NIL_THD_IS_READY(tr), + "nilSchReadyI(), #2", "already ready"); + nilDbgAssert(nil.next <= nil.current, + "nilSchReadyI(), #3", "priority ordering"); + + tr->u1.msg = msg; + tr->state = NIL_THD_READY; + tr->timeout = 0; + if (tr < nil.next) + nil.next = tr; + return tr; +} + +/** + * @brief Reschedules. + * + * @sclass + */ +void nilSchRescheduleS() { + thread_ref_t otr = nil.current; + thread_ref_t ntr = nil.next; + + if (ntr != otr) { + nil.current = ntr; +#if defined(NIL_CFG_IDLE_LEAVE_HOOK) + if (otr == &nil.threads[NIL_CFG_NUM_THREADS]) { + NIL_CFG_IDLE_LEAVE_HOOK(); + } +#endif + port_switch(ntr, otr); + } +} + +/** + * @brief Puts the current thread to sleep into the specified state with + * timeout specification. + * @details The thread goes into a sleeping state, if it is not awakened + * explicitly within the specified system time then it is forcibly + * awakened with a @p NIL_MSG_TMO low level message. + * + * @param[in] newstate the new thread state or a semaphore pointer + * @param[in] timeout the number of ticks before the operation timeouts. + * the following special values are allowed: + * - @a TIME_INFINITE no timeout. + * . + * @return The wakeup message. + * @retval NIL_MSG_TMO if a timeout occurred. + * + * @sclass + */ +msg_t nilSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) { + thread_ref_t ntr, otr = nil.current; + + nilDbgAssert(otr != &nil.threads[NIL_CFG_NUM_THREADS], + "nilSchGoSleepTimeoutS(), #1", "idle cannot sleep"); + + /* Storing the wait object for the current thread.*/ + otr->state = newstate; + +#if NIL_CFG_TIMEDELTA > 0 + if (timeout != TIME_INFINITE) { + systime_t time = nilTimeNowI() + timeout; + + /* TIMEDELTA makes sure to have enough time to reprogram the timer + before the free-running timer counter reaches the selected timeout.*/ + if (timeout < NIL_CFG_TIMEDELTA) + timeout = NIL_CFG_TIMEDELTA; + + if (nil.lasttime == nil.nexttime) { + /* Special case, first thread asking for a timeout.*/ + port_timer_start_alarm(time); + nil.nexttime = time; + } + else { + /* Special case, there are already other threads with a timeout + activated, evaluating the order.*/ + if (nilTimeIsWithin(time, nil.lasttime, nil.nexttime)) { + port_timer_set_alarm(time); + nil.nexttime = time; + } + } + + /* Timeout settings.*/ + otr->timeout = time - nil.lasttime; + } +#else + + /* Timeout settings.*/ + otr->timeout = timeout; +#endif + + /* Scanning the whole threads array.*/ + ntr = nil.threads; + while (true) { + /* Is this thread ready to execute?*/ + if (NIL_THD_IS_READY(ntr)) { + nil.current = nil.next = ntr; +#if defined(NIL_CFG_IDLE_ENTER_HOOK) + if (ntr == &nil.threads[NIL_CFG_NUM_THREADS]) { + NIL_CFG_IDLE_ENTER_HOOK(); + } +#endif + port_switch(ntr, otr); + return nil.current->u1.msg; + } + + /* Points to the next thread in lowering priority order.*/ + ntr++; + nilDbgAssert(ntr <= &nil.threads[NIL_CFG_NUM_THREADS], + "nilSchGoSleepTimeoutS(), #2", "pointer out of range"); + } +} + +/** + * @brief Sends the current thread sleeping and sets a reference variable. + * @note This function must reschedule, it can only be called from thread + * context. + * + * @param[in] trp a pointer to a thread reference object + * @param[in] timeout the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_INFINITE no timeout. + * . + * @return The wake up message. + * + * @sclass + */ +msg_t nilThdSuspendTimeoutS(thread_ref_t *trp, systime_t timeout) { + + nilDbgAssert(*trp == NULL, "nilThdSuspendTimeoutS(), #1", "not NULL"); + + *trp = nil.current; + nil.current->u1.trp = trp; + return nilSchGoSleepTimeoutS(NIL_THD_SUSP, timeout); +} + +/** + * @brief Wakes up a thread waiting on a thread reference object. + * @note This function must not reschedule because it can be called from + * ISR context. + * + * @param[in] trp a pointer to a thread reference object + * @param[in] msg the message code + * + * @iclass + */ +void nilThdResumeI(thread_ref_t *trp, msg_t msg) { + + if (*trp != NULL) { + thread_ref_t tr = *trp; + + nilDbgAssert(NIL_THD_IS_SUSP(tr), "nilThdResumeI(), #1", "not suspended"); + + *trp = NULL; + nilSchReadyI(tr, msg); + } +} + +/** + * @brief Suspends the invoking thread for the specified time. + * + * @param[in] time the delay in system ticks + * + * @api + */ +void nilThdSleep(systime_t time) { + + nilSysLock(); + nilThdSleepS(time); + nilSysUnlock(); +} + +/** + * @brief Suspends the invoking thread until the system time arrives to the + * specified value. + * + * @param[in] time absolute system time + * + * @api + */ +void nilThdSleepUntil(systime_t time) { + + nilSysLock(); + nilThdSleepUntilS(time); + nilSysUnlock(); +} + +/** + * @brief Current system time. + * @details Returns the number of system ticks since the @p nilSysInit() + * invocation. + * @note The counter can reach its maximum and then restart from zero. + * @note This function is designed to work with the @p nilThdSleepUntil(). + * + * @return The system time in ticks. + * + * @api + */ +systime_t nilTimeNow(void) { + systime_t time; + + nilSysLock(); + time = nilTimeNowI(); + nilSysUnlock(); + return time; +} + +/** + * @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. + * + * @api + */ +bool nilTimeNowIsWithin(systime_t start, systime_t end) { + + systime_t time = nilTimeNow(); + return nilTimeIsWithin(time, start, end); +} + +/** + * @brief Performs a wait operation on a semaphore with timeout specification. + * + * @param[in] sp pointer to a @p semaphore_t structure + * @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 A message specifying how the invoking thread has been + * released from the semaphore. + * @retval NIL_MSG_OK if the thread has not stopped on the semaphore or the + * semaphore has been signaled. + * @retval NIL_MSG_RST if the semaphore has been reset using @p nilSemReset(). + * @retval NIL_MSG_TMO if the semaphore has not been signaled or reset within + * the specified timeout. + * + * @api + */ +msg_t nilSemWaitTimeout(semaphore_t *sp, systime_t timeout) { + msg_t msg; + + nilSysLock(); + msg = nilSemWaitTimeoutS(sp, timeout); + nilSysUnlock(); + return msg; +} + +/** + * @brief Performs a wait operation on a semaphore with timeout specification. + * + * @param[in] sp pointer to a @p semaphore_t structure + * @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 A message specifying how the invoking thread has been + * released from the semaphore. + * @retval NIL_MSG_OK if the thread has not stopped on the semaphore or the + * semaphore has been signaled. + * @retval NIL_MSG_RST if the semaphore has been reset using @p nilSemReset(). + * @retval NIL_MSG_TMO if the semaphore has not been signaled or reset within + * the specified timeout. + * + * @sclass + */ +msg_t nilSemWaitTimeoutS(semaphore_t *sp, systime_t timeout) { + + /* Note, the semaphore counter is a volatile variable so accesses are + manually optimized.*/ + cnt_t cnt = sp->cnt; + if (cnt <= 0) { + if (TIME_IMMEDIATE == timeout) + return NIL_MSG_TMO; + sp->cnt = cnt - 1; + nil.current->u1.semp = sp; + return nilSchGoSleepTimeoutS(NIL_THD_WTSEM, timeout); + } + sp->cnt = cnt - 1; + return NIL_MSG_OK; +} + +/** + * @brief Performs a signal operation on a semaphore. + * @post This function does not reschedule so a call to a rescheduling + * function must be performed before unlocking the kernel. Note that + * interrupt handlers always reschedule on exit so an explicit + * reschedule must not be performed in ISRs. + * + * @param[in] sp pointer to a @p semaphore_t structure + * + * @api + */ +void nilSemSignal(semaphore_t *sp) { + + nilSysLock(); + nilSemSignalI(sp); + nilSchRescheduleS(); + nilSysUnlock(); +} + +/** + * @brief Performs a signal operation on a semaphore. + * @post This function does not reschedule so a call to a rescheduling + * function must be performed before unlocking the kernel. Note that + * interrupt handlers always reschedule on exit so an explicit + * reschedule must not be performed in ISRs. + * + * @param[in] sp pointer to a @p semaphore_t structure + * + * @iclass + */ +void nilSemSignalI(semaphore_t *sp) { + + if (++sp->cnt <= 0) { + thread_ref_t tr = nil.threads; + while (true) { + /* Is this thread waiting on this semaphore?*/ + if (tr->u1.semp == sp) { + + nilDbgAssert(NIL_THD_IS_WTSEM(tr), + "nilSemSignalI(), #1", "not waiting"); + + nilSchReadyI(tr, NIL_MSG_OK); + return; + } + tr++; + } + } +} + +/** + * @brief Performs a reset operation on the semaphore. + * @post After invoking this function all the threads waiting on the + * semaphore, if any, are released and the semaphore counter is set + * to the specified, non negative, value. + * @post This function does not reschedule so a call to a rescheduling + * function must be performed before unlocking the kernel. Note that + * interrupt handlers always reschedule on exit so an explicit + * reschedule must not be performed in ISRs. + * + * @param[in] sp pointer to a @p semaphore_t structure + * @param[in] n the new value of the semaphore counter. The value must + * be non-negative. + * + * @api + */ +void nilSemReset(semaphore_t *sp, cnt_t n) { + + nilSysLock(); + nilSemResetI(sp, n); + nilSchRescheduleS(); + nilSysUnlock(); +} + +/** + * @brief Performs a reset operation on the semaphore. + * @post After invoking this function all the threads waiting on the + * semaphore, if any, are released and the semaphore counter is set + * to the specified, non negative, value. + * @post This function does not reschedule so a call to a rescheduling + * function must be performed before unlocking the kernel. Note that + * interrupt handlers always reschedule on exit so an explicit + * reschedule must not be performed in ISRs. + * + * @param[in] sp pointer to a @p semaphore_t structure + * @param[in] n the new value of the semaphore counter. The value must + * be non-negative. + * + * @iclass + */ +void nilSemResetI(semaphore_t *sp, cnt_t n) { + thread_ref_t tr; + cnt_t cnt; + + cnt = sp->cnt; + sp->cnt = n; + tr = nil.threads; + while (cnt < 0) { + /* Is this thread waiting on this semaphore?*/ + if (tr->u1.semp == sp) { + + nilDbgAssert(NIL_THD_IS_WTSEM(tr), + "nilSemResetI(), #1", "not waiting"); + + cnt++; + nilSchReadyI(tr, NIL_MSG_RST); + } + tr++; + } +} + +/** @} */ -- cgit v1.2.3 From fa8b45cc5be41840b99d4a5468108568f93513c1 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 3 Sep 2013 13:21:10 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6255 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/nil/src/nil.c | 66 ++++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 45 insertions(+), 21 deletions(-) (limited to 'os/nil/src/nil.c') diff --git a/os/nil/src/nil.c b/os/nil/src/nil.c index da75ce1a9..b9b44e4c9 100644 --- a/os/nil/src/nil.c +++ b/os/nil/src/nil.c @@ -80,7 +80,7 @@ void nilSysInit(void) { tr->timeout = 0; /* Port dependent thread initialization.*/ - SETUP_CONTEXT(tr, tcp->wap, tcp->size, tcp->funcp, tcp->arg); + PORT_SETUP_CONTEXT(tr, tcp->wap, tcp->size, tcp->funcp, tcp->arg); /* Initialization hook.*/ #if defined(NIL_CFG_THREAD_EXT_INIT_HOOK) @@ -97,6 +97,35 @@ void nilSysInit(void) { nilSysEnable(); } +/** + * @brief Halts the system. + * @details This function is invoked by the operating system when an + * unrecoverable error is detected, for example because a programming + * error in the application code that triggers an assertion while + * in debug mode. + * @note Can be invoked from any system state. + * + * @special + */ +void nilSysHalt(const char *reason) { + + port_disable(); + +#if NIL_DBG_ENABLED + nil.dbg_panic_msg = reason; +#else + (void)reason; +#endif + +#if defined(NIL_CFG_SYSTEM_HALT_HOOK) || defined(__DOXYGEN__) + NIL_CFG_SYSTEM_HALT_HOOK(reason); +#endif + + /* Harmless infinite loop.*/ + while (true) + ; +} + /** * @brief Time management handler. * @note This handler has to be invoked by a periodic ISR in order to @@ -113,8 +142,7 @@ void nilSysTimerHandlerI(void) { /* Is the thread in a wait state with timeout?.*/ if (tr->timeout > 0) { - nilDbgAssert(!NIL_THD_IS_READY(tr), - "nilSysTimerHandlerI(), #1", "is ready"); + nilDbgAssert(!NIL_THD_IS_READY(tr), "is ready"); /* Did the timer reach zero?*/ if (--tr->timeout == 0) { @@ -124,7 +152,7 @@ void nilSysTimerHandlerI(void) { tr->u1.semp->cnt++; else if (NIL_THD_IS_SUSP(tr)) tr->u1.trp = NULL; - nilSchReadyI(tr, NIL_MSG_TMO); + nilSchReadyI(tr, MSG_TIMEOUT); } } /* Lock released in order to give a preemption chance on those @@ -194,11 +222,9 @@ thread_ref_t nilSchReadyI(thread_ref_t tr, msg_t msg) { nilDbgAssert((tr >= nil.threads) && (tr < &nil.threads[NIL_CFG_NUM_THREADS]), - "nilSchReadyI(), #1", "pointer out of range"); - nilDbgAssert(!NIL_THD_IS_READY(tr), - "nilSchReadyI(), #2", "already ready"); - nilDbgAssert(nil.next <= nil.current, - "nilSchReadyI(), #3", "priority ordering"); + "pointer out of range"); + nilDbgAssert(!NIL_THD_IS_READY(tr), "already ready"); + nilDbgAssert(nil.next <= nil.current, "priority ordering"); tr->u1.msg = msg; tr->state = NIL_THD_READY; @@ -249,7 +275,7 @@ msg_t nilSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) { thread_ref_t ntr, otr = nil.current; nilDbgAssert(otr != &nil.threads[NIL_CFG_NUM_THREADS], - "nilSchGoSleepTimeoutS(), #1", "idle cannot sleep"); + "idle cannot sleep"); /* Storing the wait object for the current thread.*/ otr->state = newstate; @@ -304,7 +330,7 @@ msg_t nilSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) { /* Points to the next thread in lowering priority order.*/ ntr++; nilDbgAssert(ntr <= &nil.threads[NIL_CFG_NUM_THREADS], - "nilSchGoSleepTimeoutS(), #2", "pointer out of range"); + "pointer out of range"); } } @@ -324,7 +350,7 @@ msg_t nilSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) { */ msg_t nilThdSuspendTimeoutS(thread_ref_t *trp, systime_t timeout) { - nilDbgAssert(*trp == NULL, "nilThdSuspendTimeoutS(), #1", "not NULL"); + nilDbgAssert(*trp == NULL, "not NULL"); *trp = nil.current; nil.current->u1.trp = trp; @@ -346,7 +372,7 @@ void nilThdResumeI(thread_ref_t *trp, msg_t msg) { if (*trp != NULL) { thread_ref_t tr = *trp; - nilDbgAssert(NIL_THD_IS_SUSP(tr), "nilThdResumeI(), #1", "not suspended"); + nilDbgAssert(NIL_THD_IS_SUSP(tr), "not suspended"); *trp = NULL; nilSchReadyI(tr, msg); @@ -476,13 +502,13 @@ msg_t nilSemWaitTimeoutS(semaphore_t *sp, systime_t timeout) { cnt_t cnt = sp->cnt; if (cnt <= 0) { if (TIME_IMMEDIATE == timeout) - return NIL_MSG_TMO; + return MSG_TIMEOUT; sp->cnt = cnt - 1; nil.current->u1.semp = sp; return nilSchGoSleepTimeoutS(NIL_THD_WTSEM, timeout); } sp->cnt = cnt - 1; - return NIL_MSG_OK; + return MSG_OK; } /** @@ -523,10 +549,9 @@ void nilSemSignalI(semaphore_t *sp) { /* Is this thread waiting on this semaphore?*/ if (tr->u1.semp == sp) { - nilDbgAssert(NIL_THD_IS_WTSEM(tr), - "nilSemSignalI(), #1", "not waiting"); + nilDbgAssert(NIL_THD_IS_WTSEM(tr), "not waiting"); - nilSchReadyI(tr, NIL_MSG_OK); + nilSchReadyI(tr, MSG_OK); return; } tr++; @@ -585,11 +610,10 @@ void nilSemResetI(semaphore_t *sp, cnt_t n) { /* Is this thread waiting on this semaphore?*/ if (tr->u1.semp == sp) { - nilDbgAssert(NIL_THD_IS_WTSEM(tr), - "nilSemResetI(), #1", "not waiting"); + nilDbgAssert(NIL_THD_IS_WTSEM(tr), "not waiting"); cnt++; - nilSchReadyI(tr, NIL_MSG_RST); + nilSchReadyI(tr, MSG_RESET); } tr++; } -- cgit v1.2.3 From 1292b0230ccdef3a445647185e12ac159d7a9ed8 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 3 Sep 2013 13:50:15 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6257 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/nil/src/nil.c | 152 +++++++++++++++++++++++++++---------------------------- 1 file changed, 76 insertions(+), 76 deletions(-) (limited to 'os/nil/src/nil.c') diff --git a/os/nil/src/nil.c b/os/nil/src/nil.c index b9b44e4c9..a7677aeeb 100644 --- a/os/nil/src/nil.c +++ b/os/nil/src/nil.c @@ -65,7 +65,7 @@ nil_system_t nil; * * @special */ -void nilSysInit(void) { +void chSysInit(void) { thread_ref_t tr; const thread_config_t *tcp; @@ -76,7 +76,7 @@ void nilSysInit(void) { for (tr = &nil.threads[0], tcp = nil_thd_configs; tr < &nil.threads[NIL_CFG_NUM_THREADS]; tr++, tcp++) { - tr->state = NIL_THD_READY; + tr->state = NIL_STATE_READY; tr->timeout = 0; /* Port dependent thread initialization.*/ @@ -94,7 +94,7 @@ void nilSysInit(void) { port_switch(nil.threads, &nil.threads[NIL_CFG_NUM_THREADS]); /* Interrupts enabled for the idle thread.*/ - nilSysEnable(); + chSysEnable(); } /** @@ -107,7 +107,7 @@ void nilSysInit(void) { * * @special */ -void nilSysHalt(const char *reason) { +void chSysHalt(const char *reason) { port_disable(); @@ -133,7 +133,7 @@ void nilSysHalt(const char *reason) { * * @iclass */ -void nilSysTimerHandlerI(void) { +void chSysTimerHandlerI(void) { #if NIL_CFG_TIMEDELTA == 0 thread_ref_t tr = &nil.threads[0]; @@ -142,7 +142,7 @@ void nilSysTimerHandlerI(void) { /* Is the thread in a wait state with timeout?.*/ if (tr->timeout > 0) { - nilDbgAssert(!NIL_THD_IS_READY(tr), "is ready"); + chDbgAssert(!NIL_THD_IS_READY(tr), "is ready"); /* Did the timer reach zero?*/ if (--tr->timeout == 0) { @@ -152,30 +152,30 @@ void nilSysTimerHandlerI(void) { tr->u1.semp->cnt++; else if (NIL_THD_IS_SUSP(tr)) tr->u1.trp = NULL; - nilSchReadyI(tr, MSG_TIMEOUT); + chSchReadyI(tr, MSG_TIMEOUT); } } /* Lock released in order to give a preemption chance on those architectures supporting IRQ preemption.*/ - nilSysUnlockFromISR(); + chSysUnlockFromISR(); tr++; - nilSysLockFromISR(); + chSysLockFromISR(); } while (tr < &nil.threads[NIL_CFG_NUM_THREADS]); #else thread_ref_t tr = &nil.threads[0]; systime_t next = 0; - nilDbgAssert(nil.nexttime == port_timer_get_alarm(), - "nilSysTimerHandlerI(), #1", "time mismatch"); + chDbgAssert(nil.nexttime == port_timer_get_alarm(), + "chSysTimerHandlerI(), #1", "time mismatch"); do { /* Is the thread in a wait state with timeout?.*/ if (tr->timeout > 0) { - nilDbgAssert(!NIL_THD_IS_READY(tr), - "nilSysTimerHandlerI(), #2", "is ready"); - nilDbgAssert(tr->timeout >= nil.nexttime - nil.lasttime, - "nilSysTimerHandlerI(), #3", "skipped one"); + chDbgAssert(!NIL_THD_IS_READY(tr), + "chSysTimerHandlerI(), #2", "is ready"); + chDbgAssert(tr->timeout >= nil.nexttime - nil.lasttime, + "chSysTimerHandlerI(), #3", "skipped one"); tr->timeout -= nil.nexttime - nil.lasttime; if (tr->timeout == 0) { @@ -185,7 +185,7 @@ void nilSysTimerHandlerI(void) { tr->u1.semp->cnt++; else if (NIL_THD_IS_SUSP(tr)) tr->u1.trp = NULL; - nilSchReadyI(tr, NIL_MSG_TMO); + chSchReadyI(tr, NIL_MSG_TMO); } else { if (tr->timeout <= next - 1) @@ -194,9 +194,9 @@ void nilSysTimerHandlerI(void) { } /* Lock released in order to give a preemption chance on those architectures supporting IRQ preemption.*/ - nilSysUnlockFromISR(); + chSysUnlockFromISR(); tr++; - nilSysLockFromISR(); + chSysLockFromISR(); } while (tr < &nil.threads[NIL_CFG_NUM_THREADS]); nil.lasttime = nil.nexttime; if (next > 0) { @@ -218,16 +218,16 @@ void nilSysTimerHandlerI(void) { * * @return The same reference passed as parameter. */ -thread_ref_t nilSchReadyI(thread_ref_t tr, msg_t msg) { +thread_ref_t chSchReadyI(thread_ref_t tr, msg_t msg) { - nilDbgAssert((tr >= nil.threads) && + chDbgAssert((tr >= nil.threads) && (tr < &nil.threads[NIL_CFG_NUM_THREADS]), "pointer out of range"); - nilDbgAssert(!NIL_THD_IS_READY(tr), "already ready"); - nilDbgAssert(nil.next <= nil.current, "priority ordering"); + chDbgAssert(!NIL_THD_IS_READY(tr), "already ready"); + chDbgAssert(nil.next <= nil.current, "priority ordering"); tr->u1.msg = msg; - tr->state = NIL_THD_READY; + tr->state = NIL_STATE_READY; tr->timeout = 0; if (tr < nil.next) nil.next = tr; @@ -239,7 +239,7 @@ thread_ref_t nilSchReadyI(thread_ref_t tr, msg_t msg) { * * @sclass */ -void nilSchRescheduleS() { +void chSchRescheduleS() { thread_ref_t otr = nil.current; thread_ref_t ntr = nil.next; @@ -271,10 +271,10 @@ void nilSchRescheduleS() { * * @sclass */ -msg_t nilSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) { +msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) { thread_ref_t ntr, otr = nil.current; - nilDbgAssert(otr != &nil.threads[NIL_CFG_NUM_THREADS], + chDbgAssert(otr != &nil.threads[NIL_CFG_NUM_THREADS], "idle cannot sleep"); /* Storing the wait object for the current thread.*/ @@ -282,7 +282,7 @@ msg_t nilSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) { #if NIL_CFG_TIMEDELTA > 0 if (timeout != TIME_INFINITE) { - systime_t time = nilTimeNowI() + timeout; + systime_t time = chTimeNowI() + timeout; /* TIMEDELTA makes sure to have enough time to reprogram the timer before the free-running timer counter reaches the selected timeout.*/ @@ -297,7 +297,7 @@ msg_t nilSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) { else { /* Special case, there are already other threads with a timeout activated, evaluating the order.*/ - if (nilTimeIsWithin(time, nil.lasttime, nil.nexttime)) { + if (chTimeIsWithin(time, nil.lasttime, nil.nexttime)) { port_timer_set_alarm(time); nil.nexttime = time; } @@ -329,7 +329,7 @@ msg_t nilSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) { /* Points to the next thread in lowering priority order.*/ ntr++; - nilDbgAssert(ntr <= &nil.threads[NIL_CFG_NUM_THREADS], + chDbgAssert(ntr <= &nil.threads[NIL_CFG_NUM_THREADS], "pointer out of range"); } } @@ -348,13 +348,13 @@ msg_t nilSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) { * * @sclass */ -msg_t nilThdSuspendTimeoutS(thread_ref_t *trp, systime_t timeout) { +msg_t chThdSuspendTimeoutS(thread_ref_t *trp, systime_t timeout) { - nilDbgAssert(*trp == NULL, "not NULL"); + chDbgAssert(*trp == NULL, "not NULL"); *trp = nil.current; nil.current->u1.trp = trp; - return nilSchGoSleepTimeoutS(NIL_THD_SUSP, timeout); + return chSchGoSleepTimeoutS(NIL_STATE_SUSP, timeout); } /** @@ -367,15 +367,15 @@ msg_t nilThdSuspendTimeoutS(thread_ref_t *trp, systime_t timeout) { * * @iclass */ -void nilThdResumeI(thread_ref_t *trp, msg_t msg) { +void chThdResumeI(thread_ref_t *trp, msg_t msg) { if (*trp != NULL) { thread_ref_t tr = *trp; - nilDbgAssert(NIL_THD_IS_SUSP(tr), "not suspended"); + chDbgAssert(NIL_THD_IS_SUSP(tr), "not suspended"); *trp = NULL; - nilSchReadyI(tr, msg); + chSchReadyI(tr, msg); } } @@ -386,11 +386,11 @@ void nilThdResumeI(thread_ref_t *trp, msg_t msg) { * * @api */ -void nilThdSleep(systime_t time) { +void chThdSleep(systime_t time) { - nilSysLock(); - nilThdSleepS(time); - nilSysUnlock(); + chSysLock(); + chThdSleepS(time); + chSysUnlock(); } /** @@ -401,30 +401,30 @@ void nilThdSleep(systime_t time) { * * @api */ -void nilThdSleepUntil(systime_t time) { +void chThdSleepUntil(systime_t time) { - nilSysLock(); - nilThdSleepUntilS(time); - nilSysUnlock(); + chSysLock(); + chThdSleepUntilS(time); + chSysUnlock(); } /** * @brief Current system time. - * @details Returns the number of system ticks since the @p nilSysInit() + * @details Returns the number of system ticks since the @p chSysInit() * invocation. * @note The counter can reach its maximum and then restart from zero. - * @note This function is designed to work with the @p nilThdSleepUntil(). + * @note This function is designed to work with the @p chThdSleepUntil(). * * @return The system time in ticks. * * @api */ -systime_t nilTimeNow(void) { +systime_t chTimeNow(void) { systime_t time; - nilSysLock(); - time = nilTimeNowI(); - nilSysUnlock(); + chSysLock(); + time = chTimeNowI(); + chSysUnlock(); return time; } @@ -442,10 +442,10 @@ systime_t nilTimeNow(void) { * * @api */ -bool nilTimeNowIsWithin(systime_t start, systime_t end) { +bool chTimeNowIsWithin(systime_t start, systime_t end) { - systime_t time = nilTimeNow(); - return nilTimeIsWithin(time, start, end); + systime_t time = chTimeNow(); + return chTimeIsWithin(time, start, end); } /** @@ -461,18 +461,18 @@ bool nilTimeNowIsWithin(systime_t start, systime_t end) { * released from the semaphore. * @retval NIL_MSG_OK if the thread has not stopped on the semaphore or the * semaphore has been signaled. - * @retval NIL_MSG_RST if the semaphore has been reset using @p nilSemReset(). + * @retval NIL_MSG_RST if the semaphore has been reset using @p chSemReset(). * @retval NIL_MSG_TMO if the semaphore has not been signaled or reset within * the specified timeout. * * @api */ -msg_t nilSemWaitTimeout(semaphore_t *sp, systime_t timeout) { +msg_t chSemWaitTimeout(semaphore_t *sp, systime_t timeout) { msg_t msg; - nilSysLock(); - msg = nilSemWaitTimeoutS(sp, timeout); - nilSysUnlock(); + chSysLock(); + msg = chSemWaitTimeoutS(sp, timeout); + chSysUnlock(); return msg; } @@ -489,13 +489,13 @@ msg_t nilSemWaitTimeout(semaphore_t *sp, systime_t timeout) { * released from the semaphore. * @retval NIL_MSG_OK if the thread has not stopped on the semaphore or the * semaphore has been signaled. - * @retval NIL_MSG_RST if the semaphore has been reset using @p nilSemReset(). + * @retval NIL_MSG_RST if the semaphore has been reset using @p chSemReset(). * @retval NIL_MSG_TMO if the semaphore has not been signaled or reset within * the specified timeout. * * @sclass */ -msg_t nilSemWaitTimeoutS(semaphore_t *sp, systime_t timeout) { +msg_t chSemWaitTimeoutS(semaphore_t *sp, systime_t timeout) { /* Note, the semaphore counter is a volatile variable so accesses are manually optimized.*/ @@ -505,7 +505,7 @@ msg_t nilSemWaitTimeoutS(semaphore_t *sp, systime_t timeout) { return MSG_TIMEOUT; sp->cnt = cnt - 1; nil.current->u1.semp = sp; - return nilSchGoSleepTimeoutS(NIL_THD_WTSEM, timeout); + return chSchGoSleepTimeoutS(NIL_STATE_WTSEM, timeout); } sp->cnt = cnt - 1; return MSG_OK; @@ -522,12 +522,12 @@ msg_t nilSemWaitTimeoutS(semaphore_t *sp, systime_t timeout) { * * @api */ -void nilSemSignal(semaphore_t *sp) { +void chSemSignal(semaphore_t *sp) { - nilSysLock(); - nilSemSignalI(sp); - nilSchRescheduleS(); - nilSysUnlock(); + chSysLock(); + chSemSignalI(sp); + chSchRescheduleS(); + chSysUnlock(); } /** @@ -541,7 +541,7 @@ void nilSemSignal(semaphore_t *sp) { * * @iclass */ -void nilSemSignalI(semaphore_t *sp) { +void chSemSignalI(semaphore_t *sp) { if (++sp->cnt <= 0) { thread_ref_t tr = nil.threads; @@ -549,9 +549,9 @@ void nilSemSignalI(semaphore_t *sp) { /* Is this thread waiting on this semaphore?*/ if (tr->u1.semp == sp) { - nilDbgAssert(NIL_THD_IS_WTSEM(tr), "not waiting"); + chDbgAssert(NIL_THD_IS_WTSEM(tr), "not waiting"); - nilSchReadyI(tr, MSG_OK); + chSchReadyI(tr, MSG_OK); return; } tr++; @@ -575,12 +575,12 @@ void nilSemSignalI(semaphore_t *sp) { * * @api */ -void nilSemReset(semaphore_t *sp, cnt_t n) { +void chSemReset(semaphore_t *sp, cnt_t n) { - nilSysLock(); - nilSemResetI(sp, n); - nilSchRescheduleS(); - nilSysUnlock(); + chSysLock(); + chSemResetI(sp, n); + chSchRescheduleS(); + chSysUnlock(); } /** @@ -599,7 +599,7 @@ void nilSemReset(semaphore_t *sp, cnt_t n) { * * @iclass */ -void nilSemResetI(semaphore_t *sp, cnt_t n) { +void chSemResetI(semaphore_t *sp, cnt_t n) { thread_ref_t tr; cnt_t cnt; @@ -610,10 +610,10 @@ void nilSemResetI(semaphore_t *sp, cnt_t n) { /* Is this thread waiting on this semaphore?*/ if (tr->u1.semp == sp) { - nilDbgAssert(NIL_THD_IS_WTSEM(tr), "not waiting"); + chDbgAssert(NIL_THD_IS_WTSEM(tr), "not waiting"); cnt++; - nilSchReadyI(tr, MSG_RESET); + chSchReadyI(tr, MSG_RESET); } tr++; } -- cgit v1.2.3 From 66d1c88211653eff42b6c76c8c207d43179630e8 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 4 Sep 2013 08:19:38 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6258 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/nil/src/nil.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'os/nil/src/nil.c') diff --git a/os/nil/src/nil.c b/os/nil/src/nil.c index a7677aeeb..d316f01e0 100644 --- a/os/nil/src/nil.c +++ b/os/nil/src/nil.c @@ -66,7 +66,7 @@ nil_system_t nil; * @special */ void chSysInit(void) { - thread_ref_t tr; + thread_reference_t tr; const thread_config_t *tcp; /* Port layer initialization.*/ @@ -136,7 +136,7 @@ void chSysHalt(const char *reason) { void chSysTimerHandlerI(void) { #if NIL_CFG_TIMEDELTA == 0 - thread_ref_t tr = &nil.threads[0]; + thread_reference_t tr = &nil.threads[0]; nil.systime++; do { /* Is the thread in a wait state with timeout?.*/ @@ -162,7 +162,7 @@ void chSysTimerHandlerI(void) { chSysLockFromISR(); } while (tr < &nil.threads[NIL_CFG_NUM_THREADS]); #else - thread_ref_t tr = &nil.threads[0]; + thread_reference_t tr = &nil.threads[0]; systime_t next = 0; chDbgAssert(nil.nexttime == port_timer_get_alarm(), @@ -218,7 +218,7 @@ void chSysTimerHandlerI(void) { * * @return The same reference passed as parameter. */ -thread_ref_t chSchReadyI(thread_ref_t tr, msg_t msg) { +thread_reference_t chSchReadyI(thread_reference_t tr, msg_t msg) { chDbgAssert((tr >= nil.threads) && (tr < &nil.threads[NIL_CFG_NUM_THREADS]), @@ -240,8 +240,8 @@ thread_ref_t chSchReadyI(thread_ref_t tr, msg_t msg) { * @sclass */ void chSchRescheduleS() { - thread_ref_t otr = nil.current; - thread_ref_t ntr = nil.next; + thread_reference_t otr = nil.current; + thread_reference_t ntr = nil.next; if (ntr != otr) { nil.current = ntr; @@ -272,7 +272,7 @@ void chSchRescheduleS() { * @sclass */ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) { - thread_ref_t ntr, otr = nil.current; + thread_reference_t ntr, otr = nil.current; chDbgAssert(otr != &nil.threads[NIL_CFG_NUM_THREADS], "idle cannot sleep"); @@ -348,7 +348,7 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) { * * @sclass */ -msg_t chThdSuspendTimeoutS(thread_ref_t *trp, systime_t timeout) { +msg_t chThdSuspendTimeoutS(thread_reference_t *trp, systime_t timeout) { chDbgAssert(*trp == NULL, "not NULL"); @@ -367,10 +367,10 @@ msg_t chThdSuspendTimeoutS(thread_ref_t *trp, systime_t timeout) { * * @iclass */ -void chThdResumeI(thread_ref_t *trp, msg_t msg) { +void chThdResumeI(thread_reference_t *trp, msg_t msg) { if (*trp != NULL) { - thread_ref_t tr = *trp; + thread_reference_t tr = *trp; chDbgAssert(NIL_THD_IS_SUSP(tr), "not suspended"); @@ -544,7 +544,7 @@ void chSemSignal(semaphore_t *sp) { void chSemSignalI(semaphore_t *sp) { if (++sp->cnt <= 0) { - thread_ref_t tr = nil.threads; + thread_reference_t tr = nil.threads; while (true) { /* Is this thread waiting on this semaphore?*/ if (tr->u1.semp == sp) { @@ -555,6 +555,9 @@ void chSemSignalI(semaphore_t *sp) { return; } tr++; + + chDbgAssert(tr < &nil.threads[NIL_CFG_NUM_THREADS], + "pointer out of range"); } } } @@ -600,7 +603,7 @@ void chSemReset(semaphore_t *sp, cnt_t n) { * @iclass */ void chSemResetI(semaphore_t *sp, cnt_t n) { - thread_ref_t tr; + thread_reference_t tr; cnt_t cnt; cnt = sp->cnt; @@ -616,6 +619,9 @@ void chSemResetI(semaphore_t *sp, cnt_t n) { chSchReadyI(tr, MSG_RESET); } tr++; + + chDbgAssert(tr < &nil.threads[NIL_CFG_NUM_THREADS], + "pointer out of range"); } } -- cgit v1.2.3 From a923a46007f6ae63deac2183319ba064e7b2921c Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 4 Sep 2013 10:26:42 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6259 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/nil/src/nil.c | 157 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 130 insertions(+), 27 deletions(-) (limited to 'os/nil/src/nil.c') diff --git a/os/nil/src/nil.c b/os/nil/src/nil.c index d316f01e0..809887de3 100644 --- a/os/nil/src/nil.c +++ b/os/nil/src/nil.c @@ -210,6 +210,52 @@ void chSysTimerHandlerI(void) { #endif } +/** + * @brief Returns the execution status and enters a critical zone. + * @details This functions enters into a critical zone and can be called + * from any context. Because its flexibility it is less efficient + * than @p chSysLock() which is preferable when the calling context + * is known. + * @post The system is in a critical zone. + * + * @return The previous system status, the encoding of this + * status word is architecture-dependent and opaque. + * + * @xclass + */ +syssts_t chSysGetStatusAndLockX(void) { + + syssts_t sts = port_get_irq_status(); + if (port_irq_enabled(sts)) { + if (port_is_isr_context()) + chSysLockFromISR(); + else + chSysLock(); + } + return sts; +} + +/** + * @brief Restores the specified execution status and leaves a critical zone. + * @note A call to @p chSchRescheduleS() is automatically performed + * if exiting the critical zone and if not in ISR context. + * + * @param[in] sts the system status to be restored. + * + * @xclass + */ +void chSysRestoreStatusX(syssts_t sts) { + + if (port_irq_enabled(sts)) { + if (port_is_isr_context()) + chSysUnlockFromISR(); + else { + chSchRescheduleS(); + chSysUnlock(); + } + } +} + /** * @brief Makes the specified thread ready for execution. * @@ -409,43 +455,23 @@ void chThdSleepUntil(systime_t time) { } /** - * @brief Current system time. - * @details Returns the number of system ticks since the @p chSysInit() - * invocation. - * @note The counter can reach its maximum and then restart from zero. - * @note This function is designed to work with the @p chThdSleepUntil(). - * - * @return The system time in ticks. - * - * @api - */ -systime_t chTimeNow(void) { - systime_t time; - - chSysLock(); - time = chTimeNowI(); - chSysUnlock(); - return time; -} - -/** - * @brief Checks if the current system time is within the specified time - * window. + * @brief Checks if the specified time is within the specified time window. * @note When start==end then the function returns always true because the * whole time range is specified. + * @note This function can be called from any context. * + * @param[in] time the time to be verified * @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. * - * @api + * @xclass */ -bool chTimeNowIsWithin(systime_t start, systime_t end) { +bool chVTIsTimeWithinX(systime_t time, systime_t start, systime_t end) { - systime_t time = chTimeNow(); - return chTimeIsWithin(time, start, end); + return end > start ? (time >= start) && (time < end) : + (time >= start) || (time < end); } /** @@ -625,4 +651,81 @@ void chSemResetI(semaphore_t *sp, cnt_t n) { } } +/** + * @brief Adds a set of event flags directly to the specified @p thread_t. + * + * @param[in] tp the thread to be signaled + * @param[in] mask the event flags set to be ORed + * + * @api + */ +void chEvtSignal(thread_t *tp, eventmask_t mask) { + + chSysLock(); + chEvtSignalI(tp, mask); + chSchRescheduleS(); + chSysUnlock(); +} + +/** + * @brief Adds a set of event flags directly to the specified @p thread_t. + * @post This function does not reschedule so a call to a rescheduling + * function must be performed before unlocking the kernel. Note that + * interrupt handlers always reschedule on exit so an explicit + * reschedule must not be performed in ISRs. + * + * @param[in] tp the thread to be signaled + * @param[in] mask the event flags set to be ORed + * + * @iclass + */ +void chEvtSignalI(thread_t *tp, eventmask_t mask) { + + tp->epmask |= mask; + if (NIL_THD_IS_WTOREVT(tp) && ((tp->epmask & tp->u1.ewmask) != 0)) + chSchReadyI(tp, MSG_OK); +} + +/** + * @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. + * + * @api + */ +eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t timeout) { + thread_t *ctp = nil.current; + eventmask_t m; + + chSysLock(); + + if ((m = (ctp->epmask & mask)) == 0) { + if (TIME_IMMEDIATE == timeout) { + chSysUnlock(); + return (eventmask_t)0; + } + ctp->u1.ewmask = mask; + if (chSchGoSleepTimeoutS(NIL_STATE_WTOREVT, timeout) < MSG_OK) { + chSysUnlock(); + return (eventmask_t)0; + } + m = ctp->epmask & mask; + } + ctp->epmask &= ~m; + + chSysUnlock(); + return m; +} + /** @} */ -- cgit v1.2.3 From e5e278c89f2edd0750749dfca551fc531cf317f2 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 4 Sep 2013 12:41:44 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6261 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/nil/src/nil.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'os/nil/src/nil.c') diff --git a/os/nil/src/nil.c b/os/nil/src/nil.c index 809887de3..20b454fa8 100644 --- a/os/nil/src/nil.c +++ b/os/nil/src/nil.c @@ -165,17 +165,14 @@ void chSysTimerHandlerI(void) { thread_reference_t tr = &nil.threads[0]; systime_t next = 0; - chDbgAssert(nil.nexttime == port_timer_get_alarm(), - "chSysTimerHandlerI(), #1", "time mismatch"); + chDbgAssert(nil.nexttime == port_timer_get_alarm(), "time mismatch"); do { /* Is the thread in a wait state with timeout?.*/ if (tr->timeout > 0) { - chDbgAssert(!NIL_THD_IS_READY(tr), - "chSysTimerHandlerI(), #2", "is ready"); - chDbgAssert(tr->timeout >= nil.nexttime - nil.lasttime, - "chSysTimerHandlerI(), #3", "skipped one"); + chDbgAssert(!NIL_THD_IS_READY(tr), "is ready"); + chDbgAssert(tr->timeout >= nil.nexttime - nil.lasttime, "skipped one"); tr->timeout -= nil.nexttime - nil.lasttime; if (tr->timeout == 0) { @@ -185,7 +182,7 @@ void chSysTimerHandlerI(void) { tr->u1.semp->cnt++; else if (NIL_THD_IS_SUSP(tr)) tr->u1.trp = NULL; - chSchReadyI(tr, NIL_MSG_TMO); + chSchReadyI(tr, MSG_TIMEOUT); } else { if (tr->timeout <= next - 1) @@ -328,7 +325,7 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) { #if NIL_CFG_TIMEDELTA > 0 if (timeout != TIME_INFINITE) { - systime_t time = chTimeNowI() + timeout; + systime_t time = chVTGetSystemTimeX() + timeout; /* TIMEDELTA makes sure to have enough time to reprogram the timer before the free-running timer counter reaches the selected timeout.*/ @@ -343,7 +340,7 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) { else { /* Special case, there are already other threads with a timeout activated, evaluating the order.*/ - if (chTimeIsWithin(time, nil.lasttime, nil.nexttime)) { + if (chVTIsTimeWithinX(time, nil.lasttime, nil.nexttime)) { port_timer_set_alarm(time); nil.nexttime = time; } -- cgit v1.2.3 From 95d85de7d5eb11653e1060168904171238a85721 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 5 Sep 2013 10:34:09 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6263 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/nil/src/nil.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'os/nil/src/nil.c') diff --git a/os/nil/src/nil.c b/os/nil/src/nil.c index 20b454fa8..692d72a3d 100644 --- a/os/nil/src/nil.c +++ b/os/nil/src/nil.c @@ -278,22 +278,22 @@ thread_reference_t chSchReadyI(thread_reference_t tr, msg_t msg) { } /** - * @brief Reschedules. + * @brief Reschedules if needed. * * @sclass */ -void chSchRescheduleS() { - thread_reference_t otr = nil.current; - thread_reference_t ntr = nil.next; +void chSchRescheduleS(void) { - if (ntr != otr) { - nil.current = ntr; + if (chSchIsRescRequiredI()) { + thread_reference_t otr = nil.current; + + nil.current = nil.next; #if defined(NIL_CFG_IDLE_LEAVE_HOOK) if (otr == &nil.threads[NIL_CFG_NUM_THREADS]) { NIL_CFG_IDLE_LEAVE_HOOK(); } #endif - port_switch(ntr, otr); + port_switch(nil.next, otr); } } -- cgit v1.2.3 From 986a9d1db14a5d2d4621bd44ece5fd2cfb3482cf Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 5 Sep 2013 12:33:42 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6264 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/nil/src/nil.c | 141 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 72 insertions(+), 69 deletions(-) (limited to 'os/nil/src/nil.c') diff --git a/os/nil/src/nil.c b/os/nil/src/nil.c index 692d72a3d..546854280 100644 --- a/os/nil/src/nil.c +++ b/os/nil/src/nil.c @@ -66,25 +66,28 @@ nil_system_t nil; * @special */ void chSysInit(void) { - thread_reference_t tr; + thread_t *tp; const thread_config_t *tcp; /* Port layer initialization.*/ port_init(); /* Iterates through the list of defined threads.*/ - for (tr = &nil.threads[0], tcp = nil_thd_configs; - tr < &nil.threads[NIL_CFG_NUM_THREADS]; - tr++, tcp++) { - tr->state = NIL_STATE_READY; - tr->timeout = 0; + for (tp = &nil.threads[0], tcp = nil_thd_configs; + tp < &nil.threads[NIL_CFG_NUM_THREADS]; + tp++, tcp++) { + tp->state = NIL_STATE_READY; + tp->timeout = 0; +#if NIL_CFG_USE_EVENTS + tp->epmask = 0; +#endif /* Port dependent thread initialization.*/ - PORT_SETUP_CONTEXT(tr, tcp->wap, tcp->size, tcp->funcp, tcp->arg); + PORT_SETUP_CONTEXT(tp, tcp->wap, tcp->size, tcp->funcp, tcp->arg); /* Initialization hook.*/ #if defined(NIL_CFG_THREAD_EXT_INIT_HOOK) - NIL_CFG_THREAD_EXT_INIT_HOOK(tr); + NIL_CFG_THREAD_EXT_INIT_HOOK(tp); #endif } @@ -136,65 +139,65 @@ void chSysHalt(const char *reason) { void chSysTimerHandlerI(void) { #if NIL_CFG_TIMEDELTA == 0 - thread_reference_t tr = &nil.threads[0]; + thread_t *tp = &nil.threads[0]; nil.systime++; do { /* Is the thread in a wait state with timeout?.*/ - if (tr->timeout > 0) { + if (tp->timeout > 0) { - chDbgAssert(!NIL_THD_IS_READY(tr), "is ready"); + chDbgAssert(!NIL_THD_IS_READY(tp), "is ready"); /* Did the timer reach zero?*/ - if (--tr->timeout == 0) { + if (--tp->timeout == 0) { /* Timeout on semaphores requires a special handling because the semaphore counter must be incremented.*/ - if (NIL_THD_IS_WTSEM(tr)) - tr->u1.semp->cnt++; - else if (NIL_THD_IS_SUSP(tr)) - tr->u1.trp = NULL; - chSchReadyI(tr, MSG_TIMEOUT); + if (NIL_THD_IS_WTSEM(tp)) + tp->u1.semp->cnt++; + else if (NIL_THD_IS_SUSP(tp)) + tp->u1.trp = NULL; + chSchReadyI(tp, MSG_TIMEOUT); } } /* Lock released in order to give a preemption chance on those architectures supporting IRQ preemption.*/ chSysUnlockFromISR(); - tr++; + tp++; chSysLockFromISR(); - } while (tr < &nil.threads[NIL_CFG_NUM_THREADS]); + } while (tp < &nil.threads[NIL_CFG_NUM_THREADS]); #else - thread_reference_t tr = &nil.threads[0]; + thread_t *tp = &nil.threads[0]; systime_t next = 0; chDbgAssert(nil.nexttime == port_timer_get_alarm(), "time mismatch"); do { /* Is the thread in a wait state with timeout?.*/ - if (tr->timeout > 0) { + if (tp->timeout > 0) { - chDbgAssert(!NIL_THD_IS_READY(tr), "is ready"); - chDbgAssert(tr->timeout >= nil.nexttime - nil.lasttime, "skipped one"); + chDbgAssert(!NIL_THD_IS_READY(tp), "is ready"); + chDbgAssert(tp->timeout >= nil.nexttime - nil.lasttime, "skipped one"); - tr->timeout -= nil.nexttime - nil.lasttime; - if (tr->timeout == 0) { + tp->timeout -= nil.nexttime - nil.lasttime; + if (tp->timeout == 0) { /* Timeout on semaphores requires a special handling because the semaphore counter must be incremented.*/ - if (NIL_THD_IS_WTSEM(tr)) - tr->u1.semp->cnt++; - else if (NIL_THD_IS_SUSP(tr)) - tr->u1.trp = NULL; - chSchReadyI(tr, MSG_TIMEOUT); + if (NIL_THD_IS_WTSEM(tp)) + tp->u1.semp->cnt++; + else if (NIL_THD_IS_SUSP(tp)) + tp->u1.trp = NULL; + chSchReadyI(tp, MSG_TIMEOUT); } else { - if (tr->timeout <= next - 1) - next = tr->timeout; + if (tp->timeout <= next - 1) + next = tp->timeout; } } /* Lock released in order to give a preemption chance on those architectures supporting IRQ preemption.*/ chSysUnlockFromISR(); - tr++; + tp++; chSysLockFromISR(); - } while (tr < &nil.threads[NIL_CFG_NUM_THREADS]); + } while (tp < &nil.threads[NIL_CFG_NUM_THREADS]); nil.lasttime = nil.nexttime; if (next > 0) { nil.nexttime += next; @@ -256,25 +259,25 @@ void chSysRestoreStatusX(syssts_t sts) { /** * @brief Makes the specified thread ready for execution. * - * @param[in] tr reference to the @p thread_t object + * @param[in] tp pointer to the @p thread_t object * @param[in] msg the wakeup message * * @return The same reference passed as parameter. */ -thread_reference_t chSchReadyI(thread_reference_t tr, msg_t msg) { +thread_t *chSchReadyI(thread_t *tp, msg_t msg) { - chDbgAssert((tr >= nil.threads) && - (tr < &nil.threads[NIL_CFG_NUM_THREADS]), - "pointer out of range"); - chDbgAssert(!NIL_THD_IS_READY(tr), "already ready"); + chDbgAssert((tp >= nil.threads) && + (tp < &nil.threads[NIL_CFG_NUM_THREADS]), + "pointer out of range"); + chDbgAssert(!NIL_THD_IS_READY(tp), "already ready"); chDbgAssert(nil.next <= nil.current, "priority ordering"); - tr->u1.msg = msg; - tr->state = NIL_STATE_READY; - tr->timeout = 0; - if (tr < nil.next) - nil.next = tr; - return tr; + tp->u1.msg = msg; + tp->state = NIL_STATE_READY; + tp->timeout = 0; + if (tp < nil.next) + nil.next = tp; + return tp; } /** @@ -285,15 +288,15 @@ thread_reference_t chSchReadyI(thread_reference_t tr, msg_t msg) { void chSchRescheduleS(void) { if (chSchIsRescRequiredI()) { - thread_reference_t otr = nil.current; + thread_t *otp = nil.current; nil.current = nil.next; #if defined(NIL_CFG_IDLE_LEAVE_HOOK) - if (otr == &nil.threads[NIL_CFG_NUM_THREADS]) { + if (otp == &nil.threads[NIL_CFG_NUM_THREADS]) { NIL_CFG_IDLE_LEAVE_HOOK(); } #endif - port_switch(nil.next, otr); + port_switch(nil.next, otp); } } @@ -315,13 +318,13 @@ void chSchRescheduleS(void) { * @sclass */ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) { - thread_reference_t ntr, otr = nil.current; + thread_t *ntp, *otp = nil.current; - chDbgAssert(otr != &nil.threads[NIL_CFG_NUM_THREADS], + chDbgAssert(otp != &nil.threads[NIL_CFG_NUM_THREADS], "idle cannot sleep"); /* Storing the wait object for the current thread.*/ - otr->state = newstate; + otp->state = newstate; #if NIL_CFG_TIMEDELTA > 0 if (timeout != TIME_INFINITE) { @@ -347,33 +350,33 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) { } /* Timeout settings.*/ - otr->timeout = time - nil.lasttime; + otp->timeout = time - nil.lasttime; } #else /* Timeout settings.*/ - otr->timeout = timeout; + otp->timeout = timeout; #endif /* Scanning the whole threads array.*/ - ntr = nil.threads; + ntp = nil.threads; while (true) { /* Is this thread ready to execute?*/ - if (NIL_THD_IS_READY(ntr)) { - nil.current = nil.next = ntr; + if (NIL_THD_IS_READY(ntp)) { + nil.current = nil.next = ntp; #if defined(NIL_CFG_IDLE_ENTER_HOOK) - if (ntr == &nil.threads[NIL_CFG_NUM_THREADS]) { + if (ntp == &nil.threads[NIL_CFG_NUM_THREADS]) { NIL_CFG_IDLE_ENTER_HOOK(); } #endif - port_switch(ntr, otr); + port_switch(ntp, otp); return nil.current->u1.msg; } /* Points to the next thread in lowering priority order.*/ - ntr++; - chDbgAssert(ntr <= &nil.threads[NIL_CFG_NUM_THREADS], - "pointer out of range"); + ntp++; + chDbgAssert(ntp <= &nil.threads[NIL_CFG_NUM_THREADS], + "pointer out of range"); } } @@ -626,24 +629,24 @@ void chSemReset(semaphore_t *sp, cnt_t n) { * @iclass */ void chSemResetI(semaphore_t *sp, cnt_t n) { - thread_reference_t tr; + thread_t *tp; cnt_t cnt; cnt = sp->cnt; sp->cnt = n; - tr = nil.threads; + tp = nil.threads; while (cnt < 0) { /* Is this thread waiting on this semaphore?*/ - if (tr->u1.semp == sp) { + if (tp->u1.semp == sp) { - chDbgAssert(NIL_THD_IS_WTSEM(tr), "not waiting"); + chDbgAssert(NIL_THD_IS_WTSEM(tp), "not waiting"); cnt++; - chSchReadyI(tr, MSG_RESET); + chSchReadyI(tp, MSG_RESET); } - tr++; + tp++; - chDbgAssert(tr < &nil.threads[NIL_CFG_NUM_THREADS], + chDbgAssert(tp < &nil.threads[NIL_CFG_NUM_THREADS], "pointer out of range"); } } -- cgit v1.2.3 From 15a54ae359d342b296b7740dcfaf0580d606b3c6 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 5 Sep 2013 14:54:24 +0000 Subject: Nil working on M3/M4. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6265 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/nil/src/nil.c | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) (limited to 'os/nil/src/nil.c') diff --git a/os/nil/src/nil.c b/os/nil/src/nil.c index 546854280..aefe4ccb2 100644 --- a/os/nil/src/nil.c +++ b/os/nil/src/nil.c @@ -62,6 +62,9 @@ nil_system_t nil; * @details Initializes the kernel structures, the current instructions flow * becomes the idle thread upon return. The idle thread must not * invoke any kernel primitive able to change state to not runnable. + * @note This function assumes that the @p nil global variable has been + * zeroed by the runtime environment. If this is not the case then + * make sure to clear it before calling this function. * * @special */ @@ -73,28 +76,34 @@ void chSysInit(void) { port_init(); /* Iterates through the list of defined threads.*/ - for (tp = &nil.threads[0], tcp = nil_thd_configs; - tp < &nil.threads[NIL_CFG_NUM_THREADS]; - tp++, tcp++) { - tp->state = NIL_STATE_READY; - tp->timeout = 0; -#if NIL_CFG_USE_EVENTS - tp->epmask = 0; + tp = &nil.threads[0]; + tcp = nil_thd_configs; + while (tp < &nil.threads[NIL_CFG_NUM_THREADS]) { +#if NIL_CFG_ENABLE_STACK_CHECK + tp->stklim = (stkalign_t *)tcp->wbase; #endif /* Port dependent thread initialization.*/ - PORT_SETUP_CONTEXT(tp, tcp->wap, tcp->size, tcp->funcp, tcp->arg); + PORT_SETUP_CONTEXT(tp, tcp->wend, tcp->funcp, tcp->arg); /* Initialization hook.*/ #if defined(NIL_CFG_THREAD_EXT_INIT_HOOK) NIL_CFG_THREAD_EXT_INIT_HOOK(tp); #endif + + tp++, tcp++; } +#if NIL_CFG_ENABLE_STACK_CHECK + /* The idle thread is a special case because its stack is set up by the + runtime environment.*/ + tp->stklim = THD_IDLE_BASE; +#endif + /* Runs the highest priority thread, the current one becomes the null thread.*/ nil.current = nil.next = nil.threads; - port_switch(nil.threads, &nil.threads[NIL_CFG_NUM_THREADS]); + port_switch(nil.current, tp); /* Interrupts enabled for the idle thread.*/ chSysEnable(); -- cgit v1.2.3 From 0e436b1cb6c0dea2280b09208a43af636a29ce64 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 11 Sep 2013 12:00:01 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6291 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/nil/src/nil.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'os/nil/src/nil.c') diff --git a/os/nil/src/nil.c b/os/nil/src/nil.c index aefe4ccb2..4d84d654c 100644 --- a/os/nil/src/nil.c +++ b/os/nil/src/nil.c @@ -147,7 +147,7 @@ void chSysHalt(const char *reason) { */ void chSysTimerHandlerI(void) { -#if NIL_CFG_TIMEDELTA == 0 +#if NIL_CFG_ST_TIMEDELTA == 0 thread_t *tp = &nil.threads[0]; nil.systime++; do { @@ -335,14 +335,14 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) { /* Storing the wait object for the current thread.*/ otp->state = newstate; -#if NIL_CFG_TIMEDELTA > 0 +#if NIL_CFG_ST_TIMEDELTA > 0 if (timeout != TIME_INFINITE) { systime_t time = chVTGetSystemTimeX() + timeout; /* TIMEDELTA makes sure to have enough time to reprogram the timer before the free-running timer counter reaches the selected timeout.*/ - if (timeout < NIL_CFG_TIMEDELTA) - timeout = NIL_CFG_TIMEDELTA; + if (timeout < NIL_CFG_ST_TIMEDELTA) + timeout = NIL_CFG_ST_TIMEDELTA; if (nil.lasttime == nil.nexttime) { /* Special case, first thread asking for a timeout.*/ -- cgit v1.2.3 From 7ed08258ad97ad82fd91254236a752d9d6a7f1fc Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 13 Sep 2013 12:58:50 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6300 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/nil/src/nil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/nil/src/nil.c') diff --git a/os/nil/src/nil.c b/os/nil/src/nil.c index 4d84d654c..6de52c17e 100644 --- a/os/nil/src/nil.c +++ b/os/nil/src/nil.c @@ -163,7 +163,7 @@ void chSysTimerHandlerI(void) { if (NIL_THD_IS_WTSEM(tp)) tp->u1.semp->cnt++; else if (NIL_THD_IS_SUSP(tp)) - tp->u1.trp = NULL; + *tp->u1.trp = NULL; chSchReadyI(tp, MSG_TIMEOUT); } } -- cgit v1.2.3 From cbfcf714d6979593d62bfffc861195ee4e163106 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 13 Sep 2013 12:59:53 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6301 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/nil/src/nil.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/nil/src/nil.c') diff --git a/os/nil/src/nil.c b/os/nil/src/nil.c index 6de52c17e..7f1ee3516 100644 --- a/os/nil/src/nil.c +++ b/os/nil/src/nil.c @@ -193,7 +193,7 @@ void chSysTimerHandlerI(void) { if (NIL_THD_IS_WTSEM(tp)) tp->u1.semp->cnt++; else if (NIL_THD_IS_SUSP(tp)) - tp->u1.trp = NULL; + *tp->u1.trp = NULL; chSchReadyI(tp, MSG_TIMEOUT); } else { -- cgit v1.2.3 From f32d1e094163de8cba88ddef023e588a4b44a76f Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 13 Sep 2013 13:15:31 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6302 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/nil/src/nil.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'os/nil/src/nil.c') diff --git a/os/nil/src/nil.c b/os/nil/src/nil.c index 7f1ee3516..5d9a660f7 100644 --- a/os/nil/src/nil.c +++ b/os/nil/src/nil.c @@ -337,29 +337,32 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t timeout) { #if NIL_CFG_ST_TIMEDELTA > 0 if (timeout != TIME_INFINITE) { - systime_t time = chVTGetSystemTimeX() + timeout; + systime_t abstime; /* TIMEDELTA makes sure to have enough time to reprogram the timer before the free-running timer counter reaches the selected timeout.*/ if (timeout < NIL_CFG_ST_TIMEDELTA) timeout = NIL_CFG_ST_TIMEDELTA; + /* Absolute time of the timeout event.*/ + abstime = chVTGetSystemTimeX() + timeout; + if (nil.lasttime == nil.nexttime) { /* Special case, first thread asking for a timeout.*/ - port_timer_start_alarm(time); - nil.nexttime = time; + port_timer_start_alarm(abstime); + nil.nexttime = abstime; } else { /* Special case, there are already other threads with a timeout activated, evaluating the order.*/ - if (chVTIsTimeWithinX(time, nil.lasttime, nil.nexttime)) { - port_timer_set_alarm(time); - nil.nexttime = time; + if (chVTIsTimeWithinX(abstime, nil.lasttime, nil.nexttime)) { + port_timer_set_alarm(abstime); + nil.nexttime = abstime; } } /* Timeout settings.*/ - otp->timeout = time - nil.lasttime; + otp->timeout = abstime - nil.lasttime; } #else -- cgit v1.2.3 From 202661e81e18dad821a1855caf39add96440f6cf Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 4 Nov 2013 13:35:10 +0000 Subject: Improved time range functions. Reduced size for NIL when tickless mode is used. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6416 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/nil/src/nil.c | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'os/nil/src/nil.c') diff --git a/os/nil/src/nil.c b/os/nil/src/nil.c index 5d9a660f7..9141129cb 100644 --- a/os/nil/src/nil.c +++ b/os/nil/src/nil.c @@ -466,26 +466,6 @@ void chThdSleepUntil(systime_t time) { chSysUnlock(); } -/** - * @brief Checks if the specified time is within the specified time window. - * @note When start==end then the function returns always true because the - * whole time range is specified. - * @note This function can be called from any context. - * - * @param[in] time the time to be verified - * @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 - */ -bool chVTIsTimeWithinX(systime_t time, systime_t start, systime_t end) { - - return end > start ? (time >= start) && (time < end) : - (time >= start) || (time < end); -} - /** * @brief Performs a wait operation on a semaphore with timeout specification. * -- cgit v1.2.3 From 3ecd613b00e7364c09f6d8f67ffe21bd0e21b5e6 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 29 Dec 2013 09:59:18 +0000 Subject: Fixed a bug in Nil chSemSignalI() and a similar function in its OSAL. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6581 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/nil/src/nil.c | 1 + 1 file changed, 1 insertion(+) (limited to 'os/nil/src/nil.c') diff --git a/os/nil/src/nil.c b/os/nil/src/nil.c index 9141129cb..bafcb63cd 100644 --- a/os/nil/src/nil.c +++ b/os/nil/src/nil.c @@ -566,6 +566,7 @@ void chSemSignalI(semaphore_t *sp) { while (true) { /* Is this thread waiting on this semaphore?*/ if (tr->u1.semp == sp) { + sp->cnt++; chDbgAssert(NIL_THD_IS_WTSEM(tr), "not waiting"); -- cgit v1.2.3 From 47f0e8fb7f337b65f848bf4cd59577d3967d0862 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 11 Feb 2014 09:21:53 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6699 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/nil/src/nil.c | 1 - 1 file changed, 1 deletion(-) (limited to 'os/nil/src/nil.c') diff --git a/os/nil/src/nil.c b/os/nil/src/nil.c index bafcb63cd..9141129cb 100644 --- a/os/nil/src/nil.c +++ b/os/nil/src/nil.c @@ -566,7 +566,6 @@ void chSemSignalI(semaphore_t *sp) { while (true) { /* Is this thread waiting on this semaphore?*/ if (tr->u1.semp == sp) { - sp->cnt++; chDbgAssert(NIL_THD_IS_WTSEM(tr), "not waiting"); -- cgit v1.2.3 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 --- os/nil/src/nil.c | 37 ++++++++++++++++++++++++++++++++++--- 1 file changed, 34 insertions(+), 3 deletions(-) (limited to 'os/nil/src/nil.c') 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; } -- cgit v1.2.3 From ec1fb708d84d77e700d87da8a1ca947a62eea696 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 11 Feb 2014 13:04:03 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/kernel_3_dev@6702 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/nil/src/nil.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'os/nil/src/nil.c') diff --git a/os/nil/src/nil.c b/os/nil/src/nil.c index edd717600..789256127 100644 --- a/os/nil/src/nil.c +++ b/os/nil/src/nil.c @@ -447,7 +447,9 @@ void chThdResumeI(thread_reference_t *trp, msg_t msg) { void chThdSleep(systime_t time) { chSysLock(); + chThdSleepS(time); + chSysUnlock(); } @@ -462,7 +464,9 @@ void chThdSleep(systime_t time) { void chThdSleepUntil(systime_t time) { chSysLock(); + chThdSleepUntilS(time); + chSysUnlock(); } @@ -545,8 +549,10 @@ msg_t chSemWaitTimeoutS(semaphore_t *sp, systime_t timeout) { void chSemSignal(semaphore_t *sp) { chSysLock(); + chSemSignalI(sp); chSchRescheduleS(); + chSysUnlock(); } -- cgit v1.2.3