From 1ea7355d85e316aadfd90468b3e808bb3dc95ee9 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 16 Aug 2009 13:07:24 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1073 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chcond.c | 227 ++++++++++++++++++++++++++ os/kernel/src/chdebug.c | 81 ++++++++++ os/kernel/src/chevents.c | 392 +++++++++++++++++++++++++++++++++++++++++++++ os/kernel/src/chheap.c | 276 +++++++++++++++++++++++++++++++ os/kernel/src/chlists.c | 111 +++++++++++++ os/kernel/src/chmboxes.c | 244 ++++++++++++++++++++++++++++ os/kernel/src/chmempools.c | 112 +++++++++++++ os/kernel/src/chmsg.c | 125 +++++++++++++++ os/kernel/src/chmtx.c | 299 ++++++++++++++++++++++++++++++++++ os/kernel/src/chqueues.c | 304 +++++++++++++++++++++++++++++++++++ os/kernel/src/chschd.c | 242 ++++++++++++++++++++++++++++ os/kernel/src/chsem.c | 257 +++++++++++++++++++++++++++++ os/kernel/src/chserial.c | 168 +++++++++++++++++++ os/kernel/src/chsys.c | 129 +++++++++++++++ os/kernel/src/chthreads.c | 381 +++++++++++++++++++++++++++++++++++++++++++ os/kernel/src/chvt.c | 116 ++++++++++++++ 16 files changed, 3464 insertions(+) create mode 100644 os/kernel/src/chcond.c create mode 100644 os/kernel/src/chdebug.c create mode 100644 os/kernel/src/chevents.c create mode 100644 os/kernel/src/chheap.c create mode 100644 os/kernel/src/chlists.c create mode 100644 os/kernel/src/chmboxes.c create mode 100644 os/kernel/src/chmempools.c create mode 100644 os/kernel/src/chmsg.c create mode 100644 os/kernel/src/chmtx.c create mode 100644 os/kernel/src/chqueues.c create mode 100644 os/kernel/src/chschd.c create mode 100644 os/kernel/src/chsem.c create mode 100644 os/kernel/src/chserial.c create mode 100644 os/kernel/src/chsys.c create mode 100644 os/kernel/src/chthreads.c create mode 100644 os/kernel/src/chvt.c (limited to 'os/kernel/src') diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c new file mode 100644 index 000000000..ef58f1ddf --- /dev/null +++ b/os/kernel/src/chcond.c @@ -0,0 +1,227 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 . +*/ +/* + Concepts and parts of this file are contributed by and Copyright (C) 2008 + of Leon Woestenberg. + */ + +/** + * @file chcond.c + * @brief Condition Variables code. + * @addtogroup CondVars + * @{ + */ + +#include + +#if CH_USE_CONDVARS && CH_USE_MUTEXES + +/** + * @brief Initializes s @p CondVar structure. + * + * @param[out] cp pointer to a @p CondVar structure + * @note This function can be invoked from within an interrupt handler even if + * it is not an I-Class API because it does not touch any critical kernel + * data structure. + */ +void chCondInit(CondVar *cp) { + + chDbgCheck(cp != NULL, "chCondInit"); + + queue_init(&cp->c_queue); +} + +/** + * @brief Signals one thread that is waiting on the condition variable. + * + * @param[in] cp pointer to the @p CondVar structure + */ +void chCondSignal(CondVar *cp) { + + chDbgCheck(cp != NULL, "chCondSignal"); + + chSysLock(); + if (notempty(&cp->c_queue)) /* any thread ? */ + chSchWakeupS(fifo_remove(&cp->c_queue), RDY_OK); + chSysUnlock(); +} + +/** + * @brief Signals one thread that is waiting on the condition variable. + * + * @param[in] cp pointer to the @p CondVar structure + */ +void chCondSignalI(CondVar *cp) { + + chDbgCheck(cp != NULL, "chCondSignalI"); + + if (notempty(&cp->c_queue)) /* any thread ? */ + chSchReadyI(fifo_remove(&cp->c_queue))->p_rdymsg = RDY_OK; +} + +/** + * @brief Signals all threads that are waiting on the condition variable. + * + * @param[in] cp pointer to the @p CondVar structure + */ +void chCondBroadcast(CondVar *cp) { + + chSysLock(); + chCondBroadcastI(cp); + chSchRescheduleS(); + chSysUnlock(); +} + +/** + * @brief Signals all threads that are waiting on the condition variable. + * + * @param[in] cp pointer to the @p CondVar structure + */ +void chCondBroadcastI(CondVar *cp) { + + chDbgCheck(cp != NULL, "chCondBroadcastI"); + + /* empties the condition variable queue and inserts all the Threads into the + * ready list in FIFO order. The wakeup message is set to @p RDY_RESET in + * order to make a chCondBroadcast() detectable from a chCondSignal(). */ + while (cp->c_queue.p_next != (void *)&cp->c_queue) + chSchReadyI(fifo_remove(&cp->c_queue))->p_rdymsg = RDY_RESET; +} + +/** + * @brief Waits on the condition variable releasing the mutex lock. + * @details Releases the mutex, waits on the condition variable, and finally + * acquires the mutex again. This is done atomically. + * + * @param[in] cp pointer to the @p CondVar structure + * @return The wakep mode. + * @retval RDY_OK if the condvar was signaled using chCondSignal(). + * @retval RDY_RESET if the condvar was signaled using chCondBroadcast(). + * @note The thread MUST already have locked the mutex when calling + * @p chCondWait(). + */ +msg_t chCondWait(CondVar *cp) { + msg_t msg; + + chSysLock(); + msg = chCondWaitS(cp); + chSysUnlock(); + return msg; +} + +/** + * @brief Waits on the condition variable releasing the mutex lock. + * @details Releases the mutex, waits on the condition variable, and finally + * acquires the mutex again. This is done atomically. + * + * @param[in] cp pointer to the @p CondVar structure + * @return The wakep mode. + * @retval RDY_OK if the condvar was signaled using chCondSignal(). + * @retval RDY_RESET if the condvar was signaled using chCondBroadcast(). + * @note The thread MUST already have locked the mutex when calling + * @p chCondWaitS(). + */ +msg_t chCondWaitS(CondVar *cp) { + Mutex *mp; + msg_t msg; + + chDbgCheck(cp != NULL, "chCondWaitS"); + chDbgAssert(currp->p_mtxlist != NULL, + "chCondWaitS(), #1", + "not owning a mutex"); + + mp = chMtxUnlockS(); /* unlocks the condvar mutex */ + prio_insert(currp, &cp->c_queue); /* enters the condvar queue */ + currp->p_wtcondp = cp; /* needed by the tracer */ + chSchGoSleepS(PRWTCOND); /* waits on the condvar */ + msg = currp->p_rdymsg; /* fetches the wakeup message */ + chMtxLockS(mp); /* atomically relocks the mutex */ + return msg; /* returns the wakeup message */ +} + +#if CH_USE_CONDVARS_TIMEOUT +/** + * @brief Waits on the condition variable releasing the mutex lock. + * @details Releases the mutex, waits on the condition variable, and finally + * acquires the mutex again. This is done atomically. + * + * @param[in] cp pointer to the @p CondVar structure + * @param[in] time the number of ticks before the operation timeouts, + * the special value @p TIME_INFINITE is allowed. + * It is not possible to specify zero @p TIME_IMMEDIATE + * as timeout specification because it would make no sense + * in this function. + * @return The wakep mode. + * @retval RDY_OK if the condvar was signaled using chCondSignal(). + * @retval RDY_RESET if the condvar was signaled using chCondBroadcast(). + * @retval RDY_TIMEOUT if the condvar was not signaled within the specified + * timeout. + * @note The thread MUST already have locked the mutex when calling + * @p chCondWaitTimeout(). + */ +msg_t chCondWaitTimeout(CondVar *cp, systime_t time) { + msg_t msg; + + chSysLock(); + msg = chCondWaitTimeoutS(cp, time); + chSysUnlock(); + return msg; +} + +/** + * @brief Waits on the condition variable releasing the mutex lock. + * @details Releases the mutex, waits on the condition variable, and finally + * acquires the mutex again. This is done atomically. + * + * @param[in] cp pointer to the @p CondVar structure + * @param[in] time the number of ticks before the operation timeouts, + * the special value @p TIME_INFINITE is allowed. + * It is not possible to specify zero @p TIME_IMMEDIATE + * as timeout specification because it would make no sense + * in this function. + * @return The wakep mode. + * @retval RDY_OK if the condvar was signaled using chCondSignal(). + * @retval RDY_RESET if the condvar was signaled using chCondBroadcast(). + * @retval RDY_TIMEOUT if the condvar was not signaled within the specified + * timeout. + * @note The thread MUST already have locked the mutex when calling + * @p chCondWaitTimeoutS(). + */ +msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time) { + Mutex *mp; + msg_t msg; + + chDbgCheck(cp != NULL, "chCondWaitTimeoutS"); + chDbgAssert(currp->p_mtxlist != NULL, + "chCondWaitTimeoutS(), #1", + "not owning a mutex"); + + mp = chMtxUnlockS(); /* unlocks the condvar mutex */ + prio_insert(currp, &cp->c_queue); /* enters the condvar queue */ + currp->p_wtcondp = cp; /* needed by the tracer */ + chSchGoSleepTimeoutS(PRWTCOND, time); /* waits on the condvar */ + msg = currp->p_rdymsg; /* fetches the wakeup message */ + chMtxLockS(mp); /* atomically relocks the mutex */ + return msg; /* returns the wakeup message */ +} +#endif /* CH_USE_CONDVARS_TIMEOUT */ + +#endif /* CH_USE_CONDVARS && CH_USE_MUTEXES */ + +/** @} */ diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c new file mode 100644 index 000000000..9a8120b29 --- /dev/null +++ b/os/kernel/src/chdebug.c @@ -0,0 +1,81 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chdebug.c + * @brief ChibiOS/RT Debug code. + * @addtogroup Debug + * @{ + */ + +#include + +#if CH_DBG_ENABLE_TRACE +/** + * @brief Public trace buffer. + */ +TraceBuffer trace_buffer; + +/** + * @brief Trace circular buffer subsystem initialization. + */ +void trace_init(void) { + + trace_buffer.tb_size = TRACE_BUFFER_SIZE; + trace_buffer.tb_ptr = &trace_buffer.tb_buffer[0]; +} + +/** + * @brief Inserts in the circular debug trace buffer a context switch record. + * + * @param[in] otp the thread being switched out + * @param[in] ntp the thread to be switched in + */ +void chDbgTrace(Thread *otp, Thread *ntp) { + + trace_buffer.tb_ptr->cse_wtobjp = otp->p_wtobjp; + trace_buffer.tb_ptr->cse_time = chTimeNow(); + trace_buffer.tb_ptr->cse_state = otp->p_state; + trace_buffer.tb_ptr->cse_tid = (unsigned)ntp >> 4; + if (++trace_buffer.tb_ptr >= &trace_buffer.tb_buffer[TRACE_BUFFER_SIZE]) + trace_buffer.tb_ptr = &trace_buffer.tb_buffer[0]; +} +#endif /* CH_DBG_ENABLE_TRACE */ + +#if CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK +/** + * @brief Pointer to the panic message. + * @details This pointer is meant to be accessed through the debugger, it is + * written once and then the system is halted. + */ +char *panic_msg; + +/** + * @brief Prints a panic message on the console and then halts the system. + * + * @param[in] msg the pointer to the panic message string + */ +void chDbgPanic(char *msg) { + + panic_msg = msg; + chSysHalt(); +} +#endif /* CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK */ + +/** @} */ diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c new file mode 100644 index 000000000..098adce5e --- /dev/null +++ b/os/kernel/src/chevents.c @@ -0,0 +1,392 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chevents.c + * @brief Events code. + * @addtogroup Events + * @{ + */ +#include + +#if CH_USE_EVENTS +/** + * @brief Registers an Event Listener on an Event Source. + * + * @param[in] esp pointer to the @p EventSource structure + * @param[in] elp pointer to the @p EventListener structure + * @param[in] emask the mask of event flags to be pended to the thread when the + * event source is broadcasted + * @note Multiple Event Listeners can specify the same bits to be pended. + */ +void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t emask) { + + chDbgCheck((esp != NULL) && (elp != NULL), "chEvtRegisterMask"); + + chSysLock(); + elp->el_next = esp->es_next; + esp->es_next = elp; + elp->el_listener = currp; + elp->el_mask = emask; + chSysUnlock(); +} + +/** + * @brief Unregisters an Event Listener from its Event Source. + * + * @param[in] esp pointer to the @p EventSource structure + * @param[in] elp pointer to the @p EventListener structure + * @note If the event listener is not registered on the specified event source + * then the function does nothing. + * @note For optimal performance it is better to perform the unregister + * operations in inverse order of the register operations (elements are + * found on top of the list). + */ +void chEvtUnregister(EventSource *esp, EventListener *elp) { + EventListener *p; + + chDbgCheck((esp != NULL) && (elp != NULL), "chEvtUnregister"); + + p = (EventListener *)esp; + chSysLock(); + while (p->el_next != (EventListener *)esp) { + if (p->el_next == elp) { + p->el_next = elp->el_next; + break; + } + p = p->el_next; + } + chSysUnlock(); +} + +/** + * @brief Clears the pending events specified in the mask. + * + * @param[in] mask the events to be cleared + * @return The pending events that were cleared. + */ +eventmask_t chEvtClear(eventmask_t mask) { + eventmask_t m; + + chSysLock(); + + m = currp->p_epending & mask; + currp->p_epending &= ~mask; + + chSysUnlock(); + return m; +} + +/** + * @brief Pends a set of event flags on the current thread, this is @b much + * faster than using @p chEvtBroadcast() or @p chEvtSignal(). + * + * @param[in] mask the events to be pended + * @return The current pending events mask. + */ +eventmask_t chEvtPend(eventmask_t mask) { + + chSysLock(); + + mask = (currp->p_epending |= mask); + + chSysUnlock(); + return mask; +} + +/** + * @brief Pends a set of event flags on the specified @p Thread. + * + * @param[in] tp the thread to be signaled + * @param[in] mask the event flags set to be pended + */ +void chEvtSignal(Thread *tp, eventmask_t mask) { + + chDbgCheck(tp != NULL, "chEvtSignal"); + + chSysLock(); + chEvtSignalI(tp, mask); + chSysUnlock(); +} + +/** + * @brief Pends a set of event flags on the specified @p Thread. + * + * @param[in] tp the thread to be signaled + * @param[in] mask the event flags set to be pended + */ +void chEvtSignalI(Thread *tp, eventmask_t mask) { + + chDbgCheck(tp != NULL, "chEvtSignalI"); + + tp->p_epending |= mask; + /* Test on the AND/OR conditions wait states.*/ + if (((tp->p_state == PRWTOREVT) && ((tp->p_epending & tp->p_ewmask) != 0)) || + ((tp->p_state == PRWTANDEVT) && ((tp->p_epending & tp->p_ewmask) == tp->p_ewmask))) + chSchReadyI(tp)->p_rdymsg = RDY_OK; +} + +/** + * @brief Signals all the Event Listeners registered on the specified Event + * Source. + * + * @param[in] esp pointer to the @p EventSource structure + */ +void chEvtBroadcast(EventSource *esp) { + + chSysLock(); + chEvtBroadcastI(esp); + chSchRescheduleS(); + chSysUnlock(); +} + +/** + * @brief Signals all the Event Listeners registered on the specified Event + * Source. + * + * @param[in] esp pointer to the @p EventSource structure + */ +void chEvtBroadcastI(EventSource *esp) { + EventListener *elp; + + chDbgCheck(esp != NULL, "chEvtBroadcastI"); + + elp = esp->es_next; + while (elp != (EventListener *)esp) { + chEvtSignalI(elp->el_listener, elp->el_mask); + elp = elp->el_next; + } +} + +/** + * @brief Invokes the event handlers associated with a mask. + * + * @param[in] mask mask of the events to be dispatched + * @param[in] handlers an array of @p evhandler_t. The array must have size + * equal to the number of bits in eventmask_t. + */ +void chEvtDispatch(const evhandler_t handlers[], eventmask_t mask) { + eventid_t eid; + + chDbgCheck(handlers != NULL, "chEvtDispatch"); + + eid = 0; + while (mask) { + if (mask & EVENT_MASK(eid)) { + chDbgAssert(handlers[eid] != NULL, + "chEvtDispatch(), #1", + "null handler"); + mask &= ~EVENT_MASK(eid); + handlers[eid](eid); + } + eid++; + } +} + +#if CH_OPTIMIZE_SPEED || !CH_USE_EVENTS_TIMEOUT || defined(__DOXYGEN__) +/** + * @brief Waits for exactly one of the specified events. + * @details The function waits for one event among those specified in + * @p ewmask to become pending then the event is cleared and returned. + * + * @param[in] ewmask mask of the events that the function should wait for, + * @p ALL_EVENTS enables all the events + * @return The mask of the lowest id served and cleared event. + * @note One and only one event is served in the function, the one with the + * lowest event id. The function is meant to be invoked into a loop in + * order to serve all the pending events.
+ * This means that Event Listeners with a lower event identifier have + * an higher priority. + */ +eventmask_t chEvtWaitOne(eventmask_t ewmask) { + eventmask_t m; + + chSysLock(); + + if ((m = (currp->p_epending & ewmask)) == 0) { + currp->p_ewmask = ewmask; + chSchGoSleepS(PRWTOREVT); + m = currp->p_epending & ewmask; + } + m &= -m; + currp->p_epending &= ~m; + + chSysUnlock(); + return m; +} + +/** + * @brief Waits for any of the specified events. + * @details The function waits for any event among those specified in + * @p ewmask to become pending then the events are cleared and returned. + * + * @param[in] ewmask mask of the events that the function should wait for, + * @p ALL_EVENTS enables all the events + * @return The mask of the served and cleared events. + */ +eventmask_t chEvtWaitAny(eventmask_t ewmask) { + eventmask_t m; + + chSysLock(); + + if ((m = (currp->p_epending & ewmask)) == 0) { + currp->p_ewmask = ewmask; + chSchGoSleepS(PRWTOREVT); + m = currp->p_epending & ewmask; + } + currp->p_epending &= ~m; + + chSysUnlock(); + return m; +} + +/** + * @brief Waits for all the specified events. + * @details The function waits for all the events specified in @p ewmask to + * become pending then the events are cleared and returned. + * + * @param[in] ewmask mask of the event ids that the function should wait for + * @return The mask of the served and cleared events. + */ +eventmask_t chEvtWaitAll(eventmask_t ewmask) { + + chSysLock(); + + if ((currp->p_epending & ewmask) != ewmask) { + currp->p_ewmask = ewmask; + chSchGoSleepS(PRWTANDEVT); + } + currp->p_epending &= ~ewmask; + + chSysUnlock(); + return ewmask; +} +#endif /* CH_OPTIMIZE_SPEED || !CH_USE_EVENTS_TIMEOUT */ + +#if CH_USE_EVENTS_TIMEOUT +/** + * @brief Waits for exactly one of the specified events. + * @details The function waits for one event among those specified in + * @p ewmask to become pending then the event is cleared and returned. + * + * @param[in] ewmask mask of the events that the function should wait for, + * @p ALL_EVENTS enables all the events + * @param[in] time 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 lowest id served and cleared event. + * @retval 0 if the specified timeout expired. + * @note One and only one event is served in the function, the one with the + * lowest event id. The function is meant to be invoked into a loop in + * order to serve all the pending events.
+ * This means that Event Listeners with a lower event identifier have + * an higher priority. + */ +eventmask_t chEvtWaitOneTimeout(eventmask_t ewmask, systime_t time) { + eventmask_t m; + + chSysLock(); + + if ((m = (currp->p_epending & ewmask)) == 0) { + if (TIME_IMMEDIATE == time) + return (eventmask_t)0; + currp->p_ewmask = ewmask; + if (chSchGoSleepTimeoutS(PRWTOREVT, time) < RDY_OK) + return (eventmask_t)0; + m = currp->p_epending & ewmask; + } + m &= -m; + currp->p_epending &= ~m; + + chSysUnlock(); + return m; +} + +/** + * @brief Waits for any of the specified events. + * @details The function waits for any event among those specified in + * @p ewmask to become pending then the events are cleared and + * returned. + * + * @param[in] ewmask mask of the events that the function should wait for, + * @p ALL_EVENTS enables all the events + * @param[in] time 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 specified timeout expired. + */ +eventmask_t chEvtWaitAnyTimeout(eventmask_t ewmask, systime_t time) { + eventmask_t m; + + chSysLock(); + + if ((m = (currp->p_epending & ewmask)) == 0) { + if (TIME_IMMEDIATE == time) + return (eventmask_t)0; + currp->p_ewmask = ewmask; + if (chSchGoSleepTimeoutS(PRWTOREVT, time) < RDY_OK) + return (eventmask_t)0; + m = currp->p_epending & ewmask; + } + currp->p_epending &= ~m; + + chSysUnlock(); + return m; +} + +/** + * @brief Waits for all the specified events. + * @details The function waits for all the events specified in @p ewmask to + * become pending then the events are cleared and returned. + * + * @param[in] ewmask mask of the event ids that the function should wait for + * @param[in] time 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 specified timeout expired. + */ +eventmask_t chEvtWaitAllTimeout(eventmask_t ewmask, systime_t time) { + + chSysLock(); + + if ((currp->p_epending & ewmask) != ewmask) { + if (TIME_IMMEDIATE == time) + return (eventmask_t)0; + currp->p_ewmask = ewmask; + if (chSchGoSleepTimeoutS(PRWTANDEVT, time) < RDY_OK) + return (eventmask_t)0; + } + currp->p_epending &= ~ewmask; + + chSysUnlock(); + return ewmask; +} +#endif /* CH_USE_EVENTS_TIMEOUT */ + +#endif /* CH_USE_EVENTS */ + +/** @} */ diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c new file mode 100644 index 000000000..82b1ba785 --- /dev/null +++ b/os/kernel/src/chheap.c @@ -0,0 +1,276 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chheap.c + * @brief Heap code. + * @addtogroup Heap + * @{ + */ + +#include + +#if CH_USE_HEAP + +#if !CH_USE_MALLOC_HEAP + +#define MAGIC 0xF5A0 +#define ALIGN_TYPE void * +#define ALIGN_MASK (sizeof(ALIGN_TYPE) - 1) +#define ALIGN_SIZE(p) (((size_t)(p) + ALIGN_MASK) & ~ALIGN_MASK) + +struct header { + union { + struct header *h_next; + size_t h_magic; + }; + size_t h_size; +}; + +static struct { + struct header free; /* Guaranteed to be not adjacent to the heap */ +#if CH_USE_MUTEXES +#define H_LOCK() chMtxLock(&heap.hmtx) +#define H_UNLOCK() chMtxUnlock() + Mutex hmtx; +#elif CH_USE_SEMAPHORES +#define H_LOCK() chSemWait(&heap.hsem) +#define H_UNLOCK() chSemSignal(&heap.hsem) + Semaphore hsem; +#else +#error "The heap allocator requires mutexes or semaphores to be enabled" +#endif +#if CH_HEAP_SIZE > 0 + union { + ALIGN_TYPE alignment; + char buffer[ALIGN_SIZE(CH_HEAP_SIZE)]; + }; +#endif +} heap; + +/** + * @brief Initializes the allocator subsystem. + * + * @note Internal use only. + */ +void heap_init(void) { + struct header *hp; + +#if CH_HEAP_SIZE == 0 + extern char __heap_base__; + extern char __heap_end__; + + hp = (void *)&__heap_base__; + hp->h_size = &__heap_end__ - &__heap_base__ - sizeof(struct header); +#else + hp = (void *)&heap.buffer[0]; + hp->h_size = (&heap.buffer[ALIGN_SIZE(CH_HEAP_SIZE)] - &heap.buffer[0]) - + sizeof(struct header); +#endif + hp->h_next = NULL; + heap.free.h_next = hp; + heap.free.h_size = 0; +#if CH_USE_MUTEXES + chMtxInit(&heap.hmtx); +#else + chSemInit(&heap.hsem, 1); +#endif +} + +/** + * @brief Allocates a block of memory from the heap by using the first-fit + * algorithm. + * @details The allocated block is guaranteed to be properly aligned for a + * pointer data type. + * + * @param[in] size the size of the block to be allocated. Note that the + * allocated block may be a bit bigger than the requested + * size for alignment and fragmentation reasons. + * @return A pointer to the allocated block. + * @retval NULL if the block cannot be allocated. + */ +void *chHeapAlloc(size_t size) { + struct header *qp, *hp, *fp; + + size = ALIGN_SIZE(size); + qp = &heap.free; + H_LOCK(); + + while (qp->h_next != NULL) { + hp = qp->h_next; + if (hp->h_size >= size) { + if (hp->h_size < size + sizeof(struct header)) { + /* Gets the whole block even if it is slightly bigger than the + requested size because the fragment would be too small to be + useful */ + qp->h_next = hp->h_next; + } + else { + /* Block bigger enough, must split it */ + fp = (void *)((char *)(hp) + sizeof(struct header) + size); + fp->h_next = hp->h_next; + fp->h_size = hp->h_size - sizeof(struct header) - size; + qp->h_next = fp; + hp->h_size = size; + } + hp->h_magic = MAGIC; + + H_UNLOCK(); + return (void *)(hp + 1); + } + qp = hp; + } + + H_UNLOCK(); + return NULL; +} + +#define LIMIT(p) (struct header *)((char *)(p) + \ + sizeof(struct header) + \ + (p)->h_size) + +/** + * @brief Frees a previously allocated memory block. + * + * @param[in] p the memory block pointer + */ +void chHeapFree(void *p) { + struct header *qp, *hp; + + chDbgCheck(p != NULL, "chHeapFree"); + + hp = (struct header *)p - 1; + chDbgAssert(hp->h_magic == MAGIC, + "chHeapFree(), #1", + "it is not magic"); + qp = &heap.free; + H_LOCK(); + + while (TRUE) { + + chDbgAssert((hp < qp) || (hp >= LIMIT(qp)), + "chHeapFree(), #2", + "within free block"); + + if (((qp == &heap.free) || (hp > qp)) && + ((qp->h_next == NULL) || (hp < qp->h_next))) { + /* Insertion after qp */ + hp->h_next = qp->h_next; + qp->h_next = hp; + /* Verifies if the newly inserted block should be merged */ + if (LIMIT(hp) == hp->h_next) { + /* Merge with the next block */ + hp->h_size += hp->h_next->h_size + sizeof(struct header); + hp->h_next = hp->h_next->h_next; + } + if ((LIMIT(qp) == hp)) { /* Cannot happen when qp == &heap.free */ + /* Merge with the previous block */ + qp->h_size += hp->h_size + sizeof(struct header); + qp->h_next = hp->h_next; + } + + H_UNLOCK(); + return; + } + qp = qp->h_next; + } +} + +/** + * @brief Reports the heap status. + * + * @param[in] sizep pointer to a variable that will receive the total + * fragmented free space + * @return The number of fragments in the heap. + * @note This function is meant to be used in the test suite, it should not be + * really useful for the application code. + * @note This function is not implemented when the @p CH_USE_MALLOC_HEAP + * configuration option is used (it always returns zero). + */ +size_t chHeapStatus(size_t *sizep) { + struct header *qp; + size_t n, sz; + + H_LOCK(); + + sz = 0; + for (n = 0, qp = &heap.free; qp->h_next; n++, qp = qp->h_next) + sz += qp->h_next->h_size; + if (sizep) + *sizep = sz; + + H_UNLOCK(); + return n; +} + +#else /* CH_USE_MALLOC_HEAP */ + +#include + +#if CH_USE_MUTEXES +#define H_LOCK() chMtxLock(&hmtx) +#define H_UNLOCK() chMtxLock(&hmtx) +static Mutex hmtx; +#elif CH_USE_SEMAPHORES +#define H_LOCK() chSemWait(&hsem) +#define H_UNLOCK() chSemSignal(&hsem) +static Semaphore hsem; +#else +#error "The heap allocator requires mutexes or semaphores to be enabled" +#endif + +void heap_init(void) { + +#if CH_USE_MUTEXES + chMtxInit(&hmtx); +#else + chSemInit(&hsem, 1); +#endif +} + +void *chHeapAlloc(size_t size) { + void *p; + + H_LOCK(); + p = malloc(size); + H_UNLOCK(); + return p; +} + +void chHeapFree(void *p) { + + chDbgCheck(p != NULL, "chHeapFree"); + + H_LOCK(); + free(p); + H_UNLOCK(); +} + +size_t chHeapStatus(size_t *sizep) { + + if (sizep) + *sizep = 0; + return 0; +} + +#endif /* CH_USE_MALLOC_HEAP */ + +#endif /* CH_USE_HEAP */ + +/** @} */ diff --git a/os/kernel/src/chlists.c b/os/kernel/src/chlists.c new file mode 100644 index 000000000..a2177ca63 --- /dev/null +++ b/os/kernel/src/chlists.c @@ -0,0 +1,111 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chlists.c + * @brief Thread queues/lists code. + * @addtogroup ThreadLists + * @{ + */ +#include + +#if !CH_OPTIMIZE_SPEED || defined(__DOXYGEN__) +/** + * @brief Inserts a thread into a priority ordered queue. + * + * @param[in] tp the pointer to the thread to be inserted in the list + * @param[in] tqp the pointer to the threads list header + * @note The insertion is done by scanning the list from the highest priority + * toward the lowest. + * @note This function is @b not an API. + */ +void prio_insert(Thread *tp, ThreadsQueue *tqp) { + + /* cp iterates over the queue */ + Thread *cp = (Thread *)tqp; + do { + /* iterate to next thread in queue */ + cp = cp->p_next; + /* not end of queue? and cp has equal or higher priority than tp? */ + } while ((cp != (Thread *)tqp) && (cp->p_prio >= tp->p_prio)); + /* insert before cp, point tp to next and prev in queue */ + tp->p_prev = (tp->p_next = cp)->p_prev; + /* make prev point to tp, and cp point back to tp */ + tp->p_prev->p_next = cp->p_prev = tp; +} + +/** + * @brief Inserts a Thread into a queue. + * + * @param[in] tp the pointer to the thread to be inserted in the list + * @param[in] tqp the pointer to the threads list header + * @note This function is @b not an API. + */ +void queue_insert(Thread *tp, ThreadsQueue *tqp) { + + tp->p_prev = (tp->p_next = (Thread *)tqp)->p_prev; + tp->p_prev->p_next = tqp->p_prev = tp; +} + +/** + * @brief Removes the first-out Thread from a queue and returns it. + * + * @param[in] tqp the pointer to the threads list header + * @return The removed thread pointer. + * @note This function is @b not an API. + */ +Thread *fifo_remove(ThreadsQueue *tqp) { + Thread *tp = tqp->p_next; + + (tqp->p_next = tp->p_next)->p_prev = (Thread *)tqp; + return tp; +} + +/** + * @brief Removes the last-out Thread from a queue and returns it. + * + * @param[in] tqp the pointer to the threads list header + * @return The removed thread pointer. + * @note This function is @b not an API. + */ +Thread *lifo_remove(ThreadsQueue *tqp) { + Thread *tp = tqp->p_next; + + (tqp->p_next = tp->p_next)->p_prev = (Thread *)tqp; + return tp; +} + +/** + * @brief Removes a Thread from a queue and returns it. + * @details The thread is removed from the queue regardless of its relative + * position and regardless the used insertion method. + * + * @param[in] tp the pointer to the thread to be removed from the queue + * @return The removed thread pointer. + * @note This function is @b not an API. + */ +Thread *dequeue(Thread *tp) { + + tp->p_prev->p_next = tp->p_next; + tp->p_next->p_prev = tp->p_prev; + return tp; +} +#endif /* CH_OPTIMIZE_SPEED */ + +/** @} */ diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c new file mode 100644 index 000000000..8a791a984 --- /dev/null +++ b/os/kernel/src/chmboxes.c @@ -0,0 +1,244 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chmboxes.c + * @brief Mailboxes code. + * @addtogroup Mailboxes + * @{ + */ + +#include + +#if CH_USE_MAILBOXES +/** + * @brief Initializes a Mailbox object. + * + * @param[out] mbp the pointer to the Mailbox structure to be initialized + * @param[in] buf the circular messages buffer + * @param[in] n the buffer size as number of @p msg_t + */ +void chMBInit(Mailbox *mbp, msg_t *buf, cnt_t n) { + + chDbgCheck((mbp != NULL) && (buf != NULL) && (n > 0), "chMBInit"); + + mbp->mb_buffer = mbp->mb_wrptr = mbp->mb_rdptr = buf; + mbp->mb_top = &buf[n]; + chSemInit(&mbp->mb_emptysem, n); + chSemInit(&mbp->mb_fullsem, 0); +} + +/** + * @brief Resets a Mailbox object. + * @details All the waiting threads are resumed with status @p RDY_RESET and + * the queued messages are lost. + * + * @param[in] mbp the pointer to an initialized Mailbox object + */ +void chMBReset(Mailbox *mbp) { + + chDbgCheck(mbp != NULL, "chMBReset"); + + chSysLock(); + mbp->mb_wrptr = mbp->mb_rdptr = mbp->mb_buffer; + chSemResetI(&mbp->mb_emptysem, mbp->mb_top - mbp->mb_buffer); + chSemResetI(&mbp->mb_fullsem, 0); + chSchRescheduleS(); + chSysUnlock(); +} + +/** + * @brief Posts a message into a mailbox. + * @details The invoking thread waits until a empty slot in the mailbox becomes + * available or the specified time runs out. + * + * @param[in] mbp the pointer to an initialized Mailbox object + * @param[in] msg the message to be posted on the mailbox + * @param[in] time 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 operation status. + * @retval RDY_OK if the message was correctly posted. + * @retval RDY_RESET if the mailbox was reset while waiting. + * @retval RDY_TIMEOUT if the operation timed out. + */ +msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t time) { + msg_t rdymsg; + + chSysLock(); + rdymsg = chMBPostS(mbp, msg, time); + chSysUnlock(); + return rdymsg; +} + +/** + * @brief Posts a message into a mailbox. + * @details The invoking thread waits until a empty slot in the mailbox becomes + * available or the specified time runs out. + * + * @param[in] mbp the pointer to an initialized Mailbox object + * @param[in] msg the message to be posted on the mailbox + * @param[in] time 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 operation status. + * @retval RDY_OK if the message was correctly posted. + * @retval RDY_RESET if the mailbox was reset while waiting. + * @retval RDY_TIMEOUT if the operation timed out. + */ +msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) { + msg_t rdymsg; + + chDbgCheck(mbp != NULL, "chMBPostS"); + + rdymsg = chSemWaitTimeoutS(&mbp->mb_emptysem, time); + if (rdymsg == RDY_OK) { + *mbp->mb_wrptr++ = msg; + if (mbp->mb_wrptr >= mbp->mb_top) + mbp->mb_wrptr = mbp->mb_buffer; + chSemSignalI(&mbp->mb_fullsem); + chSchRescheduleS(); + } + return rdymsg; +} + +/** + * @brief Posts an high priority message into a mailbox. + * @details The invoking thread waits until a empty slot in the mailbox becomes + * available or the specified time runs out. + * + * @param[in] mbp the pointer to an initialized Mailbox object + * @param[in] msg the message to be posted on the mailbox + * @param[in] time 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 operation status. + * @retval RDY_OK if the message was correctly posted. + * @retval RDY_RESET if the mailbox was reset while waiting. + * @retval RDY_TIMEOUT if the operation timed out. + */ +msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t time) { + msg_t rdymsg; + + chSysLock(); + rdymsg = chMBPostAheadS(mbp, msg, time); + chSysUnlock(); + return rdymsg; +} + +/** + * @brief Posts an high priority message into a mailbox. + * @details The invoking thread waits until a empty slot in the mailbox becomes + * available or the specified time runs out. + * + * @param[in] mbp the pointer to an initialized Mailbox object + * @param[in] msg the message to be posted on the mailbox + * @param[in] time 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 operation status. + * @retval RDY_OK if the message was correctly posted. + * @retval RDY_RESET if the mailbox was reset while waiting. + * @retval RDY_TIMEOUT if the operation timed out. + */ +msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) { + msg_t rdymsg; + + chDbgCheck(mbp != NULL, "chMBPostAheadS"); + + rdymsg = chSemWaitTimeoutS(&mbp->mb_emptysem, time); + if (rdymsg == RDY_OK) { + if (--mbp->mb_rdptr < mbp->mb_buffer) + mbp->mb_rdptr = mbp->mb_top - 1; + *mbp->mb_rdptr = msg; + chSemSignalI(&mbp->mb_fullsem); + chSchRescheduleS(); + } + return rdymsg; +} + +/** + * @brief Retrieves a message from a mailbox. + * @details The invoking thread waits until a message is posted in the mailbox + * or the specified time runs out. + * + * @param[in] mbp the pointer to an initialized Mailbox object + * @param[out] msgp pointer to a message variable for the received message + * @param[in] time 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 operation status. + * @retval RDY_OK if a message was correctly fetched. + * @retval RDY_RESET if the mailbox was reset while waiting. + * @retval RDY_TIMEOUT if the operation timed out. + */ +msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t time) { + msg_t rdymsg; + + chSysLock(); + rdymsg = chMBFetchS(mbp, msgp, time); + chSysUnlock(); + return rdymsg; +} + +/** + * @brief Retrieves a message from a mailbox. + * @details The invoking thread waits until a message is posted in the mailbox + * or the specified time runs out. + * + * @param[in] mbp the pointer to an initialized Mailbox object + * @param[out] msgp pointer to a message variable for the received message + * @param[in] time 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 operation status. + * @retval RDY_OK if a message was correctly fetched. + * @retval RDY_RESET if the mailbox was reset while waiting. + * @retval RDY_TIMEOUT if the operation timed out. + */ +msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t time) { + msg_t rdymsg; + + chDbgCheck((mbp != NULL) && (msgp != NULL), "chMBFetchS"); + + rdymsg = chSemWaitTimeoutS(&mbp->mb_fullsem, time); + if (rdymsg == RDY_OK) { + *msgp = *mbp->mb_rdptr++; + if (mbp->mb_rdptr >= mbp->mb_top) + mbp->mb_rdptr = mbp->mb_buffer; + chSemSignalI(&mbp->mb_emptysem); + chSchRescheduleS(); + } + return rdymsg; +} +#endif /* CH_USE_MAILBOXES */ + +/** @} */ diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c new file mode 100644 index 000000000..dd6f3d1ba --- /dev/null +++ b/os/kernel/src/chmempools.c @@ -0,0 +1,112 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chmempools.c + * @brief Memory Pools code. + * @addtogroup MemoryPools + * @{ + */ + +#include + +#if CH_USE_MEMPOOLS +/** + * @brief Initializes an empty memory pool. + * + * @param[out] mp pointer to a @p MemoryPool structure + * @param[in] size the size of the objects contained in this memory pool, + * the minimum accepted size is the size of a pointer to void + */ +void chPoolInit(MemoryPool *mp, size_t size) { + + chDbgCheck((mp != NULL) && (size >= sizeof(void *)), "chPoolInit"); + + mp->mp_next = NULL; + mp->mp_object_size = size; +} + +/** + * @brief Allocates an object from a memory pool. + * + * @param[in] mp pointer to a @p MemoryPool structure + * @return The pointer to the allocated object. + * @retval NULL if pool is empty. + */ +void *chPoolAllocI(MemoryPool *mp) { + void *objp; + + chDbgCheck(mp != NULL, "chPoolAllocI"); + + if ((objp = mp->mp_next) != NULL) + mp->mp_next = mp->mp_next->ph_next; + + return objp; +} + +/** + * @brief Allocates an object from a memory pool. + * + * @param[in] mp pointer to a @p MemoryPool structure + * @return The pointer to the allocated object. + * @retval NULL if pool is empty. + */ +void *chPoolAlloc(MemoryPool *mp) { + void *objp; + + chSysLock(); + objp = chPoolAllocI(mp); + chSysUnlock(); + return objp; +} + +/** + * @brief Releases (or adds) an object into (to) a memory pool. + * + * @param[in] mp pointer to a @p MemoryPool structure + * @param[in] objp the pointer to the object to be released or added + * @note the object is assumed to be of the right size for the specified + * memory pool. + */ +void chPoolFreeI(MemoryPool *mp, void *objp) { + struct pool_header *php = objp; + + chDbgCheck((mp != NULL) && (objp != NULL), "chPoolFreeI"); + + php->ph_next = mp->mp_next; + mp->mp_next = php; +} + +/** + * @brief Releases (or adds) an object into (to) a memory pool. + * + * @param[in] mp pointer to a @p MemoryPool structure + * @param[in] objp the pointer to the object to be released or added + * @note the object is assumed to be of the right size for the specified + * memory pool. + */ +void chPoolFree(MemoryPool *mp, void *objp) { + + chSysLock(); + chPoolFreeI(mp, objp); + chSysUnlock(); +} +#endif /* CH_USE_MEMPOOLS */ + +/** @} */ diff --git a/os/kernel/src/chmsg.c b/os/kernel/src/chmsg.c new file mode 100644 index 000000000..393ab8dad --- /dev/null +++ b/os/kernel/src/chmsg.c @@ -0,0 +1,125 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chmsg.c + * @brief Messages code. + * @addtogroup Messages + * @{ + */ + +#include + +#if CH_USE_MESSAGES + +#if CH_USE_MESSAGES_PRIORITY +#define msg_insert(tp, qp) prio_insert(tp, qp) +#else +#define msg_insert(tp, qp) queue_insert(tp, qp) +#endif + +/** + * @brief Sends a message to the specified thread. + * @details The sender is stopped until the receiver executes a + * @p chMsgRelease()after receiving the message. + * + * @param[in] tp the pointer to the thread + * @param[in] msg the message + * @return The return message from @p chMsgRelease(). + */ +msg_t chMsgSend(Thread *tp, msg_t msg) { + + chDbgCheck(tp != NULL, "chMsgSend"); + + chSysLock(); + msg_insert(currp, &tp->p_msgqueue); + currp->p_msg = msg; + currp->p_wtthdp = tp; + if (tp->p_state == PRWTMSG) + chSchReadyI(tp); + chSchGoSleepS(PRSNDMSG); + msg = currp->p_rdymsg; + chSysUnlock(); + return msg; +} + +/** + * @brief Suspends the thread and waits for an incoming message. + * + * @return The pointer to the message structure. Note, it is always the + * message associated to the thread on the top of the messages queue. + * @note You can assume that the data contained in the message is stable until + * you invoke @p chMsgRelease() because the sending thread is + * suspended until then. + */ +msg_t chMsgWait(void) { + msg_t msg; + + chSysLock(); + if (!chMsgIsPendingI(currp)) + chSchGoSleepS(PRWTMSG); + msg = chMsgGetI(currp); + chSysUnlock(); + return msg; +} + +/** + * @brief Returns the next message in the queue. + * + * @return The pointer to the message structure. Note, it is always the + * message associated to the thread on the top of the messages queue. + * If the queue is empty then @p NULL is returned. + * @note You can assume that the data pointed by the message is stable until + * you invoke @p chMsgRelease() because the sending thread is + * suspended until then. Always remember that the message data is not + * copied between the sender and the receiver, just a pointer is passed. + */ +msg_t chMsgGet(void) { + msg_t msg; + + chSysLock(); + msg = chMsgIsPendingI(currp) ? chMsgGetI(currp) : (msg_t)NULL; + chSysUnlock(); + return msg; +} + +/** + * @brief Releases the thread waiting on top of the messages queue. + * + * @param[in] msg the message returned to the message sender + * @note You can call this function only if there is a message already in the + * queue else the result will be unpredictable (a crash most likely). + * Exiting from the @p chMsgWait() ensures you have at least one + * message in the queue so it is not a big deal.
+ * The condition is only tested in debug mode in order to make this code + * as fast as possible. + */ +void chMsgRelease(msg_t msg) { + + chSysLock(); + chDbgAssert(chMsgIsPendingI(currp), + "chMsgRelease(), #1", + "no message pending"); + chSchWakeupS(fifo_remove(&currp->p_msgqueue), msg); + chSysUnlock(); +} + +#endif /* CH_USE_MESSAGES */ + +/** @} */ diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c new file mode 100644 index 000000000..5fcb6fd5e --- /dev/null +++ b/os/kernel/src/chmtx.c @@ -0,0 +1,299 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chmtx.c + * @brief Mutexes code. + * @addtogroup Mutexes + * @{ + */ + +#include + +#if CH_USE_MUTEXES + +/** + * @brief Initializes s @p Mutex structure. + * + * @param[out] mp pointer to a @p Mutex structure + * @note This function can be invoked from within an interrupt handler even if + * it is not an I-Class API because it does not touch any critical kernel + * data structure. + */ +void chMtxInit(Mutex *mp) { + + chDbgCheck(mp != NULL, "chMtxInit"); + + queue_init(&mp->m_queue); + mp->m_owner = NULL; +} + +/** + * @brief Locks the specified mutex. + * + * @param[in] mp pointer to the @p Mutex structure + */ +void chMtxLock(Mutex *mp) { + + chSysLock(); + + chMtxLockS(mp); + + chSysUnlock(); +} + +/** + * @brief Locks the specified mutex. + * + * @param[in] mp pointer to the @p Mutex structure + * @note This function must be called within a @p chSysLock() / @p chSysUnlock() + * block. + */ +void chMtxLockS(Mutex *mp) { + + chDbgCheck(mp != NULL, "chMtxLockS"); + + /* the mutex is already locked? */ + if (mp->m_owner != NULL) { + /* + * Priority inheritance protocol; explores the thread-mutex dependencies + * boosting the priority of all the affected threads to equal the priority + * of the running thread requesting the mutex. + */ + Thread *tp = mp->m_owner; + /* { tp is the thread currently owning the mutex } */ + /* the running thread has higher priority than tp? */ + while (tp->p_prio < currp->p_prio) { + /* make priority of thread tp match the running thread's priority */ + tp->p_prio = currp->p_prio; + /* + * The following states need priority queues reordering. + */ + switch (tp->p_state) { + /* thread tp is waiting on a mutex? */ + case PRWTMTX: + /* Requeues tp with its new priority on the mutex wait queue. */ + prio_insert(dequeue(tp), &tp->p_wtmtxp->m_queue); + /* boost the owner of this mutex if needed */ + tp = tp->p_wtmtxp->m_owner; + continue; +#if CH_USE_CONDVARS + case PRWTCOND: + /* Requeues tp with its new priority on the condvar queue. */ + prio_insert(dequeue(tp), &tp->p_wtcondp->c_queue); + break; +#endif +#if CH_USE_SEMAPHORES_PRIORITY + case PRWTSEM: + /* Requeues tp with its new priority on the semaphore queue. */ + prio_insert(dequeue(tp), &tp->p_wtsemp->s_queue); + break; +#endif +#if CH_USE_MESSAGES_PRIORITY + case PRSNDMSG: + /* Requeues tp with its new priority on the server thread queue. */ + prio_insert(dequeue(tp), &tp->p_wtthdp->p_msgqueue); + break; +#endif + /* thread tp is ready? */ + case PRREADY: + /* Requeue tp with its new priority on the ready list. */ + chSchReadyI(dequeue(tp)); + } + break; + } + /* sleep on the mutex */ + prio_insert(currp, &mp->m_queue); + /* thread remembers the mutex where it is waiting on */ + currp->p_wtmtxp = mp; + chSchGoSleepS(PRWTMTX); + chDbgAssert(mp->m_owner == NULL, "chMtxLockS(), #1", "still owned"); + } + /* + * The mutex is now inserted in the owned mutexes list. + */ + mp->m_owner = currp; + mp->m_next = currp->p_mtxlist; + currp->p_mtxlist = mp; +} + +/** + * @brief Tries to lock a mutex. + * @details This function does not have any overhead related to + * the priority inheritance mechanism because it does not try to + * enter a sleep state on the mutex. + * + * @param[in] mp pointer to the @p Mutex structure + * @retval TRUE if the mutex was successfully acquired + * @retval FALSE if the lock attempt failed. + */ +bool_t chMtxTryLock(Mutex *mp) { + bool_t b; + + chSysLock(); + + b = chMtxTryLockS(mp); + + chSysUnlock(); + return b; +} + +/** + * @brief Tries to lock a mutex. + * @details This function does not have any overhead related to + * the priority inheritance mechanism because it does not try to + * enter a sleep state on the mutex. + * @param[in] mp pointer to the @p Mutex structure + * @retval TRUE if the mutex was successfully acquired + * @retval FALSE if the lock attempt failed. + * @note This function must be called within a @p chSysLock() / @p chSysUnlock() + * block. + */ +bool_t chMtxTryLockS(Mutex *mp) { + + chDbgCheck(mp != NULL, "chMtxTryLockS"); + + if (mp->m_owner != NULL) + return FALSE; + mp->m_owner = currp; + mp->m_next = currp->p_mtxlist; + currp->p_mtxlist = mp; + return TRUE; +} + +/** + * @brief Unlocks the next owned mutex in reverse lock order. + * + * @return The pointer to the unlocked mutex. + */ +Mutex *chMtxUnlock(void) { + Mutex *ump, *mp; + + chSysLock(); + chDbgAssert(currp->p_mtxlist != NULL, + "chMtxUnlock(), #1", + "owned mutexes list empty"); + chDbgAssert(currp->p_mtxlist->m_owner == currp, + "chMtxUnlock(), #2", + "ownership failure"); + /* remove the top Mutex from the Threads's owned mutexes list */ + ump = currp->p_mtxlist; + currp->p_mtxlist = ump->m_next; + /* mark the Mutex as not owned */ + ump->m_owner = NULL; + /* + * If a thread is waiting on the mutex then the hard part begins. + */ + if (chMtxQueueNotEmptyS(ump)) { + /* get the highest priority thread waiting for the unlocked mutex */ + Thread *tp = fifo_remove(&ump->m_queue); + /* + * Recalculates the optimal thread priority by scanning the owned mutexes list. + */ + tprio_t newprio = currp->p_realprio; + /* iterate mp over all the (other) mutexes the current thread still owns */ + mp = currp->p_mtxlist; + while (mp != NULL) { + /* mutex mp has a higher priority thread pending? */ + if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio)) + /* boost current thread's priority to waiting thread */ + newprio = mp->m_queue.p_next->p_prio; + mp = mp->m_next; + } + /* (possibly) boost the priority of the current thread */ + currp->p_prio = newprio; + /* awaken the highest priority thread waiting for the unlocked mutex */ + chSchWakeupS(tp, RDY_OK); + } + chSysUnlock(); + return ump; +} + +/** + * @brief Unlocks the next owned mutex in reverse lock order. + * + * @return The pointer to the unlocked mutex. + * @note This function must be called within a @p chSysLock() / @p chSysUnlock() + * block. + * @note This function does not reschedule internally. + */ +Mutex *chMtxUnlockS(void) { + Mutex *ump, *mp; + + chDbgAssert(currp->p_mtxlist != NULL, + "chMtxUnlockS(), #1", + "owned mutexes list empty"); + chDbgAssert(currp->p_mtxlist->m_owner == currp, + "chMtxUnlockS(), #2", + "ownership failure"); + + /* + * Removes the top Mutex from the owned mutexes list and marks it as not owned. + */ + ump = currp->p_mtxlist; + currp->p_mtxlist = ump->m_next; + ump->m_owner = NULL; + /* + * If a thread is waiting on the mutex then the hard part begins. + */ + if (chMtxQueueNotEmptyS(ump)) { + Thread *tp = fifo_remove(&ump->m_queue); + /* + * Recalculates the optimal thread priority by scanning the owned mutexes list. + */ + tprio_t newprio = currp->p_realprio; + mp = currp->p_mtxlist; + while (mp != NULL) { + if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio)) + newprio = mp->m_queue.p_next->p_prio; + mp = mp->m_next; + } + currp->p_prio = newprio; + chSchReadyI(tp); + } + return ump; +} + +/** + * @brief Unlocks all the mutexes owned by the invoking thread. + * @details This function is MUCH MORE efficient than releasing the + * mutexes one by one and not just because the call overhead, + * this function does not have any overhead related to the priority + * inheritance mechanism. + */ +void chMtxUnlockAll(void) { + + chSysLock(); + if (currp->p_mtxlist != NULL) { + do { + Mutex *mp = currp->p_mtxlist; + currp->p_mtxlist = mp->m_next; + mp->m_owner = NULL; + if (chMtxQueueNotEmptyS(mp)) + chSchReadyI(fifo_remove(&mp->m_queue)); + } while (currp->p_mtxlist != NULL); + currp->p_prio = currp->p_realprio; + chSchRescheduleS(); + } + chSysUnlock(); +} + +#endif /* CH_USE_MUTEXES */ + +/** @} */ diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c new file mode 100644 index 000000000..a72b83696 --- /dev/null +++ b/os/kernel/src/chqueues.c @@ -0,0 +1,304 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chqueues.c + * @brief I/O Queues code. + * @addtogroup IOQueues + * @{ + */ + +#include + +#if CH_USE_QUEUES + +/** + * @brief Initializes an input queue. + * @details A Semaphore is internally initialized and works as a counter of + * the bytes contained in the queue. + * + * @param[out] iqp pointer to an @p InputQueue structure + * @param[in] buffer pointer to a memory area allocated as queue buffer + * @param[in] size size of the queue buffer + * @param[in] inotify pointer to a callback function that is invoked when + * some data is read from the queue. The value can be + * @p NULL. + * + * @note The callback is invoked from within the S-Locked system state, + * see @ref system_states. + */ +void chIQInit(InputQueue *iqp, uint8_t *buffer, + size_t size, qnotify_t inotify) { + + iqp->q_buffer = iqp->q_rdptr = iqp->q_wrptr = buffer; + iqp->q_top = buffer + size; + chSemInit(&iqp->q_sem, 0); + iqp->q_notify = inotify; +} + +/** + * @brief Resets an input queue. + * @details All the data in the input queue is erased and lost, any waiting + * thread is resumed with status @p Q_RESET. + * + * @param[in] iqp pointer to an @p InputQueue structure + * + * @note A reset operation can be used by a low level driver in order to obtain + * immediate attention from the high level layers. + */ +void chIQResetI(InputQueue *iqp) { + + iqp->q_rdptr = iqp->q_wrptr = iqp->q_buffer; + chSemResetI(&iqp->q_sem, 0); +} + +/** + * @brief Input queue write. + * @details A byte value is written into the low end of an input queue. + * + * @param[in] iqp pointer to an @p InputQueue structure + * @param[in] b the byte value to be written in the queue + * @return The operation status, it can be one of: + * @retval Q_OK if the operation has been completed with success. + * @retval Q_FULL if the queue is full and the operation cannot be completed. + */ +msg_t chIQPutI(InputQueue *iqp, uint8_t b) { + + if (chIQIsFull(iqp)) + return Q_FULL; + + *iqp->q_wrptr++ = b; + if (iqp->q_wrptr >= iqp->q_top) + iqp->q_wrptr = iqp->q_buffer; + chSemSignalI(&iqp->q_sem); + return Q_OK; +} + +/** + * @brief Input queue read with timeout. + * @details This function reads a byte value from an input queue. If the queue + * is empty then the calling thread is suspended until a byte arrives + * in the queue or a timeout occurs. + * + * @param[in] iqp pointer to an @p InputQueue 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 byte value from the queue or: + * @retval Q_TIMEOUT if the specified time expired. + * @retval Q_RESET if the queue was reset. + */ +msg_t chIQGetTimeout(InputQueue *iqp, systime_t timeout) { + uint8_t b; + msg_t msg; + + chSysLock(); + if ((msg = chSemWaitTimeoutS(&iqp->q_sem, timeout)) < RDY_OK) { + chSysUnlock(); + return msg; + } + b = *iqp->q_rdptr++; + if (iqp->q_rdptr >= iqp->q_top) + iqp->q_rdptr = iqp->q_buffer; + + if (iqp->q_notify) + iqp->q_notify(); + + chSysUnlock(); + return b; +} + +/** + * @brief Non-blocking read. + * @details The function reads data from an input queue into a buffer. The + * transfer is non-blocking and can return zero if the queue is + * empty. + * + * @param[in] iqp pointer to an @p InputQueue structure + * @param[out] buffer pointer to the buffer where the input data is copied + * @param[in] n the maximum amount of data to be transferred + * @return The number of bytes transferred. + * + * @note The function is not atomic, if you need atomicity it is suggested + * to use a semaphore or a mutex for mutual exclusion. + */ +size_t chIQRead(InputQueue *iqp, uint8_t *buffer, size_t n) { + size_t r = 0; + + while (n--) { + chSysLock(); + if (chIQIsEmpty(iqp)) { + chSysUnlock(); + break; + } + chSemFastWaitI(&iqp->q_sem); + *buffer++ = *iqp->q_rdptr++; + if (iqp->q_rdptr >= iqp->q_top) + iqp->q_rdptr = iqp->q_buffer; + chSysUnlock(); + r++; + } + if (r && iqp->q_notify) { + chSysLock(); + iqp->q_notify(); + chSysUnlock(); + } + return r; +} + +/** + * @brief Initializes an output queue. + * @details A Semaphore is internally initialized and works as a counter of + * the free bytes in the queue. + * + * @param[out] oqp pointer to an @p OutputQueue structure + * @param[in] buffer pointer to a memory area allocated as queue buffer + * @param[in] size size of the queue buffer + * @param[in] onotify pointer to a callback function that is invoked when + * some data is written to the queue. The value can be + * @p NULL. + * + * @note The callback is invoked from within the S-Locked system state, + * see @ref system_states. + */ +void chOQInit(OutputQueue *oqp, uint8_t *buffer, + size_t size, qnotify_t onotify) { + + oqp->q_buffer = oqp->q_rdptr = oqp->q_wrptr = buffer; + oqp->q_top = buffer + size; + chSemInit(&oqp->q_sem, size); + oqp->q_notify = onotify; +} + +/** + * @brief Resets an output queue. + * @details All the data in the output queue is erased and lost, any waiting + * thread is resumed with status @p Q_RESET. + * + * @param[in] oqp pointer to an @p OutputQueue structure + * + * @note A reset operation can be used by a low level driver in order to obtain + * immediate attention from the high level layers. + */ +void chOQResetI(OutputQueue *oqp) { + + oqp->q_rdptr = oqp->q_wrptr = oqp->q_buffer; + chSemResetI(&oqp->q_sem, (cnt_t)(oqp->q_top - oqp->q_buffer)); +} + +/** + * @brief Output queue write with timeout. + * @details This function writes a byte value to an output queue. If the queue + * is full then the calling thread is suspended until there is space + * in the queue or a timeout occurs. + * + * @param[in] oqp pointer to an @p OutputQueue structure + * @param[in] b the byte value to be written in the queue + * @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 operation status: + * @retval Q_OK if the operation succeeded. + * @retval Q_TIMEOUT if the specified time expired. + * @retval Q_RESET if the queue was reset. + */ +msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t timeout) { + msg_t msg; + + chSysLock(); + if ((msg = chSemWaitTimeoutS(&oqp->q_sem, timeout)) < RDY_OK) { + chSysUnlock(); + return msg; + } + *oqp->q_wrptr++ = b; + if (oqp->q_wrptr >= oqp->q_top) + oqp->q_wrptr = oqp->q_buffer; + + if (oqp->q_notify) + oqp->q_notify(); + + chSysUnlock(); + return Q_OK; +} + +/** + * @brief Output queue read. + * @details A byte value is read from the low end of an output queue. + * + * @param[in] oqp pointer to an @p OutputQueue structure + * @return The byte value from the queue or: + * @retval Q_EMPTY if the queue is empty. + */ +msg_t chOQGetI(OutputQueue *oqp) { + uint8_t b; + + if (chOQIsEmpty(oqp)) + return Q_EMPTY; + + b = *oqp->q_rdptr++; + if (oqp->q_rdptr >= oqp->q_top) + oqp->q_rdptr = oqp->q_buffer; + chSemSignalI(&oqp->q_sem); + return b; +} + +/** + * @brief Non-blocking write. + * @details The function writes data from a buffer to an output queue. The + * transfer is non-blocking and can return zero if the queue is + * already full. + * + * @param[in] oqp pointer to an @p OutputQueue structure + * @param[out] buffer pointer to the buffer where the output data is stored + * @param[in] n the maximum amount of data to be transferred + * @return The number of bytes transferred. + * + * @note The function is not atomic, if you need atomicity it is suggested + * to use a semaphore or a mutex for mutual exclusion. + */ +size_t chOQWrite(OutputQueue *oqp, uint8_t *buffer, size_t n) { + + size_t w = 0; + while (n--) { + chSysLock(); + if (chOQIsFull(oqp)) { + chSysUnlock(); + break; + } + chSemFastWaitI(&oqp->q_sem); + *oqp->q_wrptr++ = *buffer++; + if (oqp->q_wrptr >= oqp->q_top) + oqp->q_wrptr = oqp->q_buffer; + chSysUnlock(); + w++; + } + if (w && oqp->q_notify) { + chSysLock(); + oqp->q_notify(); + chSysUnlock(); + } + return w; +} +#endif /* CH_USE_QUEUES */ + +/** @} */ diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c new file mode 100644 index 000000000..3ba8b29e9 --- /dev/null +++ b/os/kernel/src/chschd.c @@ -0,0 +1,242 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chschd.c + * @brief Scheduler code. + * @addtogroup Scheduler + * @{ + */ + +#include + +/** @cond never */ +ReadyList rlist; +/** @endcond */ + +/** + * @brief Scheduler initialization. + * + * @note Internally invoked by the @p chSysInit(). + */ +void scheduler_init(void) { + + queue_init(&rlist); + rlist.r_prio = NOPRIO; +#if CH_USE_ROUNDROBIN + rlist.r_preempt = CH_TIME_QUANTUM; +#endif +} + +/** + * @brief Inserts a thread in the Ready List. + * + * @param[in] tp the Thread to be made ready + * @return The Thread pointer. + * @note The function does not reschedule, the @p chSchRescheduleS() should + * be called soon after. + */ +#if CH_OPTIMIZE_SPEED +/* NOTE: it is inlined in this module only.*/ +INLINE Thread *chSchReadyI(Thread *tp) { +#else +Thread *chSchReadyI(Thread *tp) { +#endif + Thread *cp; + + tp->p_state = PRREADY; + cp = (Thread *)&rlist; + do { + cp = cp->p_next; + } while (cp->p_prio >= tp->p_prio); + /* Insertion on p_prev.*/ + tp->p_prev = (tp->p_next = cp)->p_prev; + tp->p_prev->p_next = cp->p_prev = tp; + return tp; +} + +/** + * @brief Puts the current thread to sleep into the specified state. + * @details The thread goes into a sleeping state. The @ref thread_states are + * described into @p threads.h. + * + * @param[in] newstate the new thread state + */ +void chSchGoSleepS(tstate_t newstate) { + Thread *otp; + + (otp = currp)->p_state = newstate; + (currp = fifo_remove((void *)&rlist))->p_state = PRCURR; +#if CH_USE_ROUNDROBIN + rlist.r_preempt = CH_TIME_QUANTUM; +#endif + chDbgTrace(otp, currp); + chSysSwitchI(otp, currp); +} + +/* + * Timeout wakeup callback. + */ +static void wakeup(void *p) { + Thread *tp = (Thread *)p; + +#if CH_USE_SEMAPHORES || CH_USE_MUTEXES || CH_USE_CONDVARS + switch (tp->p_state) { +#if CH_USE_SEMAPHORES + case PRWTSEM: + chSemFastSignalI(tp->p_wtsemp); + /* Falls into, intentional. */ +#endif +#if CH_USE_MUTEXES + case PRWTMTX: +#endif +#if CH_USE_CONDVARS + case PRWTCOND: +#endif + /* States requiring dequeuing. */ + dequeue(tp); + } +#endif + chSchReadyI(tp)->p_rdymsg = RDY_TIMEOUT; +} + +/** + * @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 timeout then it is forcibly + * awakened with a @p RDY_TIMEOUT low level message. The @ref + * thread_states are described into @p threads.h. + * + * @param[in] newstate the new thread state + * @param[in] time the number of ticks before the operation timeouts, the + * special values are handled as follow: + * - @a TIME_INFINITE the thread enters an infinite sleep + * state, this is equivalent to invoking @p chSchGoSleepS() + * but, of course, less efficient. + * - @a TIME_IMMEDIATE this value is accepted but interpreted + * as a normal time specification not as an immediate timeout + * specification. + * . + * @return The wakeup message. + * @retval RDY_TIMEOUT if a timeout occurs. + */ +msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { + + if (TIME_INFINITE != time) { + VirtualTimer vt; + + chVTSetI(&vt, time, wakeup, currp); + chSchGoSleepS(newstate); + if (chVTIsArmedI(&vt)) + chVTResetI(&vt); + } + else + chSchGoSleepS(newstate); + return currp->p_rdymsg; +} + +/** + * @brief Wakes up a thread. + * @details The thread is inserted into the ready list or immediately made + * running depending on its relative priority compared to the current + * thread. + * + * @param[in] ntp the Thread to be made ready + * @param[in] msg message to the awakened thread + * @note It is equivalent to a @p chSchReadyI() followed by a + * @p chSchRescheduleS() but much more efficient. + */ +void chSchWakeupS(Thread *ntp, msg_t msg) { + + ntp->p_rdymsg = msg; + /* If the waken thread has a not-greater priority than the current + * one then it is just inserted in the ready list else it made + * running immediately and the invoking thread goes in the ready + * list instead.*/ + if (ntp->p_prio <= currp->p_prio) + chSchReadyI(ntp); + else { + Thread *otp = currp; + chSchReadyI(otp); + (currp = ntp)->p_state = PRCURR; +#if CH_USE_ROUNDROBIN + rlist.r_preempt = CH_TIME_QUANTUM; +#endif + chDbgTrace(otp, ntp); + chSysSwitchI(otp, ntp); + } +} + +/** + * @brief Switches to the first thread on the runnable queue. + * + * @note It is intended to be called if @p chSchRescRequiredI() evaluates to + * @p TRUE. + */ +void chSchDoRescheduleI(void) { + + Thread *otp = currp; + /* pick the first thread from the ready queue and makes it current */ + (currp = fifo_remove((void *)&rlist))->p_state = PRCURR; + chSchReadyI(otp); +#if CH_USE_ROUNDROBIN + rlist.r_preempt = CH_TIME_QUANTUM; +#endif + chDbgTrace(otp, currp); + chSysSwitchI(otp, currp); +} + +/** + * @brief Performs a reschedulation if a higher priority thread is runnable. + * @details If a thread with a higher priority than the current thread is in + * the ready list then make the higher priority thread running. + */ +void chSchRescheduleS(void) { + /* first thread in the runnable queue has higher priority than the running + * thread? */ + if (firstprio(&rlist) > currp->p_prio) + chSchDoRescheduleI(); +} + +/** + * @brief Evaluates if a reschedulation is required. + * @details The decision is taken by comparing the relative priorities and + * depending on the state of the round robin timeout counter. + * + * @retval TRUE if there is a thread that should go in running state. + * @retval FALSE if a reschedulation is not required. + */ +bool_t chSchRescRequiredI(void) { + tprio_t p1 = firstprio(&rlist); + tprio_t p2 = currp->p_prio; +#if CH_USE_ROUNDROBIN + /* If the running thread has not reached its time quantum, reschedule only + * if the first thread on the ready queue has a higher priority. + * Otherwise, if the running thread has used up its time quantum, reschedule + * if the first thread on the ready queue has equal or higher priority.*/ + return rlist.r_preempt ? p1 > p2 : p1 >= p2; +#else + /* If the round robin feature is not enabled then performs a simpler + * comparison.*/ + return p1 > p2; +#endif +} + +/** @} */ diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c new file mode 100644 index 000000000..9a8570580 --- /dev/null +++ b/os/kernel/src/chsem.c @@ -0,0 +1,257 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chsem.c + * @brief Semaphores code. + * @addtogroup Semaphores + * @{ + */ + +#include + +#if CH_USE_SEMAPHORES + +#if CH_USE_SEMAPHORES_PRIORITY +#define sem_insert(tp, qp) prio_insert(tp, qp) +#else +#define sem_insert(tp, qp) queue_insert(tp, qp) +#endif + +/** + * @brief Initializes a semaphore with the specified counter value. + * + * @param[out] sp pointer to a @p Semaphore structure + * @param[in] n initial value of the semaphore counter. Must be non-negative. + * @note This function can be invoked from within an interrupt handler even if + * it is not an I-Class API because it does not touch any critical kernel + * data structure. + */ +void chSemInit(Semaphore *sp, cnt_t n) { + + chDbgCheck((sp != NULL) && (n >= 0), "chSemInit"); + + queue_init(&sp->s_queue); + sp->s_cnt = n; +} + +/** + * @brief Performs a reset operation on the semaphore. + * + * @param[in] sp pointer to a @p Semaphore structure + * @param[in] n the new value of the semaphore counter. The value must be non-negative. + * @note The released threads can recognize they were waked up by a reset + * instead than a signal because the @p chSemWait() will return + * @p RDY_RESET instead of @p RDY_OK. + */ +void chSemReset(Semaphore *sp, cnt_t n) { + + chSysLock(); + chSemResetI(sp, n); + chSchRescheduleS(); + chSysUnlock(); +} + +/** + * @brief Performs a reset operation on the semaphore. + * + * @param[in] sp pointer to a @p Semaphore structure + * @param[in] n the new value of the semaphore counter. The value must be non-negative. + * @note The released threads can recognize they were waked up by a reset + * instead than a signal because the @p chSemWait() will return + * @p RDY_RESET instead of @p RDY_OK. + * @note This function does not reschedule. + */ +void chSemResetI(Semaphore *sp, cnt_t n) { + cnt_t cnt; + + chDbgCheck((sp != NULL) && (n >= 0), "chSemResetI"); + + cnt = sp->s_cnt; + sp->s_cnt = n; + while (cnt++ < 0) + chSchReadyI(lifo_remove(&sp->s_queue))->p_rdymsg = RDY_RESET; +} + +/** + * @brief Performs a wait operation on a semaphore. + * + * @param[in] sp pointer to a @p Semaphore structure + * @retval RDY_OK if the semaphore was signaled or not taken. + * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). + */ +msg_t chSemWait(Semaphore *sp) { + msg_t msg; + + chSysLock(); + msg = chSemWaitS(sp); + chSysUnlock(); + return msg; +} + +/** + * @brief Performs a wait operation on a semaphore. + * + * @param[in] sp pointer to a @p Semaphore structure + * @retval RDY_OK if the semaphore was signaled or not taken. + * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). + * @note This function must be called with interrupts disabled. + * @note This function cannot be called by an interrupt handler. + */ +msg_t chSemWaitS(Semaphore *sp) { + + chDbgCheck(sp != NULL, "chSemWaitS"); + + if (--sp->s_cnt < 0) { + sem_insert(currp, &sp->s_queue); + currp->p_wtsemp = sp; + chSchGoSleepS(PRWTSEM); + return currp->p_rdymsg; + } + return RDY_OK; +} + +/** + * @brief Performs a wait operation on a semaphore with timeout specification. + * + * @param[in] sp pointer to a @p Semaphore structure + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @retval RDY_OK if the semaphore was signaled or not taken. + * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). + * @retval RDY_TIMEOUT if the semaphore was not signaled or reset within the + * specified timeout. + */ +msg_t chSemWaitTimeout(Semaphore *sp, systime_t time) { + msg_t msg; + + chSysLock(); + msg = chSemWaitTimeoutS(sp, time); + chSysUnlock(); + return msg; +} + +/** + * @brief Performs a wait operation on a semaphore with timeout specification. + * + * @param[in] sp pointer to a @p Semaphore structure + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @retval RDY_OK if the semaphore was signaled or not taken. + * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). + * @retval RDY_TIMEOUT if the semaphore was not signaled or reset within the specified + * timeout. + */ +msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) { + + chDbgCheck(sp != NULL, "chSemWaitTimeoutS"); + + if (--sp->s_cnt < 0) { + if (TIME_IMMEDIATE == time) { + sp->s_cnt++; + return RDY_TIMEOUT; + } + sem_insert(currp, &sp->s_queue); + currp->p_wtsemp = sp; + return chSchGoSleepTimeoutS(PRWTSEM, time); + } + return RDY_OK; +} + +/** + * @brief Performs a signal operation on a semaphore. + * + * @param[in] sp pointer to a @p Semaphore structure + * @note The function is available only if the @p CH_USE_SEMAPHORES + * option is enabled in @p chconf.h. + */ +void chSemSignal(Semaphore *sp) { + + chDbgCheck(sp != NULL, "chSemSignal"); + + chSysLock(); + if (sp->s_cnt++ < 0) + chSchWakeupS(fifo_remove(&sp->s_queue), RDY_OK); + chSysUnlock(); +} + +/** + * @brief Performs a signal operation on a semaphore. + * + * @param[in] sp pointer to a @p Semaphore structure + * @note The function is available only if the @p CH_USE_SEMAPHORES + * option is enabled in @p chconf.h. + * @note This function does not reschedule. + */ +void chSemSignalI(Semaphore *sp) { + + chDbgCheck(sp != NULL, "chSemSignalI"); + + if (sp->s_cnt++ < 0) { + /* NOTE: It is done this way in order to allow a tail call on + chSchReadyI().*/ + Thread *tp = fifo_remove(&sp->s_queue); + tp->p_rdymsg = RDY_OK; + chSchReadyI(tp); + } +} + +#if CH_USE_SEMSW +/** + * @brief Performs atomic signal and wait operations on two semaphores. + * + * @param[in] sps pointer to a @p Semaphore structure to be signaled + * @param[in] spw pointer to a @p Semaphore structure to be wait on + * @retval RDY_OK if the semaphore was signaled or not taken. + * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). + * @note The function is available only if the @p CH_USE_SEMSW + * option is enabled in @p chconf.h. + */ +msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw) { + msg_t msg; + + chDbgCheck((sps != NULL) && (spw != NULL), "chSemSignalWait"); + + chSysLock(); + if (sps->s_cnt++ < 0) + chSchReadyI(fifo_remove(&sps->s_queue))->p_rdymsg = RDY_OK; + if (--spw->s_cnt < 0) { + sem_insert(currp, &spw->s_queue); + currp->p_wtsemp = spw; + chSchGoSleepS(PRWTSEM); + msg = currp->p_rdymsg; + } + else { + chSchRescheduleS(); + msg = RDY_OK; + } + chSysUnlock(); + return msg; +} +#endif /* CH_USE_SEMSW */ + +#endif /* CH_USE_SEMAPHORES */ + +/** @} */ diff --git a/os/kernel/src/chserial.c b/os/kernel/src/chserial.c new file mode 100644 index 000000000..65179689d --- /dev/null +++ b/os/kernel/src/chserial.c @@ -0,0 +1,168 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chserial.c + * @brief Serial Drivers code. + * @addtogroup Serial + * @{ + */ + +#include + +#if CH_USE_SERIAL_FULLDUPLEX + +/* + * Interface implementation, the following functions just invoke the equivalent + * queue-level function or macro. + */ +static bool_t putwouldblock(void *instance) { + + return chOQIsFull(&((FullDuplexDriver *)instance)->d2.oqueue); +} + +static bool_t getwouldblock(void *instance) { + + return chIQIsEmpty(&((FullDuplexDriver *)instance)->d2.iqueue); +} + +static msg_t put(void *instance, uint8_t b, systime_t timeout) { + + return chOQPutTimeout(&((FullDuplexDriver *)instance)->d2.oqueue, b, timeout); +} + +static msg_t get(void *instance, systime_t timeout) { + + return chIQGetTimeout(&((FullDuplexDriver *)instance)->d2.iqueue, timeout); +} + +static size_t write(void *instance, uint8_t *buffer, size_t n) { + + return chOQWrite(&((FullDuplexDriver *)instance)->d2.oqueue, buffer, n); +} + +static size_t read(void *instance, uint8_t *buffer, size_t n) { + + return chIQRead(&((FullDuplexDriver *)instance)->d2.iqueue, buffer, n); +} + +static const struct FullDuplexDriverVMT vmt = { + {putwouldblock, getwouldblock, put, get}, + {write, read}, + {} +}; + +/** + * @brief Initializes a generic full duplex driver. + * @details The HW dependent part of the initialization has to be performed + * outside, usually in the hardware initialization code. + * + * @param[out] sd pointer to a @p FullDuplexDriver structure + * @param[in] ib pointer to a memory area allocated for the Input Queue buffer + * @param[in] isize size of the Input Queue buffer + * @param[in] inotify pointer to a callback function that is invoked when + * some data is read from the Queue. The value can be + * @p NULL. + * @param[in] ob pointer to a memory area allocated for the Output Queue buffer + * @param[in] osize size of the Output Queue buffer + * @param[in] onotify pointer to a callback function that is invoked when + * some data is written in the Queue. The value can be + * @p NULL. + */ +void chFDDInit(FullDuplexDriver *sd, + uint8_t *ib, size_t isize, qnotify_t inotify, + uint8_t *ob, size_t osize, qnotify_t onotify) { + + chDbgCheck((sd != NULL) && (ib != NULL) && (ob != NULL) && + (isize > 0) && (osize > 0), "chFDDInit"); + + sd->vmt = &vmt; + chEvtInit(&sd->d1.ievent); + chEvtInit(&sd->d1.oevent); + chEvtInit(&sd->d2.sevent); + sd->d2.flags = SD_NO_ERROR; + chIQInit(&sd->d2.iqueue, ib, isize, inotify); + chOQInit(&sd->d2.oqueue, ob, osize, onotify); +} + +/** + * @brief Handles incoming data. + * @details This function must be called from the input interrupt service + * routine in order to enqueue incoming data and generate the + * related events. + * @param[in] sd pointer to a @p FullDuplexDriver structure + * @param[in] b the byte to be written in the driver's Input Queue + */ +void chFDDIncomingDataI(FullDuplexDriver *sd, uint8_t b) { + + if (chIQPutI(&sd->d2.iqueue, b) < Q_OK) + chFDDAddFlagsI(sd, SD_OVERRUN_ERROR); + else + chEvtBroadcastI(&sd->d1.ievent); +} + +/** + * @brief Handles outgoing data. + * @details Must be called from the output interrupt service routine in order + * to get the next byte to be transmitted. + * + * @param[in] sd pointer to a @p FullDuplexDriver structure + * @return The byte value read from the driver's output queue. + * @retval Q_EMPTY if the queue is empty (the lower driver usually disables + * the interrupt source when this happens). + */ +msg_t chFDDRequestDataI(FullDuplexDriver *sd) { + + msg_t b = chOQGetI(&sd->d2.oqueue); + if (b < Q_OK) + chEvtBroadcastI(&sd->d1.oevent); + return b; +} + +/** + * @brief Handles communication events/errors. + * @details Must be called from the I/O interrupt service routine in order to + * notify I/O conditions as errors, signals change etc. + * + * @param[in] sd pointer to a @p FullDuplexDriver structure + * @param[in] mask condition flags to be added to the mask + */ +void chFDDAddFlagsI(FullDuplexDriver *sd, dflags_t mask) { + + sd->d2.flags |= mask; + chEvtBroadcastI(&sd->d2.sevent); +} + +/** + * @brief Returns and clears the errors mask associated to the driver. + * + * @param[in] sd pointer to a @p FullDuplexDriver structure + * @return The condition flags modified since last time this function was + * invoked. + */ +dflags_t chFDDGetAndClearFlags(FullDuplexDriver *sd) { + dflags_t mask; + + mask = sd->d2.flags; + sd->d2.flags = SD_NO_ERROR; + return mask; +} +#endif /* CH_USE_SERIAL_FULLDUPLEX */ + +/** @} */ diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c new file mode 100644 index 000000000..217e2f2da --- /dev/null +++ b/os/kernel/src/chsys.c @@ -0,0 +1,129 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chsys.c + * @brief System related code. + * @addtogroup System + * @{ + */ + +#include + +static WORKING_AREA(idle_thread_wa, IDLE_THREAD_STACK_SIZE); + +/** + * @brief This function implements the idle thread infinite loop. + * @details The function puts the processor in the lowest power mode capable + * to serve interrupts.
+ * The priority is internally set to the minimum system value so + * that this thread is executed only if there are no other ready + * threads in the system. + * + * @param[in] p the thread parameter, unused in this scenario + */ +static void idle_thread(void *p) { + + while (TRUE) { + port_wait_for_interrupt(); + IDLE_LOOP_HOOK(); + } +} + +/** + * @brief ChibiOS/RT initialization. + * @details After executing this function the current instructions stream + * becomes the main thread. + * + * @note Interrupts should be still disabled when @p chSysInit() is invoked + * and are internally enabled. + * @note The main thread is created with priority @p NORMALPRIO. + */ +void chSysInit(void) { + static Thread mainthread; + + port_init(); + scheduler_init(); + vt_init(); +#if CH_USE_HEAP + heap_init(); +#endif +#if CH_DBG_ENABLE_TRACE + trace_init(); +#endif + + /* + * Now this instructions flow becomes the main thread. + */ + (currp = init_thread(&mainthread, NORMALPRIO))->p_state = PRCURR; + chSysEnable(); + + /* + * This thread has the lowest priority in the system, its role is just to + * serve interrupts in its context while keeping the lowest energy saving + * mode compatible with the system status. + */ + chThdCreateStatic(idle_thread_wa, sizeof(idle_thread_wa), IDLEPRIO, + (tfunc_t)idle_thread, NULL); +} + +/** + * @brief Handles time ticks for round robin preemption and timer increments. + * @details Decrements the remaining time quantum of the running thread + * and preempts it when the quantum is used up. Increments system + * time and manages the timers. + * + * @note The frequency of the timer determines the system tick granularity and, + * together with the @p CH_TIME_QUANTUM macro, the round robin interval. + */ +void chSysTimerHandlerI(void) { + +#if CH_USE_ROUNDROBIN + /* running thread has not used up quantum yet? */ + if (rlist.r_preempt > 0) + /* decrement remaining quantum */ + rlist.r_preempt--; +#endif +#if CH_DBG_THREADS_PROFILING + currp->p_time++; +#endif + chVTDoTickI(); +} + +#if CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED +void chSysLock(void) { + + chDbgAssert(currp->p_locks >= 0, + "chSysLock(), #1", + "negative nesting counter"); + if (currp->p_locks++ == 0) + port_lock(); +} + +void chSysUnlock(void) { + + chDbgAssert(currp->p_locks > 0, + "chSysUnlock(), #1", + "non-positive nesting counter"); + if (--currp->p_locks == 0) + port_unlock(); +} +#endif /* CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED */ + +/** @} */ diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c new file mode 100644 index 000000000..f8bb3b869 --- /dev/null +++ b/os/kernel/src/chthreads.c @@ -0,0 +1,381 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chthreads.c + * @brief Threads code. + * @addtogroup Threads + * @{ + */ + +#include + +/* + * Initializes a thread structure. + */ +Thread *init_thread(Thread *tp, tprio_t prio) { + + tp->p_flags = P_MEM_MODE_STATIC; + tp->p_prio = prio; + tp->p_state = PRSUSPENDED; +#if CH_USE_NESTED_LOCKS + tp->p_locks = 0; +#endif +#if CH_DBG_THREADS_PROFILING + tp->p_time = 0; +#endif +#if CH_USE_MUTEXES + /* realprio is the thread's own, non-inherited, priority */ + tp->p_realprio = prio; + tp->p_mtxlist = NULL; +#endif +#if CH_USE_WAITEXIT + tp->p_waiting = NULL; +#endif +#if CH_USE_MESSAGES + queue_init(&tp->p_msgqueue); +#endif +#if CH_USE_EVENTS + tp->p_epending = 0; +#endif + THREAD_EXT_INIT(tp); + return tp; +} + +#if CH_DBG_FILL_THREADS +static void memfill(uint8_t *startp, uint8_t *endp, uint8_t v) { + + while (startp < endp) + *startp++ = v; +} +#endif + +/** + * @brief Initializes a new thread. + * @details The new thread is initialized but not inserted in the ready list, + * the initial state is @p PRSUSPENDED. + * + * @param[out] wsp pointer to a working area dedicated to the thread stack + * @param[in] size size of the working area + * @param[in] prio the priority level for the new thread + * @param[in] pf the thread function + * @param[in] arg an argument passed to the thread function. It can be @p NULL. + * @return The pointer to the @p Thread structure allocated for the + * thread into the working space area. + * @note A thread can terminate by calling @p chThdExit() or by simply + * returning from its main function. + * @note This function can be invoked from within an interrupt handler even if + * it is not an I-Class API because it does not touch any critical kernel + * data structure. + */ +Thread *chThdInit(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) { + /* Thread structure is layed out in the lower part of the thread workspace */ + Thread *tp = wsp; + + chDbgCheck((wsp != NULL) && (size >= THD_WA_SIZE(0)) && + (prio <= HIGHPRIO) && (pf != NULL), + "chThdInit"); +#if CH_DBG_FILL_THREADS + memfill((uint8_t *)wsp, (uint8_t *)wsp + sizeof(Thread), THREAD_FILL_VALUE); + memfill((uint8_t *)wsp + sizeof(Thread), + (uint8_t *)wsp + size, STACK_FILL_VALUE); +#endif + SETUP_CONTEXT(wsp, size, pf, arg); + return init_thread(tp, prio); +} + +/** + * @brief Creates a new thread into a static memory area. + * + * @param[out] wsp pointer to a working area dedicated to the thread + * stack + * @param[in] size size of the working area + * @param[in] prio the priority level for the new thread + * @param[in] pf the thread function + * @param[in] arg an argument passed to the thread function. It can be @p NULL. + * @return The pointer to the @p Thread structure allocated for the + * thread into the working space area. + * @note A thread can terminate by calling @p chThdExit() or by simply + * returning from its main function. + */ +Thread *chThdCreateStatic(void *wsp, size_t size, + tprio_t prio, tfunc_t pf, void *arg) { + + return chThdResume(chThdInit(wsp, size, prio, pf, arg)); +} + +#if CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_HEAP +/** + * @brief Creates a new thread allocating the memory from the heap. + * + * @param[in] size size of the working area to be allocated + * @param[in] prio the priority level for the new thread + * @param[in] pf the thread function + * @param[in] arg an argument passed to the thread function. It can be @p NULL. + * @return The pointer to the @p Thread structure allocated for the + * thread into the working space area. + * @retval NULL if the memory cannot be allocated. + * @note A thread can terminate by calling @p chThdExit() or by simply + * returning from its main function. + * @note The memory allocated for the thread is not released when the thread + * terminates but when a @p chThdWait() is performed. + * @note The function is available only if the @p CH_USE_DYNAMIC, + * @p CH_USE_HEAP and @p CH_USE_WAITEXIT options are enabled + * in @p chconf.h. + */ +Thread *chThdCreateFromHeap(size_t size, tprio_t prio, tfunc_t pf, void *arg) { + void *wsp; + Thread *tp; + + wsp = chHeapAlloc(size); + if (wsp == NULL) + return NULL; + tp = chThdInit(wsp, size, prio, pf, arg); + tp->p_flags = P_MEM_MODE_HEAP; + return chThdResume(tp); +} +#endif /* CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_HEAP */ + +#if CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_MEMPOOLS +/** + * @brief Creates a new thread allocating the memory from the specified Memory + * Pool. + * + * @param[in] mp the memory pool + * @param[in] prio the priority level for the new thread + * @param[in] pf the thread function + * @param[in] arg an argument passed to the thread function. It can be @p NULL. + * @return The pointer to the @p Thread structure allocated for the + * thread into the working space area or @p NULL if the memory cannot + * be allocated. + * @retval NULL if the memory pool is empty. + * @note A thread can terminate by calling @p chThdExit() or by simply + * returning from its main function. + * @note The memory allocated for the thread is not released when the thread + * terminates but when a @p chThdWait() is performed. + * @note The function is available only if the @p CH_USE_DYNAMIC, + * @p CH_USE_MEMPOOLS and @p CH_USE_WAITEXIT options are enabled + * in @p chconf.h. + */ +Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, + tfunc_t pf, void *arg) { + void *wsp; + Thread *tp; + + chDbgCheck(mp != NULL, "chThdCreateFromMemoryPool"); + + wsp = chPoolAlloc(mp); + if (wsp == NULL) + return NULL; + tp = chThdInit(wsp, mp->mp_object_size, prio, pf, arg); + tp->p_flags = P_MEM_MODE_MEMPOOL; + tp->p_mpool = mp; + return chThdResume(tp); +} +#endif /* CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_MEMPOOLS */ + +/** + * @brief Changes the running thread priority level then reschedules if + * necessary. + * + * @param[in] newprio the new priority level of the running thread + * @return The old priority level. + * @note The function returns the real thread priority regardless of the + * current priority that could be higher than the real priority because + * the priority inheritance mechanism. + */ +tprio_t chThdSetPriority(tprio_t newprio) { + tprio_t oldprio; + + chDbgCheck((newprio >= LOWPRIO) && (newprio <= HIGHPRIO), + "chThdSetPriority"); + + chSysLock(); +#if CH_USE_MUTEXES + oldprio = currp->p_realprio; + if ((currp->p_prio == currp->p_realprio) || (newprio > currp->p_prio)) + currp->p_prio = newprio; + currp->p_realprio = newprio; +#else + oldprio = currp->p_prio; + currp->p_prio = newprio; +#endif + chSchRescheduleS(); + chSysUnlock(); + return oldprio; +} + +/** + * @brief Resumes a suspended thread. + * + * @param[in] tp the pointer to the thread + * @return The pointer to the thread. + * @note This call is supposed to resume threads created with @p chThdInit(). + * It should not be used on threads suspended using @p chThdSuspend(). + */ +Thread *chThdResume(Thread *tp) { + + chSysLock(); + chDbgAssert(tp->p_state == PRSUSPENDED, + "chThdResume(), #1", + "thread not in PRSUSPENDED state"); + chSchWakeupS(tp, RDY_OK); + chSysUnlock(); + return tp; +} + +/** + * @brief Requests a thread termination. + * + * @param[in] tp the pointer to the thread + * @note The thread is not termitated but a termination request is added to + * its @p p_flags field. The thread can read this status by + * invoking @p chThdShouldTerminate() and then terminate cleanly. + */ +void chThdTerminate(Thread *tp) { + + chSysLock(); + tp->p_flags |= P_TERMINATE; + chSysUnlock(); +} + +/** + * @brief Suspends the invoking thread for the specified time. + * + * @param[in] time the delay in system ticks, the special values are handled as + * follow: + * - @a TIME_INFINITE the thread enters an infinite sleep + * state. + * - @a TIME_IMMEDIATE this value is accepted but interpreted + * as a normal time specification not as an immediate timeout + * specification. + * . + */ +void chThdSleep(systime_t time) { + + chDbgCheck(time != TIME_INFINITE, "chThdSleep"); + + chSysLock(); + chThdSleepS(time); + chSysUnlock(); +} + +/** + * @brief Suspends the invoking thread until the system time arrives to the + * specified value. + * + * @param[in] time the absolute system time + */ +void chThdSleepUntil(systime_t time) { + + chSysLock(); + if ((time -= chTimeNow()) > 0) + chThdSleepS(time); + chSysUnlock(); +} + +/** + * @brief Terminates the current thread by specifying an exit status code. + * + * @param[in] msg the thread exit code. The code can be retrieved by using + * @p chThdWait(). + */ +void chThdExit(msg_t msg) { + Thread *tp = currp; + + chSysLock(); + tp->p_exitcode = msg; + THREAD_EXT_EXIT(tp); +#if CH_USE_WAITEXIT + if (tp->p_waiting != NULL) + chSchReadyI(tp->p_waiting); +#endif + chSchGoSleepS(PREXIT); +} + +#if CH_USE_WAITEXIT +/** + * @brief Blocks the execution of the invoking thread until the specified + * thread terminates then the exit code is returned. + * @details The memory used by the exited thread is handled in different ways + * depending on the API that spawned the thread: + * - If the thread was spawned by @p chThdCreateStatic() or by + * @p chThdInit() then nothing happens and the thread working area + * is not released or modified in any way. This is the default, + * totally static, behavior. + * - If the thread was spawned by @p chThdCreateFromHeap() then + * the working area is returned to the system heap. + * - If the thread was spawned by @p chThdCreateFromMemoryPool() + * then the working area is returned to the owning memory pool. + * . + * @param[in] tp the thread pointer + * @return The exit code from the terminated thread + * @note After invoking @p chThdWait() the thread pointer becomes invalid and + * must not be used as parameter for further system calls. + * @note The function is available only if the @p CH_USE_WAITEXIT + * option is enabled in @p chconf.h. + * @note Only one thread can be waiting for another thread at any time. You + * should imagine the threads as having a reference counter that is set + * to one when the thread is created, chThdWait() decreases the reference + * and the memory is freed when the counter reaches zero. In the current + * implementation there is no real reference counter in the thread + * structure but it is a planned extension. + */ +msg_t chThdWait(Thread *tp) { + msg_t msg; + + chDbgCheck(tp != NULL, "chThdWait"); + + chSysLock(); + + chDbgAssert(tp != currp, "chThdWait(), #1", "waiting self"); + chDbgAssert(tp->p_waiting == NULL, "chThdWait(), #2", "some other thread waiting"); + + if (tp->p_state != PREXIT) { + tp->p_waiting = currp; + chSchGoSleepS(PRWAIT); + } + msg = tp->p_exitcode; +#if !CH_USE_DYNAMIC + chSysUnlock(); + return msg; +#else /* CH_USE_DYNAMIC */ + + /* Returning memory.*/ + tmode_t mode = tp->p_flags & P_MEM_MODE_MASK; + chSysUnlock(); + + switch (mode) { +#if CH_USE_HEAP + case P_MEM_MODE_HEAP: + chHeapFree(tp); + break; +#endif +#if CH_USE_MEMPOOLS + case P_MEM_MODE_MEMPOOL: + chPoolFree(tp->p_mpool, tp); + break; +#endif + } + return msg; +#endif /* CH_USE_DYNAMIC */ +} +#endif /* CH_USE_WAITEXIT */ + +/** @} */ diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c new file mode 100644 index 000000000..c1d8734ec --- /dev/null +++ b/os/kernel/src/chvt.c @@ -0,0 +1,116 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chvt.c + * @brief Time and Virtual Timers related code. + * @addtogroup Time + * @{ + */ + +#include + +VTList vtlist; + +/** + * @brief Virtual Timers initialization. + * + * @note Internal use only. + */ +void vt_init(void) { + + vtlist.vt_next = vtlist.vt_prev = (void *)&vtlist; + vtlist.vt_time = (systime_t)-1; + vtlist.vt_systime = 0; +} + +/** + * @brief Enables a virtual timer. + * + * @param[out] vtp the @p VirtualTimer structure pointer + * @param[in] time the number of time ticks, the value @p TIME_INFINITE is not + * allowed. The value @p TIME_IMMEDIATE is allowed but + * interpreted as a normal time specification not as an + * immediate timeout specification. + * @param[in] vtfunc the timer callback function. After invoking the callback + * the timer is disabled and the structure can be disposed or + * reused. + * @param[in] par a parameter that will be passed to the callback function + * @note The associated function is invoked by an interrupt handler within + * the I-Locked state, see @ref system_states. + */ +void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) { + VirtualTimer *p; + + chDbgCheck((vtp != NULL) && (vtfunc != NULL) && (time != TIME_INFINITE), + "chVTSetI"); + + vtp->vt_par = par; + vtp->vt_func = vtfunc; + p = vtlist.vt_next; + while (p->vt_time < time) { + time -= p->vt_time; + p = p->vt_next; + } + + vtp->vt_prev = (vtp->vt_next = p)->vt_prev; + vtp->vt_prev->vt_next = p->vt_prev = vtp; + vtp->vt_time = time; + if (p != (void *)&vtlist) + p->vt_time -= time; +} + +/** + * @brief Disables a Virtual Timer. + * + * @param[in] vtp the @p VirtualTimer structure pointer + * @note The timer MUST be active when this function is invoked. + */ +void chVTResetI(VirtualTimer *vtp) { + + chDbgCheck(vtp != NULL, "chVTResetI"); + chDbgAssert(vtp->vt_func != NULL, + "chVTResetI(), #1", + "timer not set or already triggered"); + + if (vtp->vt_next != (void *)&vtlist) + vtp->vt_next->vt_time += vtp->vt_time; + vtp->vt_prev->vt_next = vtp->vt_next; + vtp->vt_next->vt_prev = vtp->vt_prev; + vtp->vt_func = NULL; +} + +/** + * @brief Checks if the current system time is within the specified time window. + * + * @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. + * @note When start==end then the function returns always true because the + * whole time range is specified. + */ +bool_t chTimeIsWithin(systime_t start, systime_t end) { + + systime_t time = chTimeNow(); + return end > start ? (time >= start) && (time < end) : + (time >= start) || (time < end); +} + +/** @} */ -- cgit v1.2.3 From f6b7b4d8448449097e44b13cff386fde5b292692 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 19 Aug 2009 11:59:01 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1079 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chserial.c | 168 ----------------------------------------------- 1 file changed, 168 deletions(-) delete mode 100644 os/kernel/src/chserial.c (limited to 'os/kernel/src') diff --git a/os/kernel/src/chserial.c b/os/kernel/src/chserial.c deleted file mode 100644 index 65179689d..000000000 --- a/os/kernel/src/chserial.c +++ /dev/null @@ -1,168 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT 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. - - ChibiOS/RT 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 chserial.c - * @brief Serial Drivers code. - * @addtogroup Serial - * @{ - */ - -#include - -#if CH_USE_SERIAL_FULLDUPLEX - -/* - * Interface implementation, the following functions just invoke the equivalent - * queue-level function or macro. - */ -static bool_t putwouldblock(void *instance) { - - return chOQIsFull(&((FullDuplexDriver *)instance)->d2.oqueue); -} - -static bool_t getwouldblock(void *instance) { - - return chIQIsEmpty(&((FullDuplexDriver *)instance)->d2.iqueue); -} - -static msg_t put(void *instance, uint8_t b, systime_t timeout) { - - return chOQPutTimeout(&((FullDuplexDriver *)instance)->d2.oqueue, b, timeout); -} - -static msg_t get(void *instance, systime_t timeout) { - - return chIQGetTimeout(&((FullDuplexDriver *)instance)->d2.iqueue, timeout); -} - -static size_t write(void *instance, uint8_t *buffer, size_t n) { - - return chOQWrite(&((FullDuplexDriver *)instance)->d2.oqueue, buffer, n); -} - -static size_t read(void *instance, uint8_t *buffer, size_t n) { - - return chIQRead(&((FullDuplexDriver *)instance)->d2.iqueue, buffer, n); -} - -static const struct FullDuplexDriverVMT vmt = { - {putwouldblock, getwouldblock, put, get}, - {write, read}, - {} -}; - -/** - * @brief Initializes a generic full duplex driver. - * @details The HW dependent part of the initialization has to be performed - * outside, usually in the hardware initialization code. - * - * @param[out] sd pointer to a @p FullDuplexDriver structure - * @param[in] ib pointer to a memory area allocated for the Input Queue buffer - * @param[in] isize size of the Input Queue buffer - * @param[in] inotify pointer to a callback function that is invoked when - * some data is read from the Queue. The value can be - * @p NULL. - * @param[in] ob pointer to a memory area allocated for the Output Queue buffer - * @param[in] osize size of the Output Queue buffer - * @param[in] onotify pointer to a callback function that is invoked when - * some data is written in the Queue. The value can be - * @p NULL. - */ -void chFDDInit(FullDuplexDriver *sd, - uint8_t *ib, size_t isize, qnotify_t inotify, - uint8_t *ob, size_t osize, qnotify_t onotify) { - - chDbgCheck((sd != NULL) && (ib != NULL) && (ob != NULL) && - (isize > 0) && (osize > 0), "chFDDInit"); - - sd->vmt = &vmt; - chEvtInit(&sd->d1.ievent); - chEvtInit(&sd->d1.oevent); - chEvtInit(&sd->d2.sevent); - sd->d2.flags = SD_NO_ERROR; - chIQInit(&sd->d2.iqueue, ib, isize, inotify); - chOQInit(&sd->d2.oqueue, ob, osize, onotify); -} - -/** - * @brief Handles incoming data. - * @details This function must be called from the input interrupt service - * routine in order to enqueue incoming data and generate the - * related events. - * @param[in] sd pointer to a @p FullDuplexDriver structure - * @param[in] b the byte to be written in the driver's Input Queue - */ -void chFDDIncomingDataI(FullDuplexDriver *sd, uint8_t b) { - - if (chIQPutI(&sd->d2.iqueue, b) < Q_OK) - chFDDAddFlagsI(sd, SD_OVERRUN_ERROR); - else - chEvtBroadcastI(&sd->d1.ievent); -} - -/** - * @brief Handles outgoing data. - * @details Must be called from the output interrupt service routine in order - * to get the next byte to be transmitted. - * - * @param[in] sd pointer to a @p FullDuplexDriver structure - * @return The byte value read from the driver's output queue. - * @retval Q_EMPTY if the queue is empty (the lower driver usually disables - * the interrupt source when this happens). - */ -msg_t chFDDRequestDataI(FullDuplexDriver *sd) { - - msg_t b = chOQGetI(&sd->d2.oqueue); - if (b < Q_OK) - chEvtBroadcastI(&sd->d1.oevent); - return b; -} - -/** - * @brief Handles communication events/errors. - * @details Must be called from the I/O interrupt service routine in order to - * notify I/O conditions as errors, signals change etc. - * - * @param[in] sd pointer to a @p FullDuplexDriver structure - * @param[in] mask condition flags to be added to the mask - */ -void chFDDAddFlagsI(FullDuplexDriver *sd, dflags_t mask) { - - sd->d2.flags |= mask; - chEvtBroadcastI(&sd->d2.sevent); -} - -/** - * @brief Returns and clears the errors mask associated to the driver. - * - * @param[in] sd pointer to a @p FullDuplexDriver structure - * @return The condition flags modified since last time this function was - * invoked. - */ -dflags_t chFDDGetAndClearFlags(FullDuplexDriver *sd) { - dflags_t mask; - - mask = sd->d2.flags; - sd->d2.flags = SD_NO_ERROR; - return mask; -} -#endif /* CH_USE_SERIAL_FULLDUPLEX */ - -/** @} */ -- cgit v1.2.3 From c4299aa2dac83bfe3cee1bf65bfa4ee9f84233bd Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 28 Aug 2009 11:54:36 +0000 Subject: Fixed bug 2846162. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1110 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 3ba8b29e9..846833286 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -138,18 +138,19 @@ static void wakeup(void *p) { * @retval RDY_TIMEOUT if a timeout occurs. */ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { + Thread *tp = currp; if (TIME_INFINITE != time) { VirtualTimer vt; - chVTSetI(&vt, time, wakeup, currp); + chVTSetI(&vt, time, wakeup, tp); chSchGoSleepS(newstate); if (chVTIsArmedI(&vt)) chVTResetI(&vt); } else chSchGoSleepS(newstate); - return currp->p_rdymsg; + return tp->p_rdymsg; } /** -- cgit v1.2.3 From 1ce340b59e0b68f7bf868914af3701b408bd1820 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 28 Aug 2009 14:53:54 +0000 Subject: Better fix for bug 2846162. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1112 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 846833286..3ba8b29e9 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -138,19 +138,18 @@ static void wakeup(void *p) { * @retval RDY_TIMEOUT if a timeout occurs. */ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { - Thread *tp = currp; if (TIME_INFINITE != time) { VirtualTimer vt; - chVTSetI(&vt, time, wakeup, tp); + chVTSetI(&vt, time, wakeup, currp); chSchGoSleepS(newstate); if (chVTIsArmedI(&vt)) chVTResetI(&vt); } else chSchGoSleepS(newstate); - return tp->p_rdymsg; + return currp->p_rdymsg; } /** -- cgit v1.2.3 From 219d8d1ec90984f9b00dcbad070895577172aee0 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 28 Aug 2009 16:10:40 +0000 Subject: Fixed more warnings from GCC 4.4.x. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1116 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 3ba8b29e9..76464d603 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -37,7 +37,7 @@ ReadyList rlist; */ void scheduler_init(void) { - queue_init(&rlist); + queue_init(&rlist.r_queue); rlist.r_prio = NOPRIO; #if CH_USE_ROUNDROBIN rlist.r_preempt = CH_TIME_QUANTUM; @@ -82,7 +82,7 @@ void chSchGoSleepS(tstate_t newstate) { Thread *otp; (otp = currp)->p_state = newstate; - (currp = fifo_remove((void *)&rlist))->p_state = PRCURR; + (currp = fifo_remove(&rlist.r_queue))->p_state = PRCURR; #if CH_USE_ROUNDROBIN rlist.r_preempt = CH_TIME_QUANTUM; #endif @@ -194,7 +194,7 @@ void chSchDoRescheduleI(void) { Thread *otp = currp; /* pick the first thread from the ready queue and makes it current */ - (currp = fifo_remove((void *)&rlist))->p_state = PRCURR; + (currp = fifo_remove(&rlist.r_queue))->p_state = PRCURR; chSchReadyI(otp); #if CH_USE_ROUNDROBIN rlist.r_preempt = CH_TIME_QUANTUM; @@ -211,7 +211,7 @@ void chSchDoRescheduleI(void) { void chSchRescheduleS(void) { /* first thread in the runnable queue has higher priority than the running * thread? */ - if (firstprio(&rlist) > currp->p_prio) + if (firstprio(&rlist.r_queue) > currp->p_prio) chSchDoRescheduleI(); } @@ -224,7 +224,7 @@ void chSchRescheduleS(void) { * @retval FALSE if a reschedulation is not required. */ bool_t chSchRescRequiredI(void) { - tprio_t p1 = firstprio(&rlist); + tprio_t p1 = firstprio(&rlist.r_queue); tprio_t p2 = currp->p_prio; #if CH_USE_ROUNDROBIN /* If the running thread has not reached its time quantum, reschedule only -- cgit v1.2.3 From 397ccffac55ffd139d0e3e82add83e51413c1347 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 30 Aug 2009 06:59:43 +0000 Subject: Documentation reorganization. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1133 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chcond.c | 2 +- os/kernel/src/chdebug.c | 2 +- os/kernel/src/chevents.c | 2 +- os/kernel/src/chheap.c | 2 +- os/kernel/src/chlists.c | 2 +- os/kernel/src/chmboxes.c | 2 +- os/kernel/src/chmempools.c | 2 +- os/kernel/src/chmsg.c | 2 +- os/kernel/src/chmtx.c | 2 +- os/kernel/src/chqueues.c | 2 +- os/kernel/src/chschd.c | 2 +- os/kernel/src/chsem.c | 2 +- os/kernel/src/chsys.c | 2 +- os/kernel/src/chthreads.c | 2 +- os/kernel/src/chvt.c | 2 +- 15 files changed, 15 insertions(+), 15 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c index ef58f1ddf..e991c32fc 100644 --- a/os/kernel/src/chcond.c +++ b/os/kernel/src/chcond.c @@ -24,7 +24,7 @@ /** * @file chcond.c * @brief Condition Variables code. - * @addtogroup CondVars + * @addtogroup condvars Condition Variables * @{ */ diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index 9a8120b29..f5e6bef7a 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -20,7 +20,7 @@ /** * @file chdebug.c * @brief ChibiOS/RT Debug code. - * @addtogroup Debug + * @addtogroup debug * @{ */ diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index 098adce5e..29c06d904 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -20,7 +20,7 @@ /** * @file chevents.c * @brief Events code. - * @addtogroup Events + * @addtogroup events * @{ */ #include diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c index 82b1ba785..b5ad50505 100644 --- a/os/kernel/src/chheap.c +++ b/os/kernel/src/chheap.c @@ -20,7 +20,7 @@ /** * @file chheap.c * @brief Heap code. - * @addtogroup Heap + * @addtogroup heap * @{ */ diff --git a/os/kernel/src/chlists.c b/os/kernel/src/chlists.c index a2177ca63..5c5d90869 100644 --- a/os/kernel/src/chlists.c +++ b/os/kernel/src/chlists.c @@ -20,7 +20,7 @@ /** * @file chlists.c * @brief Thread queues/lists code. - * @addtogroup ThreadLists + * @addtogroup internals * @{ */ #include diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c index 8a791a984..569422ca7 100644 --- a/os/kernel/src/chmboxes.c +++ b/os/kernel/src/chmboxes.c @@ -20,7 +20,7 @@ /** * @file chmboxes.c * @brief Mailboxes code. - * @addtogroup Mailboxes + * @addtogroup mailboxes * @{ */ diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c index dd6f3d1ba..a8d7da818 100644 --- a/os/kernel/src/chmempools.c +++ b/os/kernel/src/chmempools.c @@ -20,7 +20,7 @@ /** * @file chmempools.c * @brief Memory Pools code. - * @addtogroup MemoryPools + * @addtogroup pools * @{ */ diff --git a/os/kernel/src/chmsg.c b/os/kernel/src/chmsg.c index 393ab8dad..6f1be5c47 100644 --- a/os/kernel/src/chmsg.c +++ b/os/kernel/src/chmsg.c @@ -20,7 +20,7 @@ /** * @file chmsg.c * @brief Messages code. - * @addtogroup Messages + * @addtogroup messages * @{ */ diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 5fcb6fd5e..cc3c91e3e 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -20,7 +20,7 @@ /** * @file chmtx.c * @brief Mutexes code. - * @addtogroup Mutexes + * @addtogroup mutexes * @{ */ diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index a72b83696..0f78a0975 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -20,7 +20,7 @@ /** * @file chqueues.c * @brief I/O Queues code. - * @addtogroup IOQueues + * @addtogroup io_queues * @{ */ diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 76464d603..af24f5cf4 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -20,7 +20,7 @@ /** * @file chschd.c * @brief Scheduler code. - * @addtogroup Scheduler + * @addtogroup scheduler * @{ */ diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index 9a8570580..4b35f479c 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -20,7 +20,7 @@ /** * @file chsem.c * @brief Semaphores code. - * @addtogroup Semaphores + * @addtogroup semaphores * @{ */ diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 217e2f2da..8ee7375f8 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -20,7 +20,7 @@ /** * @file chsys.c * @brief System related code. - * @addtogroup System + * @addtogroup system * @{ */ diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index f8bb3b869..583bc7c04 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -20,7 +20,7 @@ /** * @file chthreads.c * @brief Threads code. - * @addtogroup Threads + * @addtogroup threads * @{ */ diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c index c1d8734ec..b3cee0ce3 100644 --- a/os/kernel/src/chvt.c +++ b/os/kernel/src/chvt.c @@ -20,7 +20,7 @@ /** * @file chvt.c * @brief Time and Virtual Timers related code. - * @addtogroup Time + * @addtogroup time * @{ */ -- cgit v1.2.3 From 7dfa36f86d896cdb824a9137a81f324c8243c4d9 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 5 Sep 2009 15:31:27 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1148 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 2 +- os/kernel/src/chthreads.c | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index af24f5cf4..6183180bc 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -211,7 +211,7 @@ void chSchDoRescheduleI(void) { void chSchRescheduleS(void) { /* first thread in the runnable queue has higher priority than the running * thread? */ - if (firstprio(&rlist.r_queue) > currp->p_prio) + if (chSchMustRescheduleS()) chSchDoRescheduleI(); } diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 583bc7c04..c18a4f8cd 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -290,6 +290,21 @@ void chThdSleepUntil(systime_t time) { chSysUnlock(); } +#if CH_USE_ROUNDROBIN +/** + * @brief Yields the time slot. + * @details Yields the CPU control to the next thread in the ready list with + * equal priority, if any. + */ +void chThdYield(void) { + + chSysLock(); + if (chSchCanYieldS()) + chSchDoRescheduleI(); + chSysUnlock(); +} +#endif /* CH_USE_ROUNDROBIN */ + /** * @brief Terminates the current thread by specifying an exit status code. * -- cgit v1.2.3 From 5d2ad7ce56f9efaba58104c60690a0d076236004 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 6 Sep 2009 08:52:46 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1151 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 55 ++++++++++++++++++++++++++++++++++++++++++----- os/kernel/src/chthreads.c | 3 +-- 2 files changed, 51 insertions(+), 7 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 6183180bc..929f114e5 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -61,7 +61,7 @@ Thread *chSchReadyI(Thread *tp) { Thread *cp; tp->p_state = PRREADY; - cp = (Thread *)&rlist; + cp = (Thread *)&rlist.r_queue; do { cp = cp->p_next; } while (cp->p_prio >= tp->p_prio); @@ -71,6 +71,22 @@ Thread *chSchReadyI(Thread *tp) { return tp; } +#if 0 +INLINE Thread *chSchReadyReverseI(Thread *tp) { + Thread *cp; + + tp->p_state = PRREADY; + cp = (Thread *)&rlist.r_queue; + do { + cp = cp->p_prev; + } while ((cp->p_prio < tp->p_prio) && (cp->p_prio < tp->p_prio)); + /* Insertion on p_next.*/ + tp->p_next = (tp->p_prev = cp)->p_next; + tp->p_next->p_prev = cp->p_next = tp; + return tp; +} +#endif + /** * @brief Puts the current thread to sleep into the specified state. * @details The thread goes into a sleeping state. The @ref thread_states are @@ -109,7 +125,7 @@ static void wakeup(void *p) { #if CH_USE_CONDVARS case PRWTCOND: #endif - /* States requiring dequeuing. */ + /* States requiring dequeuing.*/ dequeue(tp); } #endif @@ -193,7 +209,7 @@ void chSchWakeupS(Thread *ntp, msg_t msg) { void chSchDoRescheduleI(void) { Thread *otp = currp; - /* pick the first thread from the ready queue and makes it current */ + /* Pick the first thread from the ready queue and makes it current.*/ (currp = fifo_remove(&rlist.r_queue))->p_state = PRCURR; chSchReadyI(otp); #if CH_USE_ROUNDROBIN @@ -209,8 +225,8 @@ void chSchDoRescheduleI(void) { * the ready list then make the higher priority thread running. */ void chSchRescheduleS(void) { - /* first thread in the runnable queue has higher priority than the running - * thread? */ + /* First thread in the runnable queue has higher priority than the running + * thread?.*/ if (chSchMustRescheduleS()) chSchDoRescheduleI(); } @@ -239,4 +255,33 @@ bool_t chSchRescRequiredI(void) { #endif } +#if CH_USE_ROUNDROBIN +void chSchDoYieldS(void) { + + if (chSchCanYieldS()) { + Thread *cp = (Thread *)&rlist.r_queue; + Thread *otp = currp; + + /* + * Note, the following insertion code works because we know that on the + * ready list there is at least one thread with priority equal or higher + * than the current one. + */ + otp->p_state = PRREADY; + do { + cp = cp->p_prev; + } while (cp->p_prio < otp->p_prio); + /* Insertion on p_next.*/ + otp->p_next = (otp->p_prev = cp)->p_next; + otp->p_next->p_prev = cp->p_next = otp; + + /* Pick the first thread from the ready queue and makes it current.*/ + (currp = fifo_remove(&rlist.r_queue))->p_state = PRCURR; + rlist.r_preempt = CH_TIME_QUANTUM; + chDbgTrace(otp, currp); + chSysSwitchI(otp, currp); + } +} +#endif /* CH_USE_ROUNDROBIN */ + /** @} */ diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index c18a4f8cd..a3028867a 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -299,8 +299,7 @@ void chThdSleepUntil(systime_t time) { void chThdYield(void) { chSysLock(); - if (chSchCanYieldS()) - chSchDoRescheduleI(); + chSchDoYieldS(); chSysUnlock(); } #endif /* CH_USE_ROUNDROBIN */ -- cgit v1.2.3 From 7f7253bec22642ead836cb47fbca3caba57042a8 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 6 Sep 2009 09:53:29 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1152 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 16 ---------------- 1 file changed, 16 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 929f114e5..7ab32f068 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -71,22 +71,6 @@ Thread *chSchReadyI(Thread *tp) { return tp; } -#if 0 -INLINE Thread *chSchReadyReverseI(Thread *tp) { - Thread *cp; - - tp->p_state = PRREADY; - cp = (Thread *)&rlist.r_queue; - do { - cp = cp->p_prev; - } while ((cp->p_prio < tp->p_prio) && (cp->p_prio < tp->p_prio)); - /* Insertion on p_next.*/ - tp->p_next = (tp->p_prev = cp)->p_next; - tp->p_next->p_prev = cp->p_next = tp; - return tp; -} -#endif - /** * @brief Puts the current thread to sleep into the specified state. * @details The thread goes into a sleeping state. The @ref thread_states are -- cgit v1.2.3 From 1f2dd43b3ebca18d849527e1be6f93d473298677 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 6 Sep 2009 16:50:07 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1155 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 37 +++++++++++++++++-------------------- os/kernel/src/chschd.c | 10 +++++++++- 2 files changed, 26 insertions(+), 21 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index cc3c91e3e..9e568c782 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -69,7 +69,7 @@ void chMtxLockS(Mutex *mp) { chDbgCheck(mp != NULL, "chMtxLockS"); - /* the mutex is already locked? */ + /* Ia the mutex already locked? */ if (mp->m_owner != NULL) { /* * Priority inheritance protocol; explores the thread-mutex dependencies @@ -77,50 +77,47 @@ void chMtxLockS(Mutex *mp) { * of the running thread requesting the mutex. */ Thread *tp = mp->m_owner; - /* { tp is the thread currently owning the mutex } */ - /* the running thread has higher priority than tp? */ + /* {tp is the thread currently owning the mutex} */ + /* Has the running thread higher priority than tp? */ while (tp->p_prio < currp->p_prio) { - /* make priority of thread tp match the running thread's priority */ + /* Make priority of thread tp match the running thread's priority.*/ tp->p_prio = currp->p_prio; /* * The following states need priority queues reordering. */ switch (tp->p_state) { - /* thread tp is waiting on a mutex? */ case PRWTMTX: - /* Requeues tp with its new priority on the mutex wait queue. */ + /* Re-enqueues tp with its new priority on the mutex wait queue.*/ prio_insert(dequeue(tp), &tp->p_wtmtxp->m_queue); - /* boost the owner of this mutex if needed */ + /* Boost the owner of this mutex if needed.*/ tp = tp->p_wtmtxp->m_owner; continue; #if CH_USE_CONDVARS case PRWTCOND: - /* Requeues tp with its new priority on the condvar queue. */ + /* Re-enqueues tp with its new priority on the condvar queue.*/ prio_insert(dequeue(tp), &tp->p_wtcondp->c_queue); break; #endif #if CH_USE_SEMAPHORES_PRIORITY case PRWTSEM: - /* Requeues tp with its new priority on the semaphore queue. */ + /* Re-enqueues tp with its new priority on the semaphore queue.*/ prio_insert(dequeue(tp), &tp->p_wtsemp->s_queue); break; #endif #if CH_USE_MESSAGES_PRIORITY case PRSNDMSG: - /* Requeues tp with its new priority on the server thread queue. */ + /* Re-enqueues tp with its new priority on the server thread queue.*/ prio_insert(dequeue(tp), &tp->p_wtthdp->p_msgqueue); break; #endif - /* thread tp is ready? */ case PRREADY: - /* Requeue tp with its new priority on the ready list. */ + /* Re-enqueues tp with its new priority on the ready list.*/ chSchReadyI(dequeue(tp)); } break; } - /* sleep on the mutex */ + /* Sleep on the mutex.*/ prio_insert(currp, &mp->m_queue); - /* thread remembers the mutex where it is waiting on */ currp->p_wtmtxp = mp; chSchGoSleepS(PRWTMTX); chDbgAssert(mp->m_owner == NULL, "chMtxLockS(), #1", "still owned"); @@ -201,24 +198,24 @@ Mutex *chMtxUnlock(void) { * If a thread is waiting on the mutex then the hard part begins. */ if (chMtxQueueNotEmptyS(ump)) { - /* get the highest priority thread waiting for the unlocked mutex */ + /* Get the highest priority thread waiting for the unlocked mutex.*/ Thread *tp = fifo_remove(&ump->m_queue); /* * Recalculates the optimal thread priority by scanning the owned mutexes list. */ tprio_t newprio = currp->p_realprio; - /* iterate mp over all the (other) mutexes the current thread still owns */ + /* Iterate mp over all the (other) mutexes the current thread still owns.*/ mp = currp->p_mtxlist; while (mp != NULL) { - /* mutex mp has a higher priority thread pending? */ + /* Has the mutex mp a higher priority thread pending? */ if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio)) - /* boost current thread's priority to waiting thread */ + /* Boost the recalculated thread's priority to waiting thread.*/ newprio = mp->m_queue.p_next->p_prio; mp = mp->m_next; } - /* (possibly) boost the priority of the current thread */ + /* Possibly restores the priority of the current thread.*/ currp->p_prio = newprio; - /* awaken the highest priority thread waiting for the unlocked mutex */ + /* Awaken the highest priority thread waiting for the unlocked mutex.*/ chSchWakeupS(tp, RDY_OK); } chSysUnlock(); diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 7ab32f068..093a1a0c0 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -162,6 +162,7 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { * @param[in] msg message to the awakened thread * @note It is equivalent to a @p chSchReadyI() followed by a * @p chSchRescheduleS() but much more efficient. + * @note The function assumes that the current thread has the highest priority */ void chSchWakeupS(Thread *ntp, msg_t msg) { @@ -175,10 +176,17 @@ void chSchWakeupS(Thread *ntp, msg_t msg) { else { Thread *otp = currp; chSchReadyI(otp); - (currp = ntp)->p_state = PRCURR; #if CH_USE_ROUNDROBIN rlist.r_preempt = CH_TIME_QUANTUM; #endif +#if 0 + /* Shortcut for when the round robin scheduling is not enabled.*/ + otp->p_state = PRREADY; + /* Direct insertion on top of the ready list, no scanning.*/ + otp->p_next = rlist.r_queue.p_next->p_next; + otp->p_next->p_prev = rlist.r_queue.p_next = otp; +#endif + (currp = ntp)->p_state = PRCURR; chDbgTrace(otp, ntp); chSysSwitchI(otp, ntp); } -- cgit v1.2.3 From af8d2e36166b5c13f795c361752c6c6988947d11 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 6 Sep 2009 17:54:12 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1156 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 7 ------- 1 file changed, 7 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 093a1a0c0..1f7e27c93 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -178,13 +178,6 @@ void chSchWakeupS(Thread *ntp, msg_t msg) { chSchReadyI(otp); #if CH_USE_ROUNDROBIN rlist.r_preempt = CH_TIME_QUANTUM; -#endif -#if 0 - /* Shortcut for when the round robin scheduling is not enabled.*/ - otp->p_state = PRREADY; - /* Direct insertion on top of the ready list, no scanning.*/ - otp->p_next = rlist.r_queue.p_next->p_next; - otp->p_next->p_prev = rlist.r_queue.p_next = otp; #endif (currp = ntp)->p_state = PRCURR; chDbgTrace(otp, ntp); -- cgit v1.2.3 From c5496788e53c99371c2f4a36c67dcbf556176398 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 13 Sep 2009 09:38:59 +0000 Subject: Cortex-M3 related improvements. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1161 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 1f7e27c93..08ecf46a0 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -210,8 +210,7 @@ void chSchDoRescheduleI(void) { * the ready list then make the higher priority thread running. */ void chSchRescheduleS(void) { - /* First thread in the runnable queue has higher priority than the running - * thread?.*/ + if (chSchMustRescheduleS()) chSchDoRescheduleI(); } -- cgit v1.2.3 From d688b84d2585d3bedbd682417313bcb581b1a1fc Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 13 Sep 2009 12:06:08 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1162 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 08ecf46a0..7c65e3fd6 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -211,7 +211,7 @@ void chSchDoRescheduleI(void) { */ void chSchRescheduleS(void) { - if (chSchMustRescheduleS()) + if (chSchIsRescRequiredI()) chSchDoRescheduleI(); } @@ -222,8 +222,11 @@ void chSchRescheduleS(void) { * * @retval TRUE if there is a thread that should go in running state. * @retval FALSE if a reschedulation is not required. + * + * @note This function is meant to be used in the timer interrupt handler + * where @p chVTDoTickI() is invoked. */ -bool_t chSchRescRequiredI(void) { +bool_t chSchIsRescRequiredExI(void) { tprio_t p1 = firstprio(&rlist.r_queue); tprio_t p2 = currp->p_prio; #if CH_USE_ROUNDROBIN -- cgit v1.2.3 From 85786fabbfd94e480ff43a8979f074c1fd6292e1 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 11 Oct 2009 19:43:13 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1218 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmem.c | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 os/kernel/src/chmem.c (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmem.c b/os/kernel/src/chmem.c new file mode 100644 index 000000000..3ac45a6ae --- /dev/null +++ b/os/kernel/src/chmem.c @@ -0,0 +1,94 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chmem.c + * @brief Low level memory manager code. + * @addtogroup coremem + * @{ + */ + +#include + +#if CH_USE_COREMEM + +#if CH_COREMEM_SIZE == 0 + extern align_t __heap_base__; + extern align_t __heap_end__; +#else +align_t buffer[ALIGN_SIZE(CH_MEM_SIZE) / sizeof(align_t)]; +#endif + +static align_t *nextmem; +static align_t *endmem; + +void mem_init(void) { +#if CH_COREMEM_SIZE == 0 + nextmem = &__heap_base__; + endmem = &__heap_end__; +#else + nextmem = &buffer[0]; + endmem = &buffer[ALIGN_SIZE(CH_MEM_SIZE) / sizeof(align_t)]; +#endif +} + +/** + * @brief Allocates a block of memory. + * @details The size of the returned block is aligned to the alignment + * type @p align_t so it is not possible to allocate less than + * sizeof(align_t). + * + * + * @param[in] the size of the block to be allocated + * @return A pointer to the allocated memory block. + * @retval NULL allocation failed, core memory exhausted. + */ +void *chCoreAlloc(size_t size) { + void *p; + + chSysLock(); + p = chCoreAllocI(size); + chSysUnlock(); + return p; +} + +/** + * @brief Allocates a block of memory. + * @details The size of the returned block is aligned to the alignment + * type @p align_t so it is not possible to allocate less than + * sizeof(align_t). + * + * @param[in] the size of the block to be allocated. + * @return A pointer to the allocated memory block. + * @retval NULL allocation failed, core memory exhausted. + */ +void *chCoreAllocI(size_t size) { + void *p; + + size = ALIGN_SIZE(size); + if (nextmem + size > endmem) + return NULL; + p = nextmem; + nextmem += size; + return p; +} + +#endif /* CH_USE_COREMEM */ + +/** @} */ -- cgit v1.2.3 From 2c46df1916a25b7880416aee974a518cc607717a Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 16 Oct 2009 17:45:19 +0000 Subject: New heap manager. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1221 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chheap.c | 222 ++++++++++++++++++++++++++-------------------- os/kernel/src/chmem.c | 94 -------------------- os/kernel/src/chmemcore.c | 99 +++++++++++++++++++++ os/kernel/src/chsys.c | 3 + os/kernel/src/chthreads.c | 7 +- 5 files changed, 234 insertions(+), 191 deletions(-) delete mode 100644 os/kernel/src/chmem.c create mode 100644 os/kernel/src/chmemcore.c (limited to 'os/kernel/src') diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c index b5ad50505..e7a975f3d 100644 --- a/os/kernel/src/chheap.c +++ b/os/kernel/src/chheap.c @@ -28,41 +28,23 @@ #if CH_USE_HEAP -#if !CH_USE_MALLOC_HEAP - -#define MAGIC 0xF5A0 -#define ALIGN_TYPE void * -#define ALIGN_MASK (sizeof(ALIGN_TYPE) - 1) -#define ALIGN_SIZE(p) (((size_t)(p) + ALIGN_MASK) & ~ALIGN_MASK) - -struct header { - union { - struct header *h_next; - size_t h_magic; - }; - size_t h_size; -}; - -static struct { - struct header free; /* Guaranteed to be not adjacent to the heap */ +/* + * Defaults on the best synchronization mechanism available. + */ #if CH_USE_MUTEXES -#define H_LOCK() chMtxLock(&heap.hmtx) -#define H_UNLOCK() chMtxUnlock() - Mutex hmtx; -#elif CH_USE_SEMAPHORES -#define H_LOCK() chSemWait(&heap.hsem) -#define H_UNLOCK() chSemSignal(&heap.hsem) - Semaphore hsem; +#define H_LOCK(h) chMtxLock(&(h)->h_mtx) +#define H_UNLOCK(h) chMtxUnlock() #else -#error "The heap allocator requires mutexes or semaphores to be enabled" +#define H_LOCK(h) chSemWait(&(h)->h_sem) +#define H_UNLOCK(h) chSemSignal(&(h)->h_sem) #endif -#if CH_HEAP_SIZE > 0 - union { - ALIGN_TYPE alignment; - char buffer[ALIGN_SIZE(CH_HEAP_SIZE)]; - }; -#endif -} heap; + +#if !CH_USE_MALLOC_HEAP + +/** + * @brief Default heap descriptor. + */ +static MemoryHeap default_heap; /** * @brief Initializes the allocator subsystem. @@ -70,26 +52,40 @@ static struct { * @note Internal use only. */ void heap_init(void) { - struct header *hp; - -#if CH_HEAP_SIZE == 0 - extern char __heap_base__; - extern char __heap_end__; - - hp = (void *)&__heap_base__; - hp->h_size = &__heap_end__ - &__heap_base__ - sizeof(struct header); + default_heap.h_provider = chCoreAlloc; + default_heap.h_free.h_next = NULL; + default_heap.h_free.h_size = 0; +#if CH_USE_MUTEXES + chMtxInit(&default_heap.h_mtx); #else - hp = (void *)&heap.buffer[0]; - hp->h_size = (&heap.buffer[ALIGN_SIZE(CH_HEAP_SIZE)] - &heap.buffer[0]) - - sizeof(struct header); + chSemInit(&default_heap.h_sem, 1); #endif +} + +/** + * @brief Initializes a memory heap. + * + * @param[out] heapp pointer to a memory heap descriptor to be initialized + * @param[in] buf heap buffer base + * @param[in] size heap size + * + * @note Both the heap buffer base and the heap size must be aligned to + * the @p align_t type size. + */ +void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) { + struct heap_header *hp; + + chDbgCheck(MEM_IS_ALIGNED(buf) && MEM_IS_ALIGNED(size), "chHeapInit"); + + heapp->h_provider = NULL; + heapp->h_free.h_next = hp = buf; + heapp->h_free.h_size = 0; hp->h_next = NULL; - heap.free.h_next = hp; - heap.free.h_size = 0; + hp->h_size = size - sizeof(struct heap_header); #if CH_USE_MUTEXES - chMtxInit(&heap.hmtx); + chMtxInit(&heapp->h_mtx); #else - chSemInit(&heap.hsem, 1); + chSemInit(&heapp->h_sem, 1); #endif } @@ -97,53 +93,75 @@ void heap_init(void) { * @brief Allocates a block of memory from the heap by using the first-fit * algorithm. * @details The allocated block is guaranteed to be properly aligned for a - * pointer data type. + * pointer data type (@p align_t). * + * @param[in] heapp pointer to a heap descriptor or @p NULL in order to access + * the default heap. * @param[in] size the size of the block to be allocated. Note that the * allocated block may be a bit bigger than the requested * size for alignment and fragmentation reasons. * @return A pointer to the allocated block. * @retval NULL if the block cannot be allocated. */ -void *chHeapAlloc(size_t size) { - struct header *qp, *hp, *fp; +void *chHeapAlloc(MemoryHeap *heapp, size_t size) { + struct heap_header *qp, *hp, *fp; - size = ALIGN_SIZE(size); - qp = &heap.free; - H_LOCK(); + if (heapp == NULL) + heapp = &default_heap; + + size = MEM_ALIGN_SIZE(size); + qp = &heapp->h_free; + H_LOCK(heapp); while (qp->h_next != NULL) { hp = qp->h_next; if (hp->h_size >= size) { - if (hp->h_size < size + sizeof(struct header)) { - /* Gets the whole block even if it is slightly bigger than the - requested size because the fragment would be too small to be - useful */ + if (hp->h_size < size + sizeof(struct heap_header)) { + /* + * Gets the whole block even if it is slightly bigger than the + * requested size because the fragment would be too small to be + * useful. + */ qp->h_next = hp->h_next; } else { - /* Block bigger enough, must split it */ - fp = (void *)((char *)(hp) + sizeof(struct header) + size); + /* + * Block bigger enough, must split it. + */ + fp = (void *)((uint8_t *)(hp) + sizeof(struct heap_header) + size); fp->h_next = hp->h_next; - fp->h_size = hp->h_size - sizeof(struct header) - size; + fp->h_size = hp->h_size - sizeof(struct heap_header) - size; qp->h_next = fp; hp->h_size = size; } - hp->h_magic = MAGIC; + hp->h_heap = heapp; - H_UNLOCK(); + H_UNLOCK(heapp); return (void *)(hp + 1); } qp = hp; } - H_UNLOCK(); + H_UNLOCK(heapp); + + /* + * More memory is required, tries to get it from the associated provider. + */ + if (heapp->h_provider) { + hp = heapp->h_provider(size + sizeof(struct heap_header)); + if (hp != NULL) { + hp->h_heap = heapp; + hp->h_size = size; + hp++; + return (void *)hp; + } + } return NULL; } -#define LIMIT(p) (struct header *)((char *)(p) + \ - sizeof(struct header) + \ - (p)->h_size) +#define LIMIT(p) (struct heap_header *)((uint8_t *)(p) + \ + sizeof(struct heap_header) + \ + (p)->h_size) /** * @brief Frees a previously allocated memory block. @@ -151,50 +169,59 @@ void *chHeapAlloc(size_t size) { * @param[in] p the memory block pointer */ void chHeapFree(void *p) { - struct header *qp, *hp; + struct heap_header *qp, *hp; + MemoryHeap *heapp; chDbgCheck(p != NULL, "chHeapFree"); - hp = (struct header *)p - 1; - chDbgAssert(hp->h_magic == MAGIC, - "chHeapFree(), #1", - "it is not magic"); - qp = &heap.free; - H_LOCK(); + hp = (struct heap_header *)p - 1; + heapp = hp->h_heap; + qp = &heapp->h_free; + H_LOCK(heapp); while (TRUE) { - chDbgAssert((hp < qp) || (hp >= LIMIT(qp)), - "chHeapFree(), #2", + "chHeapFree(), #1", "within free block"); - if (((qp == &heap.free) || (hp > qp)) && + if (((qp == &heapp->h_free) || (hp > qp)) && ((qp->h_next == NULL) || (hp < qp->h_next))) { - /* Insertion after qp */ + /* + * Insertion after qp. + */ hp->h_next = qp->h_next; qp->h_next = hp; - /* Verifies if the newly inserted block should be merged */ + /* + * Verifies if the newly inserted block should be merged. + */ if (LIMIT(hp) == hp->h_next) { - /* Merge with the next block */ - hp->h_size += hp->h_next->h_size + sizeof(struct header); + /* + * Merge with the next block. + */ + hp->h_size += hp->h_next->h_size + sizeof(struct heap_header); hp->h_next = hp->h_next->h_next; } - if ((LIMIT(qp) == hp)) { /* Cannot happen when qp == &heap.free */ - /* Merge with the previous block */ - qp->h_size += hp->h_size + sizeof(struct header); + if ((LIMIT(qp) == hp)) { + /* + * Merge with the previous block. + */ + qp->h_size += hp->h_size + sizeof(struct heap_header); qp->h_next = hp->h_next; } - - H_UNLOCK(); - return; + break; } qp = qp->h_next; } + + H_UNLOCK(heapp); + return; } /** * @brief Reports the heap status. * + * @param[in] heapp pointer to a heap descriptor or @p NULL in order to access + * the default heap. * @param[in] sizep pointer to a variable that will receive the total * fragmented free space * @return The number of fragments in the heap. @@ -203,19 +230,22 @@ void chHeapFree(void *p) { * @note This function is not implemented when the @p CH_USE_MALLOC_HEAP * configuration option is used (it always returns zero). */ -size_t chHeapStatus(size_t *sizep) { - struct header *qp; +size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep) { + struct heap_header *qp; size_t n, sz; - H_LOCK(); + if (heapp == NULL) + heapp = &default_heap; + + H_LOCK(heapp); sz = 0; - for (n = 0, qp = &heap.free; qp->h_next; n++, qp = qp->h_next) + for (n = 0, qp = &heapp->h_free; qp->h_next; n++, qp = qp->h_next) sz += qp->h_next->h_size; if (sizep) *sizep = sz; - H_UNLOCK(); + H_UNLOCK(heapp); return n; } @@ -231,8 +261,6 @@ static Mutex hmtx; #define H_LOCK() chSemWait(&hsem) #define H_UNLOCK() chSemSignal(&hsem) static Semaphore hsem; -#else -#error "The heap allocator requires mutexes or semaphores to be enabled" #endif void heap_init(void) { @@ -244,9 +272,11 @@ void heap_init(void) { #endif } -void *chHeapAlloc(size_t size) { +void *chHeapAlloc(MemoryHeap *heapp, size_t size) { void *p; + chDbgCheck(heapp == NULL, "chHeapAlloc"); + H_LOCK(); p = malloc(size); H_UNLOCK(); @@ -262,7 +292,9 @@ void chHeapFree(void *p) { H_UNLOCK(); } -size_t chHeapStatus(size_t *sizep) { +size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep) { + + chDbgCheck(heapp == NULL, "chHeapStatus"); if (sizep) *sizep = 0; diff --git a/os/kernel/src/chmem.c b/os/kernel/src/chmem.c deleted file mode 100644 index 3ac45a6ae..000000000 --- a/os/kernel/src/chmem.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT 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. - - ChibiOS/RT 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 chmem.c - * @brief Low level memory manager code. - * @addtogroup coremem - * @{ - */ - -#include - -#if CH_USE_COREMEM - -#if CH_COREMEM_SIZE == 0 - extern align_t __heap_base__; - extern align_t __heap_end__; -#else -align_t buffer[ALIGN_SIZE(CH_MEM_SIZE) / sizeof(align_t)]; -#endif - -static align_t *nextmem; -static align_t *endmem; - -void mem_init(void) { -#if CH_COREMEM_SIZE == 0 - nextmem = &__heap_base__; - endmem = &__heap_end__; -#else - nextmem = &buffer[0]; - endmem = &buffer[ALIGN_SIZE(CH_MEM_SIZE) / sizeof(align_t)]; -#endif -} - -/** - * @brief Allocates a block of memory. - * @details The size of the returned block is aligned to the alignment - * type @p align_t so it is not possible to allocate less than - * sizeof(align_t). - * - * - * @param[in] the size of the block to be allocated - * @return A pointer to the allocated memory block. - * @retval NULL allocation failed, core memory exhausted. - */ -void *chCoreAlloc(size_t size) { - void *p; - - chSysLock(); - p = chCoreAllocI(size); - chSysUnlock(); - return p; -} - -/** - * @brief Allocates a block of memory. - * @details The size of the returned block is aligned to the alignment - * type @p align_t so it is not possible to allocate less than - * sizeof(align_t). - * - * @param[in] the size of the block to be allocated. - * @return A pointer to the allocated memory block. - * @retval NULL allocation failed, core memory exhausted. - */ -void *chCoreAllocI(size_t size) { - void *p; - - size = ALIGN_SIZE(size); - if (nextmem + size > endmem) - return NULL; - p = nextmem; - nextmem += size; - return p; -} - -#endif /* CH_USE_COREMEM */ - -/** @} */ diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c new file mode 100644 index 000000000..87ef6037a --- /dev/null +++ b/os/kernel/src/chmemcore.c @@ -0,0 +1,99 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chmemcore.c + * @brief Core memory manager code. + * @addtogroup memcore + * @{ + */ + +#include + +#if CH_USE_MEMCORE + +#if CH_MEMCORE_SIZE == 0 + extern align_t __heap_base__; + extern align_t __heap_end__; +#else +align_t buffer[ALIGN_SIZE(CH_MEMCORE_SIZE) / sizeof(align_t)]; +#endif + +static align_t *nextmem; +static align_t *endmem; + +/** + * @brief Low level memory manager initialization. + * + * @note Internal use only. + */ +void core_init(void) { +#if CH_MEMCORE_SIZE == 0 + nextmem = &__heap_base__; + endmem = &__heap_end__; +#else + nextmem = &buffer[0]; + endmem = &buffer[ALIGN_SIZE(CH_MEMCORE_SIZE) / sizeof(align_t)]; +#endif +} + +/** + * @brief Allocates a block of memory. + * @details The size of the returned block is aligned to the alignment + * type @p align_t so it is not possible to allocate less than + * sizeof(align_t). + * + * + * @param[in] the size of the block to be allocated + * @return A pointer to the allocated memory block. + * @retval NULL allocation failed, core memory exhausted. + */ +void *chCoreAlloc(size_t size) { + void *p; + + chSysLock(); + p = chCoreAllocI(size); + chSysUnlock(); + return p; +} + +/** + * @brief Allocates a block of memory. + * @details The size of the returned block is aligned to the alignment + * type @p align_t so it is not possible to allocate less than + * sizeof(align_t). + * + * @param[in] the size of the block to be allocated. + * @return A pointer to the allocated memory block. + * @retval NULL allocation failed, core memory exhausted. + */ +void *chCoreAllocI(size_t size) { + void *p; + + size = MEM_ALIGN_SIZE(size); + if (nextmem + size > endmem) + return NULL; + p = nextmem; + nextmem += size; + return p; +} + +#endif /* CH_USE_MEMCORE */ + +/** @} */ diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 8ee7375f8..7d42eb644 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -61,6 +61,9 @@ void chSysInit(void) { port_init(); scheduler_init(); vt_init(); +#if CH_USE_MEMCORE + core_init(); +#endif #if CH_USE_HEAP heap_init(); #endif diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index a3028867a..89d1d6329 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -124,6 +124,8 @@ Thread *chThdCreateStatic(void *wsp, size_t size, /** * @brief Creates a new thread allocating the memory from the heap. * + * @param[in] heapp heap from which allocate the memory or NULL for the + * default heap * @param[in] size size of the working area to be allocated * @param[in] prio the priority level for the new thread * @param[in] pf the thread function @@ -139,11 +141,12 @@ Thread *chThdCreateStatic(void *wsp, size_t size, * @p CH_USE_HEAP and @p CH_USE_WAITEXIT options are enabled * in @p chconf.h. */ -Thread *chThdCreateFromHeap(size_t size, tprio_t prio, tfunc_t pf, void *arg) { +Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size, + tprio_t prio, tfunc_t pf, void *arg) { void *wsp; Thread *tp; - wsp = chHeapAlloc(size); + wsp = chHeapAlloc(heapp, size); if (wsp == NULL) return NULL; tp = chThdInit(wsp, size, prio, pf, arg); -- cgit v1.2.3 From d61cb88dab424a8edcf3b2a06a0c7ea18890208a Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 17 Oct 2009 07:35:31 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1224 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmemcore.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index 87ef6037a..4efc63e52 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -32,7 +32,7 @@ extern align_t __heap_base__; extern align_t __heap_end__; #else -align_t buffer[ALIGN_SIZE(CH_MEMCORE_SIZE) / sizeof(align_t)]; +align_t buffer[MEM_ALIGN_SIZE(CH_MEMCORE_SIZE) / sizeof(align_t)]; #endif static align_t *nextmem; @@ -49,7 +49,7 @@ void core_init(void) { endmem = &__heap_end__; #else nextmem = &buffer[0]; - endmem = &buffer[ALIGN_SIZE(CH_MEMCORE_SIZE) / sizeof(align_t)]; + endmem = &buffer[MEM_ALIGN_SIZE(CH_MEMCORE_SIZE) / sizeof(align_t)]; #endif } -- cgit v1.2.3 From a7cfbdaf10a03aa10236958bdba38479b301fc4f Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 17 Oct 2009 08:05:52 +0000 Subject: Coverage for the new modules. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1225 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmemcore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index 4efc63e52..00e04a2d6 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -87,7 +87,7 @@ void *chCoreAllocI(size_t size) { void *p; size = MEM_ALIGN_SIZE(size); - if (nextmem + size > endmem) + if ((size_t)((uint8_t *)endmem - (uint8_t *)nextmem) < size) return NULL; p = nextmem; nextmem += size; -- cgit v1.2.3 From 34fd822f84d409fa649934251fae01994de7888b Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 17 Oct 2009 09:21:59 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1226 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmemcore.c | 4 ++-- os/kernel/src/chmempools.c | 23 ++++++++++++++++++----- 2 files changed, 20 insertions(+), 7 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index 00e04a2d6..7177fe432 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -60,7 +60,7 @@ void core_init(void) { * sizeof(align_t). * * - * @param[in] the size of the block to be allocated + * @param[in] size the size of the block to be allocated * @return A pointer to the allocated memory block. * @retval NULL allocation failed, core memory exhausted. */ @@ -79,7 +79,7 @@ void *chCoreAlloc(size_t size) { * type @p align_t so it is not possible to allocate less than * sizeof(align_t). * - * @param[in] the size of the block to be allocated. + * @param[in] size the size of the block to be allocated. * @return A pointer to the allocated memory block. * @retval NULL allocation failed, core memory exhausted. */ diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c index a8d7da818..76ef39b58 100644 --- a/os/kernel/src/chmempools.c +++ b/os/kernel/src/chmempools.c @@ -32,14 +32,20 @@ * * @param[out] mp pointer to a @p MemoryPool structure * @param[in] size the size of the objects contained in this memory pool, - * the minimum accepted size is the size of a pointer to void + * the minimum accepted size is the size of a pointer to void. + * + * @note The size is internally aligned to be a multiple of the @p align_t + * type size. */ void chPoolInit(MemoryPool *mp, size_t size) { chDbgCheck((mp != NULL) && (size >= sizeof(void *)), "chPoolInit"); mp->mp_next = NULL; - mp->mp_object_size = size; + mp->mp_object_size = MEM_ALIGN_SIZE(size); +#if CH_USE_MEMCORE + mp->mp_usecore = FALSE; +#endif } /** @@ -56,7 +62,10 @@ void *chPoolAllocI(MemoryPool *mp) { if ((objp = mp->mp_next) != NULL) mp->mp_next = mp->mp_next->ph_next; - +#if CH_USE_MEMCORE + else if (mp->mp_usecore) + objp = chCoreAllocI(mp->mp_object_size); +#endif return objp; } @@ -81,13 +90,17 @@ void *chPoolAlloc(MemoryPool *mp) { * * @param[in] mp pointer to a @p MemoryPool structure * @param[in] objp the pointer to the object to be released or added - * @note the object is assumed to be of the right size for the specified + * + * @note The object is assumed to be of the right size for the specified * memory pool. + * @note The object is assumed to be memory aligned to the size of @p align_t + * type. */ void chPoolFreeI(MemoryPool *mp, void *objp) { struct pool_header *php = objp; - chDbgCheck((mp != NULL) && (objp != NULL), "chPoolFreeI"); + chDbgCheck((mp != NULL) && (objp != NULL) && MEM_IS_ALIGNED(objp), + "chPoolFreeI"); php->ph_next = mp->mp_next; mp->mp_next = php; -- cgit v1.2.3 From 26ed3732876a649fb02a83e768e4392034d65653 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 17 Oct 2009 10:33:37 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1229 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsys.c | 1 + 1 file changed, 1 insertion(+) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 7d42eb644..326699ea0 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -40,6 +40,7 @@ static WORKING_AREA(idle_thread_wa, IDLE_THREAD_STACK_SIZE); */ static void idle_thread(void *p) { + (void)p; while (TRUE) { port_wait_for_interrupt(); IDLE_LOOP_HOOK(); -- cgit v1.2.3 From 404fe109397d80016f71c57f42ee6cd0cbfe96d1 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 17 Oct 2009 15:42:19 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1236 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 17 ++++++++++------- os/kernel/src/chsys.c | 2 +- os/kernel/src/chthreads.c | 2 -- 3 files changed, 11 insertions(+), 10 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 7c65e3fd6..150169481 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -39,7 +39,7 @@ void scheduler_init(void) { queue_init(&rlist.r_queue); rlist.r_prio = NOPRIO; -#if CH_USE_ROUNDROBIN +#if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; #endif } @@ -83,7 +83,7 @@ void chSchGoSleepS(tstate_t newstate) { (otp = currp)->p_state = newstate; (currp = fifo_remove(&rlist.r_queue))->p_state = PRCURR; -#if CH_USE_ROUNDROBIN +#if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; #endif chDbgTrace(otp, currp); @@ -176,7 +176,7 @@ void chSchWakeupS(Thread *ntp, msg_t msg) { else { Thread *otp = currp; chSchReadyI(otp); -#if CH_USE_ROUNDROBIN +#if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; #endif (currp = ntp)->p_state = PRCURR; @@ -197,7 +197,7 @@ void chSchDoRescheduleI(void) { /* Pick the first thread from the ready queue and makes it current.*/ (currp = fifo_remove(&rlist.r_queue))->p_state = PRCURR; chSchReadyI(otp); -#if CH_USE_ROUNDROBIN +#if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; #endif chDbgTrace(otp, currp); @@ -229,7 +229,7 @@ void chSchRescheduleS(void) { bool_t chSchIsRescRequiredExI(void) { tprio_t p1 = firstprio(&rlist.r_queue); tprio_t p2 = currp->p_prio; -#if CH_USE_ROUNDROBIN +#if CH_TIME_QUANTUM > 0 /* If the running thread has not reached its time quantum, reschedule only * if the first thread on the ready queue has a higher priority. * Otherwise, if the running thread has used up its time quantum, reschedule @@ -242,7 +242,11 @@ bool_t chSchIsRescRequiredExI(void) { #endif } -#if CH_USE_ROUNDROBIN +/** + * @brief Yields the time slot. + * @details Yields the CPU control to the next thread in the ready list with + * equal priority, if any. + */ void chSchDoYieldS(void) { if (chSchCanYieldS()) { @@ -269,6 +273,5 @@ void chSchDoYieldS(void) { chSysSwitchI(otp, currp); } } -#endif /* CH_USE_ROUNDROBIN */ /** @} */ diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 326699ea0..06fdbc822 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -98,7 +98,7 @@ void chSysInit(void) { */ void chSysTimerHandlerI(void) { -#if CH_USE_ROUNDROBIN +#if CH_TIME_QUANTUM > 0 /* running thread has not used up quantum yet? */ if (rlist.r_preempt > 0) /* decrement remaining quantum */ diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 89d1d6329..70b0c3ace 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -293,7 +293,6 @@ void chThdSleepUntil(systime_t time) { chSysUnlock(); } -#if CH_USE_ROUNDROBIN /** * @brief Yields the time slot. * @details Yields the CPU control to the next thread in the ready list with @@ -305,7 +304,6 @@ void chThdYield(void) { chSchDoYieldS(); chSysUnlock(); } -#endif /* CH_USE_ROUNDROBIN */ /** * @brief Terminates the current thread by specifying an exit status code. -- cgit v1.2.3 From 2c41c0d442aa3cea412fba318d4fe0a7cfd276d6 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 19 Oct 2009 18:33:53 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1241 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chdebug.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index f5e6bef7a..3049e03e7 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -62,7 +62,8 @@ void chDbgTrace(Thread *otp, Thread *ntp) { /** * @brief Pointer to the panic message. * @details This pointer is meant to be accessed through the debugger, it is - * written once and then the system is halted. + * written once and then the system is halted. This variable can be + * set to @p NULL if the halt is caused by a stack overflow. */ char *panic_msg; -- cgit v1.2.3 From 7d689a5fae4f0950c8cb8e291744465ea5d2ca93 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 20 Oct 2009 17:26:27 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1242 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chheap.c | 8 ++++---- os/kernel/src/chmempools.c | 12 ++++++------ 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c index e7a975f3d..d1dab1580 100644 --- a/os/kernel/src/chheap.c +++ b/os/kernel/src/chheap.c @@ -19,8 +19,8 @@ /** * @file chheap.c - * @brief Heap code. - * @addtogroup heap + * @brief Heaps code. + * @addtogroup heaps * @{ */ @@ -47,7 +47,7 @@ static MemoryHeap default_heap; /** - * @brief Initializes the allocator subsystem. + * @brief Initializes the default heap. * * @note Internal use only. */ @@ -63,7 +63,7 @@ void heap_init(void) { } /** - * @brief Initializes a memory heap. + * @brief Initializes a memory heap from a static memory area. * * @param[out] heapp pointer to a memory heap descriptor to be initialized * @param[in] buf heap buffer base diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c index 76ef39b58..97d619520 100644 --- a/os/kernel/src/chmempools.c +++ b/os/kernel/src/chmempools.c @@ -33,19 +33,19 @@ * @param[out] mp pointer to a @p MemoryPool structure * @param[in] size the size of the objects contained in this memory pool, * the minimum accepted size is the size of a pointer to void. + * @param[in] provider memory provider function for the memory pool or + * @p NULL if the pool is not allowed to grow automatically * * @note The size is internally aligned to be a multiple of the @p align_t * type size. */ -void chPoolInit(MemoryPool *mp, size_t size) { +void chPoolInit(MemoryPool *mp, size_t size, memgetfunc_t provider) { chDbgCheck((mp != NULL) && (size >= sizeof(void *)), "chPoolInit"); mp->mp_next = NULL; mp->mp_object_size = MEM_ALIGN_SIZE(size); -#if CH_USE_MEMCORE - mp->mp_usecore = FALSE; -#endif + mp->mp_provider = provider; } /** @@ -63,8 +63,8 @@ void *chPoolAllocI(MemoryPool *mp) { if ((objp = mp->mp_next) != NULL) mp->mp_next = mp->mp_next->ph_next; #if CH_USE_MEMCORE - else if (mp->mp_usecore) - objp = chCoreAllocI(mp->mp_object_size); + else if (mp->mp_provider != NULL) + objp = mp->mp_provider(mp->mp_object_size); #endif return objp; } -- cgit v1.2.3 From 43f9fd4180030081daae9122bd57a521ec9c58e1 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 30 Oct 2009 15:45:38 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1258 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chheap.c | 2 +- os/kernel/src/chschd.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c index d1dab1580..203d69d13 100644 --- a/os/kernel/src/chheap.c +++ b/os/kernel/src/chheap.c @@ -255,7 +255,7 @@ size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep) { #if CH_USE_MUTEXES #define H_LOCK() chMtxLock(&hmtx) -#define H_UNLOCK() chMtxLock(&hmtx) +#define H_UNLOCK() chMtxUnock() static Mutex hmtx; #elif CH_USE_SEMAPHORES #define H_LOCK() chSemWait(&hsem) diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 150169481..87c2e2f8c 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -268,7 +268,9 @@ void chSchDoYieldS(void) { /* Pick the first thread from the ready queue and makes it current.*/ (currp = fifo_remove(&rlist.r_queue))->p_state = PRCURR; +#if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; +#endif chDbgTrace(otp, currp); chSysSwitchI(otp, currp); } -- cgit v1.2.3 From bdb7f4ab20bd3daf261ab93dfe733e0ff11dca0f Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 8 Dec 2009 17:37:49 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1397 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chcond.c | 2 +- os/kernel/src/chdebug.c | 2 +- os/kernel/src/chevents.c | 2 +- os/kernel/src/chheap.c | 2 +- os/kernel/src/chlists.c | 2 +- os/kernel/src/chmboxes.c | 2 +- os/kernel/src/chmemcore.c | 2 +- os/kernel/src/chmempools.c | 2 +- os/kernel/src/chmsg.c | 2 +- os/kernel/src/chmtx.c | 2 +- os/kernel/src/chqueues.c | 2 +- os/kernel/src/chschd.c | 2 +- os/kernel/src/chsem.c | 2 +- os/kernel/src/chsys.c | 2 +- os/kernel/src/chthreads.c | 2 +- os/kernel/src/chvt.c | 2 +- 16 files changed, 16 insertions(+), 16 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c index e991c32fc..39b5fd1fc 100644 --- a/os/kernel/src/chcond.c +++ b/os/kernel/src/chcond.c @@ -28,7 +28,7 @@ * @{ */ -#include +#include "ch.h" #if CH_USE_CONDVARS && CH_USE_MUTEXES diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index 3049e03e7..4868090b5 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -24,7 +24,7 @@ * @{ */ -#include +#include "ch.h" #if CH_DBG_ENABLE_TRACE /** diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index 29c06d904..70cab9d70 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -23,7 +23,7 @@ * @addtogroup events * @{ */ -#include +#include "ch.h" #if CH_USE_EVENTS /** diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c index 203d69d13..d9d88d78b 100644 --- a/os/kernel/src/chheap.c +++ b/os/kernel/src/chheap.c @@ -24,7 +24,7 @@ * @{ */ -#include +#include "ch.h" #if CH_USE_HEAP diff --git a/os/kernel/src/chlists.c b/os/kernel/src/chlists.c index 5c5d90869..da48b678e 100644 --- a/os/kernel/src/chlists.c +++ b/os/kernel/src/chlists.c @@ -23,7 +23,7 @@ * @addtogroup internals * @{ */ -#include +#include "ch.h" #if !CH_OPTIMIZE_SPEED || defined(__DOXYGEN__) /** diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c index 569422ca7..3bcf687fc 100644 --- a/os/kernel/src/chmboxes.c +++ b/os/kernel/src/chmboxes.c @@ -24,7 +24,7 @@ * @{ */ -#include +#include "ch.h" #if CH_USE_MAILBOXES /** diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index 7177fe432..47c579432 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -24,7 +24,7 @@ * @{ */ -#include +#include "ch.h" #if CH_USE_MEMCORE diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c index 97d619520..02bbcee45 100644 --- a/os/kernel/src/chmempools.c +++ b/os/kernel/src/chmempools.c @@ -24,7 +24,7 @@ * @{ */ -#include +#include "ch.h" #if CH_USE_MEMPOOLS /** diff --git a/os/kernel/src/chmsg.c b/os/kernel/src/chmsg.c index 6f1be5c47..e3c82ec5a 100644 --- a/os/kernel/src/chmsg.c +++ b/os/kernel/src/chmsg.c @@ -24,7 +24,7 @@ * @{ */ -#include +#include "ch.h" #if CH_USE_MESSAGES diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 9e568c782..21ec5b997 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -24,7 +24,7 @@ * @{ */ -#include +#include "ch.h" #if CH_USE_MUTEXES diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index 0f78a0975..a346ee07f 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -24,7 +24,7 @@ * @{ */ -#include +#include "ch.h" #if CH_USE_QUEUES diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 87c2e2f8c..15f7a1a16 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -24,7 +24,7 @@ * @{ */ -#include +#include "ch.h" /** @cond never */ ReadyList rlist; diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index 4b35f479c..dba765da9 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -24,7 +24,7 @@ * @{ */ -#include +#include "ch.h" #if CH_USE_SEMAPHORES diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 06fdbc822..29c225b4c 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -24,7 +24,7 @@ * @{ */ -#include +#include "ch.h" static WORKING_AREA(idle_thread_wa, IDLE_THREAD_STACK_SIZE); diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 70b0c3ace..6755b0b48 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -24,7 +24,7 @@ * @{ */ -#include +#include "ch.h" /* * Initializes a thread structure. diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c index b3cee0ce3..60d0a789b 100644 --- a/os/kernel/src/chvt.c +++ b/os/kernel/src/chvt.c @@ -24,7 +24,7 @@ * @{ */ -#include +#include "ch.h" VTList vtlist; -- cgit v1.2.3 From f2c5dc67eab392655278f2d34b31190dbf94bac1 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 11 Dec 2009 15:55:08 +0000 Subject: Fixed bug 2912528. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1414 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmemcore.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index 47c579432..214504df7 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -28,15 +28,8 @@ #if CH_USE_MEMCORE -#if CH_MEMCORE_SIZE == 0 - extern align_t __heap_base__; - extern align_t __heap_end__; -#else -align_t buffer[MEM_ALIGN_SIZE(CH_MEMCORE_SIZE) / sizeof(align_t)]; -#endif - -static align_t *nextmem; -static align_t *endmem; +static uint8_t *nextmem; +static uint8_t *endmem; /** * @brief Low level memory manager initialization. @@ -45,11 +38,14 @@ static align_t *endmem; */ void core_init(void) { #if CH_MEMCORE_SIZE == 0 + extern uint8_t __heap_base__; + extern uint8_t __heap_end__; nextmem = &__heap_base__; endmem = &__heap_end__; #else - nextmem = &buffer[0]; - endmem = &buffer[MEM_ALIGN_SIZE(CH_MEMCORE_SIZE) / sizeof(align_t)]; + static align_t buffer[MEM_ALIGN_SIZE(CH_MEMCORE_SIZE) / sizeof(align_t)]; + nextmem = (uint8_t *)&buffer[0]; + endmem = (uint8_t *)&buffer[MEM_ALIGN_SIZE(CH_MEMCORE_SIZE) / sizeof(align_t)]; #endif } @@ -87,7 +83,7 @@ void *chCoreAllocI(size_t size) { void *p; size = MEM_ALIGN_SIZE(size); - if ((size_t)((uint8_t *)endmem - (uint8_t *)nextmem) < size) + if ((size_t)(endmem - nextmem) < size) return NULL; p = nextmem; nextmem += size; -- cgit v1.2.3 From 320a3f140e693a0d8647fd05ec6d2d4cb10c523a Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 30 Dec 2009 13:28:10 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1484 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chevents.c | 2 +- os/kernel/src/chmemcore.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index 70cab9d70..64636da66 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -175,7 +175,7 @@ void chEvtBroadcastI(EventSource *esp) { } /** - * @brief Invokes the event handlers associated with a mask. + * @brief Invokes the event handlers associated to an event flags mask. * * @param[in] mask mask of the events to be dispatched * @param[in] handlers an array of @p evhandler_t. The array must have size diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index 214504df7..65962bde1 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -50,7 +50,7 @@ void core_init(void) { } /** - * @brief Allocates a block of memory. + * @brief Allocates a memory block. * @details The size of the returned block is aligned to the alignment * type @p align_t so it is not possible to allocate less than * sizeof(align_t). @@ -70,7 +70,7 @@ void *chCoreAlloc(size_t size) { } /** - * @brief Allocates a block of memory. + * @brief Allocates a memory block. * @details The size of the returned block is aligned to the alignment * type @p align_t so it is not possible to allocate less than * sizeof(align_t). -- cgit v1.2.3 From 855fe2391d07c5dab27129ad626541482fe8d782 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 5 Jan 2010 17:14:09 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1501 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chqueues.c | 145 ++++++++++++++++++++++++----------------------- 1 file changed, 75 insertions(+), 70 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index a346ee07f..f4111a814 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -34,33 +34,30 @@ * the bytes contained in the queue. * * @param[out] iqp pointer to an @p InputQueue structure - * @param[in] buffer pointer to a memory area allocated as queue buffer + * @param[in] bp pointer to a memory area allocated as queue buffer * @param[in] size size of the queue buffer - * @param[in] inotify pointer to a callback function that is invoked when - * some data is read from the queue. The value can be - * @p NULL. + * @param[in] infy pointer to a callback function that is invoked when + * data is read from the queue. The value can be @p NULL. * * @note The callback is invoked from within the S-Locked system state, * see @ref system_states. */ -void chIQInit(InputQueue *iqp, uint8_t *buffer, - size_t size, qnotify_t inotify) { +void chIQInit(InputQueue *iqp, uint8_t *bp, size_t size, qnotify_t infy) { - iqp->q_buffer = iqp->q_rdptr = iqp->q_wrptr = buffer; - iqp->q_top = buffer + size; + iqp->q_buffer = iqp->q_rdptr = iqp->q_wrptr = bp; + iqp->q_top = bp + size; + iqp->q_notify = infy; chSemInit(&iqp->q_sem, 0); - iqp->q_notify = inotify; } /** * @brief Resets an input queue. * @details All the data in the input queue is erased and lost, any waiting * thread is resumed with status @p Q_RESET. - * - * @param[in] iqp pointer to an @p InputQueue structure - * * @note A reset operation can be used by a low level driver in order to obtain * immediate attention from the high level layers. + * + * @param[in] iqp pointer to an @p InputQueue structure */ void chIQResetI(InputQueue *iqp) { @@ -97,7 +94,7 @@ msg_t chIQPutI(InputQueue *iqp, uint8_t b) { * in the queue or a timeout occurs. * * @param[in] iqp pointer to an @p InputQueue structure - * @param[in] timeout the number of ticks before the operation timeouts, + * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. @@ -106,12 +103,12 @@ msg_t chIQPutI(InputQueue *iqp, uint8_t b) { * @retval Q_TIMEOUT if the specified time expired. * @retval Q_RESET if the queue was reset. */ -msg_t chIQGetTimeout(InputQueue *iqp, systime_t timeout) { +msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) { uint8_t b; msg_t msg; chSysLock(); - if ((msg = chSemWaitTimeoutS(&iqp->q_sem, timeout)) < RDY_OK) { + if ((msg = chSemWaitTimeoutS(&iqp->q_sem, time)) < RDY_OK) { chSysUnlock(); return msg; } @@ -127,40 +124,45 @@ msg_t chIQGetTimeout(InputQueue *iqp, systime_t timeout) { } /** - * @brief Non-blocking read. + * @brief Input queue read with timeout. * @details The function reads data from an input queue into a buffer. The - * transfer is non-blocking and can return zero if the queue is - * empty. + * operation completes when the specified amount of data has been + * transferred or after the specified timeout or if the queue has + * been reset. + * @note The function is not atomic, if you need atomicity it is suggested + * to use a semaphore or a mutex for mutual exclusion. + * @note The queue callback is invoked one time for each byte removed + * from the queue. * * @param[in] iqp pointer to an @p InputQueue structure - * @param[out] buffer pointer to the buffer where the input data is copied + * @param[out] bp pointer to the data buffer * @param[in] n the maximum amount of data to be transferred - * @return The number of bytes transferred. - * - * @note The function is not atomic, if you need atomicity it is suggested - * to use a semaphore or a mutex for mutual exclusion. + * @param[in] time 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 number of bytes effectively transferred. */ -size_t chIQRead(InputQueue *iqp, uint8_t *buffer, size_t n) { +size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, + size_t n, systime_t time) { + qnotify_t nfy = iqp->q_notify; size_t r = 0; - while (n--) { + do { chSysLock(); - if (chIQIsEmpty(iqp)) { + if (chSemWaitTimeoutS(&iqp->q_sem, time) != RDY_OK) { chSysUnlock(); - break; + return r; } - chSemFastWaitI(&iqp->q_sem); - *buffer++ = *iqp->q_rdptr++; + *bp++ = *iqp->q_rdptr++; if (iqp->q_rdptr >= iqp->q_top) iqp->q_rdptr = iqp->q_buffer; - chSysUnlock(); + if (nfy) + nfy(); + chSysUnlock(); /* Gives a preemption chance in a controlled point.*/ r++; - } - if (r && iqp->q_notify) { - chSysLock(); - iqp->q_notify(); - chSysUnlock(); - } + } while (--n > 0); return r; } @@ -170,22 +172,20 @@ size_t chIQRead(InputQueue *iqp, uint8_t *buffer, size_t n) { * the free bytes in the queue. * * @param[out] oqp pointer to an @p OutputQueue structure - * @param[in] buffer pointer to a memory area allocated as queue buffer + * @param[in] bp pointer to a memory area allocated as queue buffer * @param[in] size size of the queue buffer - * @param[in] onotify pointer to a callback function that is invoked when - * some data is written to the queue. The value can be - * @p NULL. + * @param[in] onfy pointer to a callback function that is invoked when + * data is written to the queue. The value can be @p NULL. * * @note The callback is invoked from within the S-Locked system state, * see @ref system_states. */ -void chOQInit(OutputQueue *oqp, uint8_t *buffer, - size_t size, qnotify_t onotify) { +void chOQInit(OutputQueue *oqp, uint8_t *bp, size_t size, qnotify_t onfy) { - oqp->q_buffer = oqp->q_rdptr = oqp->q_wrptr = buffer; - oqp->q_top = buffer + size; + oqp->q_buffer = oqp->q_rdptr = oqp->q_wrptr = bp; + oqp->q_top = bp + size; + oqp->q_notify = onfy; chSemInit(&oqp->q_sem, size); - oqp->q_notify = onotify; } /** @@ -212,7 +212,7 @@ void chOQResetI(OutputQueue *oqp) { * * @param[in] oqp pointer to an @p OutputQueue structure * @param[in] b the byte value to be written in the queue - * @param[in] timeout the number of ticks before the operation timeouts, + * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. @@ -222,11 +222,11 @@ void chOQResetI(OutputQueue *oqp) { * @retval Q_TIMEOUT if the specified time expired. * @retval Q_RESET if the queue was reset. */ -msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t timeout) { +msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t time) { msg_t msg; chSysLock(); - if ((msg = chSemWaitTimeoutS(&oqp->q_sem, timeout)) < RDY_OK) { + if ((msg = chSemWaitTimeoutS(&oqp->q_sem, time)) < RDY_OK) { chSysUnlock(); return msg; } @@ -263,40 +263,45 @@ msg_t chOQGetI(OutputQueue *oqp) { } /** - * @brief Non-blocking write. + * @brief Output queue write with timeout. * @details The function writes data from a buffer to an output queue. The - * transfer is non-blocking and can return zero if the queue is - * already full. + * operation completes when the specified amount of data has been + * transferred or after the specified timeout or if the queue has + * been reset. + * @note The function is not atomic, if you need atomicity it is suggested + * to use a semaphore or a mutex for mutual exclusion. + * @note The queue callback is invoked one time for each byte inserted + * into the queue. * * @param[in] oqp pointer to an @p OutputQueue structure - * @param[out] buffer pointer to the buffer where the output data is stored + * @param[out] bp pointer to the data buffer * @param[in] n the maximum amount of data to be transferred - * @return The number of bytes transferred. - * - * @note The function is not atomic, if you need atomicity it is suggested - * to use a semaphore or a mutex for mutual exclusion. + * @param[in] time 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 number of bytes effectively transferred. */ -size_t chOQWrite(OutputQueue *oqp, uint8_t *buffer, size_t n) { - +size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp, + size_t n, systime_t time) { + qnotify_t nfy = oqp->q_notify; size_t w = 0; - while (n--) { + + do { chSysLock(); - if (chOQIsFull(oqp)) { + if (chSemWaitTimeoutS(&oqp->q_sem, time) != RDY_OK) { chSysUnlock(); - break; + return w; } - chSemFastWaitI(&oqp->q_sem); - *oqp->q_wrptr++ = *buffer++; + *oqp->q_wrptr++ = *bp++; if (oqp->q_wrptr >= oqp->q_top) oqp->q_wrptr = oqp->q_buffer; - chSysUnlock(); + if (nfy) + nfy(); + chSysUnlock(); /* Gives a preemption chance in a controlled point.*/ w++; - } - if (w && oqp->q_notify) { - chSysLock(); - oqp->q_notify(); - chSysUnlock(); - } + } while (--n > 0); return w; } #endif /* CH_USE_QUEUES */ -- cgit v1.2.3 From 78167cbb9fcc6c3e215c6827d0df5035d1c6d079 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 6 Jan 2010 09:40:39 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1504 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chqueues.c | 64 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 44 insertions(+), 20 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index f4111a814..6a951f223 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -131,8 +131,8 @@ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) { * been reset. * @note The function is not atomic, if you need atomicity it is suggested * to use a semaphore or a mutex for mutual exclusion. - * @note The queue callback is invoked one time for each byte removed - * from the queue. + * @note The queue callback is invoked before entering a sleep state and at + * the end of the transfer. * * @param[in] iqp pointer to an @p InputQueue structure * @param[out] bp pointer to the data buffer @@ -149,12 +149,18 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, qnotify_t nfy = iqp->q_notify; size_t r = 0; - do { - chSysLock(); - if (chSemWaitTimeoutS(&iqp->q_sem, time) != RDY_OK) { - chSysUnlock(); - return r; + chSysLock(); + while (TRUE) { + if (chIQIsEmpty(iqp)) { + if (nfy) + nfy(); + if ((chSemWaitTimeoutS(&iqp->q_sem, time) != RDY_OK)) { + chSysUnlock(); + return r; + } } + else + chSemFastWaitI(&iqp->q_sem); *bp++ = *iqp->q_rdptr++; if (iqp->q_rdptr >= iqp->q_top) iqp->q_rdptr = iqp->q_buffer; @@ -162,8 +168,15 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, nfy(); chSysUnlock(); /* Gives a preemption chance in a controlled point.*/ r++; - } while (--n > 0); - return r; + if (--n == 0) { + chSysLock(); + if (nfy) + nfy(); + chSysUnlock(); + return r; + } + chSysLock(); + } } /** @@ -270,8 +283,8 @@ msg_t chOQGetI(OutputQueue *oqp) { * been reset. * @note The function is not atomic, if you need atomicity it is suggested * to use a semaphore or a mutex for mutual exclusion. - * @note The queue callback is invoked one time for each byte inserted - * into the queue. + * @note The queue callback is invoked before entering a sleep state and at + * the end of the transfer. * * @param[in] oqp pointer to an @p OutputQueue structure * @param[out] bp pointer to the data buffer @@ -288,21 +301,32 @@ size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp, qnotify_t nfy = oqp->q_notify; size_t w = 0; - do { - chSysLock(); - if (chSemWaitTimeoutS(&oqp->q_sem, time) != RDY_OK) { - chSysUnlock(); - return w; + chSysLock(); + while (TRUE) { + if (chOQIsFull(oqp)) { + if (nfy) + nfy(); + if ((chSemWaitTimeoutS(&oqp->q_sem, time) != RDY_OK)) { + chSysUnlock(); + return w; + } } + else + chSemFastWaitI(&oqp->q_sem); *oqp->q_wrptr++ = *bp++; if (oqp->q_wrptr >= oqp->q_top) oqp->q_wrptr = oqp->q_buffer; - if (nfy) - nfy(); chSysUnlock(); /* Gives a preemption chance in a controlled point.*/ w++; - } while (--n > 0); - return w; + if (--n == 0) { + chSysLock(); + if (nfy) + nfy(); + chSysUnlock(); + return w; + } + chSysLock(); + } } #endif /* CH_USE_QUEUES */ -- cgit v1.2.3 From 19aff238cb04c02491e65f391f2fcceb09da4dd5 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 8 Jan 2010 13:37:23 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1510 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chlists.c | 22 +++++++++++++--------- os/kernel/src/chsys.c | 4 ++-- 2 files changed, 15 insertions(+), 11 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chlists.c b/os/kernel/src/chlists.c index da48b678e..4b87105bc 100644 --- a/os/kernel/src/chlists.c +++ b/os/kernel/src/chlists.c @@ -28,12 +28,12 @@ #if !CH_OPTIMIZE_SPEED || defined(__DOXYGEN__) /** * @brief Inserts a thread into a priority ordered queue. - * - * @param[in] tp the pointer to the thread to be inserted in the list - * @param[in] tqp the pointer to the threads list header * @note The insertion is done by scanning the list from the highest priority * toward the lowest. * @note This function is @b not an API. + * + * @param[in] tp the pointer to the thread to be inserted in the list + * @param[in] tqp the pointer to the threads list header */ void prio_insert(Thread *tp, ThreadsQueue *tqp) { @@ -52,10 +52,10 @@ void prio_insert(Thread *tp, ThreadsQueue *tqp) { /** * @brief Inserts a Thread into a queue. + * @note This function is @b not an API. * * @param[in] tp the pointer to the thread to be inserted in the list * @param[in] tqp the pointer to the threads list header - * @note This function is @b not an API. */ void queue_insert(Thread *tp, ThreadsQueue *tqp) { @@ -65,10 +65,12 @@ void queue_insert(Thread *tp, ThreadsQueue *tqp) { /** * @brief Removes the first-out Thread from a queue and returns it. + * @note If the queue is priority ordered then this function returns the + * thread with the highest priority. + * @note This function is @b not an API. * * @param[in] tqp the pointer to the threads list header * @return The removed thread pointer. - * @note This function is @b not an API. */ Thread *fifo_remove(ThreadsQueue *tqp) { Thread *tp = tqp->p_next; @@ -79,15 +81,17 @@ Thread *fifo_remove(ThreadsQueue *tqp) { /** * @brief Removes the last-out Thread from a queue and returns it. + * @note If the queue is priority ordered then this function returns the + * thread with the lowest priority. + * @note This function is @b not an API. * * @param[in] tqp the pointer to the threads list header * @return The removed thread pointer. - * @note This function is @b not an API. */ Thread *lifo_remove(ThreadsQueue *tqp) { - Thread *tp = tqp->p_next; + Thread *tp = tqp->p_prev; - (tqp->p_next = tp->p_next)->p_prev = (Thread *)tqp; + (tqp->p_prev = tp->p_prev)->p_next = (Thread *)tqp; return tp; } @@ -95,10 +99,10 @@ Thread *lifo_remove(ThreadsQueue *tqp) { * @brief Removes a Thread from a queue and returns it. * @details The thread is removed from the queue regardless of its relative * position and regardless the used insertion method. + * @note This function is @b not an API. * * @param[in] tp the pointer to the thread to be removed from the queue * @return The removed thread pointer. - * @note This function is @b not an API. */ Thread *dequeue(Thread *tp) { diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 29c225b4c..74ee794a3 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -99,9 +99,9 @@ void chSysInit(void) { void chSysTimerHandlerI(void) { #if CH_TIME_QUANTUM > 0 - /* running thread has not used up quantum yet? */ + /* Running thread has not used up quantum yet? */ if (rlist.r_preempt > 0) - /* decrement remaining quantum */ + /* Decrement remaining quantum.*/ rlist.r_preempt--; #endif #if CH_DBG_THREADS_PROFILING -- cgit v1.2.3 From 7bd8164f8ff6ffd0a9458d44e18097582adae201 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 20 Jan 2010 14:39:34 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1532 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chcond.c | 36 ++++++++++++++++++------------------ os/kernel/src/chevents.c | 32 +++++++++++++++++--------------- os/kernel/src/chmsg.c | 10 +++++----- os/kernel/src/chmtx.c | 24 ++++++++++++------------ os/kernel/src/chschd.c | 26 +++++++++++++------------- os/kernel/src/chsem.c | 22 +++++++++++----------- os/kernel/src/chsys.c | 2 +- os/kernel/src/chthreads.c | 32 ++++++++++++++++---------------- 8 files changed, 93 insertions(+), 91 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c index 39b5fd1fc..a7ba23ed5 100644 --- a/os/kernel/src/chcond.c +++ b/os/kernel/src/chcond.c @@ -72,7 +72,7 @@ void chCondSignalI(CondVar *cp) { chDbgCheck(cp != NULL, "chCondSignalI"); if (notempty(&cp->c_queue)) /* any thread ? */ - chSchReadyI(fifo_remove(&cp->c_queue))->p_rdymsg = RDY_OK; + chSchReadyI(fifo_remove(&cp->c_queue))->p_u.rdymsg = RDY_OK; } /** @@ -97,11 +97,11 @@ void chCondBroadcastI(CondVar *cp) { chDbgCheck(cp != NULL, "chCondBroadcastI"); - /* empties the condition variable queue and inserts all the Threads into the + /* Empties the condition variable queue and inserts all the Threads into the * ready list in FIFO order. The wakeup message is set to @p RDY_RESET in - * order to make a chCondBroadcast() detectable from a chCondSignal(). */ + * order to make a chCondBroadcast() detectable from a chCondSignal().*/ while (cp->c_queue.p_next != (void *)&cp->c_queue) - chSchReadyI(fifo_remove(&cp->c_queue))->p_rdymsg = RDY_RESET; + chSchReadyI(fifo_remove(&cp->c_queue))->p_u.rdymsg = RDY_RESET; } /** @@ -146,13 +146,13 @@ msg_t chCondWaitS(CondVar *cp) { "chCondWaitS(), #1", "not owning a mutex"); - mp = chMtxUnlockS(); /* unlocks the condvar mutex */ - prio_insert(currp, &cp->c_queue); /* enters the condvar queue */ - currp->p_wtcondp = cp; /* needed by the tracer */ - chSchGoSleepS(PRWTCOND); /* waits on the condvar */ - msg = currp->p_rdymsg; /* fetches the wakeup message */ - chMtxLockS(mp); /* atomically relocks the mutex */ - return msg; /* returns the wakeup message */ + mp = chMtxUnlockS(); + prio_insert(currp, &cp->c_queue); + currp->p_u.wtobjp = cp; + chSchGoSleepS(THD_STATE_WTCOND); + msg = currp->p_u.rdymsg; + chMtxLockS(mp); + return msg; } #if CH_USE_CONDVARS_TIMEOUT @@ -212,13 +212,13 @@ msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time) { "chCondWaitTimeoutS(), #1", "not owning a mutex"); - mp = chMtxUnlockS(); /* unlocks the condvar mutex */ - prio_insert(currp, &cp->c_queue); /* enters the condvar queue */ - currp->p_wtcondp = cp; /* needed by the tracer */ - chSchGoSleepTimeoutS(PRWTCOND, time); /* waits on the condvar */ - msg = currp->p_rdymsg; /* fetches the wakeup message */ - chMtxLockS(mp); /* atomically relocks the mutex */ - return msg; /* returns the wakeup message */ + mp = chMtxUnlockS(); + prio_insert(currp, &cp->c_queue); + currp->p_u.wtobjp = cp; + chSchGoSleepTimeoutS(THD_STATE_WTCOND, time); + msg = currp->p_u.rdymsg; + chMtxLockS(mp); + return msg; } #endif /* CH_USE_CONDVARS_TIMEOUT */ diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index 64636da66..580b0aea9 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -137,9 +137,11 @@ void chEvtSignalI(Thread *tp, eventmask_t mask) { tp->p_epending |= mask; /* Test on the AND/OR conditions wait states.*/ - if (((tp->p_state == PRWTOREVT) && ((tp->p_epending & tp->p_ewmask) != 0)) || - ((tp->p_state == PRWTANDEVT) && ((tp->p_epending & tp->p_ewmask) == tp->p_ewmask))) - chSchReadyI(tp)->p_rdymsg = RDY_OK; + if (((tp->p_state == THD_STATE_WTOREVT) && + ((tp->p_epending & tp->p_u.ewmask) != 0)) || + ((tp->p_state == THD_STATE_WTANDEVT) && + ((tp->p_epending & tp->p_u.ewmask) == tp->p_u.ewmask))) + chSchReadyI(tp)->p_u.rdymsg = RDY_OK; } /** @@ -220,8 +222,8 @@ eventmask_t chEvtWaitOne(eventmask_t ewmask) { chSysLock(); if ((m = (currp->p_epending & ewmask)) == 0) { - currp->p_ewmask = ewmask; - chSchGoSleepS(PRWTOREVT); + currp->p_u.ewmask = ewmask; + chSchGoSleepS(THD_STATE_WTOREVT); m = currp->p_epending & ewmask; } m &= -m; @@ -246,8 +248,8 @@ eventmask_t chEvtWaitAny(eventmask_t ewmask) { chSysLock(); if ((m = (currp->p_epending & ewmask)) == 0) { - currp->p_ewmask = ewmask; - chSchGoSleepS(PRWTOREVT); + currp->p_u.ewmask = ewmask; + chSchGoSleepS(THD_STATE_WTOREVT); m = currp->p_epending & ewmask; } currp->p_epending &= ~m; @@ -269,8 +271,8 @@ eventmask_t chEvtWaitAll(eventmask_t ewmask) { chSysLock(); if ((currp->p_epending & ewmask) != ewmask) { - currp->p_ewmask = ewmask; - chSchGoSleepS(PRWTANDEVT); + currp->p_u.ewmask = ewmask; + chSchGoSleepS(THD_STATE_WTANDEVT); } currp->p_epending &= ~ewmask; @@ -308,8 +310,8 @@ eventmask_t chEvtWaitOneTimeout(eventmask_t ewmask, systime_t time) { if ((m = (currp->p_epending & ewmask)) == 0) { if (TIME_IMMEDIATE == time) return (eventmask_t)0; - currp->p_ewmask = ewmask; - if (chSchGoSleepTimeoutS(PRWTOREVT, time) < RDY_OK) + currp->p_u.ewmask = ewmask; + if (chSchGoSleepTimeoutS(THD_STATE_WTOREVT, time) < RDY_OK) return (eventmask_t)0; m = currp->p_epending & ewmask; } @@ -344,8 +346,8 @@ eventmask_t chEvtWaitAnyTimeout(eventmask_t ewmask, systime_t time) { if ((m = (currp->p_epending & ewmask)) == 0) { if (TIME_IMMEDIATE == time) return (eventmask_t)0; - currp->p_ewmask = ewmask; - if (chSchGoSleepTimeoutS(PRWTOREVT, time) < RDY_OK) + currp->p_u.ewmask = ewmask; + if (chSchGoSleepTimeoutS(THD_STATE_WTOREVT, time) < RDY_OK) return (eventmask_t)0; m = currp->p_epending & ewmask; } @@ -376,8 +378,8 @@ eventmask_t chEvtWaitAllTimeout(eventmask_t ewmask, systime_t time) { if ((currp->p_epending & ewmask) != ewmask) { if (TIME_IMMEDIATE == time) return (eventmask_t)0; - currp->p_ewmask = ewmask; - if (chSchGoSleepTimeoutS(PRWTANDEVT, time) < RDY_OK) + currp->p_u.ewmask = ewmask; + if (chSchGoSleepTimeoutS(THD_STATE_WTANDEVT, time) < RDY_OK) return (eventmask_t)0; } currp->p_epending &= ~ewmask; diff --git a/os/kernel/src/chmsg.c b/os/kernel/src/chmsg.c index e3c82ec5a..577e82693 100644 --- a/os/kernel/src/chmsg.c +++ b/os/kernel/src/chmsg.c @@ -50,11 +50,11 @@ msg_t chMsgSend(Thread *tp, msg_t msg) { chSysLock(); msg_insert(currp, &tp->p_msgqueue); currp->p_msg = msg; - currp->p_wtthdp = tp; - if (tp->p_state == PRWTMSG) + currp->p_u.wtobjp = tp; + if (tp->p_state == THD_STATE_WTMSG) chSchReadyI(tp); - chSchGoSleepS(PRSNDMSG); - msg = currp->p_rdymsg; + chSchGoSleepS(THD_STATE_SNDMSG); + msg = currp->p_u.rdymsg; chSysUnlock(); return msg; } @@ -73,7 +73,7 @@ msg_t chMsgWait(void) { chSysLock(); if (!chMsgIsPendingI(currp)) - chSchGoSleepS(PRWTMSG); + chSchGoSleepS(THD_STATE_WTMSG); msg = chMsgGetI(currp); chSysUnlock(); return msg; diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 21ec5b997..962356db8 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -86,31 +86,31 @@ void chMtxLockS(Mutex *mp) { * The following states need priority queues reordering. */ switch (tp->p_state) { - case PRWTMTX: + case THD_STATE_WTMTX: /* Re-enqueues tp with its new priority on the mutex wait queue.*/ - prio_insert(dequeue(tp), &tp->p_wtmtxp->m_queue); + prio_insert(dequeue(tp), (ThreadsQueue *)&tp->p_u.wtobjp); /* Boost the owner of this mutex if needed.*/ - tp = tp->p_wtmtxp->m_owner; + tp = ((Mutex *)tp->p_u.wtobjp)->m_owner; continue; #if CH_USE_CONDVARS - case PRWTCOND: + case THD_STATE_WTCOND: /* Re-enqueues tp with its new priority on the condvar queue.*/ - prio_insert(dequeue(tp), &tp->p_wtcondp->c_queue); + prio_insert(dequeue(tp), (ThreadsQueue *)&tp->p_u.wtobjp); break; #endif #if CH_USE_SEMAPHORES_PRIORITY - case PRWTSEM: + case THD_STATE_WTSEM: /* Re-enqueues tp with its new priority on the semaphore queue.*/ - prio_insert(dequeue(tp), &tp->p_wtsemp->s_queue); + prio_insert(dequeue(tp), (ThreadsQueue *)&tp->p_u.wtobjp); break; #endif #if CH_USE_MESSAGES_PRIORITY - case PRSNDMSG: + case THD_STATE_SNDMSG: /* Re-enqueues tp with its new priority on the server thread queue.*/ - prio_insert(dequeue(tp), &tp->p_wtthdp->p_msgqueue); + prio_insert(dequeue(tp), ((Thread *)tp->p_u.wtobjp)->p_msgqueue); break; #endif - case PRREADY: + case THD_STATE_READY: /* Re-enqueues tp with its new priority on the ready list.*/ chSchReadyI(dequeue(tp)); } @@ -118,8 +118,8 @@ void chMtxLockS(Mutex *mp) { } /* Sleep on the mutex.*/ prio_insert(currp, &mp->m_queue); - currp->p_wtmtxp = mp; - chSchGoSleepS(PRWTMTX); + currp->p_u.wtobjp = mp; + chSchGoSleepS(THD_STATE_WTMTX); chDbgAssert(mp->m_owner == NULL, "chMtxLockS(), #1", "still owned"); } /* diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 15f7a1a16..f7be9c6a8 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -60,7 +60,7 @@ Thread *chSchReadyI(Thread *tp) { #endif Thread *cp; - tp->p_state = PRREADY; + tp->p_state = THD_STATE_READY; cp = (Thread *)&rlist.r_queue; do { cp = cp->p_next; @@ -82,7 +82,7 @@ void chSchGoSleepS(tstate_t newstate) { Thread *otp; (otp = currp)->p_state = newstate; - (currp = fifo_remove(&rlist.r_queue))->p_state = PRCURR; + (currp = fifo_remove(&rlist.r_queue))->p_state = THD_STATE_CURRENT; #if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; #endif @@ -99,21 +99,21 @@ static void wakeup(void *p) { #if CH_USE_SEMAPHORES || CH_USE_MUTEXES || CH_USE_CONDVARS switch (tp->p_state) { #if CH_USE_SEMAPHORES - case PRWTSEM: - chSemFastSignalI(tp->p_wtsemp); + case THD_STATE_WTSEM: + chSemFastSignalI((Semaphore *)tp->p_u.wtobjp); /* Falls into, intentional. */ #endif #if CH_USE_MUTEXES - case PRWTMTX: + case THD_STATE_WTMTX: #endif #if CH_USE_CONDVARS - case PRWTCOND: + case THD_STATE_WTCOND: #endif /* States requiring dequeuing.*/ dequeue(tp); } #endif - chSchReadyI(tp)->p_rdymsg = RDY_TIMEOUT; + chSchReadyI(tp)->p_u.rdymsg = RDY_TIMEOUT; } /** @@ -149,7 +149,7 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { } else chSchGoSleepS(newstate); - return currp->p_rdymsg; + return currp->p_u.rdymsg; } /** @@ -166,7 +166,7 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { */ void chSchWakeupS(Thread *ntp, msg_t msg) { - ntp->p_rdymsg = msg; + ntp->p_u.rdymsg = msg; /* If the waken thread has a not-greater priority than the current * one then it is just inserted in the ready list else it made * running immediately and the invoking thread goes in the ready @@ -179,7 +179,7 @@ void chSchWakeupS(Thread *ntp, msg_t msg) { #if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; #endif - (currp = ntp)->p_state = PRCURR; + (currp = ntp)->p_state = THD_STATE_CURRENT; chDbgTrace(otp, ntp); chSysSwitchI(otp, ntp); } @@ -195,7 +195,7 @@ void chSchDoRescheduleI(void) { Thread *otp = currp; /* Pick the first thread from the ready queue and makes it current.*/ - (currp = fifo_remove(&rlist.r_queue))->p_state = PRCURR; + (currp = fifo_remove(&rlist.r_queue))->p_state = THD_STATE_CURRENT; chSchReadyI(otp); #if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; @@ -258,7 +258,7 @@ void chSchDoYieldS(void) { * ready list there is at least one thread with priority equal or higher * than the current one. */ - otp->p_state = PRREADY; + otp->p_state = THD_STATE_READY; do { cp = cp->p_prev; } while (cp->p_prio < otp->p_prio); @@ -267,7 +267,7 @@ void chSchDoYieldS(void) { otp->p_next->p_prev = cp->p_next = otp; /* Pick the first thread from the ready queue and makes it current.*/ - (currp = fifo_remove(&rlist.r_queue))->p_state = PRCURR; + (currp = fifo_remove(&rlist.r_queue))->p_state = THD_STATE_CURRENT; #if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; #endif diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index dba765da9..c78d52f74 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -86,7 +86,7 @@ void chSemResetI(Semaphore *sp, cnt_t n) { cnt = sp->s_cnt; sp->s_cnt = n; while (cnt++ < 0) - chSchReadyI(lifo_remove(&sp->s_queue))->p_rdymsg = RDY_RESET; + chSchReadyI(lifo_remove(&sp->s_queue))->p_u.rdymsg = RDY_RESET; } /** @@ -120,9 +120,9 @@ msg_t chSemWaitS(Semaphore *sp) { if (--sp->s_cnt < 0) { sem_insert(currp, &sp->s_queue); - currp->p_wtsemp = sp; - chSchGoSleepS(PRWTSEM); - return currp->p_rdymsg; + currp->p_u.wtobjp = sp; + chSchGoSleepS(THD_STATE_WTSEM); + return currp->p_u.rdymsg; } return RDY_OK; } @@ -174,8 +174,8 @@ msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) { return RDY_TIMEOUT; } sem_insert(currp, &sp->s_queue); - currp->p_wtsemp = sp; - return chSchGoSleepTimeoutS(PRWTSEM, time); + currp->p_u.wtobjp = sp; + return chSchGoSleepTimeoutS(THD_STATE_WTSEM, time); } return RDY_OK; } @@ -213,7 +213,7 @@ void chSemSignalI(Semaphore *sp) { /* NOTE: It is done this way in order to allow a tail call on chSchReadyI().*/ Thread *tp = fifo_remove(&sp->s_queue); - tp->p_rdymsg = RDY_OK; + tp->p_u.rdymsg = RDY_OK; chSchReadyI(tp); } } @@ -236,12 +236,12 @@ msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw) { chSysLock(); if (sps->s_cnt++ < 0) - chSchReadyI(fifo_remove(&sps->s_queue))->p_rdymsg = RDY_OK; + chSchReadyI(fifo_remove(&sps->s_queue))->p_u.rdymsg = RDY_OK; if (--spw->s_cnt < 0) { sem_insert(currp, &spw->s_queue); - currp->p_wtsemp = spw; - chSchGoSleepS(PRWTSEM); - msg = currp->p_rdymsg; + currp->p_u.wtobjp = spw; + chSchGoSleepS(THD_STATE_WTSEM); + msg = currp->p_u.rdymsg; } else { chSchRescheduleS(); diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 74ee794a3..2863f253c 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -75,7 +75,7 @@ void chSysInit(void) { /* * Now this instructions flow becomes the main thread. */ - (currp = init_thread(&mainthread, NORMALPRIO))->p_state = PRCURR; + (currp = init_thread(&mainthread, NORMALPRIO))->p_state = THD_STATE_CURRENT; chSysEnable(); /* diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 6755b0b48..e372a6e5c 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -31,9 +31,9 @@ */ Thread *init_thread(Thread *tp, tprio_t prio) { - tp->p_flags = P_MEM_MODE_STATIC; + tp->p_flags = THD_MEM_MODE_STATIC; tp->p_prio = prio; - tp->p_state = PRSUSPENDED; + tp->p_state = THD_STATE_SUSPENDED; #if CH_USE_NESTED_LOCKS tp->p_locks = 0; #endif @@ -69,7 +69,7 @@ static void memfill(uint8_t *startp, uint8_t *endp, uint8_t v) { /** * @brief Initializes a new thread. * @details The new thread is initialized but not inserted in the ready list, - * the initial state is @p PRSUSPENDED. + * the initial state is @p THD_STATE_SUSPENDED. * * @param[out] wsp pointer to a working area dedicated to the thread stack * @param[in] size size of the working area @@ -150,7 +150,7 @@ Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size, if (wsp == NULL) return NULL; tp = chThdInit(wsp, size, prio, pf, arg); - tp->p_flags = P_MEM_MODE_HEAP; + tp->p_flags = THD_MEM_MODE_HEAP; return chThdResume(tp); } #endif /* CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_HEAP */ @@ -187,7 +187,7 @@ Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, if (wsp == NULL) return NULL; tp = chThdInit(wsp, mp->mp_object_size, prio, pf, arg); - tp->p_flags = P_MEM_MODE_MEMPOOL; + tp->p_flags = THD_MEM_MODE_MEMPOOL; tp->p_mpool = mp; return chThdResume(tp); } @@ -235,9 +235,9 @@ tprio_t chThdSetPriority(tprio_t newprio) { Thread *chThdResume(Thread *tp) { chSysLock(); - chDbgAssert(tp->p_state == PRSUSPENDED, + chDbgAssert(tp->p_state == THD_STATE_SUSPENDED, "chThdResume(), #1", - "thread not in PRSUSPENDED state"); + "thread not in THD_STATE_SUSPENDED state"); chSchWakeupS(tp, RDY_OK); chSysUnlock(); return tp; @@ -254,7 +254,7 @@ Thread *chThdResume(Thread *tp) { void chThdTerminate(Thread *tp) { chSysLock(); - tp->p_flags |= P_TERMINATE; + tp->p_flags |= THD_TERMINATE; chSysUnlock(); } @@ -315,13 +315,13 @@ void chThdExit(msg_t msg) { Thread *tp = currp; chSysLock(); - tp->p_exitcode = msg; + tp->p_u.exitcode = msg; THREAD_EXT_EXIT(tp); #if CH_USE_WAITEXIT if (tp->p_waiting != NULL) chSchReadyI(tp->p_waiting); #endif - chSchGoSleepS(PREXIT); + chSchGoSleepS(THD_STATE_FINAL); } #if CH_USE_WAITEXIT @@ -362,28 +362,28 @@ msg_t chThdWait(Thread *tp) { chDbgAssert(tp != currp, "chThdWait(), #1", "waiting self"); chDbgAssert(tp->p_waiting == NULL, "chThdWait(), #2", "some other thread waiting"); - if (tp->p_state != PREXIT) { + if (tp->p_state != THD_STATE_FINAL) { tp->p_waiting = currp; - chSchGoSleepS(PRWAIT); + chSchGoSleepS(THD_STATE_WTEXIT); } - msg = tp->p_exitcode; + msg = tp->p_u.exitcode; #if !CH_USE_DYNAMIC chSysUnlock(); return msg; #else /* CH_USE_DYNAMIC */ /* Returning memory.*/ - tmode_t mode = tp->p_flags & P_MEM_MODE_MASK; + tmode_t mode = tp->p_flags & THD_MEM_MODE_MASK; chSysUnlock(); switch (mode) { #if CH_USE_HEAP - case P_MEM_MODE_HEAP: + case THD_MEM_MODE_HEAP: chHeapFree(tp); break; #endif #if CH_USE_MEMPOOLS - case P_MEM_MODE_MEMPOOL: + case THD_MEM_MODE_MEMPOOL: chPoolFree(tp->p_mpool, tp); break; #endif -- cgit v1.2.3 From 14005a2ffefe28adb2ce2cfdad24be782090c089 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 20 Jan 2010 19:37:07 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1533 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 962356db8..d319b9316 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -88,26 +88,26 @@ void chMtxLockS(Mutex *mp) { switch (tp->p_state) { case THD_STATE_WTMTX: /* Re-enqueues tp with its new priority on the mutex wait queue.*/ - prio_insert(dequeue(tp), (ThreadsQueue *)&tp->p_u.wtobjp); + prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); /* Boost the owner of this mutex if needed.*/ tp = ((Mutex *)tp->p_u.wtobjp)->m_owner; continue; #if CH_USE_CONDVARS case THD_STATE_WTCOND: /* Re-enqueues tp with its new priority on the condvar queue.*/ - prio_insert(dequeue(tp), (ThreadsQueue *)&tp->p_u.wtobjp); + prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); break; #endif #if CH_USE_SEMAPHORES_PRIORITY case THD_STATE_WTSEM: /* Re-enqueues tp with its new priority on the semaphore queue.*/ - prio_insert(dequeue(tp), (ThreadsQueue *)&tp->p_u.wtobjp); + prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); break; #endif #if CH_USE_MESSAGES_PRIORITY case THD_STATE_SNDMSG: /* Re-enqueues tp with its new priority on the server thread queue.*/ - prio_insert(dequeue(tp), ((Thread *)tp->p_u.wtobjp)->p_msgqueue); + prio_insert(dequeue(tp), &((Thread *)tp->p_u.wtobjp)->p_msgqueue); break; #endif case THD_STATE_READY: -- cgit v1.2.3 From 85016e2a2622a64719e8baa58dd493b6b99aa793 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 20 Jan 2010 20:45:56 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1534 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmsg.c | 4 ++-- os/kernel/src/chmtx.c | 23 ++++++++--------------- 2 files changed, 10 insertions(+), 17 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmsg.c b/os/kernel/src/chmsg.c index 577e82693..2f5a7a127 100644 --- a/os/kernel/src/chmsg.c +++ b/os/kernel/src/chmsg.c @@ -48,9 +48,9 @@ msg_t chMsgSend(Thread *tp, msg_t msg) { chDbgCheck(tp != NULL, "chMsgSend"); chSysLock(); - msg_insert(currp, &tp->p_msgqueue); currp->p_msg = msg; - currp->p_u.wtobjp = tp; + currp->p_u.wtobjp = &tp->p_msgqueue; + msg_insert(currp, &tp->p_msgqueue); if (tp->p_state == THD_STATE_WTMSG) chSchReadyI(tp); chSchGoSleepS(THD_STATE_SNDMSG); diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index d319b9316..c14db4ad0 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -77,37 +77,30 @@ void chMtxLockS(Mutex *mp) { * of the running thread requesting the mutex. */ Thread *tp = mp->m_owner; - /* {tp is the thread currently owning the mutex} */ - /* Has the running thread higher priority than tp? */ + /* Does the running thread have higher priority than the mutex + * ownning thread? */ while (tp->p_prio < currp->p_prio) { /* Make priority of thread tp match the running thread's priority.*/ tp->p_prio = currp->p_prio; - /* - * The following states need priority queues reordering. - */ + /* The following states need priority queues reordering.*/ switch (tp->p_state) { case THD_STATE_WTMTX: - /* Re-enqueues tp with its new priority on the mutex wait queue.*/ + /* Re-enqueues the mutex owner with its new priority.*/ prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); - /* Boost the owner of this mutex if needed.*/ tp = ((Mutex *)tp->p_u.wtobjp)->m_owner; continue; +#if CH_USE_CONDVARS | CH_USE_SEMAPHORES_PRIORITY | CH_USE_MESSAGES_PRIORITY #if CH_USE_CONDVARS case THD_STATE_WTCOND: - /* Re-enqueues tp with its new priority on the condvar queue.*/ - prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); - break; #endif #if CH_USE_SEMAPHORES_PRIORITY case THD_STATE_WTSEM: - /* Re-enqueues tp with its new priority on the semaphore queue.*/ - prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); - break; #endif #if CH_USE_MESSAGES_PRIORITY case THD_STATE_SNDMSG: - /* Re-enqueues tp with its new priority on the server thread queue.*/ - prio_insert(dequeue(tp), &((Thread *)tp->p_u.wtobjp)->p_msgqueue); +#endif + /* Re-enqueues tp with its new priority on the queue.*/ + prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); break; #endif case THD_STATE_READY: -- cgit v1.2.3 From 8cdf2dba5b8113538f2c7c8c7728cc868398d636 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 20 Jan 2010 21:08:28 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1535 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmsg.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmsg.c b/os/kernel/src/chmsg.c index 2f5a7a127..6c0c6a81a 100644 --- a/os/kernel/src/chmsg.c +++ b/os/kernel/src/chmsg.c @@ -44,17 +44,18 @@ * @return The return message from @p chMsgRelease(). */ msg_t chMsgSend(Thread *tp, msg_t msg) { + Thread *ctp = currp; chDbgCheck(tp != NULL, "chMsgSend"); chSysLock(); - currp->p_msg = msg; - currp->p_u.wtobjp = &tp->p_msgqueue; - msg_insert(currp, &tp->p_msgqueue); + ctp->p_msg = msg; + ctp->p_u.wtobjp = &tp->p_msgqueue; + msg_insert(ctp, &tp->p_msgqueue); if (tp->p_state == THD_STATE_WTMSG) chSchReadyI(tp); chSchGoSleepS(THD_STATE_SNDMSG); - msg = currp->p_u.rdymsg; + msg = ctp->p_u.rdymsg; chSysUnlock(); return msg; } -- cgit v1.2.3 From 6ce39015268cb3a30adc9890a312be39857e1464 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 21 Jan 2010 17:25:57 +0000 Subject: Mutexes optimizations. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1536 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 118 ++++++++++++++++++++++++-------------------------- 1 file changed, 56 insertions(+), 62 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index c14db4ad0..9d66022c2 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -66,22 +66,21 @@ void chMtxLock(Mutex *mp) { * block. */ void chMtxLockS(Mutex *mp) { + Thread *ctp = currp; chDbgCheck(mp != NULL, "chMtxLockS"); /* Ia the mutex already locked? */ if (mp->m_owner != NULL) { - /* - * Priority inheritance protocol; explores the thread-mutex dependencies - * boosting the priority of all the affected threads to equal the priority - * of the running thread requesting the mutex. - */ + /* Priority inheritance protocol; explores the thread-mutex dependencies + boosting the priority of all the affected threads to equal the priority + of the running thread requesting the mutex.*/ Thread *tp = mp->m_owner; /* Does the running thread have higher priority than the mutex - * ownning thread? */ - while (tp->p_prio < currp->p_prio) { + ownning thread? */ + while (tp->p_prio < ctp->p_prio) { /* Make priority of thread tp match the running thread's priority.*/ - tp->p_prio = currp->p_prio; + tp->p_prio = ctp->p_prio; /* The following states need priority queues reordering.*/ switch (tp->p_state) { case THD_STATE_WTMTX: @@ -110,17 +109,15 @@ void chMtxLockS(Mutex *mp) { break; } /* Sleep on the mutex.*/ - prio_insert(currp, &mp->m_queue); - currp->p_u.wtobjp = mp; + prio_insert(ctp, &mp->m_queue); + ctp->p_u.wtobjp = mp; chSchGoSleepS(THD_STATE_WTMTX); chDbgAssert(mp->m_owner == NULL, "chMtxLockS(), #1", "still owned"); } - /* - * The mutex is now inserted in the owned mutexes list. - */ - mp->m_owner = currp; - mp->m_next = currp->p_mtxlist; - currp->p_mtxlist = mp; + /* The mutex is now inserted in the owned mutexes list.*/ + mp->m_owner = ctp; + mp->m_next = ctp->p_mtxlist; + ctp->p_mtxlist = mp; } /** @@ -173,43 +170,40 @@ bool_t chMtxTryLockS(Mutex *mp) { * @return The pointer to the unlocked mutex. */ Mutex *chMtxUnlock(void) { + Thread *ctp = currp; Mutex *ump, *mp; chSysLock(); - chDbgAssert(currp->p_mtxlist != NULL, + chDbgAssert(ctp->p_mtxlist != NULL, "chMtxUnlock(), #1", "owned mutexes list empty"); - chDbgAssert(currp->p_mtxlist->m_owner == currp, + chDbgAssert(ctp->p_mtxlist->m_owner == ctp, "chMtxUnlock(), #2", "ownership failure"); - /* remove the top Mutex from the Threads's owned mutexes list */ - ump = currp->p_mtxlist; - currp->p_mtxlist = ump->m_next; - /* mark the Mutex as not owned */ + /* Removes the top Mutex from the Threads's owned mutexes list and matk it + as not owned.*/ + ump = ctp->p_mtxlist; + ctp->p_mtxlist = ump->m_next; ump->m_owner = NULL; - /* - * If a thread is waiting on the mutex then the hard part begins. - */ + /* If a thread is waiting on the mutex then the fun part begins.*/ if (chMtxQueueNotEmptyS(ump)) { - /* Get the highest priority thread waiting for the unlocked mutex.*/ - Thread *tp = fifo_remove(&ump->m_queue); - /* - * Recalculates the optimal thread priority by scanning the owned mutexes list. - */ - tprio_t newprio = currp->p_realprio; - /* Iterate mp over all the (other) mutexes the current thread still owns.*/ - mp = currp->p_mtxlist; + /* Recalculates the optimal thread priority by scanning the owned + mutexes list.*/ + tprio_t newprio = ctp->p_realprio; + mp = ctp->p_mtxlist; while (mp != NULL) { - /* Has the mutex mp a higher priority thread pending? */ + /* If the highest priority thread waiting in the mutexes list has a + greater priority than the current thread base priority then the final + priority will have at least that priority.*/ if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio)) - /* Boost the recalculated thread's priority to waiting thread.*/ newprio = mp->m_queue.p_next->p_prio; mp = mp->m_next; } - /* Possibly restores the priority of the current thread.*/ - currp->p_prio = newprio; - /* Awaken the highest priority thread waiting for the unlocked mutex.*/ - chSchWakeupS(tp, RDY_OK); + /* Assigns to the current thread the highest priority among all the + waiting threads.*/ + ctp->p_prio = newprio; + /* Awakens the highest priority thread waiting for the unlocked mutex.*/ + chSchWakeupS(fifo_remove(&ump->m_queue), RDY_OK); } chSysUnlock(); return ump; @@ -224,38 +218,37 @@ Mutex *chMtxUnlock(void) { * @note This function does not reschedule internally. */ Mutex *chMtxUnlockS(void) { + Thread *ctp = currp; Mutex *ump, *mp; - chDbgAssert(currp->p_mtxlist != NULL, + chDbgAssert(ctp->p_mtxlist != NULL, "chMtxUnlockS(), #1", "owned mutexes list empty"); - chDbgAssert(currp->p_mtxlist->m_owner == currp, + chDbgAssert(ctp->p_mtxlist->m_owner == ctp, "chMtxUnlockS(), #2", "ownership failure"); - /* - * Removes the top Mutex from the owned mutexes list and marks it as not owned. - */ - ump = currp->p_mtxlist; - currp->p_mtxlist = ump->m_next; + /* Removes the top Mutex from the owned mutexes list and marks it as not + owned.*/ + ump = ctp->p_mtxlist; + ctp->p_mtxlist = ump->m_next; ump->m_owner = NULL; - /* - * If a thread is waiting on the mutex then the hard part begins. - */ + /* If a thread is waiting on the mutex then the fun part begins.*/ if (chMtxQueueNotEmptyS(ump)) { - Thread *tp = fifo_remove(&ump->m_queue); - /* - * Recalculates the optimal thread priority by scanning the owned mutexes list. - */ - tprio_t newprio = currp->p_realprio; - mp = currp->p_mtxlist; + /* Recalculates the optimal thread priority by scanning the owned + mutexes list.*/ + tprio_t newprio = ctp->p_realprio; + mp = ctp->p_mtxlist; while (mp != NULL) { + /* If the highest priority thread waiting in the mutexes list has a + greater priority than the current thread base priority then the final + priority will have at least that priority.*/ if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio)) newprio = mp->m_queue.p_next->p_prio; mp = mp->m_next; } - currp->p_prio = newprio; - chSchReadyI(tp); + ctp->p_prio = newprio; + chSchReadyI(fifo_remove(&ump->m_queue)); } return ump; } @@ -268,17 +261,18 @@ Mutex *chMtxUnlockS(void) { * inheritance mechanism. */ void chMtxUnlockAll(void) { + Thread *ctp = currp; chSysLock(); - if (currp->p_mtxlist != NULL) { + if (ctp->p_mtxlist != NULL) { do { - Mutex *mp = currp->p_mtxlist; - currp->p_mtxlist = mp->m_next; + Mutex *mp = ctp->p_mtxlist; + ctp->p_mtxlist = mp->m_next; mp->m_owner = NULL; if (chMtxQueueNotEmptyS(mp)) chSchReadyI(fifo_remove(&mp->m_queue)); - } while (currp->p_mtxlist != NULL); - currp->p_prio = currp->p_realprio; + } while (ctp->p_mtxlist != NULL); + ctp->p_prio = ctp->p_realprio; chSchRescheduleS(); } chSysUnlock(); -- cgit v1.2.3 From ea02b6612f7f377f77cbdebe29d0d52f30e5fdeb Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 21 Jan 2010 18:06:33 +0000 Subject: Condvars optimizations. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1537 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chcond.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c index a7ba23ed5..9e1a70cc4 100644 --- a/os/kernel/src/chcond.c +++ b/os/kernel/src/chcond.c @@ -138,19 +138,20 @@ msg_t chCondWait(CondVar *cp) { * @p chCondWaitS(). */ msg_t chCondWaitS(CondVar *cp) { + Thread *ctp = currp; Mutex *mp; msg_t msg; chDbgCheck(cp != NULL, "chCondWaitS"); - chDbgAssert(currp->p_mtxlist != NULL, + chDbgAssert(ctp->p_mtxlist != NULL, "chCondWaitS(), #1", "not owning a mutex"); mp = chMtxUnlockS(); - prio_insert(currp, &cp->c_queue); - currp->p_u.wtobjp = cp; + prio_insert(ctp, &cp->c_queue); + ctp->p_u.wtobjp = cp; chSchGoSleepS(THD_STATE_WTCOND); - msg = currp->p_u.rdymsg; + msg = ctp->p_u.rdymsg; chMtxLockS(mp); return msg; } @@ -204,19 +205,20 @@ msg_t chCondWaitTimeout(CondVar *cp, systime_t time) { * @p chCondWaitTimeoutS(). */ msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time) { + Thread *ctp = currp; Mutex *mp; msg_t msg; chDbgCheck(cp != NULL, "chCondWaitTimeoutS"); - chDbgAssert(currp->p_mtxlist != NULL, + chDbgAssert(ctp->p_mtxlist != NULL, "chCondWaitTimeoutS(), #1", "not owning a mutex"); mp = chMtxUnlockS(); - prio_insert(currp, &cp->c_queue); - currp->p_u.wtobjp = cp; + prio_insert(ctp, &cp->c_queue); + ctp->p_u.wtobjp = cp; chSchGoSleepTimeoutS(THD_STATE_WTCOND, time); - msg = currp->p_u.rdymsg; + msg = ctp->p_u.rdymsg; chMtxLockS(mp); return msg; } -- cgit v1.2.3 From 11a6a2bf6476beda7a3a6d8504aa74c03c3b9731 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 21 Jan 2010 19:57:30 +0000 Subject: Events subsystem optimizations. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1538 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chevents.c | 50 +++++++++++++++++++++++++++--------------------- 1 file changed, 28 insertions(+), 22 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index 580b0aea9..9da61adaf 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -217,17 +217,18 @@ void chEvtDispatch(const evhandler_t handlers[], eventmask_t mask) { * an higher priority. */ eventmask_t chEvtWaitOne(eventmask_t ewmask) { + Thread *ctp = currp; eventmask_t m; chSysLock(); - if ((m = (currp->p_epending & ewmask)) == 0) { - currp->p_u.ewmask = ewmask; + if ((m = (ctp->p_epending & ewmask)) == 0) { + ctp->p_u.ewmask = ewmask; chSchGoSleepS(THD_STATE_WTOREVT); - m = currp->p_epending & ewmask; + m = ctp->p_epending & ewmask; } m &= -m; - currp->p_epending &= ~m; + ctp->p_epending &= ~m; chSysUnlock(); return m; @@ -243,16 +244,17 @@ eventmask_t chEvtWaitOne(eventmask_t ewmask) { * @return The mask of the served and cleared events. */ eventmask_t chEvtWaitAny(eventmask_t ewmask) { + Thread *ctp = currp; eventmask_t m; chSysLock(); - if ((m = (currp->p_epending & ewmask)) == 0) { - currp->p_u.ewmask = ewmask; + if ((m = (ctp->p_epending & ewmask)) == 0) { + ctp->p_u.ewmask = ewmask; chSchGoSleepS(THD_STATE_WTOREVT); - m = currp->p_epending & ewmask; + m = ctp->p_epending & ewmask; } - currp->p_epending &= ~m; + ctp->p_epending &= ~m; chSysUnlock(); return m; @@ -267,14 +269,15 @@ eventmask_t chEvtWaitAny(eventmask_t ewmask) { * @return The mask of the served and cleared events. */ eventmask_t chEvtWaitAll(eventmask_t ewmask) { + Thread *ctp = currp; chSysLock(); - if ((currp->p_epending & ewmask) != ewmask) { - currp->p_u.ewmask = ewmask; + if ((ctp->p_epending & ewmask) != ewmask) { + ctp->p_u.ewmask = ewmask; chSchGoSleepS(THD_STATE_WTANDEVT); } - currp->p_epending &= ~ewmask; + ctp->p_epending &= ~ewmask; chSysUnlock(); return ewmask; @@ -303,20 +306,21 @@ eventmask_t chEvtWaitAll(eventmask_t ewmask) { * an higher priority. */ eventmask_t chEvtWaitOneTimeout(eventmask_t ewmask, systime_t time) { + Thread *ctp = currp; eventmask_t m; chSysLock(); - if ((m = (currp->p_epending & ewmask)) == 0) { + if ((m = (ctp->p_epending & ewmask)) == 0) { if (TIME_IMMEDIATE == time) return (eventmask_t)0; - currp->p_u.ewmask = ewmask; + ctp->p_u.ewmask = ewmask; if (chSchGoSleepTimeoutS(THD_STATE_WTOREVT, time) < RDY_OK) return (eventmask_t)0; - m = currp->p_epending & ewmask; + m = ctp->p_epending & ewmask; } m &= -m; - currp->p_epending &= ~m; + ctp->p_epending &= ~m; chSysUnlock(); return m; @@ -339,19 +343,20 @@ eventmask_t chEvtWaitOneTimeout(eventmask_t ewmask, systime_t time) { * @retval 0 if the specified timeout expired. */ eventmask_t chEvtWaitAnyTimeout(eventmask_t ewmask, systime_t time) { + Thread *ctp = currp; eventmask_t m; chSysLock(); - if ((m = (currp->p_epending & ewmask)) == 0) { + if ((m = (ctp->p_epending & ewmask)) == 0) { if (TIME_IMMEDIATE == time) return (eventmask_t)0; - currp->p_u.ewmask = ewmask; + ctp->p_u.ewmask = ewmask; if (chSchGoSleepTimeoutS(THD_STATE_WTOREVT, time) < RDY_OK) return (eventmask_t)0; - m = currp->p_epending & ewmask; + m = ctp->p_epending & ewmask; } - currp->p_epending &= ~m; + ctp->p_epending &= ~m; chSysUnlock(); return m; @@ -372,17 +377,18 @@ eventmask_t chEvtWaitAnyTimeout(eventmask_t ewmask, systime_t time) { * @retval 0 if the specified timeout expired. */ eventmask_t chEvtWaitAllTimeout(eventmask_t ewmask, systime_t time) { + Thread *ctp = currp; chSysLock(); - if ((currp->p_epending & ewmask) != ewmask) { + if ((ctp->p_epending & ewmask) != ewmask) { if (TIME_IMMEDIATE == time) return (eventmask_t)0; - currp->p_u.ewmask = ewmask; + ctp->p_u.ewmask = ewmask; if (chSchGoSleepTimeoutS(THD_STATE_WTANDEVT, time) < RDY_OK) return (eventmask_t)0; } - currp->p_epending &= ~ewmask; + ctp->p_epending &= ~ewmask; chSysUnlock(); return ewmask; -- cgit v1.2.3 From 86eb39129b8ac6ba74778c72261f2048c2da1114 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 24 Jan 2010 09:04:55 +0000 Subject: Changes suggested by Adamo and Enrico. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1543 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chheap.c | 46 +++++++++++++++++++++++----------------------- os/kernel/src/chthreads.c | 8 ++++++-- os/kernel/src/chvt.c | 2 +- 3 files changed, 30 insertions(+), 26 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c index d9d88d78b..e434fd2ab 100644 --- a/os/kernel/src/chheap.c +++ b/os/kernel/src/chheap.c @@ -53,7 +53,7 @@ static MemoryHeap default_heap; */ void heap_init(void) { default_heap.h_provider = chCoreAlloc; - default_heap.h_free.h_next = NULL; + default_heap.h_free.h_u.next = (struct heap_header *)NULL; default_heap.h_free.h_size = 0; #if CH_USE_MUTEXES chMtxInit(&default_heap.h_mtx); @@ -70,17 +70,17 @@ void heap_init(void) { * @param[in] size heap size * * @note Both the heap buffer base and the heap size must be aligned to - * the @p align_t type size. + * the @p align_t type size. */ void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) { struct heap_header *hp; chDbgCheck(MEM_IS_ALIGNED(buf) && MEM_IS_ALIGNED(size), "chHeapInit"); - heapp->h_provider = NULL; - heapp->h_free.h_next = hp = buf; + heapp->h_provider = (memgetfunc_t)NULL; + heapp->h_free.h_u.next = hp = buf; heapp->h_free.h_size = 0; - hp->h_next = NULL; + hp->h_u.next = NULL; hp->h_size = size - sizeof(struct heap_header); #if CH_USE_MUTEXES chMtxInit(&heapp->h_mtx); @@ -113,8 +113,8 @@ void *chHeapAlloc(MemoryHeap *heapp, size_t size) { qp = &heapp->h_free; H_LOCK(heapp); - while (qp->h_next != NULL) { - hp = qp->h_next; + while (qp->h_u.next != NULL) { + hp = qp->h_u.next; if (hp->h_size >= size) { if (hp->h_size < size + sizeof(struct heap_header)) { /* @@ -122,19 +122,19 @@ void *chHeapAlloc(MemoryHeap *heapp, size_t size) { * requested size because the fragment would be too small to be * useful. */ - qp->h_next = hp->h_next; + qp->h_u.next = hp->h_u.next; } else { /* * Block bigger enough, must split it. */ fp = (void *)((uint8_t *)(hp) + sizeof(struct heap_header) + size); - fp->h_next = hp->h_next; + fp->h_u.next = hp->h_u.next; fp->h_size = hp->h_size - sizeof(struct heap_header) - size; - qp->h_next = fp; + qp->h_u.next = fp; hp->h_size = size; } - hp->h_heap = heapp; + hp->h_u.heap = heapp; H_UNLOCK(heapp); return (void *)(hp + 1); @@ -150,7 +150,7 @@ void *chHeapAlloc(MemoryHeap *heapp, size_t size) { if (heapp->h_provider) { hp = heapp->h_provider(size + sizeof(struct heap_header)); if (hp != NULL) { - hp->h_heap = heapp; + hp->h_u.heap = heapp; hp->h_size = size; hp++; return (void *)hp; @@ -175,7 +175,7 @@ void chHeapFree(void *p) { chDbgCheck(p != NULL, "chHeapFree"); hp = (struct heap_header *)p - 1; - heapp = hp->h_heap; + heapp = hp->h_u.heap; qp = &heapp->h_free; H_LOCK(heapp); @@ -185,32 +185,32 @@ void chHeapFree(void *p) { "within free block"); if (((qp == &heapp->h_free) || (hp > qp)) && - ((qp->h_next == NULL) || (hp < qp->h_next))) { + ((qp->h_u.next == NULL) || (hp < qp->h_u.next))) { /* * Insertion after qp. */ - hp->h_next = qp->h_next; - qp->h_next = hp; + hp->h_u.next = qp->h_u.next; + qp->h_u.next = hp; /* * Verifies if the newly inserted block should be merged. */ - if (LIMIT(hp) == hp->h_next) { + if (LIMIT(hp) == hp->h_u.next) { /* * Merge with the next block. */ - hp->h_size += hp->h_next->h_size + sizeof(struct heap_header); - hp->h_next = hp->h_next->h_next; + hp->h_size += hp->h_u.next->h_size + sizeof(struct heap_header); + hp->h_u.next = hp->h_u.next->h_u.next; } if ((LIMIT(qp) == hp)) { /* * Merge with the previous block. */ qp->h_size += hp->h_size + sizeof(struct heap_header); - qp->h_next = hp->h_next; + qp->h_u.next = hp->h_u.next; } break; } - qp = qp->h_next; + qp = qp->h_u.next; } H_UNLOCK(heapp); @@ -240,8 +240,8 @@ size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep) { H_LOCK(heapp); sz = 0; - for (n = 0, qp = &heapp->h_free; qp->h_next; n++, qp = qp->h_next) - sz += qp->h_next->h_size; + for (n = 0, qp = &heapp->h_free; qp->h_u.next; n++, qp = qp->h_u.next) + sz += qp->h_u.next->h_size; if (sizep) *sizep = sz; diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index e372a6e5c..6aab8f891 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -354,13 +354,17 @@ void chThdExit(msg_t msg) { */ msg_t chThdWait(Thread *tp) { msg_t msg; +#if CH_USE_DYNAMIC + tmode_t mode; +#endif chDbgCheck(tp != NULL, "chThdWait"); chSysLock(); chDbgAssert(tp != currp, "chThdWait(), #1", "waiting self"); - chDbgAssert(tp->p_waiting == NULL, "chThdWait(), #2", "some other thread waiting"); + chDbgAssert(tp->p_waiting == NULL, "chThdWait(), #2", + "some other thread waiting"); if (tp->p_state != THD_STATE_FINAL) { tp->p_waiting = currp; @@ -373,7 +377,7 @@ msg_t chThdWait(Thread *tp) { #else /* CH_USE_DYNAMIC */ /* Returning memory.*/ - tmode_t mode = tp->p_flags & THD_MEM_MODE_MASK; + mode = tp->p_flags & THD_MEM_MODE_MASK; chSysUnlock(); switch (mode) { diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c index 60d0a789b..5acde49aa 100644 --- a/os/kernel/src/chvt.c +++ b/os/kernel/src/chvt.c @@ -93,7 +93,7 @@ void chVTResetI(VirtualTimer *vtp) { vtp->vt_next->vt_time += vtp->vt_time; vtp->vt_prev->vt_next = vtp->vt_next; vtp->vt_next->vt_prev = vtp->vt_prev; - vtp->vt_func = NULL; + vtp->vt_func = (vtfunc_t)NULL; } /** -- cgit v1.2.3 From 7f8dfe2fd3e770c2e0435e9c56f5db5fd11ed6f7 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 31 Jan 2010 09:27:49 +0000 Subject: Implemented thread reference counters and related APIs. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1556 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chlists.c | 28 +++++++++++ os/kernel/src/chthreads.c | 122 ++++++++++++++++++++++++++++------------------ 2 files changed, 102 insertions(+), 48 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chlists.c b/os/kernel/src/chlists.c index 4b87105bc..53f91649a 100644 --- a/os/kernel/src/chlists.c +++ b/os/kernel/src/chlists.c @@ -110,6 +110,34 @@ Thread *dequeue(Thread *tp) { tp->p_next->p_prev = tp->p_prev; return tp; } + +/** + * @brief Pushes a Thread on top of a stack list. + * @note This function is @b not an API. + * + * @param[in] tp the pointer to the thread to be inserted in the list + * @param[in] tlp the pointer to the threads list header + */ +void list_insert(Thread *tp, ThreadsList *tlp) { + + tp->p_next = tlp->p_next; + tlp->p_next = tp; +} + +/** + * @brief Pops a Thread from the top of a stack list and returns it. + * @note The list must be non-empty before calling this function. + * @note This function is @b not an API. + * + * @param[in] tlp the pointer to the threads list header + * @return The removed thread pointer. + */ +Thread *list_remove(ThreadsList *tlp) { + + Thread *tp = tlp->p_next; + tlp->p_next = tp->p_next; + return tp; +} #endif /* CH_OPTIMIZE_SPEED */ /** @} */ diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 6aab8f891..26183706a 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -26,14 +26,17 @@ #include "ch.h" -/* - * Initializes a thread structure. +/** + * @brief Initializes a thread structure. */ Thread *init_thread(Thread *tp, tprio_t prio) { tp->p_flags = THD_MEM_MODE_STATIC; tp->p_prio = prio; tp->p_state = THD_STATE_SUSPENDED; +#if CH_USE_DYNAMIC + tp->p_refs = 1; +#endif #if CH_USE_NESTED_LOCKS tp->p_locks = 0; #endif @@ -41,12 +44,11 @@ Thread *init_thread(Thread *tp, tprio_t prio) { tp->p_time = 0; #endif #if CH_USE_MUTEXES - /* realprio is the thread's own, non-inherited, priority */ tp->p_realprio = prio; tp->p_mtxlist = NULL; #endif #if CH_USE_WAITEXIT - tp->p_waiting = NULL; + list_init(&tp->p_waiting); #endif #if CH_USE_MESSAGES queue_init(&tp->p_msgqueue); @@ -120,7 +122,7 @@ Thread *chThdCreateStatic(void *wsp, size_t size, return chThdResume(chThdInit(wsp, size, prio, pf, arg)); } -#if CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_HEAP +#if CH_USE_DYNAMIC && CH_USE_HEAP /** * @brief Creates a new thread allocating the memory from the heap. * @@ -153,9 +155,9 @@ Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size, tp->p_flags = THD_MEM_MODE_HEAP; return chThdResume(tp); } -#endif /* CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_HEAP */ +#endif /* CH_USE_DYNAMIC && CH_USE_HEAP */ -#if CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_MEMPOOLS +#if CH_USE_DYNAMIC && CH_USE_MEMPOOLS /** * @brief Creates a new thread allocating the memory from the specified Memory * Pool. @@ -191,7 +193,7 @@ Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, tp->p_mpool = mp; return chThdResume(tp); } -#endif /* CH_USE_DYNAMIC && CH_USE_WAITEXIT && CH_USE_MEMPOOLS */ +#endif /* CH_USE_DYNAMIC && CH_USE_MEMPOOLS */ /** * @brief Changes the running thread priority level then reschedules if @@ -310,6 +312,7 @@ void chThdYield(void) { * * @param[in] msg the thread exit code. The code can be retrieved by using * @p chThdWait(). + * @return The same thread pointer passed as parameter. */ void chThdExit(msg_t msg) { Thread *tp = currp; @@ -318,17 +321,67 @@ void chThdExit(msg_t msg) { tp->p_u.exitcode = msg; THREAD_EXT_EXIT(tp); #if CH_USE_WAITEXIT - if (tp->p_waiting != NULL) - chSchReadyI(tp->p_waiting); + while (notempty(&tp->p_waiting)) + chSchReadyI(list_remove(&tp->p_waiting)); #endif chSchGoSleepS(THD_STATE_FINAL); } -#if CH_USE_WAITEXIT +#if CH_USE_DYNAMIC || defined(__DOXYGEN__) +Thread *chThdAddRef(Thread *tp) { + + chSysLock(); + chDbgAssert(tp->p_refs < 255, "chThdAddRef(), #1", "too many references"); + tp->p_refs++; + chSysUnlock(); + return tp; +} /** - * @brief Blocks the execution of the invoking thread until the specified - * thread terminates then the exit code is returned. - * @details The memory used by the exited thread is handled in different ways + * @brief Releases a reference to a thread object. + * @details If the references counter reaches zero and the thread is in + * @p THD_STATE_FINAL state then the thread's memory is returned + * to the proper allocator. + * @note Static threads are not affected. + * + * @param[in] tp the thread pointer + * @return The same thread pointer passed as parameter. + */ +Thread *chThdRelease(Thread *tp) { + trefs_t refs; + + chSysLock(); + chDbgAssert(tp->p_refs > 0, "chThdRelease(), #1", "not referenced"); + refs = --tp->p_refs; + chSysUnlock(); + + /* If the references counter reaches zero then the memory can be returned + to the proper allocator. Of course static threads are not affected.*/ + if (refs == 0) { + switch (tp->p_flags & THD_MEM_MODE_MASK) { +#if CH_USE_HEAP + case THD_MEM_MODE_HEAP: + chHeapFree(tp); + break; +#endif +#if CH_USE_MEMPOOLS + case THD_MEM_MODE_MEMPOOL: + chPoolFree(tp->p_mpool, tp); + break; +#endif + } + } + return tp; +} +#endif /* CH_USE_DYNAMIC */ + +#if CH_USE_WAITEXIT || defined(__DOXYGEN__) +/** + * @brief Blocks the execution of the invoking thread until the specified + * thread terminates then the exit code is returned. + * @details This function waits that the specified thread terminates then + * decrements its reference counter, if the counter reaches zero then + * the thread working area is returned to the proper allocator.
+ * The memory used by the exited thread is handled in different ways * depending on the API that spawned the thread: * - If the thread was spawned by @p chThdCreateStatic() or by * @p chThdInit() then nothing happens and the thread working area @@ -339,61 +392,34 @@ void chThdExit(msg_t msg) { * - If the thread was spawned by @p chThdCreateFromMemoryPool() * then the working area is returned to the owning memory pool. * . + * Please read the @ref article_lifecycle article for more details. * @param[in] tp the thread pointer * @return The exit code from the terminated thread * @note After invoking @p chThdWait() the thread pointer becomes invalid and * must not be used as parameter for further system calls. * @note The function is available only if the @p CH_USE_WAITEXIT * option is enabled in @p chconf.h. - * @note Only one thread can be waiting for another thread at any time. You - * should imagine the threads as having a reference counter that is set - * to one when the thread is created, chThdWait() decreases the reference - * and the memory is freed when the counter reaches zero. In the current - * implementation there is no real reference counter in the thread - * structure but it is a planned extension. + * @note If @p CH_USE_DYNAMIC is not specified this function just waits for + * the thread termination, no memory allocators are involved. */ msg_t chThdWait(Thread *tp) { msg_t msg; -#if CH_USE_DYNAMIC - tmode_t mode; -#endif chDbgCheck(tp != NULL, "chThdWait"); chSysLock(); - chDbgAssert(tp != currp, "chThdWait(), #1", "waiting self"); - chDbgAssert(tp->p_waiting == NULL, "chThdWait(), #2", - "some other thread waiting"); - + chDbgAssert(tp->p_refs > 0, "chThdWait(), #2", "not referenced"); if (tp->p_state != THD_STATE_FINAL) { - tp->p_waiting = currp; + list_insert(currp, &tp->p_waiting); chSchGoSleepS(THD_STATE_WTEXIT); } msg = tp->p_u.exitcode; -#if !CH_USE_DYNAMIC chSysUnlock(); - return msg; -#else /* CH_USE_DYNAMIC */ - - /* Returning memory.*/ - mode = tp->p_flags & THD_MEM_MODE_MASK; - chSysUnlock(); - - switch (mode) { -#if CH_USE_HEAP - case THD_MEM_MODE_HEAP: - chHeapFree(tp); - break; -#endif -#if CH_USE_MEMPOOLS - case THD_MEM_MODE_MEMPOOL: - chPoolFree(tp->p_mpool, tp); - break; +#if CH_USE_DYNAMIC + chThdRelease(tp); #endif - } return msg; -#endif /* CH_USE_DYNAMIC */ } #endif /* CH_USE_WAITEXIT */ -- cgit v1.2.3 From e515bcf581c92643c21eb6ed53ba0d0b1604fe4b Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 2 Feb 2010 20:20:12 +0000 Subject: Implemented registry subsystem (still in progress). git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1558 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 8 +- os/kernel/src/chthreads.c | 222 +++++++++++++++++++++++++--------------------- 2 files changed, 127 insertions(+), 103 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index f7be9c6a8..5b4d18133 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -26,9 +26,10 @@ #include "ch.h" -/** @cond never */ +/** + * @brief Ready list header. + */ ReadyList rlist; -/** @endcond */ /** * @brief Scheduler initialization. @@ -42,6 +43,9 @@ void scheduler_init(void) { #if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; #endif +#if CH_USE_REGISTRY + rlist.p_newer = rlist.p_older = (Thread *)&rlist; +#endif } /** diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 26183706a..95b1e68bf 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -27,13 +27,21 @@ #include "ch.h" /** - * @brief Initializes a thread structure. + * @brief Initializes a thread structure. + * + * @param[in] tp pointer to the thread + * @param[in] prio the priority level for the new thread + * + * @return The same thread pointer passed as parameter. */ Thread *init_thread(Thread *tp, tprio_t prio) { tp->p_flags = THD_MEM_MODE_STATIC; tp->p_prio = prio; tp->p_state = THD_STATE_SUSPENDED; +#if CH_USE_REGISTRY + REG_INSERT(tp); +#endif #if CH_USE_DYNAMIC tp->p_refs = 1; #endif @@ -69,22 +77,23 @@ static void memfill(uint8_t *startp, uint8_t *endp, uint8_t v) { #endif /** - * @brief Initializes a new thread. + * @brief Initializes a new thread. * @details The new thread is initialized but not inserted in the ready list, * the initial state is @p THD_STATE_SUSPENDED. + * @note A thread can terminate by calling @p chThdExit() or by simply + * returning from its main function. + * @note This function can be invoked from within an interrupt handler + * even if it is not an I-Class API because it does not touch + * any critical kernel data structure. * - * @param[out] wsp pointer to a working area dedicated to the thread stack - * @param[in] size size of the working area - * @param[in] prio the priority level for the new thread - * @param[in] pf the thread function - * @param[in] arg an argument passed to the thread function. It can be @p NULL. - * @return The pointer to the @p Thread structure allocated for the - * thread into the working space area. - * @note A thread can terminate by calling @p chThdExit() or by simply - * returning from its main function. - * @note This function can be invoked from within an interrupt handler even if - * it is not an I-Class API because it does not touch any critical kernel - * data structure. + * @param[out] wsp pointer to a working area dedicated to the thread stack + * @param[in] size size of the working area + * @param[in] prio the priority level for the new thread + * @param[in] pf the thread function + * @param[in] arg an argument passed to the thread function. It can be + * @p NULL. + * @return The pointer to the @p Thread structure allocated for the + * thread into the working space area. */ Thread *chThdInit(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) { /* Thread structure is layed out in the lower part of the thread workspace */ @@ -103,18 +112,18 @@ Thread *chThdInit(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) { } /** - * @brief Creates a new thread into a static memory area. + * @brief Creates a new thread into a static memory area. + * @note A thread can terminate by calling @p chThdExit() or by simply + * returning from its main function. * - * @param[out] wsp pointer to a working area dedicated to the thread - * stack - * @param[in] size size of the working area - * @param[in] prio the priority level for the new thread - * @param[in] pf the thread function - * @param[in] arg an argument passed to the thread function. It can be @p NULL. - * @return The pointer to the @p Thread structure allocated for the - * thread into the working space area. - * @note A thread can terminate by calling @p chThdExit() or by simply - * returning from its main function. + * @param[out] wsp pointer to a working area dedicated to the thread stack + * @param[in] size size of the working area + * @param[in] prio the priority level for the new thread + * @param[in] pf the thread function + * @param[in] arg an argument passed to the thread function. It can be + * @p NULL. + * @return The pointer to the @p Thread structure allocated for the + * thread into the working space area. */ Thread *chThdCreateStatic(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) { @@ -124,24 +133,25 @@ Thread *chThdCreateStatic(void *wsp, size_t size, #if CH_USE_DYNAMIC && CH_USE_HEAP /** - * @brief Creates a new thread allocating the memory from the heap. + * @brief Creates a new thread allocating the memory from the heap. + * @note A thread can terminate by calling @p chThdExit() or by simply + * returning from its main function. + * @note The memory allocated for the thread is not released when the thread + * terminates but when a @p chThdWait() is performed. + * @note The function is available only if the @p CH_USE_DYNAMIC, + * @p CH_USE_HEAP and @p CH_USE_WAITEXIT options are enabled + * in @p chconf.h. * - * @param[in] heapp heap from which allocate the memory or NULL for the + * @param[in] heapp heap from which allocate the memory or @p NULL for the * default heap - * @param[in] size size of the working area to be allocated - * @param[in] prio the priority level for the new thread - * @param[in] pf the thread function - * @param[in] arg an argument passed to the thread function. It can be @p NULL. - * @return The pointer to the @p Thread structure allocated for the - * thread into the working space area. - * @retval NULL if the memory cannot be allocated. - * @note A thread can terminate by calling @p chThdExit() or by simply - * returning from its main function. - * @note The memory allocated for the thread is not released when the thread - * terminates but when a @p chThdWait() is performed. - * @note The function is available only if the @p CH_USE_DYNAMIC, - * @p CH_USE_HEAP and @p CH_USE_WAITEXIT options are enabled - * in @p chconf.h. + * @param[in] size size of the working area to be allocated + * @param[in] prio the priority level for the new thread + * @param[in] pf the thread function + * @param[in] arg an argument passed to the thread function. It can be + * @p NULL. + * @return The pointer to the @p Thread structure allocated for the + * thread into the working space area. + * @retval NULL if the memory cannot be allocated. */ Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size, tprio_t prio, tfunc_t pf, void *arg) { @@ -159,24 +169,25 @@ Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size, #if CH_USE_DYNAMIC && CH_USE_MEMPOOLS /** - * @brief Creates a new thread allocating the memory from the specified Memory - * Pool. + * @brief Creates a new thread allocating the memory from the specified + * Memory Pool. + * @note A thread can terminate by calling @p chThdExit() or by simply + * returning from its main function. + * @note The memory allocated for the thread is not released when the thread + * terminates but when a @p chThdWait() is performed. + * @note The function is available only if the @p CH_USE_DYNAMIC, + * @p CH_USE_MEMPOOLS and @p CH_USE_WAITEXIT options are enabled + * in @p chconf.h. * - * @param[in] mp the memory pool - * @param[in] prio the priority level for the new thread - * @param[in] pf the thread function - * @param[in] arg an argument passed to the thread function. It can be @p NULL. - * @return The pointer to the @p Thread structure allocated for the - * thread into the working space area or @p NULL if the memory cannot - * be allocated. - * @retval NULL if the memory pool is empty. - * @note A thread can terminate by calling @p chThdExit() or by simply - * returning from its main function. - * @note The memory allocated for the thread is not released when the thread - * terminates but when a @p chThdWait() is performed. - * @note The function is available only if the @p CH_USE_DYNAMIC, - * @p CH_USE_MEMPOOLS and @p CH_USE_WAITEXIT options are enabled - * in @p chconf.h. + * @param[in] mp pointer to the memory pool object + * @param[in] prio the priority level for the new thread + * @param[in] pf the thread function + * @param[in] arg an argument passed to the thread function. It can be + * @p NULL. + * @return The pointer to the @p Thread structure allocated for the + * thread into the working space area or @p NULL if the memory cannot + * be allocated. + * @retval NULL if the memory pool is empty. */ Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, tfunc_t pf, void *arg) { @@ -196,14 +207,14 @@ Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, #endif /* CH_USE_DYNAMIC && CH_USE_MEMPOOLS */ /** - * @brief Changes the running thread priority level then reschedules if - * necessary. + * @brief Changes the running thread priority level then reschedules if + * necessary. + * @note The function returns the real thread priority regardless of the + * current priority that could be higher than the real priority + * because the priority inheritance mechanism. * * @param[in] newprio the new priority level of the running thread - * @return The old priority level. - * @note The function returns the real thread priority regardless of the - * current priority that could be higher than the real priority because - * the priority inheritance mechanism. + * @return The old priority level. */ tprio_t chThdSetPriority(tprio_t newprio) { tprio_t oldprio; @@ -227,12 +238,11 @@ tprio_t chThdSetPriority(tprio_t newprio) { } /** - * @brief Resumes a suspended thread. + * @brief Resumes a suspended thread. + * @note Use this function to resume threads created with @p chThdInit(). * - * @param[in] tp the pointer to the thread - * @return The pointer to the thread. - * @note This call is supposed to resume threads created with @p chThdInit(). - * It should not be used on threads suspended using @p chThdSuspend(). + * @param[in] tp pointer to the thread + * @return The pointer to the thread. */ Thread *chThdResume(Thread *tp) { @@ -246,12 +256,12 @@ Thread *chThdResume(Thread *tp) { } /** - * @brief Requests a thread termination. + * @brief Requests a thread termination. + * @note The thread is not terminated but a termination request is added to + * its @p p_flags field. The thread can read this status by + * invoking @p chThdShouldTerminate() and then terminate cleanly. * - * @param[in] tp the pointer to the thread - * @note The thread is not termitated but a termination request is added to - * its @p p_flags field. The thread can read this status by - * invoking @p chThdShouldTerminate() and then terminate cleanly. + * @param[in] tp pointer to the thread */ void chThdTerminate(Thread *tp) { @@ -261,16 +271,16 @@ void chThdTerminate(Thread *tp) { } /** - * @brief Suspends the invoking thread for the specified time. + * @brief Suspends the invoking thread for the specified time. * - * @param[in] time the delay in system ticks, the special values are handled as - * follow: - * - @a TIME_INFINITE the thread enters an infinite sleep - * state. - * - @a TIME_IMMEDIATE this value is accepted but interpreted - * as a normal time specification not as an immediate timeout - * specification. - * . + * @param[in] time the delay in system ticks, the special values are handled + * as follow: + * - @a TIME_INFINITE the thread enters an infinite sleep + * state. + * - @a TIME_IMMEDIATE this value is accepted but interpreted + * as a normal time specification not as an immediate + * timeout specification. + * . */ void chThdSleep(systime_t time) { @@ -282,10 +292,10 @@ void chThdSleep(systime_t time) { } /** - * @brief Suspends the invoking thread until the system time arrives to the - * specified value. + * @brief Suspends the invoking thread until the system time arrives to the + * specified value. * - * @param[in] time the absolute system time + * @param[in] time absolute system time */ void chThdSleepUntil(systime_t time) { @@ -296,7 +306,7 @@ void chThdSleepUntil(systime_t time) { } /** - * @brief Yields the time slot. + * @brief Yields the time slot. * @details Yields the CPU control to the next thread in the ready list with * equal priority, if any. */ @@ -308,11 +318,11 @@ void chThdYield(void) { } /** - * @brief Terminates the current thread by specifying an exit status code. + * @brief Terminates the current thread by specifying an exit status code. * - * @param[in] msg the thread exit code. The code can be retrieved by using - * @p chThdWait(). - * @return The same thread pointer passed as parameter. + * @param[in] msg thread exit code. The code can be retrieved by using + * @p chThdWait(). + * @return The same thread pointer passed as parameter. */ void chThdExit(msg_t msg) { Thread *tp = currp; @@ -323,11 +333,20 @@ void chThdExit(msg_t msg) { #if CH_USE_WAITEXIT while (notempty(&tp->p_waiting)) chSchReadyI(list_remove(&tp->p_waiting)); +#endif +#if CH_USE_REGISTRY + REG_REMOVE(tp); #endif chSchGoSleepS(THD_STATE_FINAL); } #if CH_USE_DYNAMIC || defined(__DOXYGEN__) +/** + * @brief Adds a reference to a thread object. + * + * @param[in] tp pointer to the thread + * @return The same thread pointer passed as parameter. + */ Thread *chThdAddRef(Thread *tp) { chSysLock(); @@ -343,8 +362,8 @@ Thread *chThdAddRef(Thread *tp) { * to the proper allocator. * @note Static threads are not affected. * - * @param[in] tp the thread pointer - * @return The same thread pointer passed as parameter. + * @param[in] tp pointer to the thread + * @return The same thread pointer passed as parameter. */ Thread *chThdRelease(Thread *tp) { trefs_t refs; @@ -393,14 +412,15 @@ Thread *chThdRelease(Thread *tp) { * then the working area is returned to the owning memory pool. * . * Please read the @ref article_lifecycle article for more details. - * @param[in] tp the thread pointer - * @return The exit code from the terminated thread - * @note After invoking @p chThdWait() the thread pointer becomes invalid and - * must not be used as parameter for further system calls. - * @note The function is available only if the @p CH_USE_WAITEXIT - * option is enabled in @p chconf.h. - * @note If @p CH_USE_DYNAMIC is not specified this function just waits for - * the thread termination, no memory allocators are involved. + * @note After invoking @p chThdWait() the thread pointer becomes invalid + * and must not be used as parameter for further system calls. + * @note The function is available only if the @p CH_USE_WAITEXIT + * option is enabled in @p chconf.h. + * @note If @p CH_USE_DYNAMIC is not specified this function just waits for + * the thread termination, no memory allocators are involved. + * + * @param[in] tp pointer to the thread + * @return The exit code from the terminated thread */ msg_t chThdWait(Thread *tp) { msg_t msg; -- cgit v1.2.3 From ca20fd81f6f5cba290763cf08243f582841cf770 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 2 Feb 2010 21:27:53 +0000 Subject: Forgot files... git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1560 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chregistry.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 77 insertions(+) create mode 100644 os/kernel/src/chregistry.c (limited to 'os/kernel/src') diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c new file mode 100644 index 000000000..186d97e35 --- /dev/null +++ b/os/kernel/src/chregistry.c @@ -0,0 +1,77 @@ +/* + ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chregistry.c + * @brief Threads registry code. + * @addtogroup registry + * @{ + */ +#include "ch.h" + +#if CH_USE_REGISTRY + +/** + * @brief Returns the first thread in the system. + * @details Returns the most ancient thread in the system, usually this is + * the main thread unless it terminated. + * @note A reference is added to the returned thread in order to make sure + * it status is not lost. + * + * @return A reference to the first thread. + */ +Thread *chRegFirstThread(void) { + Thread *tp; + + chSysLock(); + (tp = rlist.p_newer)->p_refs++; + chSysUnlock(); + return tp; +} + +/** + * @brief Returns the thread next to the specified one. + * @details The reference counter of the specified thread is decremented and + * the reference counter of the returned thread is incremented. + * + * @param[in] tp pointer to the thread + * @return A reference to the next thread. + * @retval NULL if there is no next thread. + */ +Thread *chRegNextThread(Thread *tp) { + + chSysLock(); + chDbgAssert(tp->p_refs > 0, "chRegNextThread(), #1", + "not referenced"); + tp->p_refs--; + if (tp->p_newer != (Thread *)&rlist) { + tp = tp->p_newer; + chDbgAssert(tp->p_refs < 255, "chRegNextThread(), #2", + "too many references"); + tp->p_refs++; + } + else + tp = NULL; + chSysUnlock(); + return tp; +} + +#endif /* CH_USE_REGISTRY */ + +/** @} */ -- cgit v1.2.3 From 7e9725de2ff3c472785320c5f5cff1103e5284c5 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 2 Feb 2010 21:33:14 +0000 Subject: Improved descriptions. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1561 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chthreads.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 95b1e68bf..fc697d1e9 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -345,7 +345,8 @@ void chThdExit(msg_t msg) { * @brief Adds a reference to a thread object. * * @param[in] tp pointer to the thread - * @return The same thread pointer passed as parameter. + * @return The same thread pointer passed as parameter representing the + * new reference. */ Thread *chThdAddRef(Thread *tp) { @@ -357,15 +358,14 @@ Thread *chThdAddRef(Thread *tp) { } /** * @brief Releases a reference to a thread object. - * @details If the references counter reaches zero and the thread is in - * @p THD_STATE_FINAL state then the thread's memory is returned - * to the proper allocator. + * @details If the references counter reaches zero and the thread + * is in the @p THD_STATE_FINAL state then the thread's memory is + * returned to the proper allocator. * @note Static threads are not affected. * * @param[in] tp pointer to the thread - * @return The same thread pointer passed as parameter. */ -Thread *chThdRelease(Thread *tp) { +void chThdRelease(Thread *tp) { trefs_t refs; chSysLock(); @@ -389,7 +389,6 @@ Thread *chThdRelease(Thread *tp) { #endif } } - return tp; } #endif /* CH_USE_DYNAMIC */ @@ -397,7 +396,7 @@ Thread *chThdRelease(Thread *tp) { /** * @brief Blocks the execution of the invoking thread until the specified * thread terminates then the exit code is returned. - * @details This function waits that the specified thread terminates then + * @details This function waits for the specified thread to terminate then * decrements its reference counter, if the counter reaches zero then * the thread working area is returned to the proper allocator.
* The memory used by the exited thread is handled in different ways -- cgit v1.2.3 From babbdde78b97b1ed21e4ca7c45c55029701f9a12 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 2 Feb 2010 21:34:10 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1562 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chthreads.c | 1 + 1 file changed, 1 insertion(+) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index fc697d1e9..e28efa43c 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -356,6 +356,7 @@ Thread *chThdAddRef(Thread *tp) { chSysUnlock(); return tp; } + /** * @brief Releases a reference to a thread object. * @details If the references counter reaches zero and the thread -- cgit v1.2.3 From 217d1529c1a126054fbdb9e071cd103194fd499e Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 3 Feb 2010 18:40:10 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1564 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmemcore.c | 30 +++++++++++++++++++----------- os/kernel/src/chregistry.c | 2 ++ 2 files changed, 21 insertions(+), 11 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index 65962bde1..6cf42788b 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -32,9 +32,8 @@ static uint8_t *nextmem; static uint8_t *endmem; /** - * @brief Low level memory manager initialization. - * - * @note Internal use only. + * @brief Low level memory manager initialization. + * @note Internal use only. */ void core_init(void) { #if CH_MEMCORE_SIZE == 0 @@ -50,15 +49,15 @@ void core_init(void) { } /** - * @brief Allocates a memory block. + * @brief Allocates a memory block. * @details The size of the returned block is aligned to the alignment * type @p align_t so it is not possible to allocate less than * sizeof(align_t). * * - * @param[in] size the size of the block to be allocated - * @return A pointer to the allocated memory block. - * @retval NULL allocation failed, core memory exhausted. + * @param[in] size the size of the block to be allocated + * @return A pointer to the allocated memory block. + * @retval NULL allocation failed, core memory exhausted. */ void *chCoreAlloc(size_t size) { void *p; @@ -70,14 +69,14 @@ void *chCoreAlloc(size_t size) { } /** - * @brief Allocates a memory block. + * @brief Allocates a memory block. * @details The size of the returned block is aligned to the alignment * type @p align_t so it is not possible to allocate less than * sizeof(align_t). * - * @param[in] size the size of the block to be allocated. - * @return A pointer to the allocated memory block. - * @retval NULL allocation failed, core memory exhausted. + * @param[in] size the size of the block to be allocated. + * @return A pointer to the allocated memory block. + * @retval NULL allocation failed, core memory exhausted. */ void *chCoreAllocI(size_t size) { void *p; @@ -90,6 +89,15 @@ void *chCoreAllocI(size_t size) { return p; } +/** + * @brief Core memory left. + * + * @return The size, in bytes, of the free core memory. + */ +size_t chCoreFree(void) { + + return (size_t)(endmem - nextmem); +} #endif /* CH_USE_MEMCORE */ /** @} */ diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c index 186d97e35..b02d5f1fb 100644 --- a/os/kernel/src/chregistry.c +++ b/os/kernel/src/chregistry.c @@ -33,6 +33,8 @@ * the main thread unless it terminated. * @note A reference is added to the returned thread in order to make sure * it status is not lost. + * @note This function cannot return @p NULL because there is always at + * least one thread in the system. * * @return A reference to the first thread. */ -- cgit v1.2.3 From f17db1931e95f5ebb42f557b6eead2bf1320db5a Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 6 Feb 2010 10:55:53 +0000 Subject: Reformatted doxygen tags into the kernel sources to make them more readable. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1567 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chcond.c | 123 +++++++++++----------- os/kernel/src/chdebug.c | 21 ++-- os/kernel/src/chevents.c | 247 +++++++++++++++++++++++---------------------- os/kernel/src/chheap.c | 100 ++++++++---------- os/kernel/src/chlists.c | 85 ++++++++-------- os/kernel/src/chmboxes.c | 161 ++++++++++++++--------------- os/kernel/src/chmemcore.c | 19 ++-- os/kernel/src/chmempools.c | 65 ++++++------ os/kernel/src/chmsg.c | 60 ++++++----- os/kernel/src/chmtx.c | 55 +++++----- os/kernel/src/chqueues.c | 177 ++++++++++++++++---------------- os/kernel/src/chregistry.c | 13 +-- os/kernel/src/chschd.c | 111 ++++++++++---------- os/kernel/src/chsem.c | 135 ++++++++++++------------- os/kernel/src/chsys.c | 35 +++---- os/kernel/src/chthreads.c | 126 ++++++++++++----------- os/kernel/src/chvt.c | 59 ++++++----- 17 files changed, 787 insertions(+), 805 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c index 9e1a70cc4..21f3a22e2 100644 --- a/os/kernel/src/chcond.c +++ b/os/kernel/src/chcond.c @@ -22,8 +22,9 @@ */ /** - * @file chcond.c - * @brief Condition Variables code. + * @file chcond.c + * @brief Condition Variables code. + * * @addtogroup condvars Condition Variables * @{ */ @@ -33,12 +34,12 @@ #if CH_USE_CONDVARS && CH_USE_MUTEXES /** - * @brief Initializes s @p CondVar structure. + * @brief Initializes s @p CondVar structure. + * @note This function can be invoked from within an interrupt handler even + * if it is not an I-Class API because it does not touch any critical + * kernel data structure. * - * @param[out] cp pointer to a @p CondVar structure - * @note This function can be invoked from within an interrupt handler even if - * it is not an I-Class API because it does not touch any critical kernel - * data structure. + * @param[out] cp pointer to a @p CondVar structure */ void chCondInit(CondVar *cp) { @@ -48,37 +49,37 @@ void chCondInit(CondVar *cp) { } /** - * @brief Signals one thread that is waiting on the condition variable. + * @brief Signals one thread that is waiting on the condition variable. * - * @param[in] cp pointer to the @p CondVar structure + * @param[in] cp pointer to the @p CondVar structure */ void chCondSignal(CondVar *cp) { chDbgCheck(cp != NULL, "chCondSignal"); chSysLock(); - if (notempty(&cp->c_queue)) /* any thread ? */ + if (notempty(&cp->c_queue)) chSchWakeupS(fifo_remove(&cp->c_queue), RDY_OK); chSysUnlock(); } /** - * @brief Signals one thread that is waiting on the condition variable. + * @brief Signals one thread that is waiting on the condition variable. * - * @param[in] cp pointer to the @p CondVar structure + * @param[in] cp pointer to the @p CondVar structure */ void chCondSignalI(CondVar *cp) { chDbgCheck(cp != NULL, "chCondSignalI"); - if (notempty(&cp->c_queue)) /* any thread ? */ + if (notempty(&cp->c_queue)) chSchReadyI(fifo_remove(&cp->c_queue))->p_u.rdymsg = RDY_OK; } /** - * @brief Signals all threads that are waiting on the condition variable. + * @brief Signals all threads that are waiting on the condition variable. * - * @param[in] cp pointer to the @p CondVar structure + * @param[in] cp pointer to the @p CondVar structure */ void chCondBroadcast(CondVar *cp) { @@ -89,32 +90,32 @@ void chCondBroadcast(CondVar *cp) { } /** - * @brief Signals all threads that are waiting on the condition variable. + * @brief Signals all threads that are waiting on the condition variable. * - * @param[in] cp pointer to the @p CondVar structure + * @param[in] cp pointer to the @p CondVar structure */ void chCondBroadcastI(CondVar *cp) { chDbgCheck(cp != NULL, "chCondBroadcastI"); /* Empties the condition variable queue and inserts all the Threads into the - * ready list in FIFO order. The wakeup message is set to @p RDY_RESET in - * order to make a chCondBroadcast() detectable from a chCondSignal().*/ + ready list in FIFO order. The wakeup message is set to @p RDY_RESET in + order to make a chCondBroadcast() detectable from a chCondSignal().*/ while (cp->c_queue.p_next != (void *)&cp->c_queue) chSchReadyI(fifo_remove(&cp->c_queue))->p_u.rdymsg = RDY_RESET; } /** - * @brief Waits on the condition variable releasing the mutex lock. + * @brief Waits on the condition variable releasing the mutex lock. * @details Releases the mutex, waits on the condition variable, and finally * acquires the mutex again. This is done atomically. + * @note The thread MUST already have locked the mutex when calling + * @p chCondWait(). * - * @param[in] cp pointer to the @p CondVar structure - * @return The wakep mode. - * @retval RDY_OK if the condvar was signaled using chCondSignal(). - * @retval RDY_RESET if the condvar was signaled using chCondBroadcast(). - * @note The thread MUST already have locked the mutex when calling - * @p chCondWait(). + * @param[in] cp pointer to the @p CondVar structure + * @return The wakep mode. + * @retval RDY_OK if the condvar was signaled using @p chCondSignal(). + * @retval RDY_RESET if the condvar was signaled using @p chCondBroadcast(). */ msg_t chCondWait(CondVar *cp) { msg_t msg; @@ -126,16 +127,16 @@ msg_t chCondWait(CondVar *cp) { } /** - * @brief Waits on the condition variable releasing the mutex lock. + * @brief Waits on the condition variable releasing the mutex lock. * @details Releases the mutex, waits on the condition variable, and finally * acquires the mutex again. This is done atomically. + * @note The thread MUST already have locked the mutex when calling + * @p chCondWaitS(). * - * @param[in] cp pointer to the @p CondVar structure - * @return The wakep mode. - * @retval RDY_OK if the condvar was signaled using chCondSignal(). - * @retval RDY_RESET if the condvar was signaled using chCondBroadcast(). - * @note The thread MUST already have locked the mutex when calling - * @p chCondWaitS(). + * @param[in] cp pointer to the @p CondVar structure + * @return The wakep mode. + * @retval RDY_OK if the condvar was signaled using @p chCondSignal(). + * @retval RDY_RESET if the condvar was signaled using @p chCondBroadcast(). */ msg_t chCondWaitS(CondVar *cp) { Thread *ctp = currp; @@ -158,23 +159,23 @@ msg_t chCondWaitS(CondVar *cp) { #if CH_USE_CONDVARS_TIMEOUT /** - * @brief Waits on the condition variable releasing the mutex lock. + * @brief Waits on the condition variable releasing the mutex lock. * @details Releases the mutex, waits on the condition variable, and finally * acquires the mutex again. This is done atomically. + * @note The thread MUST already have locked the mutex when calling + * @p chCondWaitTimeout(). * - * @param[in] cp pointer to the @p CondVar structure - * @param[in] time the number of ticks before the operation timeouts, - * the special value @p TIME_INFINITE is allowed. - * It is not possible to specify zero @p TIME_IMMEDIATE - * as timeout specification because it would make no sense - * in this function. - * @return The wakep mode. - * @retval RDY_OK if the condvar was signaled using chCondSignal(). - * @retval RDY_RESET if the condvar was signaled using chCondBroadcast(). - * @retval RDY_TIMEOUT if the condvar was not signaled within the specified - * timeout. - * @note The thread MUST already have locked the mutex when calling - * @p chCondWaitTimeout(). + * @param[in] cp pointer to the @p CondVar structure + * @param[in] time the number of ticks before the operation timeouts, + * the special value @p TIME_INFINITE is allowed. + * It is not possible to specify zero @p TIME_IMMEDIATE + * as timeout specification because it would make no sense + * in this function. + * @return The wakep mode. + * @retval RDY_OK if the condvar was signaled using @p chCondSignal(). + * @retval RDY_RESET if the condvar was signaled using @p chCondBroadcast(). + * @retval RDY_TIMEOUT if the condvar was not signaled @p within the specified + * timeout. */ msg_t chCondWaitTimeout(CondVar *cp, systime_t time) { msg_t msg; @@ -186,23 +187,23 @@ msg_t chCondWaitTimeout(CondVar *cp, systime_t time) { } /** - * @brief Waits on the condition variable releasing the mutex lock. + * @brief Waits on the condition variable releasing the mutex lock. * @details Releases the mutex, waits on the condition variable, and finally * acquires the mutex again. This is done atomically. + * @note The thread MUST already have locked the mutex when calling + * @p chCondWaitTimeoutS(). * - * @param[in] cp pointer to the @p CondVar structure - * @param[in] time the number of ticks before the operation timeouts, - * the special value @p TIME_INFINITE is allowed. - * It is not possible to specify zero @p TIME_IMMEDIATE - * as timeout specification because it would make no sense - * in this function. - * @return The wakep mode. - * @retval RDY_OK if the condvar was signaled using chCondSignal(). - * @retval RDY_RESET if the condvar was signaled using chCondBroadcast(). - * @retval RDY_TIMEOUT if the condvar was not signaled within the specified - * timeout. - * @note The thread MUST already have locked the mutex when calling - * @p chCondWaitTimeoutS(). + * @param[in] cp pointer to the @p CondVar structure + * @param[in] time the number of ticks before the operation timeouts, + * the special value @p TIME_INFINITE is allowed. + * It is not possible to specify zero @p TIME_IMMEDIATE + * as timeout specification because it would make no sense + * in this function. + * @return The wakep mode. + * @retval RDY_OK if the condvar was signaled using @p chCondSignal(). + * @retval RDY_RESET if the condvar was signaled using @p chCondBroadcast(). + * @retval RDY_TIMEOUT if the condvar was not signaled within the specified + * timeout. */ msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time) { Thread *ctp = currp; diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index 4868090b5..8a5b58744 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -18,8 +18,9 @@ */ /** - * @file chdebug.c - * @brief ChibiOS/RT Debug code. + * @file chdebug.c + * @brief ChibiOS/RT Debug code. + * * @addtogroup debug * @{ */ @@ -28,12 +29,12 @@ #if CH_DBG_ENABLE_TRACE /** - * @brief Public trace buffer. + * @brief Public trace buffer. */ TraceBuffer trace_buffer; /** - * @brief Trace circular buffer subsystem initialization. + * @brief Trace circular buffer subsystem initialization. */ void trace_init(void) { @@ -42,10 +43,10 @@ void trace_init(void) { } /** - * @brief Inserts in the circular debug trace buffer a context switch record. + * @brief Inserts in the circular debug trace buffer a context switch record. * - * @param[in] otp the thread being switched out - * @param[in] ntp the thread to be switched in + * @param[in] otp the thread being switched out + * @param[in] ntp the thread to be switched in */ void chDbgTrace(Thread *otp, Thread *ntp) { @@ -60,7 +61,7 @@ void chDbgTrace(Thread *otp, Thread *ntp) { #if CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK /** - * @brief Pointer to the panic message. + * @brief Pointer to the panic message. * @details This pointer is meant to be accessed through the debugger, it is * written once and then the system is halted. This variable can be * set to @p NULL if the halt is caused by a stack overflow. @@ -68,9 +69,9 @@ void chDbgTrace(Thread *otp, Thread *ntp) { char *panic_msg; /** - * @brief Prints a panic message on the console and then halts the system. + * @brief Prints a panic message on the console and then halts the system. * - * @param[in] msg the pointer to the panic message string + * @param[in] msg the pointer to the panic message string */ void chDbgPanic(char *msg) { diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index 9da61adaf..310f04212 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -18,8 +18,9 @@ */ /** - * @file chevents.c - * @brief Events code. + * @file chevents.c + * @brief Events code. + * * @addtogroup events * @{ */ @@ -27,15 +28,15 @@ #if CH_USE_EVENTS /** - * @brief Registers an Event Listener on an Event Source. + * @brief Registers an Event Listener on an Event Source. + * @note Multiple Event Listeners can specify the same bits to be pended. * - * @param[in] esp pointer to the @p EventSource structure - * @param[in] elp pointer to the @p EventListener structure - * @param[in] emask the mask of event flags to be pended to the thread when the - * event source is broadcasted - * @note Multiple Event Listeners can specify the same bits to be pended. + * @param[in] esp pointer to the @p EventSource structure + * @param[in] elp pointer to the @p EventListener structure + * @param[in] mask the mask of event flags to be pended to the thread when + * the event source is broadcasted */ -void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t emask) { +void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t mask) { chDbgCheck((esp != NULL) && (elp != NULL), "chEvtRegisterMask"); @@ -43,20 +44,20 @@ void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t emask) elp->el_next = esp->es_next; esp->es_next = elp; elp->el_listener = currp; - elp->el_mask = emask; + elp->el_mask = mask; chSysUnlock(); } /** - * @brief Unregisters an Event Listener from its Event Source. + * @brief Unregisters an Event Listener from its Event Source. + * @note If the event listener is not registered on the specified event + * source then the function does nothing. + * @note For optimal performance it is better to perform the unregister + * operations in inverse order of the register operations (elements + * are found on top of the list). * - * @param[in] esp pointer to the @p EventSource structure - * @param[in] elp pointer to the @p EventListener structure - * @note If the event listener is not registered on the specified event source - * then the function does nothing. - * @note For optimal performance it is better to perform the unregister - * operations in inverse order of the register operations (elements are - * found on top of the list). + * @param[in] esp pointer to the @p EventSource structure + * @param[in] elp pointer to the @p EventListener structure */ void chEvtUnregister(EventSource *esp, EventListener *elp) { EventListener *p; @@ -76,10 +77,10 @@ void chEvtUnregister(EventSource *esp, EventListener *elp) { } /** - * @brief Clears the pending events specified in the mask. + * @brief Clears the pending events specified in the mask. * - * @param[in] mask the events to be cleared - * @return The pending events that were cleared. + * @param[in] mask the events to be cleared + * @return The pending events that were cleared. */ eventmask_t chEvtClear(eventmask_t mask) { eventmask_t m; @@ -94,11 +95,11 @@ eventmask_t chEvtClear(eventmask_t mask) { } /** - * @brief Pends a set of event flags on the current thread, this is @b much - * faster than using @p chEvtBroadcast() or @p chEvtSignal(). + * @brief Pends a set of event flags on the current thread, this is @b much + * faster than using @p chEvtBroadcast() or @p chEvtSignal(). * - * @param[in] mask the events to be pended - * @return The current pending events mask. + * @param[in] mask the events to be pended + * @return The current pending events mask. */ eventmask_t chEvtPend(eventmask_t mask) { @@ -111,10 +112,10 @@ eventmask_t chEvtPend(eventmask_t mask) { } /** - * @brief Pends a set of event flags on the specified @p Thread. + * @brief Pends a set of event flags on the specified @p Thread. * - * @param[in] tp the thread to be signaled - * @param[in] mask the event flags set to be pended + * @param[in] tp the thread to be signaled + * @param[in] mask the event flags set to be pended */ void chEvtSignal(Thread *tp, eventmask_t mask) { @@ -126,10 +127,10 @@ void chEvtSignal(Thread *tp, eventmask_t mask) { } /** - * @brief Pends a set of event flags on the specified @p Thread. + * @brief Pends a set of event flags on the specified @p Thread. * - * @param[in] tp the thread to be signaled - * @param[in] mask the event flags set to be pended + * @param[in] tp the thread to be signaled + * @param[in] mask the event flags set to be pended */ void chEvtSignalI(Thread *tp, eventmask_t mask) { @@ -145,10 +146,10 @@ void chEvtSignalI(Thread *tp, eventmask_t mask) { } /** - * @brief Signals all the Event Listeners registered on the specified Event - * Source. + * @brief Signals all the Event Listeners registered on the specified Event + * Source. * - * @param[in] esp pointer to the @p EventSource structure + * @param[in] esp pointer to the @p EventSource structure */ void chEvtBroadcast(EventSource *esp) { @@ -159,10 +160,10 @@ void chEvtBroadcast(EventSource *esp) { } /** - * @brief Signals all the Event Listeners registered on the specified Event - * Source. + * @brief Signals all the Event Listeners registered on the specified Event + * Source. * - * @param[in] esp pointer to the @p EventSource structure + * @param[in] esp pointer to the @p EventSource structure */ void chEvtBroadcastI(EventSource *esp) { EventListener *elp; @@ -177,11 +178,11 @@ void chEvtBroadcastI(EventSource *esp) { } /** - * @brief Invokes the event handlers associated to an event flags mask. + * @brief Invokes the event handlers associated to an event flags mask. * - * @param[in] mask mask of the events to be dispatched - * @param[in] handlers an array of @p evhandler_t. The array must have size - * equal to the number of bits in eventmask_t. + * @param[in] mask mask of the events to be dispatched + * @param[in] handlers an array of @p evhandler_t. The array must have size + * equal to the number of bits in eventmask_t. */ void chEvtDispatch(const evhandler_t handlers[], eventmask_t mask) { eventid_t eid; @@ -203,29 +204,29 @@ void chEvtDispatch(const evhandler_t handlers[], eventmask_t mask) { #if CH_OPTIMIZE_SPEED || !CH_USE_EVENTS_TIMEOUT || defined(__DOXYGEN__) /** - * @brief Waits for exactly one of the specified events. + * @brief Waits for exactly one of the specified events. * @details The function waits for one event among those specified in - * @p ewmask to become pending then the event is cleared and returned. + * @p mask to become pending then the event is cleared and returned. + * @note One and only one event is served in the function, the one with the + * lowest event id. The function is meant to be invoked into a loop in + * order to serve all the pending events.
+ * This means that Event Listeners with a lower event identifier have + * an higher priority. * - * @param[in] ewmask mask of the events that the function should wait for, - * @p ALL_EVENTS enables all the events - * @return The mask of the lowest id served and cleared event. - * @note One and only one event is served in the function, the one with the - * lowest event id. The function is meant to be invoked into a loop in - * order to serve all the pending events.
- * This means that Event Listeners with a lower event identifier have - * an higher priority. + * @param[in] mask mask of the events that the function should wait for, + * @p ALL_EVENTS enables all the events + * @return The mask of the lowest id served and cleared event. */ -eventmask_t chEvtWaitOne(eventmask_t ewmask) { +eventmask_t chEvtWaitOne(eventmask_t mask) { Thread *ctp = currp; eventmask_t m; chSysLock(); - if ((m = (ctp->p_epending & ewmask)) == 0) { - ctp->p_u.ewmask = ewmask; + if ((m = (ctp->p_epending & mask)) == 0) { + ctp->p_u.ewmask = mask; chSchGoSleepS(THD_STATE_WTOREVT); - m = ctp->p_epending & ewmask; + m = ctp->p_epending & mask; } m &= -m; ctp->p_epending &= ~m; @@ -235,24 +236,24 @@ eventmask_t chEvtWaitOne(eventmask_t ewmask) { } /** - * @brief Waits for any of the specified events. + * @brief Waits for any of the specified events. * @details The function waits for any event among those specified in - * @p ewmask to become pending then the events are cleared and returned. + * @p mask to become pending then the events are cleared and returned. * - * @param[in] ewmask mask of the events that the function should wait for, - * @p ALL_EVENTS enables all the events - * @return The mask of the served and cleared events. + * @param[in] mask mask of the events that the function should wait for, + * @p ALL_EVENTS enables all the events + * @return The mask of the served and cleared events. */ -eventmask_t chEvtWaitAny(eventmask_t ewmask) { +eventmask_t chEvtWaitAny(eventmask_t mask) { Thread *ctp = currp; eventmask_t m; chSysLock(); - if ((m = (ctp->p_epending & ewmask)) == 0) { - ctp->p_u.ewmask = ewmask; + if ((m = (ctp->p_epending & mask)) == 0) { + ctp->p_u.ewmask = mask; chSchGoSleepS(THD_STATE_WTOREVT); - m = ctp->p_epending & ewmask; + m = ctp->p_epending & mask; } ctp->p_epending &= ~m; @@ -261,63 +262,63 @@ eventmask_t chEvtWaitAny(eventmask_t ewmask) { } /** - * @brief Waits for all the specified events. - * @details The function waits for all the events specified in @p ewmask to + * @brief Waits for all the specified events. + * @details The function waits for all the events specified in @p mask to * become pending then the events are cleared and returned. * - * @param[in] ewmask mask of the event ids that the function should wait for - * @return The mask of the served and cleared events. + * @param[in] mask mask of the event ids that the function should wait for + * @return The mask of the served and cleared events. */ -eventmask_t chEvtWaitAll(eventmask_t ewmask) { +eventmask_t chEvtWaitAll(eventmask_t mask) { Thread *ctp = currp; chSysLock(); - if ((ctp->p_epending & ewmask) != ewmask) { - ctp->p_u.ewmask = ewmask; + if ((ctp->p_epending & mask) != mask) { + ctp->p_u.ewmask = mask; chSchGoSleepS(THD_STATE_WTANDEVT); } - ctp->p_epending &= ~ewmask; + ctp->p_epending &= ~mask; chSysUnlock(); - return ewmask; + return mask; } #endif /* CH_OPTIMIZE_SPEED || !CH_USE_EVENTS_TIMEOUT */ #if CH_USE_EVENTS_TIMEOUT /** - * @brief Waits for exactly one of the specified events. + * @brief Waits for exactly one of the specified events. * @details The function waits for one event among those specified in - * @p ewmask to become pending then the event is cleared and returned. + * @p mask to become pending then the event is cleared and returned. + * @note One and only one event is served in the function, the one with the + * lowest event id. The function is meant to be invoked into a loop in + * order to serve all the pending events.
+ * This means that Event Listeners with a lower event identifier have + * an higher priority. * - * @param[in] ewmask mask of the events that the function should wait for, - * @p ALL_EVENTS enables all the events - * @param[in] time 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 lowest id served and cleared event. - * @retval 0 if the specified timeout expired. - * @note One and only one event is served in the function, the one with the - * lowest event id. The function is meant to be invoked into a loop in - * order to serve all the pending events.
- * This means that Event Listeners with a lower event identifier have - * an higher priority. + * @param[in] mask mask of the events that the function should wait for, + * @p ALL_EVENTS enables all the events + * @param[in] time 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 lowest id served and cleared event. + * @retval 0 if the specified timeout expired. */ -eventmask_t chEvtWaitOneTimeout(eventmask_t ewmask, systime_t time) { +eventmask_t chEvtWaitOneTimeout(eventmask_t mask, systime_t time) { Thread *ctp = currp; eventmask_t m; chSysLock(); - if ((m = (ctp->p_epending & ewmask)) == 0) { + if ((m = (ctp->p_epending & mask)) == 0) { if (TIME_IMMEDIATE == time) return (eventmask_t)0; - ctp->p_u.ewmask = ewmask; + ctp->p_u.ewmask = mask; if (chSchGoSleepTimeoutS(THD_STATE_WTOREVT, time) < RDY_OK) return (eventmask_t)0; - m = ctp->p_epending & ewmask; + m = ctp->p_epending & mask; } m &= -m; ctp->p_epending &= ~m; @@ -327,34 +328,34 @@ eventmask_t chEvtWaitOneTimeout(eventmask_t ewmask, systime_t time) { } /** - * @brief Waits for any of the specified events. + * @brief Waits for any of the specified events. * @details The function waits for any event among those specified in - * @p ewmask to become pending then the events are cleared and + * @p mask to become pending then the events are cleared and * returned. * - * @param[in] ewmask mask of the events that the function should wait for, - * @p ALL_EVENTS enables all the events - * @param[in] time 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 specified timeout expired. + * @param[in] mask mask of the events that the function should wait for, + * @p ALL_EVENTS enables all the events + * @param[in] time 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 specified timeout expired. */ -eventmask_t chEvtWaitAnyTimeout(eventmask_t ewmask, systime_t time) { +eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t time) { Thread *ctp = currp; eventmask_t m; chSysLock(); - if ((m = (ctp->p_epending & ewmask)) == 0) { + if ((m = (ctp->p_epending & mask)) == 0) { if (TIME_IMMEDIATE == time) return (eventmask_t)0; - ctp->p_u.ewmask = ewmask; + ctp->p_u.ewmask = mask; if (chSchGoSleepTimeoutS(THD_STATE_WTOREVT, time) < RDY_OK) return (eventmask_t)0; - m = ctp->p_epending & ewmask; + m = ctp->p_epending & mask; } ctp->p_epending &= ~m; @@ -363,35 +364,35 @@ eventmask_t chEvtWaitAnyTimeout(eventmask_t ewmask, systime_t time) { } /** - * @brief Waits for all the specified events. - * @details The function waits for all the events specified in @p ewmask to + * @brief Waits for all the specified events. + * @details The function waits for all the events specified in @p mask to * become pending then the events are cleared and returned. * - * @param[in] ewmask mask of the event ids that the function should wait for - * @param[in] time 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 specified timeout expired. + * @param[in] mask mask of the event ids that the function should wait for + * @param[in] time 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 specified timeout expired. */ -eventmask_t chEvtWaitAllTimeout(eventmask_t ewmask, systime_t time) { +eventmask_t chEvtWaitAllTimeout(eventmask_t mask, systime_t time) { Thread *ctp = currp; chSysLock(); - if ((ctp->p_epending & ewmask) != ewmask) { + if ((ctp->p_epending & mask) != mask) { if (TIME_IMMEDIATE == time) return (eventmask_t)0; - ctp->p_u.ewmask = ewmask; + ctp->p_u.ewmask = mask; if (chSchGoSleepTimeoutS(THD_STATE_WTANDEVT, time) < RDY_OK) return (eventmask_t)0; } - ctp->p_epending &= ~ewmask; + ctp->p_epending &= ~mask; chSysUnlock(); - return ewmask; + return mask; } #endif /* CH_USE_EVENTS_TIMEOUT */ diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c index e434fd2ab..45431d5f4 100644 --- a/os/kernel/src/chheap.c +++ b/os/kernel/src/chheap.c @@ -18,8 +18,9 @@ */ /** - * @file chheap.c - * @brief Heaps code. + * @file chheap.c + * @brief Heaps code. + * * @addtogroup heaps * @{ */ @@ -42,14 +43,13 @@ #if !CH_USE_MALLOC_HEAP /** - * @brief Default heap descriptor. + * @brief Default heap descriptor. */ static MemoryHeap default_heap; /** - * @brief Initializes the default heap. - * - * @note Internal use only. + * @brief Initializes the default heap. + * @note Internal use only. */ void heap_init(void) { default_heap.h_provider = chCoreAlloc; @@ -63,14 +63,13 @@ void heap_init(void) { } /** - * @brief Initializes a memory heap from a static memory area. - * - * @param[out] heapp pointer to a memory heap descriptor to be initialized - * @param[in] buf heap buffer base - * @param[in] size heap size + * @brief Initializes a memory heap from a static memory area. + * @note Both the heap buffer base and the heap size must be aligned to + * the @p align_t type size. * - * @note Both the heap buffer base and the heap size must be aligned to - * the @p align_t type size. + * @param[out] heapp pointer to the memory heap descriptor to be initialized + * @param[in] buf heap buffer base + * @param[in] size heap size */ void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) { struct heap_header *hp; @@ -90,18 +89,18 @@ void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) { } /** - * @brief Allocates a block of memory from the heap by using the first-fit - * algorithm. + * @brief Allocates a block of memory from the heap by using the first-fit + * algorithm. * @details The allocated block is guaranteed to be properly aligned for a * pointer data type (@p align_t). * - * @param[in] heapp pointer to a heap descriptor or @p NULL in order to access - * the default heap. - * @param[in] size the size of the block to be allocated. Note that the - * allocated block may be a bit bigger than the requested - * size for alignment and fragmentation reasons. - * @return A pointer to the allocated block. - * @retval NULL if the block cannot be allocated. + * @param[in] heapp pointer to a heap descriptor or @p NULL in order to + * access the default heap. + * @param[in] size the size of the block to be allocated. Note that the + * allocated block may be a bit bigger than the requested + * size for alignment and fragmentation reasons. + * @return A pointer to the allocated block. + * @retval NULL if the block cannot be allocated. */ void *chHeapAlloc(MemoryHeap *heapp, size_t size) { struct heap_header *qp, *hp, *fp; @@ -117,17 +116,13 @@ void *chHeapAlloc(MemoryHeap *heapp, size_t size) { hp = qp->h_u.next; if (hp->h_size >= size) { if (hp->h_size < size + sizeof(struct heap_header)) { - /* - * Gets the whole block even if it is slightly bigger than the - * requested size because the fragment would be too small to be - * useful. - */ + /* Gets the whole block even if it is slightly bigger than the + requested size because the fragment would be too small to be + useful.*/ qp->h_u.next = hp->h_u.next; } else { - /* - * Block bigger enough, must split it. - */ + /* Block bigger enough, must split it.*/ fp = (void *)((uint8_t *)(hp) + sizeof(struct heap_header) + size); fp->h_u.next = hp->h_u.next; fp->h_size = hp->h_size - sizeof(struct heap_header) - size; @@ -144,9 +139,8 @@ void *chHeapAlloc(MemoryHeap *heapp, size_t size) { H_UNLOCK(heapp); - /* - * More memory is required, tries to get it from the associated provider. - */ + /* More memory is required, tries to get it from the associated provider + else fails.*/ if (heapp->h_provider) { hp = heapp->h_provider(size + sizeof(struct heap_header)); if (hp != NULL) { @@ -164,9 +158,9 @@ void *chHeapAlloc(MemoryHeap *heapp, size_t size) { (p)->h_size) /** - * @brief Frees a previously allocated memory block. + * @brief Frees a previously allocated memory block. * - * @param[in] p the memory block pointer + * @param[in] p pointer to the memory block to be freed */ void chHeapFree(void *p) { struct heap_header *qp, *hp; @@ -186,25 +180,17 @@ void chHeapFree(void *p) { if (((qp == &heapp->h_free) || (hp > qp)) && ((qp->h_u.next == NULL) || (hp < qp->h_u.next))) { - /* - * Insertion after qp. - */ + /* Insertion after qp.*/ hp->h_u.next = qp->h_u.next; qp->h_u.next = hp; - /* - * Verifies if the newly inserted block should be merged. - */ + /* Verifies if the newly inserted block should be merged.*/ if (LIMIT(hp) == hp->h_u.next) { - /* - * Merge with the next block. - */ + /* Merge with the next block.*/ hp->h_size += hp->h_u.next->h_size + sizeof(struct heap_header); hp->h_u.next = hp->h_u.next->h_u.next; } if ((LIMIT(qp) == hp)) { - /* - * Merge with the previous block. - */ + /* Merge with the previous block.*/ qp->h_size += hp->h_size + sizeof(struct heap_header); qp->h_u.next = hp->h_u.next; } @@ -218,17 +204,17 @@ void chHeapFree(void *p) { } /** - * @brief Reports the heap status. + * @brief Reports the heap status. + * @note This function is meant to be used in the test suite, it should + * not be really useful for the application code. + * @note This function is not implemented when the @p CH_USE_MALLOC_HEAP + * configuration option is used (it always returns zero). * - * @param[in] heapp pointer to a heap descriptor or @p NULL in order to access - * the default heap. - * @param[in] sizep pointer to a variable that will receive the total - * fragmented free space - * @return The number of fragments in the heap. - * @note This function is meant to be used in the test suite, it should not be - * really useful for the application code. - * @note This function is not implemented when the @p CH_USE_MALLOC_HEAP - * configuration option is used (it always returns zero). + * @param[in] heapp pointer to a heap descriptor or @p NULL in order to + * access the default heap. + * @param[in] sizep pointer to a variable that will receive the total + * fragmented free space + * @return The number of fragments in the heap. */ size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep) { struct heap_header *qp; diff --git a/os/kernel/src/chlists.c b/os/kernel/src/chlists.c index 53f91649a..2aeb55ecb 100644 --- a/os/kernel/src/chlists.c +++ b/os/kernel/src/chlists.c @@ -18,8 +18,9 @@ */ /** - * @file chlists.c - * @brief Thread queues/lists code. + * @file chlists.c + * @brief Thread queues/lists code. + * * @addtogroup internals * @{ */ @@ -27,35 +28,35 @@ #if !CH_OPTIMIZE_SPEED || defined(__DOXYGEN__) /** - * @brief Inserts a thread into a priority ordered queue. - * @note The insertion is done by scanning the list from the highest priority - * toward the lowest. - * @note This function is @b not an API. + * @brief Inserts a thread into a priority ordered queue. + * @note The insertion is done by scanning the list from the highest priority + * toward the lowest. + * @note This function is @b not an API. * - * @param[in] tp the pointer to the thread to be inserted in the list - * @param[in] tqp the pointer to the threads list header + * @param[in] tp the pointer to the thread to be inserted in the list + * @param[in] tqp the pointer to the threads list header */ void prio_insert(Thread *tp, ThreadsQueue *tqp) { - /* cp iterates over the queue */ + /* cp iterates over the queue.*/ Thread *cp = (Thread *)tqp; do { - /* iterate to next thread in queue */ + /* Iterate to next thread in queue.*/ cp = cp->p_next; - /* not end of queue? and cp has equal or higher priority than tp? */ + /* Not end of queue? and cp has equal or higher priority than tp?.*/ } while ((cp != (Thread *)tqp) && (cp->p_prio >= tp->p_prio)); - /* insert before cp, point tp to next and prev in queue */ + /* Insert before cp, point tp to next and prev in queue.*/ tp->p_prev = (tp->p_next = cp)->p_prev; - /* make prev point to tp, and cp point back to tp */ + /* Make prev point to tp, and cp point back to tp.*/ tp->p_prev->p_next = cp->p_prev = tp; } /** - * @brief Inserts a Thread into a queue. - * @note This function is @b not an API. + * @brief Inserts a Thread into a queue. + * @note This function is @b not an API. * - * @param[in] tp the pointer to the thread to be inserted in the list - * @param[in] tqp the pointer to the threads list header + * @param[in] tp the pointer to the thread to be inserted in the list + * @param[in] tqp the pointer to the threads list header */ void queue_insert(Thread *tp, ThreadsQueue *tqp) { @@ -64,13 +65,13 @@ void queue_insert(Thread *tp, ThreadsQueue *tqp) { } /** - * @brief Removes the first-out Thread from a queue and returns it. - * @note If the queue is priority ordered then this function returns the - * thread with the highest priority. - * @note This function is @b not an API. + * @brief Removes the first-out Thread from a queue and returns it. + * @note If the queue is priority ordered then this function returns the + * thread with the highest priority. + * @note This function is @b not an API. * - * @param[in] tqp the pointer to the threads list header - * @return The removed thread pointer. + * @param[in] tqp the pointer to the threads list header + * @return The removed thread pointer. */ Thread *fifo_remove(ThreadsQueue *tqp) { Thread *tp = tqp->p_next; @@ -80,13 +81,13 @@ Thread *fifo_remove(ThreadsQueue *tqp) { } /** - * @brief Removes the last-out Thread from a queue and returns it. - * @note If the queue is priority ordered then this function returns the - * thread with the lowest priority. - * @note This function is @b not an API. + * @brief Removes the last-out Thread from a queue and returns it. + * @note If the queue is priority ordered then this function returns the + * thread with the lowest priority. + * @note This function is @b not an API. * - * @param[in] tqp the pointer to the threads list header - * @return The removed thread pointer. + * @param[in] tqp the pointer to the threads list header + * @return The removed thread pointer. */ Thread *lifo_remove(ThreadsQueue *tqp) { Thread *tp = tqp->p_prev; @@ -96,13 +97,13 @@ Thread *lifo_remove(ThreadsQueue *tqp) { } /** - * @brief Removes a Thread from a queue and returns it. + * @brief Removes a Thread from a queue and returns it. * @details The thread is removed from the queue regardless of its relative * position and regardless the used insertion method. - * @note This function is @b not an API. + * @note This function is @b not an API. * - * @param[in] tp the pointer to the thread to be removed from the queue - * @return The removed thread pointer. + * @param[in] tp the pointer to the thread to be removed from the queue + * @return The removed thread pointer. */ Thread *dequeue(Thread *tp) { @@ -112,11 +113,11 @@ Thread *dequeue(Thread *tp) { } /** - * @brief Pushes a Thread on top of a stack list. - * @note This function is @b not an API. + * @brief Pushes a Thread on top of a stack list. + * @note This function is @b not an API. * - * @param[in] tp the pointer to the thread to be inserted in the list - * @param[in] tlp the pointer to the threads list header + * @param[in] tp the pointer to the thread to be inserted in the list + * @param[in] tlp the pointer to the threads list header */ void list_insert(Thread *tp, ThreadsList *tlp) { @@ -125,12 +126,12 @@ void list_insert(Thread *tp, ThreadsList *tlp) { } /** - * @brief Pops a Thread from the top of a stack list and returns it. - * @note The list must be non-empty before calling this function. - * @note This function is @b not an API. + * @brief Pops a Thread from the top of a stack list and returns it. + * @note The list must be non-empty before calling this function. + * @note This function is @b not an API. * - * @param[in] tlp the pointer to the threads list header - * @return The removed thread pointer. + * @param[in] tlp the pointer to the threads list header + * @return The removed thread pointer. */ Thread *list_remove(ThreadsList *tlp) { diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c index 3bcf687fc..aee514f84 100644 --- a/os/kernel/src/chmboxes.c +++ b/os/kernel/src/chmboxes.c @@ -18,8 +18,9 @@ */ /** - * @file chmboxes.c - * @brief Mailboxes code. + * @file chmboxes.c + * @brief Mailboxes code. + * * @addtogroup mailboxes * @{ */ @@ -28,11 +29,11 @@ #if CH_USE_MAILBOXES /** - * @brief Initializes a Mailbox object. + * @brief Initializes a Mailbox object. * - * @param[out] mbp the pointer to the Mailbox structure to be initialized - * @param[in] buf the circular messages buffer - * @param[in] n the buffer size as number of @p msg_t + * @param[out] mbp the pointer to the Mailbox structure to be initialized + * @param[in] buf the circular messages buffer + * @param[in] n the buffer size as number of @p msg_t */ void chMBInit(Mailbox *mbp, msg_t *buf, cnt_t n) { @@ -45,11 +46,11 @@ void chMBInit(Mailbox *mbp, msg_t *buf, cnt_t n) { } /** - * @brief Resets a Mailbox object. + * @brief Resets a Mailbox object. * @details All the waiting threads are resumed with status @p RDY_RESET and * the queued messages are lost. * - * @param[in] mbp the pointer to an initialized Mailbox object + * @param[in] mbp the pointer to an initialized Mailbox object */ void chMBReset(Mailbox *mbp) { @@ -64,21 +65,21 @@ void chMBReset(Mailbox *mbp) { } /** - * @brief Posts a message into a mailbox. + * @brief Posts a message into a mailbox. * @details The invoking thread waits until a empty slot in the mailbox becomes * available or the specified time runs out. * - * @param[in] mbp the pointer to an initialized Mailbox object - * @param[in] msg the message to be posted on the mailbox - * @param[in] time 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 operation status. - * @retval RDY_OK if the message was correctly posted. - * @retval RDY_RESET if the mailbox was reset while waiting. - * @retval RDY_TIMEOUT if the operation timed out. + * @param[in] mbp the pointer to an initialized Mailbox object + * @param[in] msg the message to be posted on the mailbox + * @param[in] time 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 operation status. + * @retval RDY_OK if the message was correctly posted. + * @retval RDY_RESET if the mailbox was reset while waiting. + * @retval RDY_TIMEOUT if the operation timed out. */ msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t time) { msg_t rdymsg; @@ -90,21 +91,21 @@ msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t time) { } /** - * @brief Posts a message into a mailbox. + * @brief Posts a message into a mailbox. * @details The invoking thread waits until a empty slot in the mailbox becomes * available or the specified time runs out. * - * @param[in] mbp the pointer to an initialized Mailbox object - * @param[in] msg the message to be posted on the mailbox - * @param[in] time 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 operation status. - * @retval RDY_OK if the message was correctly posted. - * @retval RDY_RESET if the mailbox was reset while waiting. - * @retval RDY_TIMEOUT if the operation timed out. + * @param[in] mbp the pointer to an initialized Mailbox object + * @param[in] msg the message to be posted on the mailbox + * @param[in] time 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 operation status. + * @retval RDY_OK if the message was correctly posted. + * @retval RDY_RESET if the mailbox was reset while waiting. + * @retval RDY_TIMEOUT if the operation timed out. */ msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) { msg_t rdymsg; @@ -123,21 +124,21 @@ msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) { } /** - * @brief Posts an high priority message into a mailbox. + * @brief Posts an high priority message into a mailbox. * @details The invoking thread waits until a empty slot in the mailbox becomes * available or the specified time runs out. * - * @param[in] mbp the pointer to an initialized Mailbox object - * @param[in] msg the message to be posted on the mailbox - * @param[in] time 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 operation status. - * @retval RDY_OK if the message was correctly posted. - * @retval RDY_RESET if the mailbox was reset while waiting. - * @retval RDY_TIMEOUT if the operation timed out. + * @param[in] mbp the pointer to an initialized Mailbox object + * @param[in] msg the message to be posted on the mailbox + * @param[in] time 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 operation status. + * @retval RDY_OK if the message was correctly posted. + * @retval RDY_RESET if the mailbox was reset while waiting. + * @retval RDY_TIMEOUT if the operation timed out. */ msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t time) { msg_t rdymsg; @@ -149,21 +150,21 @@ msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t time) { } /** - * @brief Posts an high priority message into a mailbox. + * @brief Posts an high priority message into a mailbox. * @details The invoking thread waits until a empty slot in the mailbox becomes * available or the specified time runs out. * - * @param[in] mbp the pointer to an initialized Mailbox object - * @param[in] msg the message to be posted on the mailbox - * @param[in] time 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 operation status. - * @retval RDY_OK if the message was correctly posted. - * @retval RDY_RESET if the mailbox was reset while waiting. - * @retval RDY_TIMEOUT if the operation timed out. + * @param[in] mbp the pointer to an initialized Mailbox object + * @param[in] msg the message to be posted on the mailbox + * @param[in] time 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 operation status. + * @retval RDY_OK if the message was correctly posted. + * @retval RDY_RESET if the mailbox was reset while waiting. + * @retval RDY_TIMEOUT if the operation timed out. */ msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) { msg_t rdymsg; @@ -182,21 +183,21 @@ msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) { } /** - * @brief Retrieves a message from a mailbox. + * @brief Retrieves a message from a mailbox. * @details The invoking thread waits until a message is posted in the mailbox * or the specified time runs out. * - * @param[in] mbp the pointer to an initialized Mailbox object - * @param[out] msgp pointer to a message variable for the received message - * @param[in] time 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 operation status. - * @retval RDY_OK if a message was correctly fetched. - * @retval RDY_RESET if the mailbox was reset while waiting. - * @retval RDY_TIMEOUT if the operation timed out. + * @param[in] mbp the pointer to an initialized Mailbox object + * @param[out] msgp pointer to a message variable for the received message + * @param[in] time 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 operation status. + * @retval RDY_OK if a message was correctly fetched. + * @retval RDY_RESET if the mailbox was reset while waiting. + * @retval RDY_TIMEOUT if the operation timed out. */ msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t time) { msg_t rdymsg; @@ -208,21 +209,21 @@ msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t time) { } /** - * @brief Retrieves a message from a mailbox. + * @brief Retrieves a message from a mailbox. * @details The invoking thread waits until a message is posted in the mailbox * or the specified time runs out. * - * @param[in] mbp the pointer to an initialized Mailbox object - * @param[out] msgp pointer to a message variable for the received message - * @param[in] time 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 operation status. - * @retval RDY_OK if a message was correctly fetched. - * @retval RDY_RESET if the mailbox was reset while waiting. - * @retval RDY_TIMEOUT if the operation timed out. + * @param[in] mbp the pointer to an initialized Mailbox object + * @param[out] msgp pointer to a message variable for the received message + * @param[in] time 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 operation status. + * @retval RDY_OK if a message was correctly fetched. + * @retval RDY_RESET if the mailbox was reset while waiting. + * @retval RDY_TIMEOUT if the operation timed out. */ msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t time) { msg_t rdymsg; diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index 6cf42788b..8269deb48 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -18,8 +18,9 @@ */ /** - * @file chmemcore.c - * @brief Core memory manager code. + * @file chmemcore.c + * @brief Core memory manager code. + * * @addtogroup memcore * @{ */ @@ -55,9 +56,9 @@ void core_init(void) { * sizeof(align_t). * * - * @param[in] size the size of the block to be allocated - * @return A pointer to the allocated memory block. - * @retval NULL allocation failed, core memory exhausted. + * @param[in] size the size of the block to be allocated + * @return A pointer to the allocated memory block. + * @retval NULL allocation failed, core memory exhausted. */ void *chCoreAlloc(size_t size) { void *p; @@ -74,9 +75,9 @@ void *chCoreAlloc(size_t size) { * type @p align_t so it is not possible to allocate less than * sizeof(align_t). * - * @param[in] size the size of the block to be allocated. - * @return A pointer to the allocated memory block. - * @retval NULL allocation failed, core memory exhausted. + * @param[in] size the size of the block to be allocated. + * @return A pointer to the allocated memory block. + * @retval NULL allocation failed, core memory exhausted. */ void *chCoreAllocI(size_t size) { void *p; @@ -92,7 +93,7 @@ void *chCoreAllocI(size_t size) { /** * @brief Core memory left. * - * @return The size, in bytes, of the free core memory. + * @return The size, in bytes, of the free core memory. */ size_t chCoreFree(void) { diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c index 02bbcee45..1e827c128 100644 --- a/os/kernel/src/chmempools.c +++ b/os/kernel/src/chmempools.c @@ -18,8 +18,9 @@ */ /** - * @file chmempools.c - * @brief Memory Pools code. + * @file chmempools.c + * @brief Memory Pools code. + * * @addtogroup pools * @{ */ @@ -28,16 +29,17 @@ #if CH_USE_MEMPOOLS /** - * @brief Initializes an empty memory pool. - * - * @param[out] mp pointer to a @p MemoryPool structure - * @param[in] size the size of the objects contained in this memory pool, - * the minimum accepted size is the size of a pointer to void. - * @param[in] provider memory provider function for the memory pool or - * @p NULL if the pool is not allowed to grow automatically + * @brief Initializes an empty memory pool. + * @note The size is internally aligned to be a multiple of the @p align_t + * type size. * - * @note The size is internally aligned to be a multiple of the @p align_t - * type size. + * @param[out] mp pointer to a @p MemoryPool structure + * @param[in] size the size of the objects contained in this memory pool, + * the minimum accepted size is the size of a pointer to + * void. + * @param[in] provider memory provider function for the memory pool or + * @p NULL if the pool is not allowed to grow + * automatically */ void chPoolInit(MemoryPool *mp, size_t size, memgetfunc_t provider) { @@ -49,11 +51,11 @@ void chPoolInit(MemoryPool *mp, size_t size, memgetfunc_t provider) { } /** - * @brief Allocates an object from a memory pool. + * @brief Allocates an object from a memory pool. * - * @param[in] mp pointer to a @p MemoryPool structure - * @return The pointer to the allocated object. - * @retval NULL if pool is empty. + * @param[in] mp pointer to a @p MemoryPool structure + * @return The pointer to the allocated object. + * @retval NULL if pool is empty. */ void *chPoolAllocI(MemoryPool *mp) { void *objp; @@ -70,11 +72,11 @@ void *chPoolAllocI(MemoryPool *mp) { } /** - * @brief Allocates an object from a memory pool. + * @brief Allocates an object from a memory pool. * - * @param[in] mp pointer to a @p MemoryPool structure - * @return The pointer to the allocated object. - * @retval NULL if pool is empty. + * @param[in] mp pointer to a @p MemoryPool structure + * @return The pointer to the allocated object. + * @retval NULL if pool is empty. */ void *chPoolAlloc(MemoryPool *mp) { void *objp; @@ -86,15 +88,14 @@ void *chPoolAlloc(MemoryPool *mp) { } /** - * @brief Releases (or adds) an object into (to) a memory pool. - * - * @param[in] mp pointer to a @p MemoryPool structure - * @param[in] objp the pointer to the object to be released or added + * @brief Releases (or adds) an object into (to) a memory pool. + * @note The object is assumed to be of the right size for the specified + * memory pool. + * @note The object is assumed to be memory aligned to the size of @p align_t + * type. * - * @note The object is assumed to be of the right size for the specified - * memory pool. - * @note The object is assumed to be memory aligned to the size of @p align_t - * type. + * @param[in] mp pointer to a @p MemoryPool structure + * @param[in] objp the pointer to the object to be released or added */ void chPoolFreeI(MemoryPool *mp, void *objp) { struct pool_header *php = objp; @@ -107,12 +108,12 @@ void chPoolFreeI(MemoryPool *mp, void *objp) { } /** - * @brief Releases (or adds) an object into (to) a memory pool. + * @brief Releases (or adds) an object into (to) a memory pool. + * @note The object is assumed to be of the right size for the specified + * memory pool. * - * @param[in] mp pointer to a @p MemoryPool structure - * @param[in] objp the pointer to the object to be released or added - * @note the object is assumed to be of the right size for the specified - * memory pool. + * @param[in] mp pointer to a @p MemoryPool structure + * @param[in] objp the pointer to the object to be released or added */ void chPoolFree(MemoryPool *mp, void *objp) { diff --git a/os/kernel/src/chmsg.c b/os/kernel/src/chmsg.c index 6c0c6a81a..9b6afd950 100644 --- a/os/kernel/src/chmsg.c +++ b/os/kernel/src/chmsg.c @@ -18,8 +18,9 @@ */ /** - * @file chmsg.c - * @brief Messages code. + * @file chmsg.c + * @brief Messages code. + * * @addtogroup messages * @{ */ @@ -35,13 +36,13 @@ #endif /** - * @brief Sends a message to the specified thread. + * @brief Sends a message to the specified thread. * @details The sender is stopped until the receiver executes a * @p chMsgRelease()after receiving the message. * - * @param[in] tp the pointer to the thread - * @param[in] msg the message - * @return The return message from @p chMsgRelease(). + * @param[in] tp the pointer to the thread + * @param[in] msg the message + * @return The answer message from @p chMsgRelease(). */ msg_t chMsgSend(Thread *tp, msg_t msg) { Thread *ctp = currp; @@ -61,13 +62,14 @@ msg_t chMsgSend(Thread *tp, msg_t msg) { } /** - * @brief Suspends the thread and waits for an incoming message. + * @brief Suspends the thread and waits for an incoming message. + * @note You can assume that the data contained in the message is stable + * until you invoke @p chMsgRelease() because the sending thread is + * suspended until then. * - * @return The pointer to the message structure. Note, it is always the - * message associated to the thread on the top of the messages queue. - * @note You can assume that the data contained in the message is stable until - * you invoke @p chMsgRelease() because the sending thread is - * suspended until then. + * @return The pointer to the message structure. Note, it is + * always the message associated to the thread on the + * top of the messages queue. */ msg_t chMsgWait(void) { msg_t msg; @@ -81,15 +83,17 @@ msg_t chMsgWait(void) { } /** - * @brief Returns the next message in the queue. + * @brief Returns the next message in the queue. + * @note You can assume that the data pointed by the message is stable until + * you invoke @p chMsgRelease() because the sending thread is + * suspended until then. Always remember that the message data is not + * copied between the sender and the receiver, just a pointer is + * passed. * - * @return The pointer to the message structure. Note, it is always the - * message associated to the thread on the top of the messages queue. - * If the queue is empty then @p NULL is returned. - * @note You can assume that the data pointed by the message is stable until - * you invoke @p chMsgRelease() because the sending thread is - * suspended until then. Always remember that the message data is not - * copied between the sender and the receiver, just a pointer is passed. + * @return The pointer to the message structure. Note, it is + * always the message associated to the thread on the + * top of the messages queue. + * @retval NULL if the queue is empty. */ msg_t chMsgGet(void) { msg_t msg; @@ -101,15 +105,15 @@ msg_t chMsgGet(void) { } /** - * @brief Releases the thread waiting on top of the messages queue. + * @brief Releases the thread waiting on top of the messages queue. + * @note You can call this function only if there is a message already in + * the queue else the result will be unpredictable (a crash most likely). + * Exiting from the @p chMsgWait() ensures you have at least one + * message in the queue so it is not a big deal.
+ * The condition is only tested in debug mode in order to make this + * code as fast as possible. * - * @param[in] msg the message returned to the message sender - * @note You can call this function only if there is a message already in the - * queue else the result will be unpredictable (a crash most likely). - * Exiting from the @p chMsgWait() ensures you have at least one - * message in the queue so it is not a big deal.
- * The condition is only tested in debug mode in order to make this code - * as fast as possible. + * @param[in] msg the message returned to the message sender */ void chMsgRelease(msg_t msg) { diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 9d66022c2..d5335c0aa 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -18,8 +18,9 @@ */ /** - * @file chmtx.c - * @brief Mutexes code. + * @file chmtx.c + * @brief Mutexes code. + * * @addtogroup mutexes * @{ */ @@ -29,12 +30,9 @@ #if CH_USE_MUTEXES /** - * @brief Initializes s @p Mutex structure. + * @brief Initializes s @p Mutex structure. * - * @param[out] mp pointer to a @p Mutex structure - * @note This function can be invoked from within an interrupt handler even if - * it is not an I-Class API because it does not touch any critical kernel - * data structure. + * @param[out] mp pointer to a @p Mutex structure */ void chMtxInit(Mutex *mp) { @@ -45,9 +43,9 @@ void chMtxInit(Mutex *mp) { } /** - * @brief Locks the specified mutex. + * @brief Locks the specified mutex. * - * @param[in] mp pointer to the @p Mutex structure + * @param[in] mp pointer to the @p Mutex structure */ void chMtxLock(Mutex *mp) { @@ -59,11 +57,9 @@ void chMtxLock(Mutex *mp) { } /** - * @brief Locks the specified mutex. + * @brief Locks the specified mutex. * - * @param[in] mp pointer to the @p Mutex structure - * @note This function must be called within a @p chSysLock() / @p chSysUnlock() - * block. + * @param[in] mp pointer to the @p Mutex structure */ void chMtxLockS(Mutex *mp) { Thread *ctp = currp; @@ -121,14 +117,14 @@ void chMtxLockS(Mutex *mp) { } /** - * @brief Tries to lock a mutex. + * @brief Tries to lock a mutex. * @details This function does not have any overhead related to * the priority inheritance mechanism because it does not try to * enter a sleep state on the mutex. * - * @param[in] mp pointer to the @p Mutex structure - * @retval TRUE if the mutex was successfully acquired - * @retval FALSE if the lock attempt failed. + * @param[in] mp pointer to the @p Mutex structure + * @retval TRUE if the mutex was successfully acquired + * @retval FALSE if the lock attempt failed. */ bool_t chMtxTryLock(Mutex *mp) { bool_t b; @@ -142,15 +138,14 @@ bool_t chMtxTryLock(Mutex *mp) { } /** - * @brief Tries to lock a mutex. + * @brief Tries to lock a mutex. * @details This function does not have any overhead related to * the priority inheritance mechanism because it does not try to * enter a sleep state on the mutex. - * @param[in] mp pointer to the @p Mutex structure - * @retval TRUE if the mutex was successfully acquired - * @retval FALSE if the lock attempt failed. - * @note This function must be called within a @p chSysLock() / @p chSysUnlock() - * block. + * + * @param[in] mp pointer to the @p Mutex structure + * @retval TRUE if the mutex was successfully acquired + * @retval FALSE if the lock attempt failed. */ bool_t chMtxTryLockS(Mutex *mp) { @@ -165,9 +160,9 @@ bool_t chMtxTryLockS(Mutex *mp) { } /** - * @brief Unlocks the next owned mutex in reverse lock order. + * @brief Unlocks the next owned mutex in reverse lock order. * - * @return The pointer to the unlocked mutex. + * @return The pointer to the unlocked mutex. */ Mutex *chMtxUnlock(void) { Thread *ctp = currp; @@ -210,12 +205,10 @@ Mutex *chMtxUnlock(void) { } /** - * @brief Unlocks the next owned mutex in reverse lock order. + * @brief Unlocks the next owned mutex in reverse lock order. + * @note This function does not reschedule internally. * - * @return The pointer to the unlocked mutex. - * @note This function must be called within a @p chSysLock() / @p chSysUnlock() - * block. - * @note This function does not reschedule internally. + * @return The pointer to the unlocked mutex. */ Mutex *chMtxUnlockS(void) { Thread *ctp = currp; @@ -254,7 +247,7 @@ Mutex *chMtxUnlockS(void) { } /** - * @brief Unlocks all the mutexes owned by the invoking thread. + * @brief Unlocks all the mutexes owned by the invoking thread. * @details This function is MUCH MORE efficient than releasing the * mutexes one by one and not just because the call overhead, * this function does not have any overhead related to the priority diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index 6a951f223..50f1f2401 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -18,8 +18,9 @@ */ /** - * @file chqueues.c - * @brief I/O Queues code. + * @file chqueues.c + * @brief I/O Queues code. + * * @addtogroup io_queues * @{ */ @@ -29,18 +30,17 @@ #if CH_USE_QUEUES /** - * @brief Initializes an input queue. + * @brief Initializes an input queue. * @details A Semaphore is internally initialized and works as a counter of * the bytes contained in the queue. + * @note The callback is invoked from within the S-Locked system state, + * see @ref system_states. * - * @param[out] iqp pointer to an @p InputQueue structure - * @param[in] bp pointer to a memory area allocated as queue buffer - * @param[in] size size of the queue buffer - * @param[in] infy pointer to a callback function that is invoked when - * data is read from the queue. The value can be @p NULL. - * - * @note The callback is invoked from within the S-Locked system state, - * see @ref system_states. + * @param[out] iqp pointer to an @p InputQueue structure + * @param[in] bp pointer to a memory area allocated as queue buffer + * @param[in] size size of the queue buffer + * @param[in] infy pointer to a callback function that is invoked when + * data is read from the queue. The value can be @p NULL. */ void chIQInit(InputQueue *iqp, uint8_t *bp, size_t size, qnotify_t infy) { @@ -51,13 +51,13 @@ void chIQInit(InputQueue *iqp, uint8_t *bp, size_t size, qnotify_t infy) { } /** - * @brief Resets an input queue. + * @brief Resets an input queue. * @details All the data in the input queue is erased and lost, any waiting * thread is resumed with status @p Q_RESET. - * @note A reset operation can be used by a low level driver in order to obtain - * immediate attention from the high level layers. + * @note A reset operation can be used by a low level driver in order to + * obtain immediate attention from the high level layers. * - * @param[in] iqp pointer to an @p InputQueue structure + * @param[in] iqp pointer to an @p InputQueue structure */ void chIQResetI(InputQueue *iqp) { @@ -66,14 +66,15 @@ void chIQResetI(InputQueue *iqp) { } /** - * @brief Input queue write. + * @brief Input queue write. * @details A byte value is written into the low end of an input queue. * - * @param[in] iqp pointer to an @p InputQueue structure - * @param[in] b the byte value to be written in the queue - * @return The operation status, it can be one of: - * @retval Q_OK if the operation has been completed with success. - * @retval Q_FULL if the queue is full and the operation cannot be completed. + * @param[in] iqp pointer to an @p InputQueue structure + * @param[in] b the byte value to be written in the queue + * @return The operation status, it can be one of: + * @retval Q_OK if the operation has been completed with success. + * @retval Q_FULL if the queue is full and the operation cannot be + * completed. */ msg_t chIQPutI(InputQueue *iqp, uint8_t b) { @@ -88,20 +89,20 @@ msg_t chIQPutI(InputQueue *iqp, uint8_t b) { } /** - * @brief Input queue read with timeout. + * @brief Input queue read with timeout. * @details This function reads a byte value from an input queue. If the queue * is empty then the calling thread is suspended until a byte arrives * in the queue or a timeout occurs. * - * @param[in] iqp pointer to an @p InputQueue structure - * @param[in] time 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 byte value from the queue or: - * @retval Q_TIMEOUT if the specified time expired. - * @retval Q_RESET if the queue was reset. + * @param[in] iqp pointer to an @p InputQueue structure + * @param[in] time 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 byte value from the queue or: + * @retval Q_TIMEOUT if the specified time expired. + * @retval Q_RESET if the queue was reset. */ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) { uint8_t b; @@ -124,25 +125,25 @@ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) { } /** - * @brief Input queue read with timeout. + * @brief Input queue read with timeout. * @details The function reads data from an input queue into a buffer. The * operation completes when the specified amount of data has been * transferred or after the specified timeout or if the queue has * been reset. - * @note The function is not atomic, if you need atomicity it is suggested - * to use a semaphore or a mutex for mutual exclusion. - * @note The queue callback is invoked before entering a sleep state and at - * the end of the transfer. + * @note The function is not atomic, if you need atomicity it is suggested + * to use a semaphore or a mutex for mutual exclusion. + * @note The queue callback is invoked before entering a sleep state and at + * the end of the transfer. * - * @param[in] iqp pointer to an @p InputQueue structure - * @param[out] bp pointer to the data buffer - * @param[in] n the maximum amount of data to be transferred - * @param[in] time 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 number of bytes effectively transferred. + * @param[in] iqp pointer to an @p InputQueue structure + * @param[out] bp pointer to the data buffer + * @param[in] n the maximum amount of data to be transferred + * @param[in] time 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 number of bytes effectively transferred. */ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, size_t n, systime_t time) { @@ -180,18 +181,17 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, } /** - * @brief Initializes an output queue. + * @brief Initializes an output queue. * @details A Semaphore is internally initialized and works as a counter of * the free bytes in the queue. + * @note The callback is invoked from within the S-Locked system state, + * see @ref system_states. * - * @param[out] oqp pointer to an @p OutputQueue structure - * @param[in] bp pointer to a memory area allocated as queue buffer - * @param[in] size size of the queue buffer - * @param[in] onfy pointer to a callback function that is invoked when - * data is written to the queue. The value can be @p NULL. - * - * @note The callback is invoked from within the S-Locked system state, - * see @ref system_states. + * @param[out] oqp pointer to an @p OutputQueue structure + * @param[in] bp pointer to a memory area allocated as queue buffer + * @param[in] size size of the queue buffer + * @param[in] onfy pointer to a callback function that is invoked when + * data is written to the queue. The value can be @p NULL. */ void chOQInit(OutputQueue *oqp, uint8_t *bp, size_t size, qnotify_t onfy) { @@ -202,14 +202,13 @@ void chOQInit(OutputQueue *oqp, uint8_t *bp, size_t size, qnotify_t onfy) { } /** - * @brief Resets an output queue. + * @brief Resets an output queue. * @details All the data in the output queue is erased and lost, any waiting * thread is resumed with status @p Q_RESET. + * @note A reset operation can be used by a low level driver in order to + * obtain immediate attention from the high level layers. * - * @param[in] oqp pointer to an @p OutputQueue structure - * - * @note A reset operation can be used by a low level driver in order to obtain - * immediate attention from the high level layers. + * @param[in] oqp pointer to an @p OutputQueue structure */ void chOQResetI(OutputQueue *oqp) { @@ -218,22 +217,22 @@ void chOQResetI(OutputQueue *oqp) { } /** - * @brief Output queue write with timeout. + * @brief Output queue write with timeout. * @details This function writes a byte value to an output queue. If the queue * is full then the calling thread is suspended until there is space * in the queue or a timeout occurs. * - * @param[in] oqp pointer to an @p OutputQueue structure - * @param[in] b the byte value to be written in the queue - * @param[in] time 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 operation status: - * @retval Q_OK if the operation succeeded. - * @retval Q_TIMEOUT if the specified time expired. - * @retval Q_RESET if the queue was reset. + * @param[in] oqp pointer to an @p OutputQueue structure + * @param[in] b the byte value to be written in the queue + * @param[in] time 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 operation status: + * @retval Q_OK if the operation succeeded. + * @retval Q_TIMEOUT if the specified time expired. + * @retval Q_RESET if the queue was reset. */ msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t time) { msg_t msg; @@ -255,12 +254,12 @@ msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t time) { } /** - * @brief Output queue read. + * @brief Output queue read. * @details A byte value is read from the low end of an output queue. * - * @param[in] oqp pointer to an @p OutputQueue structure - * @return The byte value from the queue or: - * @retval Q_EMPTY if the queue is empty. + * @param[in] oqp pointer to an @p OutputQueue structure + * @return The byte value from the queue or: + * @retval Q_EMPTY if the queue is empty. */ msg_t chOQGetI(OutputQueue *oqp) { uint8_t b; @@ -276,25 +275,25 @@ msg_t chOQGetI(OutputQueue *oqp) { } /** - * @brief Output queue write with timeout. + * @brief Output queue write with timeout. * @details The function writes data from a buffer to an output queue. The * operation completes when the specified amount of data has been * transferred or after the specified timeout or if the queue has * been reset. - * @note The function is not atomic, if you need atomicity it is suggested - * to use a semaphore or a mutex for mutual exclusion. - * @note The queue callback is invoked before entering a sleep state and at - * the end of the transfer. + * @note The function is not atomic, if you need atomicity it is suggested + * to use a semaphore or a mutex for mutual exclusion. + * @note The queue callback is invoked before entering a sleep state and at + * the end of the transfer. * - * @param[in] oqp pointer to an @p OutputQueue structure - * @param[out] bp pointer to the data buffer - * @param[in] n the maximum amount of data to be transferred - * @param[in] time 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 number of bytes effectively transferred. + * @param[in] oqp pointer to an @p OutputQueue structure + * @param[out] bp pointer to the data buffer + * @param[in] n the maximum amount of data to be transferred + * @param[in] time 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 number of bytes effectively transferred. */ size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp, size_t n, systime_t time) { diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c index b02d5f1fb..05573acbf 100644 --- a/os/kernel/src/chregistry.c +++ b/os/kernel/src/chregistry.c @@ -18,8 +18,9 @@ */ /** - * @file chregistry.c - * @brief Threads registry code. + * @file chregistry.c + * @brief Threads registry code. + * * @addtogroup registry * @{ */ @@ -36,7 +37,7 @@ * @note This function cannot return @p NULL because there is always at * least one thread in the system. * - * @return A reference to the first thread. + * @return A reference to the first thread. */ Thread *chRegFirstThread(void) { Thread *tp; @@ -52,9 +53,9 @@ Thread *chRegFirstThread(void) { * @details The reference counter of the specified thread is decremented and * the reference counter of the returned thread is incremented. * - * @param[in] tp pointer to the thread - * @return A reference to the next thread. - * @retval NULL if there is no next thread. + * @param[in] tp pointer to the thread + * @return A reference to the next thread. + * @retval NULL if there is no next thread. */ Thread *chRegNextThread(Thread *tp) { diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 5b4d18133..5bd016226 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -18,8 +18,9 @@ */ /** - * @file chschd.c - * @brief Scheduler code. + * @file chschd.c + * @brief Scheduler code. + * * @addtogroup scheduler * @{ */ @@ -27,14 +28,13 @@ #include "ch.h" /** - * @brief Ready list header. + * @brief Ready list header. */ ReadyList rlist; /** - * @brief Scheduler initialization. - * - * @note Internally invoked by the @p chSysInit(). + * @brief Scheduler initialization. + * @note Internally invoked by the @p chSysInit(), not an API. */ void scheduler_init(void) { @@ -49,12 +49,12 @@ void scheduler_init(void) { } /** - * @brief Inserts a thread in the Ready List. + * @brief Inserts a thread in the Ready List. + * @note The function does not reschedule, the @p chSchRescheduleS() should + * be called soon after. * - * @param[in] tp the Thread to be made ready - * @return The Thread pointer. - * @note The function does not reschedule, the @p chSchRescheduleS() should - * be called soon after. + * @param[in] tp the Thread to be made ready + * @return The Thread pointer. */ #if CH_OPTIMIZE_SPEED /* NOTE: it is inlined in this module only.*/ @@ -76,11 +76,11 @@ Thread *chSchReadyI(Thread *tp) { } /** - * @brief Puts the current thread to sleep into the specified state. + * @brief Puts the current thread to sleep into the specified state. * @details The thread goes into a sleeping state. The @ref thread_states are * described into @p threads.h. * - * @param[in] newstate the new thread state + * @param[in] newstate the new thread state */ void chSchGoSleepS(tstate_t newstate) { Thread *otp; @@ -121,24 +121,24 @@ static void wakeup(void *p) { } /** - * @brief Puts the current thread to sleep into the specified state with - * timeout specification. + * @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 timeout then it is forcibly * awakened with a @p RDY_TIMEOUT low level message. The @ref * thread_states are described into @p threads.h. * - * @param[in] newstate the new thread state - * @param[in] time the number of ticks before the operation timeouts, the - * special values are handled as follow: - * - @a TIME_INFINITE the thread enters an infinite sleep - * state, this is equivalent to invoking @p chSchGoSleepS() - * but, of course, less efficient. - * - @a TIME_IMMEDIATE this value is accepted but interpreted - * as a normal time specification not as an immediate timeout - * specification. - * . - * @return The wakeup message. + * @param[in] newstate the new thread state + * @param[in] time the number of ticks before the operation timeouts, the + * special values are handled as follow: + * - @a TIME_INFINITE the thread enters an infinite sleep + * state, this is equivalent to invoking + * @p chSchGoSleepS() but, of course, less efficient. + * - @a TIME_IMMEDIATE this value is accepted but + * interpreted as a normal time specification not as an + * immediate timeout specification. + * . + * @return The wakeup message. * @retval RDY_TIMEOUT if a timeout occurs. */ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { @@ -157,24 +157,25 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { } /** - * @brief Wakes up a thread. + * @brief Wakes up a thread. * @details The thread is inserted into the ready list or immediately made * running depending on its relative priority compared to the current * thread. + * @note It is equivalent to a @p chSchReadyI() followed by a + * @p chSchRescheduleS() but much more efficient. + * @note The function assumes that the current thread has the highest + * priority. * - * @param[in] ntp the Thread to be made ready - * @param[in] msg message to the awakened thread - * @note It is equivalent to a @p chSchReadyI() followed by a - * @p chSchRescheduleS() but much more efficient. - * @note The function assumes that the current thread has the highest priority + * @param[in] ntp the Thread to be made ready + * @param[in] msg message to the awakened thread */ void chSchWakeupS(Thread *ntp, msg_t msg) { ntp->p_u.rdymsg = msg; /* If the waken thread has a not-greater priority than the current - * one then it is just inserted in the ready list else it made - * running immediately and the invoking thread goes in the ready - * list instead.*/ + one then it is just inserted in the ready list else it made + running immediately and the invoking thread goes in the ready + list instead.*/ if (ntp->p_prio <= currp->p_prio) chSchReadyI(ntp); else { @@ -190,10 +191,9 @@ void chSchWakeupS(Thread *ntp, msg_t msg) { } /** - * @brief Switches to the first thread on the runnable queue. - * - * @note It is intended to be called if @p chSchRescRequiredI() evaluates to - * @p TRUE. + * @brief Switches to the first thread on the runnable queue. + * @note It is intended to be called if @p chSchRescRequiredI() evaluates + * to @p TRUE. */ void chSchDoRescheduleI(void) { @@ -209,7 +209,7 @@ void chSchDoRescheduleI(void) { } /** - * @brief Performs a reschedulation if a higher priority thread is runnable. + * @brief Performs a reschedulation if a higher priority thread is runnable. * @details If a thread with a higher priority than the current thread is in * the ready list then make the higher priority thread running. */ @@ -220,34 +220,33 @@ void chSchRescheduleS(void) { } /** - * @brief Evaluates if a reschedulation is required. + * @brief Evaluates if a reschedulation is required. * @details The decision is taken by comparing the relative priorities and * depending on the state of the round robin timeout counter. + * @note This function is meant to be used in the timer interrupt handler + * where @p chVTDoTickI() is invoked. * - * @retval TRUE if there is a thread that should go in running state. - * @retval FALSE if a reschedulation is not required. - * - * @note This function is meant to be used in the timer interrupt handler - * where @p chVTDoTickI() is invoked. + * @retval TRUE if there is a thread that should go in running state. + * @retval FALSE if a reschedulation is not required. */ bool_t chSchIsRescRequiredExI(void) { tprio_t p1 = firstprio(&rlist.r_queue); tprio_t p2 = currp->p_prio; #if CH_TIME_QUANTUM > 0 /* If the running thread has not reached its time quantum, reschedule only - * if the first thread on the ready queue has a higher priority. - * Otherwise, if the running thread has used up its time quantum, reschedule - * if the first thread on the ready queue has equal or higher priority.*/ + if the first thread on the ready queue has a higher priority. + Otherwise, if the running thread has used up its time quantum, reschedule + if the first thread on the ready queue has equal or higher priority.*/ return rlist.r_preempt ? p1 > p2 : p1 >= p2; #else - /* If the round robin feature is not enabled then performs a simpler - * comparison.*/ + /* If the round robin preemption feature is not enabled then performs a + simpler comparison.*/ return p1 > p2; #endif } /** - * @brief Yields the time slot. + * @brief Yields the time slot. * @details Yields the CPU control to the next thread in the ready list with * equal priority, if any. */ @@ -257,11 +256,9 @@ void chSchDoYieldS(void) { Thread *cp = (Thread *)&rlist.r_queue; Thread *otp = currp; - /* - * Note, the following insertion code works because we know that on the - * ready list there is at least one thread with priority equal or higher - * than the current one. - */ + /* Note, the following insertion code works because we know that on the + ready list there is at least one thread with priority equal or higher + than the current one.*/ otp->p_state = THD_STATE_READY; do { cp = cp->p_prev; diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index c78d52f74..b4ff0d9bc 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -18,8 +18,9 @@ */ /** - * @file chsem.c - * @brief Semaphores code. + * @file chsem.c + * @brief Semaphores code. + * * @addtogroup semaphores * @{ */ @@ -35,13 +36,11 @@ #endif /** - * @brief Initializes a semaphore with the specified counter value. + * @brief Initializes a semaphore with the specified counter value. * - * @param[out] sp pointer to a @p Semaphore structure - * @param[in] n initial value of the semaphore counter. Must be non-negative. - * @note This function can be invoked from within an interrupt handler even if - * it is not an I-Class API because it does not touch any critical kernel - * data structure. + * @param[out] sp pointer to a @p Semaphore structure + * @param[in] n initial value of the semaphore counter. Must be + * non-negative. */ void chSemInit(Semaphore *sp, cnt_t n) { @@ -52,13 +51,14 @@ void chSemInit(Semaphore *sp, cnt_t n) { } /** - * @brief Performs a reset operation on the semaphore. + * @brief Performs a reset operation on the semaphore. + * @note The released threads can recognize they were waked up by a reset + * rather than a signal because the @p chSemWait() will return + * @p RDY_RESET instead of @p RDY_OK. * - * @param[in] sp pointer to a @p Semaphore structure - * @param[in] n the new value of the semaphore counter. The value must be non-negative. - * @note The released threads can recognize they were waked up by a reset - * instead than a signal because the @p chSemWait() will return - * @p RDY_RESET instead of @p RDY_OK. + * @param[in] sp pointer to a @p Semaphore structure + * @param[in] n the new value of the semaphore counter. The value must + * be non-negative. */ void chSemReset(Semaphore *sp, cnt_t n) { @@ -69,14 +69,15 @@ void chSemReset(Semaphore *sp, cnt_t n) { } /** - * @brief Performs a reset operation on the semaphore. + * @brief Performs a reset operation on the semaphore. + * @note The released threads can recognize they were waked up by a reset + * rather than a signal because the @p chSemWait() will return + * @p RDY_RESET instead of @p RDY_OK. + * @note This function does not reschedule. * - * @param[in] sp pointer to a @p Semaphore structure - * @param[in] n the new value of the semaphore counter. The value must be non-negative. - * @note The released threads can recognize they were waked up by a reset - * instead than a signal because the @p chSemWait() will return - * @p RDY_RESET instead of @p RDY_OK. - * @note This function does not reschedule. + * @param[in] sp pointer to a @p Semaphore structure + * @param[in] n the new value of the semaphore counter. The value must + * be non-negative. */ void chSemResetI(Semaphore *sp, cnt_t n) { cnt_t cnt; @@ -90,11 +91,11 @@ void chSemResetI(Semaphore *sp, cnt_t n) { } /** - * @brief Performs a wait operation on a semaphore. + * @brief Performs a wait operation on a semaphore. * - * @param[in] sp pointer to a @p Semaphore structure - * @retval RDY_OK if the semaphore was signaled or not taken. - * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). + * @param[in] sp pointer to a @p Semaphore structure + * @retval RDY_OK if the semaphore was signaled or not taken. + * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). */ msg_t chSemWait(Semaphore *sp) { msg_t msg; @@ -106,13 +107,11 @@ msg_t chSemWait(Semaphore *sp) { } /** - * @brief Performs a wait operation on a semaphore. + * @brief Performs a wait operation on a semaphore. * - * @param[in] sp pointer to a @p Semaphore structure - * @retval RDY_OK if the semaphore was signaled or not taken. - * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). - * @note This function must be called with interrupts disabled. - * @note This function cannot be called by an interrupt handler. + * @param[in] sp pointer to a @p Semaphore structure + * @retval RDY_OK if the semaphore was signaled or not taken. + * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). */ msg_t chSemWaitS(Semaphore *sp) { @@ -128,18 +127,18 @@ msg_t chSemWaitS(Semaphore *sp) { } /** - * @brief Performs a wait operation on a semaphore with timeout specification. + * @brief Performs a wait operation on a semaphore with timeout specification. * - * @param[in] sp pointer to a @p Semaphore structure - * @param[in] time the number of ticks before the operation timeouts, - * the following special values are allowed: - * - @a TIME_IMMEDIATE immediate timeout. - * - @a TIME_INFINITE no timeout. - * . - * @retval RDY_OK if the semaphore was signaled or not taken. - * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). - * @retval RDY_TIMEOUT if the semaphore was not signaled or reset within the - * specified timeout. + * @param[in] sp pointer to a @p Semaphore structure + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @retval RDY_OK if the semaphore was signaled or not taken. + * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). + * @retval RDY_TIMEOUT if the semaphore was not signaled or reset within the + * specified timeout. */ msg_t chSemWaitTimeout(Semaphore *sp, systime_t time) { msg_t msg; @@ -151,18 +150,18 @@ msg_t chSemWaitTimeout(Semaphore *sp, systime_t time) { } /** - * @brief Performs a wait operation on a semaphore with timeout specification. + * @brief Performs a wait operation on a semaphore with timeout specification. * - * @param[in] sp pointer to a @p Semaphore structure - * @param[in] time the number of ticks before the operation timeouts, - * the following special values are allowed: - * - @a TIME_IMMEDIATE immediate timeout. - * - @a TIME_INFINITE no timeout. - * . - * @retval RDY_OK if the semaphore was signaled or not taken. - * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). - * @retval RDY_TIMEOUT if the semaphore was not signaled or reset within the specified - * timeout. + * @param[in] sp pointer to a @p Semaphore structure + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @retval RDY_OK if the semaphore was signaled or not taken. + * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). + * @retval RDY_TIMEOUT if the semaphore was not signaled or reset within the + * specified timeout. */ msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) { @@ -181,11 +180,9 @@ msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) { } /** - * @brief Performs a signal operation on a semaphore. + * @brief Performs a signal operation on a semaphore. * - * @param[in] sp pointer to a @p Semaphore structure - * @note The function is available only if the @p CH_USE_SEMAPHORES - * option is enabled in @p chconf.h. + * @param[in] sp pointer to a @p Semaphore structure */ void chSemSignal(Semaphore *sp) { @@ -198,19 +195,17 @@ void chSemSignal(Semaphore *sp) { } /** - * @brief Performs a signal operation on a semaphore. + * @brief Performs a signal operation on a semaphore. + * @note This function does not reschedule. * - * @param[in] sp pointer to a @p Semaphore structure - * @note The function is available only if the @p CH_USE_SEMAPHORES - * option is enabled in @p chconf.h. - * @note This function does not reschedule. + * @param[in] sp pointer to a @p Semaphore structure */ void chSemSignalI(Semaphore *sp) { chDbgCheck(sp != NULL, "chSemSignalI"); if (sp->s_cnt++ < 0) { - /* NOTE: It is done this way in order to allow a tail call on + /* note, it is done this way in order to allow a tail call on chSchReadyI().*/ Thread *tp = fifo_remove(&sp->s_queue); tp->p_u.rdymsg = RDY_OK; @@ -220,14 +215,14 @@ void chSemSignalI(Semaphore *sp) { #if CH_USE_SEMSW /** - * @brief Performs atomic signal and wait operations on two semaphores. + * @brief Performs atomic signal and wait operations on two semaphores. + * @note The function is available only if the @p CH_USE_SEMSW + * option is enabled in @p chconf.h. * - * @param[in] sps pointer to a @p Semaphore structure to be signaled - * @param[in] spw pointer to a @p Semaphore structure to be wait on - * @retval RDY_OK if the semaphore was signaled or not taken. - * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). - * @note The function is available only if the @p CH_USE_SEMSW - * option is enabled in @p chconf.h. + * @param[in] sps pointer to a @p Semaphore structure to be signaled + * @param[in] spw pointer to a @p Semaphore structure to be wait on + * @retval RDY_OK if the semaphore was signaled or not taken. + * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). */ msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw) { msg_t msg; diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 2863f253c..8c252609d 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -18,8 +18,9 @@ */ /** - * @file chsys.c - * @brief System related code. + * @file chsys.c + * @brief System related code. + * * @addtogroup system * @{ */ @@ -29,7 +30,7 @@ static WORKING_AREA(idle_thread_wa, IDLE_THREAD_STACK_SIZE); /** - * @brief This function implements the idle thread infinite loop. + * @brief This function implements the idle thread infinite loop. * @details The function puts the processor in the lowest power mode capable * to serve interrupts.
* The priority is internally set to the minimum system value so @@ -48,13 +49,12 @@ static void idle_thread(void *p) { } /** - * @brief ChibiOS/RT initialization. + * @brief ChibiOS/RT initialization. * @details After executing this function the current instructions stream * becomes the main thread. - * - * @note Interrupts should be still disabled when @p chSysInit() is invoked - * and are internally enabled. - * @note The main thread is created with priority @p NORMALPRIO. + * @note Interrupts should be still disabled when @p chSysInit() is invoked + * and are internally enabled. + * @note The main thread is created with priority @p NORMALPRIO. */ void chSysInit(void) { static Thread mainthread; @@ -72,29 +72,26 @@ void chSysInit(void) { trace_init(); #endif - /* - * Now this instructions flow becomes the main thread. - */ + /* Now this instructions flow becomes the main thread.*/ (currp = init_thread(&mainthread, NORMALPRIO))->p_state = THD_STATE_CURRENT; chSysEnable(); - /* - * This thread has the lowest priority in the system, its role is just to - * serve interrupts in its context while keeping the lowest energy saving - * mode compatible with the system status. - */ + /* This thread has the lowest priority in the system, its role is just to + serve interrupts in its context while keeping the lowest energy saving + mode compatible with the system status.*/ chThdCreateStatic(idle_thread_wa, sizeof(idle_thread_wa), IDLEPRIO, (tfunc_t)idle_thread, NULL); } /** - * @brief Handles time ticks for round robin preemption and timer increments. + * @brief Handles time ticks for round robin preemption and timer increments. * @details Decrements the remaining time quantum of the running thread * and preempts it when the quantum is used up. Increments system * time and manages the timers. * - * @note The frequency of the timer determines the system tick granularity and, - * together with the @p CH_TIME_QUANTUM macro, the round robin interval. + * @note The frequency of the timer determines the system tick granularity + * and, together with the @p CH_TIME_QUANTUM macro, the round robin + * interval. */ void chSysTimerHandlerI(void) { diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index e28efa43c..f96cea942 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -18,8 +18,9 @@ */ /** - * @file chthreads.c - * @brief Threads code. + * @file chthreads.c + * @brief Threads code. + * * @addtogroup threads * @{ */ @@ -29,10 +30,9 @@ /** * @brief Initializes a thread structure. * - * @param[in] tp pointer to the thread - * @param[in] prio the priority level for the new thread - * - * @return The same thread pointer passed as parameter. + * @param[in] tp pointer to the thread + * @param[in] prio the priority level for the new thread + * @return The same thread pointer passed as parameter. */ Thread *init_thread(Thread *tp, tprio_t prio) { @@ -86,14 +86,14 @@ static void memfill(uint8_t *startp, uint8_t *endp, uint8_t v) { * even if it is not an I-Class API because it does not touch * any critical kernel data structure. * - * @param[out] wsp pointer to a working area dedicated to the thread stack - * @param[in] size size of the working area - * @param[in] prio the priority level for the new thread - * @param[in] pf the thread function - * @param[in] arg an argument passed to the thread function. It can be - * @p NULL. - * @return The pointer to the @p Thread structure allocated for the - * thread into the working space area. + * @param[out] wsp pointer to a working area dedicated to the thread stack + * @param[in] size size of the working area + * @param[in] prio the priority level for the new thread + * @param[in] pf the thread function + * @param[in] arg an argument passed to the thread function. It can be + * @p NULL. + * @return The pointer to the @p Thread structure allocated for + * the thread into the working space area. */ Thread *chThdInit(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) { /* Thread structure is layed out in the lower part of the thread workspace */ @@ -116,14 +116,14 @@ Thread *chThdInit(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) { * @note A thread can terminate by calling @p chThdExit() or by simply * returning from its main function. * - * @param[out] wsp pointer to a working area dedicated to the thread stack - * @param[in] size size of the working area - * @param[in] prio the priority level for the new thread - * @param[in] pf the thread function - * @param[in] arg an argument passed to the thread function. It can be - * @p NULL. - * @return The pointer to the @p Thread structure allocated for the - * thread into the working space area. + * @param[out] wsp pointer to a working area dedicated to the thread stack + * @param[in] size size of the working area + * @param[in] prio the priority level for the new thread + * @param[in] pf the thread function + * @param[in] arg an argument passed to the thread function. It can be + * @p NULL. + * @return The pointer to the @p Thread structure allocated for + * the thread into the working space area. */ Thread *chThdCreateStatic(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) { @@ -142,16 +142,16 @@ Thread *chThdCreateStatic(void *wsp, size_t size, * @p CH_USE_HEAP and @p CH_USE_WAITEXIT options are enabled * in @p chconf.h. * - * @param[in] heapp heap from which allocate the memory or @p NULL for the - * default heap - * @param[in] size size of the working area to be allocated - * @param[in] prio the priority level for the new thread - * @param[in] pf the thread function - * @param[in] arg an argument passed to the thread function. It can be - * @p NULL. - * @return The pointer to the @p Thread structure allocated for the - * thread into the working space area. - * @retval NULL if the memory cannot be allocated. + * @param[in] heapp heap from which allocate the memory or @p NULL for the + * default heap + * @param[in] size size of the working area to be allocated + * @param[in] prio the priority level for the new thread + * @param[in] pf the thread function + * @param[in] arg an argument passed to the thread function. It can be + * @p NULL. + * @return The pointer to the @p Thread structure allocated for + * the thread into the working space area. + * @retval NULL if the memory cannot be allocated. */ Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size, tprio_t prio, tfunc_t pf, void *arg) { @@ -179,15 +179,14 @@ Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size, * @p CH_USE_MEMPOOLS and @p CH_USE_WAITEXIT options are enabled * in @p chconf.h. * - * @param[in] mp pointer to the memory pool object - * @param[in] prio the priority level for the new thread - * @param[in] pf the thread function - * @param[in] arg an argument passed to the thread function. It can be - * @p NULL. - * @return The pointer to the @p Thread structure allocated for the - * thread into the working space area or @p NULL if the memory cannot - * be allocated. - * @retval NULL if the memory pool is empty. + * @param[in] mp pointer to the memory pool object + * @param[in] prio the priority level for the new thread + * @param[in] pf the thread function + * @param[in] arg an argument passed to the thread function. It can be + * @p NULL. + * @return The pointer to the @p Thread structure allocated for + * the thread into the working space area. + * @retval NULL if the memory pool is empty. */ Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, tfunc_t pf, void *arg) { @@ -213,8 +212,8 @@ Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, * current priority that could be higher than the real priority * because the priority inheritance mechanism. * - * @param[in] newprio the new priority level of the running thread - * @return The old priority level. + * @param[in] newprio the new priority level of the running thread + * @return The old priority level. */ tprio_t chThdSetPriority(tprio_t newprio) { tprio_t oldprio; @@ -241,8 +240,8 @@ tprio_t chThdSetPriority(tprio_t newprio) { * @brief Resumes a suspended thread. * @note Use this function to resume threads created with @p chThdInit(). * - * @param[in] tp pointer to the thread - * @return The pointer to the thread. + * @param[in] tp pointer to the thread + * @return The pointer to the thread. */ Thread *chThdResume(Thread *tp) { @@ -261,7 +260,7 @@ Thread *chThdResume(Thread *tp) { * its @p p_flags field. The thread can read this status by * invoking @p chThdShouldTerminate() and then terminate cleanly. * - * @param[in] tp pointer to the thread + * @param[in] tp pointer to the thread */ void chThdTerminate(Thread *tp) { @@ -273,14 +272,14 @@ void chThdTerminate(Thread *tp) { /** * @brief Suspends the invoking thread for the specified time. * - * @param[in] time the delay in system ticks, the special values are handled - * as follow: - * - @a TIME_INFINITE the thread enters an infinite sleep - * state. - * - @a TIME_IMMEDIATE this value is accepted but interpreted - * as a normal time specification not as an immediate - * timeout specification. - * . + * @param[in] time the delay in system ticks, the special values are + * handled as follow: + * - @a TIME_INFINITE the thread enters an infinite sleep + * state. + * - @a TIME_IMMEDIATE this value is accepted but + * interpreted as a normal time specification not as an + * immediate timeout specification. + * . */ void chThdSleep(systime_t time) { @@ -295,7 +294,7 @@ void chThdSleep(systime_t time) { * @brief Suspends the invoking thread until the system time arrives to the * specified value. * - * @param[in] time absolute system time + * @param[in] time absolute system time */ void chThdSleepUntil(systime_t time) { @@ -320,9 +319,8 @@ void chThdYield(void) { /** * @brief Terminates the current thread by specifying an exit status code. * - * @param[in] msg thread exit code. The code can be retrieved by using - * @p chThdWait(). - * @return The same thread pointer passed as parameter. + * @param[in] msg thread exit code. The code can be retrieved by using + * @p chThdWait(). */ void chThdExit(msg_t msg) { Thread *tp = currp; @@ -344,9 +342,9 @@ void chThdExit(msg_t msg) { /** * @brief Adds a reference to a thread object. * - * @param[in] tp pointer to the thread - * @return The same thread pointer passed as parameter representing the - * new reference. + * @param[in] tp pointer to the thread + * @return The same thread pointer passed as parameter + * representing the new reference. */ Thread *chThdAddRef(Thread *tp) { @@ -364,7 +362,7 @@ Thread *chThdAddRef(Thread *tp) { * returned to the proper allocator. * @note Static threads are not affected. * - * @param[in] tp pointer to the thread + * @param[in] tp pointer to the thread */ void chThdRelease(Thread *tp) { trefs_t refs; @@ -419,8 +417,8 @@ void chThdRelease(Thread *tp) { * @note If @p CH_USE_DYNAMIC is not specified this function just waits for * the thread termination, no memory allocators are involved. * - * @param[in] tp pointer to the thread - * @return The exit code from the terminated thread + * @param[in] tp pointer to the thread + * @return The exit code from the terminated thread. */ msg_t chThdWait(Thread *tp) { msg_t msg; diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c index 5acde49aa..9558a1cb7 100644 --- a/os/kernel/src/chvt.c +++ b/os/kernel/src/chvt.c @@ -18,20 +18,23 @@ */ /** - * @file chvt.c - * @brief Time and Virtual Timers related code. + * @file chvt.c + * @brief Time and Virtual Timers related code. + * * @addtogroup time * @{ */ #include "ch.h" +/** + * @brief Virtual timers delta list header. + */ VTList vtlist; /** - * @brief Virtual Timers initialization. - * - * @note Internal use only. + * @brief Virtual Timers initialization. + * @note Internal use only. */ void vt_init(void) { @@ -41,19 +44,20 @@ void vt_init(void) { } /** - * @brief Enables a virtual timer. + * @brief Enables a virtual timer. + * @note The associated function is invoked by an interrupt handler within + * the I-Locked state, see @ref system_states. * - * @param[out] vtp the @p VirtualTimer structure pointer - * @param[in] time the number of time ticks, the value @p TIME_INFINITE is not - * allowed. The value @p TIME_IMMEDIATE is allowed but - * interpreted as a normal time specification not as an - * immediate timeout specification. - * @param[in] vtfunc the timer callback function. After invoking the callback - * the timer is disabled and the structure can be disposed or - * reused. - * @param[in] par a parameter that will be passed to the callback function - * @note The associated function is invoked by an interrupt handler within - * the I-Locked state, see @ref system_states. + * @param[out] vtp the @p VirtualTimer structure pointer + * @param[in] time the number of time ticks, the value @p TIME_INFINITE + * is notallowed. The value @p TIME_IMMEDIATE is allowed + * but interpreted as a normal time specification not as + * an immediate timeout specification. + * @param[in] vtfunc the timer callback function. After invoking the + * callback the timer is disabled and the structure can + * be disposed or reused. + * @param[in] par a parameter that will be passed to the callback + * function */ void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) { VirtualTimer *p; @@ -77,10 +81,10 @@ void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) { } /** - * @brief Disables a Virtual Timer. + * @brief Disables a Virtual Timer. + * @note The timer MUST be active when this function is invoked. * - * @param[in] vtp the @p VirtualTimer structure pointer - * @note The timer MUST be active when this function is invoked. + * @param[in] vtp the @p VirtualTimer structure pointer */ void chVTResetI(VirtualTimer *vtp) { @@ -97,14 +101,15 @@ void chVTResetI(VirtualTimer *vtp) { } /** - * @brief Checks if the current system time is within the specified time window. + * @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. - * @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. */ bool_t chTimeIsWithin(systime_t start, systime_t end) { -- cgit v1.2.3 From 8e428dbd1a48615c36c8c086dd51079050c9fb1c Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 6 Feb 2010 12:31:09 +0000 Subject: Kernel headers cleanup. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1568 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chlists.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chlists.c b/os/kernel/src/chlists.c index 2aeb55ecb..9b309ceea 100644 --- a/os/kernel/src/chlists.c +++ b/os/kernel/src/chlists.c @@ -20,6 +20,9 @@ /** * @file chlists.c * @brief Thread queues/lists code. + * @note All the functions present in this module, while public, are not + * an OS API and should not be directly used in the user applications + * code. * * @addtogroup internals * @{ -- cgit v1.2.3 From 4d832fdf1c1ca932d16198df7b3c04dcd083e7e2 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 12 Feb 2010 18:51:48 +0000 Subject: Few fixes to the new code after the batch build test. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1592 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chregistry.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c index 05573acbf..b6555df40 100644 --- a/os/kernel/src/chregistry.c +++ b/os/kernel/src/chregistry.c @@ -43,7 +43,10 @@ Thread *chRegFirstThread(void) { Thread *tp; chSysLock(); - (tp = rlist.p_newer)->p_refs++; + tp = rlist.p_newer; +#if CH_USE_DYNAMIC + tp->p_refs++; +#endif chSysUnlock(); return tp; } @@ -60,14 +63,18 @@ Thread *chRegFirstThread(void) { Thread *chRegNextThread(Thread *tp) { chSysLock(); +#if CH_USE_DYNAMIC chDbgAssert(tp->p_refs > 0, "chRegNextThread(), #1", "not referenced"); tp->p_refs--; +#endif if (tp->p_newer != (Thread *)&rlist) { tp = tp->p_newer; +#if CH_USE_DYNAMIC chDbgAssert(tp->p_refs < 255, "chRegNextThread(), #2", "too many references"); tp->p_refs++; +#endif } else tp = NULL; -- cgit v1.2.3 From 60f8ed2a0b990b82862af1df2f146126dac0eb73 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 12 Feb 2010 18:55:06 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1593 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chthreads.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index f96cea942..6f67f7093 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -427,7 +427,9 @@ msg_t chThdWait(Thread *tp) { chSysLock(); chDbgAssert(tp != currp, "chThdWait(), #1", "waiting self"); +#if CH_USE_DYNAMIC chDbgAssert(tp->p_refs > 0, "chThdWait(), #2", "not referenced"); +#endif if (tp->p_state != THD_STATE_FINAL) { list_insert(currp, &tp->p_waiting); chSchGoSleepS(THD_STATE_WTEXIT); -- cgit v1.2.3 From d9442768e2c56370801118cd719d7fa131066b39 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 12 Feb 2010 19:00:37 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1594 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chdebug.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index 8a5b58744..38626387b 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -50,7 +50,7 @@ void trace_init(void) { */ void chDbgTrace(Thread *otp, Thread *ntp) { - trace_buffer.tb_ptr->cse_wtobjp = otp->p_wtobjp; + trace_buffer.tb_ptr->cse_wtobjp = otp->p_u.wtobjp; trace_buffer.tb_ptr->cse_time = chTimeNow(); trace_buffer.tb_ptr->cse_state = otp->p_state; trace_buffer.tb_ptr->cse_tid = (unsigned)ntp >> 4; -- cgit v1.2.3 From 0c85d7906646524a75121867ba02dd1bb809cd21 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 16 Feb 2010 19:21:42 +0000 Subject: Tentative fix for bug 2952961. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1619 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chheap.c | 80 +++++++++++++++++++++++------------------------ os/kernel/src/chmemcore.c | 10 +++--- 2 files changed, 46 insertions(+), 44 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c index 45431d5f4..91b7d01bc 100644 --- a/os/kernel/src/chheap.c +++ b/os/kernel/src/chheap.c @@ -53,8 +53,8 @@ static MemoryHeap default_heap; */ void heap_init(void) { default_heap.h_provider = chCoreAlloc; - default_heap.h_free.h_u.next = (struct heap_header *)NULL; - default_heap.h_free.h_size = 0; + default_heap.h_free.h.u.next = (union heap_header *)NULL; + default_heap.h_free.h.size = 0; #if CH_USE_MUTEXES chMtxInit(&default_heap.h_mtx); #else @@ -72,15 +72,15 @@ void heap_init(void) { * @param[in] size heap size */ void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) { - struct heap_header *hp; + union heap_header *hp; chDbgCheck(MEM_IS_ALIGNED(buf) && MEM_IS_ALIGNED(size), "chHeapInit"); heapp->h_provider = (memgetfunc_t)NULL; - heapp->h_free.h_u.next = hp = buf; - heapp->h_free.h_size = 0; - hp->h_u.next = NULL; - hp->h_size = size - sizeof(struct heap_header); + heapp->h_free.h.u.next = hp = buf; + heapp->h_free.h.size = 0; + hp->h.u.next = NULL; + hp->h.size = size - sizeof(union heap_header); #if CH_USE_MUTEXES chMtxInit(&heapp->h_mtx); #else @@ -103,7 +103,7 @@ void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) { * @retval NULL if the block cannot be allocated. */ void *chHeapAlloc(MemoryHeap *heapp, size_t size) { - struct heap_header *qp, *hp, *fp; + union heap_header *qp, *hp, *fp; if (heapp == NULL) heapp = &default_heap; @@ -112,24 +112,24 @@ void *chHeapAlloc(MemoryHeap *heapp, size_t size) { qp = &heapp->h_free; H_LOCK(heapp); - while (qp->h_u.next != NULL) { - hp = qp->h_u.next; - if (hp->h_size >= size) { - if (hp->h_size < size + sizeof(struct heap_header)) { + while (qp->h.u.next != NULL) { + hp = qp->h.u.next; + if (hp->h.size >= size) { + if (hp->h.size < size + sizeof(union heap_header)) { /* Gets the whole block even if it is slightly bigger than the requested size because the fragment would be too small to be useful.*/ - qp->h_u.next = hp->h_u.next; + qp->h.u.next = hp->h.u.next; } else { /* Block bigger enough, must split it.*/ - fp = (void *)((uint8_t *)(hp) + sizeof(struct heap_header) + size); - fp->h_u.next = hp->h_u.next; - fp->h_size = hp->h_size - sizeof(struct heap_header) - size; - qp->h_u.next = fp; - hp->h_size = size; + fp = (void *)((uint8_t *)(hp) + sizeof(union heap_header) + size); + fp->h.u.next = hp->h.u.next; + fp->h.size = hp->h.size - sizeof(union heap_header) - size; + qp->h.u.next = fp; + hp->h.size = size; } - hp->h_u.heap = heapp; + hp->h.u.heap = heapp; H_UNLOCK(heapp); return (void *)(hp + 1); @@ -142,10 +142,10 @@ void *chHeapAlloc(MemoryHeap *heapp, size_t size) { /* More memory is required, tries to get it from the associated provider else fails.*/ if (heapp->h_provider) { - hp = heapp->h_provider(size + sizeof(struct heap_header)); + hp = heapp->h_provider(size + sizeof(union heap_header)); if (hp != NULL) { - hp->h_u.heap = heapp; - hp->h_size = size; + hp->h.u.heap = heapp; + hp->h.size = size; hp++; return (void *)hp; } @@ -153,9 +153,9 @@ void *chHeapAlloc(MemoryHeap *heapp, size_t size) { return NULL; } -#define LIMIT(p) (struct heap_header *)((uint8_t *)(p) + \ - sizeof(struct heap_header) + \ - (p)->h_size) +#define LIMIT(p) (union heap_header *)((uint8_t *)(p) + \ + sizeof(union heap_header) + \ + (p)->h.size) /** * @brief Frees a previously allocated memory block. @@ -163,13 +163,13 @@ void *chHeapAlloc(MemoryHeap *heapp, size_t size) { * @param[in] p pointer to the memory block to be freed */ void chHeapFree(void *p) { - struct heap_header *qp, *hp; + union heap_header *qp, *hp; MemoryHeap *heapp; chDbgCheck(p != NULL, "chHeapFree"); - hp = (struct heap_header *)p - 1; - heapp = hp->h_u.heap; + hp = (union heap_header *)p - 1; + heapp = hp->h.u.heap; qp = &heapp->h_free; H_LOCK(heapp); @@ -179,24 +179,24 @@ void chHeapFree(void *p) { "within free block"); if (((qp == &heapp->h_free) || (hp > qp)) && - ((qp->h_u.next == NULL) || (hp < qp->h_u.next))) { + ((qp->h.u.next == NULL) || (hp < qp->h.u.next))) { /* Insertion after qp.*/ - hp->h_u.next = qp->h_u.next; - qp->h_u.next = hp; + hp->h.u.next = qp->h.u.next; + qp->h.u.next = hp; /* Verifies if the newly inserted block should be merged.*/ - if (LIMIT(hp) == hp->h_u.next) { + if (LIMIT(hp) == hp->h.u.next) { /* Merge with the next block.*/ - hp->h_size += hp->h_u.next->h_size + sizeof(struct heap_header); - hp->h_u.next = hp->h_u.next->h_u.next; + hp->h.size += hp->h.u.next->h.size + sizeof(union heap_header); + hp->h.u.next = hp->h.u.next->h.u.next; } if ((LIMIT(qp) == hp)) { /* Merge with the previous block.*/ - qp->h_size += hp->h_size + sizeof(struct heap_header); - qp->h_u.next = hp->h_u.next; + qp->h.size += hp->h.size + sizeof(union heap_header); + qp->h.u.next = hp->h.u.next; } break; } - qp = qp->h_u.next; + qp = qp->h.u.next; } H_UNLOCK(heapp); @@ -217,7 +217,7 @@ void chHeapFree(void *p) { * @return The number of fragments in the heap. */ size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep) { - struct heap_header *qp; + union heap_header *qp; size_t n, sz; if (heapp == NULL) @@ -226,8 +226,8 @@ size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep) { H_LOCK(heapp); sz = 0; - for (n = 0, qp = &heapp->h_free; qp->h_u.next; n++, qp = qp->h_u.next) - sz += qp->h_u.next->h_size; + for (n = 0, qp = &heapp->h_free; qp->h.u.next; n++, qp = qp->h.u.next) + sz += qp->h.u.next->h.size; if (sizep) *sizep = sz; diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index 8269deb48..d5adbef48 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -43,17 +43,19 @@ void core_init(void) { nextmem = &__heap_base__; endmem = &__heap_end__; #else - static align_t buffer[MEM_ALIGN_SIZE(CH_MEMCORE_SIZE) / sizeof(align_t)]; + static stkalign_t buffer[MEM_ALIGN_SIZE(CH_MEMCORE_SIZE) / + sizeof(stkalign_t)]; nextmem = (uint8_t *)&buffer[0]; - endmem = (uint8_t *)&buffer[MEM_ALIGN_SIZE(CH_MEMCORE_SIZE) / sizeof(align_t)]; + endmem = (uint8_t *)&buffer[MEM_ALIGN_SIZE(CH_MEMCORE_SIZE) / + sizeof(stkalign_t)]; #endif } /** * @brief Allocates a memory block. * @details The size of the returned block is aligned to the alignment - * type @p align_t so it is not possible to allocate less than - * sizeof(align_t). + * type @p stkalign_t so it is not possible to allocate less + * than sizeof(stkalign_t). * * * @param[in] size the size of the block to be allocated -- cgit v1.2.3 From 157b6f9695e7f72f2d54b231c19cb4045710ed01 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 21 Feb 2010 07:24:53 +0000 Subject: Updated license dates. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1646 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chcond.c | 2 +- os/kernel/src/chdebug.c | 4 +- os/kernel/src/chevents.c | 2 +- os/kernel/src/chheap.c | 2 +- os/kernel/src/chlists.c | 2 +- os/kernel/src/chmboxes.c | 4 +- os/kernel/src/chmemcore.c | 6 +- os/kernel/src/chmempools.c | 2 +- os/kernel/src/chmsg.c | 2 +- os/kernel/src/chmtx.c | 552 ++++++++++++++-------------- os/kernel/src/chqueues.c | 2 +- os/kernel/src/chregistry.c | 6 +- os/kernel/src/chschd.c | 560 ++++++++++++++-------------- os/kernel/src/chsem.c | 2 +- os/kernel/src/chsys.c | 260 ++++++------- os/kernel/src/chthreads.c | 892 ++++++++++++++++++++++----------------------- os/kernel/src/chvt.c | 4 +- 17 files changed, 1152 insertions(+), 1152 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c index 21f3a22e2..f0ec50c4f 100644 --- a/os/kernel/src/chcond.c +++ b/os/kernel/src/chcond.c @@ -1,5 +1,5 @@ /* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index 38626387b..ebe93e8a5 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -1,5 +1,5 @@ /* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. This file is part of ChibiOS/RT. @@ -64,7 +64,7 @@ void chDbgTrace(Thread *otp, Thread *ntp) { * @brief Pointer to the panic message. * @details This pointer is meant to be accessed through the debugger, it is * written once and then the system is halted. This variable can be - * set to @p NULL if the halt is caused by a stack overflow. + * set to @p NULL if the halt is caused by a stack overflow. */ char *panic_msg; diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index 310f04212..e3c0b07ba 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -1,5 +1,5 @@ /* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c index 91b7d01bc..ce8ce385b 100644 --- a/os/kernel/src/chheap.c +++ b/os/kernel/src/chheap.c @@ -1,5 +1,5 @@ /* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chlists.c b/os/kernel/src/chlists.c index 9b309ceea..f722f94cb 100644 --- a/os/kernel/src/chlists.c +++ b/os/kernel/src/chlists.c @@ -1,5 +1,5 @@ /* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c index aee514f84..3811fc5da 100644 --- a/os/kernel/src/chmboxes.c +++ b/os/kernel/src/chmboxes.c @@ -1,5 +1,5 @@ /* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. This file is part of ChibiOS/RT. @@ -33,7 +33,7 @@ * * @param[out] mbp the pointer to the Mailbox structure to be initialized * @param[in] buf the circular messages buffer - * @param[in] n the buffer size as number of @p msg_t + * @param[in] n the buffer size as number of @p msg_t */ void chMBInit(Mailbox *mbp, msg_t *buf, cnt_t n) { diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index d5adbef48..435120a33 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -1,5 +1,5 @@ /* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. This file is part of ChibiOS/RT. @@ -60,7 +60,7 @@ void core_init(void) { * * @param[in] size the size of the block to be allocated * @return A pointer to the allocated memory block. - * @retval NULL allocation failed, core memory exhausted. + * @retval NULL allocation failed, core memory exhausted. */ void *chCoreAlloc(size_t size) { void *p; @@ -95,7 +95,7 @@ void *chCoreAllocI(size_t size) { /** * @brief Core memory left. * - * @return The size, in bytes, of the free core memory. + * @return The size, in bytes, of the free core memory. */ size_t chCoreFree(void) { diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c index 1e827c128..f79e20353 100644 --- a/os/kernel/src/chmempools.c +++ b/os/kernel/src/chmempools.c @@ -1,5 +1,5 @@ /* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chmsg.c b/os/kernel/src/chmsg.c index 9b6afd950..411c5fed3 100644 --- a/os/kernel/src/chmsg.c +++ b/os/kernel/src/chmsg.c @@ -1,5 +1,5 @@ /* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index d5335c0aa..336df8a6e 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -1,276 +1,276 @@ -/* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT 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. - - ChibiOS/RT 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 chmtx.c - * @brief Mutexes code. - * - * @addtogroup mutexes - * @{ - */ - -#include "ch.h" - -#if CH_USE_MUTEXES - -/** - * @brief Initializes s @p Mutex structure. - * - * @param[out] mp pointer to a @p Mutex structure - */ -void chMtxInit(Mutex *mp) { - - chDbgCheck(mp != NULL, "chMtxInit"); - - queue_init(&mp->m_queue); - mp->m_owner = NULL; -} - -/** - * @brief Locks the specified mutex. - * - * @param[in] mp pointer to the @p Mutex structure - */ -void chMtxLock(Mutex *mp) { - - chSysLock(); - - chMtxLockS(mp); - - chSysUnlock(); -} - -/** - * @brief Locks the specified mutex. - * - * @param[in] mp pointer to the @p Mutex structure - */ -void chMtxLockS(Mutex *mp) { - Thread *ctp = currp; - - chDbgCheck(mp != NULL, "chMtxLockS"); - - /* Ia the mutex already locked? */ - if (mp->m_owner != NULL) { - /* Priority inheritance protocol; explores the thread-mutex dependencies - boosting the priority of all the affected threads to equal the priority - of the running thread requesting the mutex.*/ - Thread *tp = mp->m_owner; - /* Does the running thread have higher priority than the mutex - ownning thread? */ - while (tp->p_prio < ctp->p_prio) { - /* Make priority of thread tp match the running thread's priority.*/ - tp->p_prio = ctp->p_prio; - /* The following states need priority queues reordering.*/ - switch (tp->p_state) { - case THD_STATE_WTMTX: - /* Re-enqueues the mutex owner with its new priority.*/ - prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); - tp = ((Mutex *)tp->p_u.wtobjp)->m_owner; - continue; -#if CH_USE_CONDVARS | CH_USE_SEMAPHORES_PRIORITY | CH_USE_MESSAGES_PRIORITY -#if CH_USE_CONDVARS - case THD_STATE_WTCOND: -#endif -#if CH_USE_SEMAPHORES_PRIORITY - case THD_STATE_WTSEM: -#endif -#if CH_USE_MESSAGES_PRIORITY - case THD_STATE_SNDMSG: -#endif - /* Re-enqueues tp with its new priority on the queue.*/ - prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); - break; -#endif - case THD_STATE_READY: - /* Re-enqueues tp with its new priority on the ready list.*/ - chSchReadyI(dequeue(tp)); - } - break; - } - /* Sleep on the mutex.*/ - prio_insert(ctp, &mp->m_queue); - ctp->p_u.wtobjp = mp; - chSchGoSleepS(THD_STATE_WTMTX); - chDbgAssert(mp->m_owner == NULL, "chMtxLockS(), #1", "still owned"); - } - /* The mutex is now inserted in the owned mutexes list.*/ - mp->m_owner = ctp; - mp->m_next = ctp->p_mtxlist; - ctp->p_mtxlist = mp; -} - -/** - * @brief Tries to lock a mutex. - * @details This function does not have any overhead related to - * the priority inheritance mechanism because it does not try to - * enter a sleep state on the mutex. - * - * @param[in] mp pointer to the @p Mutex structure - * @retval TRUE if the mutex was successfully acquired - * @retval FALSE if the lock attempt failed. - */ -bool_t chMtxTryLock(Mutex *mp) { - bool_t b; - - chSysLock(); - - b = chMtxTryLockS(mp); - - chSysUnlock(); - return b; -} - -/** - * @brief Tries to lock a mutex. - * @details This function does not have any overhead related to - * the priority inheritance mechanism because it does not try to - * enter a sleep state on the mutex. - * - * @param[in] mp pointer to the @p Mutex structure - * @retval TRUE if the mutex was successfully acquired - * @retval FALSE if the lock attempt failed. - */ -bool_t chMtxTryLockS(Mutex *mp) { - - chDbgCheck(mp != NULL, "chMtxTryLockS"); - - if (mp->m_owner != NULL) - return FALSE; - mp->m_owner = currp; - mp->m_next = currp->p_mtxlist; - currp->p_mtxlist = mp; - return TRUE; -} - -/** - * @brief Unlocks the next owned mutex in reverse lock order. - * - * @return The pointer to the unlocked mutex. - */ -Mutex *chMtxUnlock(void) { - Thread *ctp = currp; - Mutex *ump, *mp; - - chSysLock(); - chDbgAssert(ctp->p_mtxlist != NULL, - "chMtxUnlock(), #1", - "owned mutexes list empty"); - chDbgAssert(ctp->p_mtxlist->m_owner == ctp, - "chMtxUnlock(), #2", - "ownership failure"); - /* Removes the top Mutex from the Threads's owned mutexes list and matk it - as not owned.*/ - ump = ctp->p_mtxlist; - ctp->p_mtxlist = ump->m_next; - ump->m_owner = NULL; - /* If a thread is waiting on the mutex then the fun part begins.*/ - if (chMtxQueueNotEmptyS(ump)) { - /* Recalculates the optimal thread priority by scanning the owned - mutexes list.*/ - tprio_t newprio = ctp->p_realprio; - mp = ctp->p_mtxlist; - while (mp != NULL) { - /* If the highest priority thread waiting in the mutexes list has a - greater priority than the current thread base priority then the final - priority will have at least that priority.*/ - if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio)) - newprio = mp->m_queue.p_next->p_prio; - mp = mp->m_next; - } - /* Assigns to the current thread the highest priority among all the - waiting threads.*/ - ctp->p_prio = newprio; - /* Awakens the highest priority thread waiting for the unlocked mutex.*/ - chSchWakeupS(fifo_remove(&ump->m_queue), RDY_OK); - } - chSysUnlock(); - return ump; -} - -/** - * @brief Unlocks the next owned mutex in reverse lock order. - * @note This function does not reschedule internally. - * - * @return The pointer to the unlocked mutex. - */ -Mutex *chMtxUnlockS(void) { - Thread *ctp = currp; - Mutex *ump, *mp; - - chDbgAssert(ctp->p_mtxlist != NULL, - "chMtxUnlockS(), #1", - "owned mutexes list empty"); - chDbgAssert(ctp->p_mtxlist->m_owner == ctp, - "chMtxUnlockS(), #2", - "ownership failure"); - - /* Removes the top Mutex from the owned mutexes list and marks it as not - owned.*/ - ump = ctp->p_mtxlist; - ctp->p_mtxlist = ump->m_next; - ump->m_owner = NULL; - /* If a thread is waiting on the mutex then the fun part begins.*/ - if (chMtxQueueNotEmptyS(ump)) { - /* Recalculates the optimal thread priority by scanning the owned - mutexes list.*/ - tprio_t newprio = ctp->p_realprio; - mp = ctp->p_mtxlist; - while (mp != NULL) { - /* If the highest priority thread waiting in the mutexes list has a - greater priority than the current thread base priority then the final - priority will have at least that priority.*/ - if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio)) - newprio = mp->m_queue.p_next->p_prio; - mp = mp->m_next; - } - ctp->p_prio = newprio; - chSchReadyI(fifo_remove(&ump->m_queue)); - } - return ump; -} - -/** - * @brief Unlocks all the mutexes owned by the invoking thread. - * @details This function is MUCH MORE efficient than releasing the - * mutexes one by one and not just because the call overhead, - * this function does not have any overhead related to the priority - * inheritance mechanism. - */ -void chMtxUnlockAll(void) { - Thread *ctp = currp; - - chSysLock(); - if (ctp->p_mtxlist != NULL) { - do { - Mutex *mp = ctp->p_mtxlist; - ctp->p_mtxlist = mp->m_next; - mp->m_owner = NULL; - if (chMtxQueueNotEmptyS(mp)) - chSchReadyI(fifo_remove(&mp->m_queue)); - } while (ctp->p_mtxlist != NULL); - ctp->p_prio = ctp->p_realprio; - chSchRescheduleS(); - } - chSysUnlock(); -} - -#endif /* CH_USE_MUTEXES */ - -/** @} */ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chmtx.c + * @brief Mutexes code. + * + * @addtogroup mutexes + * @{ + */ + +#include "ch.h" + +#if CH_USE_MUTEXES + +/** + * @brief Initializes s @p Mutex structure. + * + * @param[out] mp pointer to a @p Mutex structure + */ +void chMtxInit(Mutex *mp) { + + chDbgCheck(mp != NULL, "chMtxInit"); + + queue_init(&mp->m_queue); + mp->m_owner = NULL; +} + +/** + * @brief Locks the specified mutex. + * + * @param[in] mp pointer to the @p Mutex structure + */ +void chMtxLock(Mutex *mp) { + + chSysLock(); + + chMtxLockS(mp); + + chSysUnlock(); +} + +/** + * @brief Locks the specified mutex. + * + * @param[in] mp pointer to the @p Mutex structure + */ +void chMtxLockS(Mutex *mp) { + Thread *ctp = currp; + + chDbgCheck(mp != NULL, "chMtxLockS"); + + /* Ia the mutex already locked? */ + if (mp->m_owner != NULL) { + /* Priority inheritance protocol; explores the thread-mutex dependencies + boosting the priority of all the affected threads to equal the priority + of the running thread requesting the mutex.*/ + Thread *tp = mp->m_owner; + /* Does the running thread have higher priority than the mutex + ownning thread? */ + while (tp->p_prio < ctp->p_prio) { + /* Make priority of thread tp match the running thread's priority.*/ + tp->p_prio = ctp->p_prio; + /* The following states need priority queues reordering.*/ + switch (tp->p_state) { + case THD_STATE_WTMTX: + /* Re-enqueues the mutex owner with its new priority.*/ + prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); + tp = ((Mutex *)tp->p_u.wtobjp)->m_owner; + continue; +#if CH_USE_CONDVARS | CH_USE_SEMAPHORES_PRIORITY | CH_USE_MESSAGES_PRIORITY +#if CH_USE_CONDVARS + case THD_STATE_WTCOND: +#endif +#if CH_USE_SEMAPHORES_PRIORITY + case THD_STATE_WTSEM: +#endif +#if CH_USE_MESSAGES_PRIORITY + case THD_STATE_SNDMSG: +#endif + /* Re-enqueues tp with its new priority on the queue.*/ + prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); + break; +#endif + case THD_STATE_READY: + /* Re-enqueues tp with its new priority on the ready list.*/ + chSchReadyI(dequeue(tp)); + } + break; + } + /* Sleep on the mutex.*/ + prio_insert(ctp, &mp->m_queue); + ctp->p_u.wtobjp = mp; + chSchGoSleepS(THD_STATE_WTMTX); + chDbgAssert(mp->m_owner == NULL, "chMtxLockS(), #1", "still owned"); + } + /* The mutex is now inserted in the owned mutexes list.*/ + mp->m_owner = ctp; + mp->m_next = ctp->p_mtxlist; + ctp->p_mtxlist = mp; +} + +/** + * @brief Tries to lock a mutex. + * @details This function does not have any overhead related to + * the priority inheritance mechanism because it does not try to + * enter a sleep state on the mutex. + * + * @param[in] mp pointer to the @p Mutex structure + * @retval TRUE if the mutex was successfully acquired + * @retval FALSE if the lock attempt failed. + */ +bool_t chMtxTryLock(Mutex *mp) { + bool_t b; + + chSysLock(); + + b = chMtxTryLockS(mp); + + chSysUnlock(); + return b; +} + +/** + * @brief Tries to lock a mutex. + * @details This function does not have any overhead related to + * the priority inheritance mechanism because it does not try to + * enter a sleep state on the mutex. + * + * @param[in] mp pointer to the @p Mutex structure + * @retval TRUE if the mutex was successfully acquired + * @retval FALSE if the lock attempt failed. + */ +bool_t chMtxTryLockS(Mutex *mp) { + + chDbgCheck(mp != NULL, "chMtxTryLockS"); + + if (mp->m_owner != NULL) + return FALSE; + mp->m_owner = currp; + mp->m_next = currp->p_mtxlist; + currp->p_mtxlist = mp; + return TRUE; +} + +/** + * @brief Unlocks the next owned mutex in reverse lock order. + * + * @return The pointer to the unlocked mutex. + */ +Mutex *chMtxUnlock(void) { + Thread *ctp = currp; + Mutex *ump, *mp; + + chSysLock(); + chDbgAssert(ctp->p_mtxlist != NULL, + "chMtxUnlock(), #1", + "owned mutexes list empty"); + chDbgAssert(ctp->p_mtxlist->m_owner == ctp, + "chMtxUnlock(), #2", + "ownership failure"); + /* Removes the top Mutex from the Threads's owned mutexes list and matk it + as not owned.*/ + ump = ctp->p_mtxlist; + ctp->p_mtxlist = ump->m_next; + ump->m_owner = NULL; + /* If a thread is waiting on the mutex then the fun part begins.*/ + if (chMtxQueueNotEmptyS(ump)) { + /* Recalculates the optimal thread priority by scanning the owned + mutexes list.*/ + tprio_t newprio = ctp->p_realprio; + mp = ctp->p_mtxlist; + while (mp != NULL) { + /* If the highest priority thread waiting in the mutexes list has a + greater priority than the current thread base priority then the final + priority will have at least that priority.*/ + if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio)) + newprio = mp->m_queue.p_next->p_prio; + mp = mp->m_next; + } + /* Assigns to the current thread the highest priority among all the + waiting threads.*/ + ctp->p_prio = newprio; + /* Awakens the highest priority thread waiting for the unlocked mutex.*/ + chSchWakeupS(fifo_remove(&ump->m_queue), RDY_OK); + } + chSysUnlock(); + return ump; +} + +/** + * @brief Unlocks the next owned mutex in reverse lock order. + * @note This function does not reschedule internally. + * + * @return The pointer to the unlocked mutex. + */ +Mutex *chMtxUnlockS(void) { + Thread *ctp = currp; + Mutex *ump, *mp; + + chDbgAssert(ctp->p_mtxlist != NULL, + "chMtxUnlockS(), #1", + "owned mutexes list empty"); + chDbgAssert(ctp->p_mtxlist->m_owner == ctp, + "chMtxUnlockS(), #2", + "ownership failure"); + + /* Removes the top Mutex from the owned mutexes list and marks it as not + owned.*/ + ump = ctp->p_mtxlist; + ctp->p_mtxlist = ump->m_next; + ump->m_owner = NULL; + /* If a thread is waiting on the mutex then the fun part begins.*/ + if (chMtxQueueNotEmptyS(ump)) { + /* Recalculates the optimal thread priority by scanning the owned + mutexes list.*/ + tprio_t newprio = ctp->p_realprio; + mp = ctp->p_mtxlist; + while (mp != NULL) { + /* If the highest priority thread waiting in the mutexes list has a + greater priority than the current thread base priority then the final + priority will have at least that priority.*/ + if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio)) + newprio = mp->m_queue.p_next->p_prio; + mp = mp->m_next; + } + ctp->p_prio = newprio; + chSchReadyI(fifo_remove(&ump->m_queue)); + } + return ump; +} + +/** + * @brief Unlocks all the mutexes owned by the invoking thread. + * @details This function is MUCH MORE efficient than releasing the + * mutexes one by one and not just because the call overhead, + * this function does not have any overhead related to the priority + * inheritance mechanism. + */ +void chMtxUnlockAll(void) { + Thread *ctp = currp; + + chSysLock(); + if (ctp->p_mtxlist != NULL) { + do { + Mutex *mp = ctp->p_mtxlist; + ctp->p_mtxlist = mp->m_next; + mp->m_owner = NULL; + if (chMtxQueueNotEmptyS(mp)) + chSchReadyI(fifo_remove(&mp->m_queue)); + } while (ctp->p_mtxlist != NULL); + ctp->p_prio = ctp->p_realprio; + chSchRescheduleS(); + } + chSysUnlock(); +} + +#endif /* CH_USE_MUTEXES */ + +/** @} */ diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index 50f1f2401..2f8d1b569 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -1,5 +1,5 @@ /* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c index b6555df40..8d4ffa4e8 100644 --- a/os/kernel/src/chregistry.c +++ b/os/kernel/src/chregistry.c @@ -1,5 +1,5 @@ /* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. This file is part of ChibiOS/RT. @@ -37,7 +37,7 @@ * @note This function cannot return @p NULL because there is always at * least one thread in the system. * - * @return A reference to the first thread. + * @return A reference to the first thread. */ Thread *chRegFirstThread(void) { Thread *tp; @@ -55,7 +55,7 @@ Thread *chRegFirstThread(void) { * @brief Returns the thread next to the specified one. * @details The reference counter of the specified thread is decremented and * the reference counter of the returned thread is incremented. - * + * * @param[in] tp pointer to the thread * @return A reference to the next thread. * @retval NULL if there is no next thread. diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 5bd016226..8cfd5cd81 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -1,280 +1,280 @@ -/* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT 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. - - ChibiOS/RT 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 chschd.c - * @brief Scheduler code. - * - * @addtogroup scheduler - * @{ - */ - -#include "ch.h" - -/** - * @brief Ready list header. - */ -ReadyList rlist; - -/** - * @brief Scheduler initialization. - * @note Internally invoked by the @p chSysInit(), not an API. - */ -void scheduler_init(void) { - - queue_init(&rlist.r_queue); - rlist.r_prio = NOPRIO; -#if CH_TIME_QUANTUM > 0 - rlist.r_preempt = CH_TIME_QUANTUM; -#endif -#if CH_USE_REGISTRY - rlist.p_newer = rlist.p_older = (Thread *)&rlist; -#endif -} - -/** - * @brief Inserts a thread in the Ready List. - * @note The function does not reschedule, the @p chSchRescheduleS() should - * be called soon after. - * - * @param[in] tp the Thread to be made ready - * @return The Thread pointer. - */ -#if CH_OPTIMIZE_SPEED -/* NOTE: it is inlined in this module only.*/ -INLINE Thread *chSchReadyI(Thread *tp) { -#else -Thread *chSchReadyI(Thread *tp) { -#endif - Thread *cp; - - tp->p_state = THD_STATE_READY; - cp = (Thread *)&rlist.r_queue; - do { - cp = cp->p_next; - } while (cp->p_prio >= tp->p_prio); - /* Insertion on p_prev.*/ - tp->p_prev = (tp->p_next = cp)->p_prev; - tp->p_prev->p_next = cp->p_prev = tp; - return tp; -} - -/** - * @brief Puts the current thread to sleep into the specified state. - * @details The thread goes into a sleeping state. The @ref thread_states are - * described into @p threads.h. - * - * @param[in] newstate the new thread state - */ -void chSchGoSleepS(tstate_t newstate) { - Thread *otp; - - (otp = currp)->p_state = newstate; - (currp = fifo_remove(&rlist.r_queue))->p_state = THD_STATE_CURRENT; -#if CH_TIME_QUANTUM > 0 - rlist.r_preempt = CH_TIME_QUANTUM; -#endif - chDbgTrace(otp, currp); - chSysSwitchI(otp, currp); -} - -/* - * Timeout wakeup callback. - */ -static void wakeup(void *p) { - Thread *tp = (Thread *)p; - -#if CH_USE_SEMAPHORES || CH_USE_MUTEXES || CH_USE_CONDVARS - switch (tp->p_state) { -#if CH_USE_SEMAPHORES - case THD_STATE_WTSEM: - chSemFastSignalI((Semaphore *)tp->p_u.wtobjp); - /* Falls into, intentional. */ -#endif -#if CH_USE_MUTEXES - case THD_STATE_WTMTX: -#endif -#if CH_USE_CONDVARS - case THD_STATE_WTCOND: -#endif - /* States requiring dequeuing.*/ - dequeue(tp); - } -#endif - chSchReadyI(tp)->p_u.rdymsg = RDY_TIMEOUT; -} - -/** - * @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 timeout then it is forcibly - * awakened with a @p RDY_TIMEOUT low level message. The @ref - * thread_states are described into @p threads.h. - * - * @param[in] newstate the new thread state - * @param[in] time the number of ticks before the operation timeouts, the - * special values are handled as follow: - * - @a TIME_INFINITE the thread enters an infinite sleep - * state, this is equivalent to invoking - * @p chSchGoSleepS() but, of course, less efficient. - * - @a TIME_IMMEDIATE this value is accepted but - * interpreted as a normal time specification not as an - * immediate timeout specification. - * . - * @return The wakeup message. - * @retval RDY_TIMEOUT if a timeout occurs. - */ -msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { - - if (TIME_INFINITE != time) { - VirtualTimer vt; - - chVTSetI(&vt, time, wakeup, currp); - chSchGoSleepS(newstate); - if (chVTIsArmedI(&vt)) - chVTResetI(&vt); - } - else - chSchGoSleepS(newstate); - return currp->p_u.rdymsg; -} - -/** - * @brief Wakes up a thread. - * @details The thread is inserted into the ready list or immediately made - * running depending on its relative priority compared to the current - * thread. - * @note It is equivalent to a @p chSchReadyI() followed by a - * @p chSchRescheduleS() but much more efficient. - * @note The function assumes that the current thread has the highest - * priority. - * - * @param[in] ntp the Thread to be made ready - * @param[in] msg message to the awakened thread - */ -void chSchWakeupS(Thread *ntp, msg_t msg) { - - ntp->p_u.rdymsg = msg; - /* If the waken thread has a not-greater priority than the current - one then it is just inserted in the ready list else it made - running immediately and the invoking thread goes in the ready - list instead.*/ - if (ntp->p_prio <= currp->p_prio) - chSchReadyI(ntp); - else { - Thread *otp = currp; - chSchReadyI(otp); -#if CH_TIME_QUANTUM > 0 - rlist.r_preempt = CH_TIME_QUANTUM; -#endif - (currp = ntp)->p_state = THD_STATE_CURRENT; - chDbgTrace(otp, ntp); - chSysSwitchI(otp, ntp); - } -} - -/** - * @brief Switches to the first thread on the runnable queue. - * @note It is intended to be called if @p chSchRescRequiredI() evaluates - * to @p TRUE. - */ -void chSchDoRescheduleI(void) { - - Thread *otp = currp; - /* Pick the first thread from the ready queue and makes it current.*/ - (currp = fifo_remove(&rlist.r_queue))->p_state = THD_STATE_CURRENT; - chSchReadyI(otp); -#if CH_TIME_QUANTUM > 0 - rlist.r_preempt = CH_TIME_QUANTUM; -#endif - chDbgTrace(otp, currp); - chSysSwitchI(otp, currp); -} - -/** - * @brief Performs a reschedulation if a higher priority thread is runnable. - * @details If a thread with a higher priority than the current thread is in - * the ready list then make the higher priority thread running. - */ -void chSchRescheduleS(void) { - - if (chSchIsRescRequiredI()) - chSchDoRescheduleI(); -} - -/** - * @brief Evaluates if a reschedulation is required. - * @details The decision is taken by comparing the relative priorities and - * depending on the state of the round robin timeout counter. - * @note This function is meant to be used in the timer interrupt handler - * where @p chVTDoTickI() is invoked. - * - * @retval TRUE if there is a thread that should go in running state. - * @retval FALSE if a reschedulation is not required. - */ -bool_t chSchIsRescRequiredExI(void) { - tprio_t p1 = firstprio(&rlist.r_queue); - tprio_t p2 = currp->p_prio; -#if CH_TIME_QUANTUM > 0 - /* If the running thread has not reached its time quantum, reschedule only - if the first thread on the ready queue has a higher priority. - Otherwise, if the running thread has used up its time quantum, reschedule - if the first thread on the ready queue has equal or higher priority.*/ - return rlist.r_preempt ? p1 > p2 : p1 >= p2; -#else - /* If the round robin preemption feature is not enabled then performs a - simpler comparison.*/ - return p1 > p2; -#endif -} - -/** - * @brief Yields the time slot. - * @details Yields the CPU control to the next thread in the ready list with - * equal priority, if any. - */ -void chSchDoYieldS(void) { - - if (chSchCanYieldS()) { - Thread *cp = (Thread *)&rlist.r_queue; - Thread *otp = currp; - - /* Note, the following insertion code works because we know that on the - ready list there is at least one thread with priority equal or higher - than the current one.*/ - otp->p_state = THD_STATE_READY; - do { - cp = cp->p_prev; - } while (cp->p_prio < otp->p_prio); - /* Insertion on p_next.*/ - otp->p_next = (otp->p_prev = cp)->p_next; - otp->p_next->p_prev = cp->p_next = otp; - - /* Pick the first thread from the ready queue and makes it current.*/ - (currp = fifo_remove(&rlist.r_queue))->p_state = THD_STATE_CURRENT; -#if CH_TIME_QUANTUM > 0 - rlist.r_preempt = CH_TIME_QUANTUM; -#endif - chDbgTrace(otp, currp); - chSysSwitchI(otp, currp); - } -} - -/** @} */ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chschd.c + * @brief Scheduler code. + * + * @addtogroup scheduler + * @{ + */ + +#include "ch.h" + +/** + * @brief Ready list header. + */ +ReadyList rlist; + +/** + * @brief Scheduler initialization. + * @note Internally invoked by the @p chSysInit(), not an API. + */ +void scheduler_init(void) { + + queue_init(&rlist.r_queue); + rlist.r_prio = NOPRIO; +#if CH_TIME_QUANTUM > 0 + rlist.r_preempt = CH_TIME_QUANTUM; +#endif +#if CH_USE_REGISTRY + rlist.p_newer = rlist.p_older = (Thread *)&rlist; +#endif +} + +/** + * @brief Inserts a thread in the Ready List. + * @note The function does not reschedule, the @p chSchRescheduleS() should + * be called soon after. + * + * @param[in] tp the Thread to be made ready + * @return The Thread pointer. + */ +#if CH_OPTIMIZE_SPEED +/* NOTE: it is inlined in this module only.*/ +INLINE Thread *chSchReadyI(Thread *tp) { +#else +Thread *chSchReadyI(Thread *tp) { +#endif + Thread *cp; + + tp->p_state = THD_STATE_READY; + cp = (Thread *)&rlist.r_queue; + do { + cp = cp->p_next; + } while (cp->p_prio >= tp->p_prio); + /* Insertion on p_prev.*/ + tp->p_prev = (tp->p_next = cp)->p_prev; + tp->p_prev->p_next = cp->p_prev = tp; + return tp; +} + +/** + * @brief Puts the current thread to sleep into the specified state. + * @details The thread goes into a sleeping state. The @ref thread_states are + * described into @p threads.h. + * + * @param[in] newstate the new thread state + */ +void chSchGoSleepS(tstate_t newstate) { + Thread *otp; + + (otp = currp)->p_state = newstate; + (currp = fifo_remove(&rlist.r_queue))->p_state = THD_STATE_CURRENT; +#if CH_TIME_QUANTUM > 0 + rlist.r_preempt = CH_TIME_QUANTUM; +#endif + chDbgTrace(otp, currp); + chSysSwitchI(otp, currp); +} + +/* + * Timeout wakeup callback. + */ +static void wakeup(void *p) { + Thread *tp = (Thread *)p; + +#if CH_USE_SEMAPHORES || CH_USE_MUTEXES || CH_USE_CONDVARS + switch (tp->p_state) { +#if CH_USE_SEMAPHORES + case THD_STATE_WTSEM: + chSemFastSignalI((Semaphore *)tp->p_u.wtobjp); + /* Falls into, intentional. */ +#endif +#if CH_USE_MUTEXES + case THD_STATE_WTMTX: +#endif +#if CH_USE_CONDVARS + case THD_STATE_WTCOND: +#endif + /* States requiring dequeuing.*/ + dequeue(tp); + } +#endif + chSchReadyI(tp)->p_u.rdymsg = RDY_TIMEOUT; +} + +/** + * @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 timeout then it is forcibly + * awakened with a @p RDY_TIMEOUT low level message. The @ref + * thread_states are described into @p threads.h. + * + * @param[in] newstate the new thread state + * @param[in] time the number of ticks before the operation timeouts, the + * special values are handled as follow: + * - @a TIME_INFINITE the thread enters an infinite sleep + * state, this is equivalent to invoking + * @p chSchGoSleepS() but, of course, less efficient. + * - @a TIME_IMMEDIATE this value is accepted but + * interpreted as a normal time specification not as an + * immediate timeout specification. + * . + * @return The wakeup message. + * @retval RDY_TIMEOUT if a timeout occurs. + */ +msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { + + if (TIME_INFINITE != time) { + VirtualTimer vt; + + chVTSetI(&vt, time, wakeup, currp); + chSchGoSleepS(newstate); + if (chVTIsArmedI(&vt)) + chVTResetI(&vt); + } + else + chSchGoSleepS(newstate); + return currp->p_u.rdymsg; +} + +/** + * @brief Wakes up a thread. + * @details The thread is inserted into the ready list or immediately made + * running depending on its relative priority compared to the current + * thread. + * @note It is equivalent to a @p chSchReadyI() followed by a + * @p chSchRescheduleS() but much more efficient. + * @note The function assumes that the current thread has the highest + * priority. + * + * @param[in] ntp the Thread to be made ready + * @param[in] msg message to the awakened thread + */ +void chSchWakeupS(Thread *ntp, msg_t msg) { + + ntp->p_u.rdymsg = msg; + /* If the waken thread has a not-greater priority than the current + one then it is just inserted in the ready list else it made + running immediately and the invoking thread goes in the ready + list instead.*/ + if (ntp->p_prio <= currp->p_prio) + chSchReadyI(ntp); + else { + Thread *otp = currp; + chSchReadyI(otp); +#if CH_TIME_QUANTUM > 0 + rlist.r_preempt = CH_TIME_QUANTUM; +#endif + (currp = ntp)->p_state = THD_STATE_CURRENT; + chDbgTrace(otp, ntp); + chSysSwitchI(otp, ntp); + } +} + +/** + * @brief Switches to the first thread on the runnable queue. + * @note It is intended to be called if @p chSchRescRequiredI() evaluates + * to @p TRUE. + */ +void chSchDoRescheduleI(void) { + + Thread *otp = currp; + /* Pick the first thread from the ready queue and makes it current.*/ + (currp = fifo_remove(&rlist.r_queue))->p_state = THD_STATE_CURRENT; + chSchReadyI(otp); +#if CH_TIME_QUANTUM > 0 + rlist.r_preempt = CH_TIME_QUANTUM; +#endif + chDbgTrace(otp, currp); + chSysSwitchI(otp, currp); +} + +/** + * @brief Performs a reschedulation if a higher priority thread is runnable. + * @details If a thread with a higher priority than the current thread is in + * the ready list then make the higher priority thread running. + */ +void chSchRescheduleS(void) { + + if (chSchIsRescRequiredI()) + chSchDoRescheduleI(); +} + +/** + * @brief Evaluates if a reschedulation is required. + * @details The decision is taken by comparing the relative priorities and + * depending on the state of the round robin timeout counter. + * @note This function is meant to be used in the timer interrupt handler + * where @p chVTDoTickI() is invoked. + * + * @retval TRUE if there is a thread that should go in running state. + * @retval FALSE if a reschedulation is not required. + */ +bool_t chSchIsRescRequiredExI(void) { + tprio_t p1 = firstprio(&rlist.r_queue); + tprio_t p2 = currp->p_prio; +#if CH_TIME_QUANTUM > 0 + /* If the running thread has not reached its time quantum, reschedule only + if the first thread on the ready queue has a higher priority. + Otherwise, if the running thread has used up its time quantum, reschedule + if the first thread on the ready queue has equal or higher priority.*/ + return rlist.r_preempt ? p1 > p2 : p1 >= p2; +#else + /* If the round robin preemption feature is not enabled then performs a + simpler comparison.*/ + return p1 > p2; +#endif +} + +/** + * @brief Yields the time slot. + * @details Yields the CPU control to the next thread in the ready list with + * equal priority, if any. + */ +void chSchDoYieldS(void) { + + if (chSchCanYieldS()) { + Thread *cp = (Thread *)&rlist.r_queue; + Thread *otp = currp; + + /* Note, the following insertion code works because we know that on the + ready list there is at least one thread with priority equal or higher + than the current one.*/ + otp->p_state = THD_STATE_READY; + do { + cp = cp->p_prev; + } while (cp->p_prio < otp->p_prio); + /* Insertion on p_next.*/ + otp->p_next = (otp->p_prev = cp)->p_next; + otp->p_next->p_prev = cp->p_next = otp; + + /* Pick the first thread from the ready queue and makes it current.*/ + (currp = fifo_remove(&rlist.r_queue))->p_state = THD_STATE_CURRENT; +#if CH_TIME_QUANTUM > 0 + rlist.r_preempt = CH_TIME_QUANTUM; +#endif + chDbgTrace(otp, currp); + chSysSwitchI(otp, currp); + } +} + +/** @} */ diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index b4ff0d9bc..7af52d8b6 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -1,5 +1,5 @@ /* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 8c252609d..2003f690b 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -1,130 +1,130 @@ -/* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT 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. - - ChibiOS/RT 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 chsys.c - * @brief System related code. - * - * @addtogroup system - * @{ - */ - -#include "ch.h" - -static WORKING_AREA(idle_thread_wa, IDLE_THREAD_STACK_SIZE); - -/** - * @brief This function implements the idle thread infinite loop. - * @details The function puts the processor in the lowest power mode capable - * to serve interrupts.
- * The priority is internally set to the minimum system value so - * that this thread is executed only if there are no other ready - * threads in the system. - * - * @param[in] p the thread parameter, unused in this scenario - */ -static void idle_thread(void *p) { - - (void)p; - while (TRUE) { - port_wait_for_interrupt(); - IDLE_LOOP_HOOK(); - } -} - -/** - * @brief ChibiOS/RT initialization. - * @details After executing this function the current instructions stream - * becomes the main thread. - * @note Interrupts should be still disabled when @p chSysInit() is invoked - * and are internally enabled. - * @note The main thread is created with priority @p NORMALPRIO. - */ -void chSysInit(void) { - static Thread mainthread; - - port_init(); - scheduler_init(); - vt_init(); -#if CH_USE_MEMCORE - core_init(); -#endif -#if CH_USE_HEAP - heap_init(); -#endif -#if CH_DBG_ENABLE_TRACE - trace_init(); -#endif - - /* Now this instructions flow becomes the main thread.*/ - (currp = init_thread(&mainthread, NORMALPRIO))->p_state = THD_STATE_CURRENT; - chSysEnable(); - - /* This thread has the lowest priority in the system, its role is just to - serve interrupts in its context while keeping the lowest energy saving - mode compatible with the system status.*/ - chThdCreateStatic(idle_thread_wa, sizeof(idle_thread_wa), IDLEPRIO, - (tfunc_t)idle_thread, NULL); -} - -/** - * @brief Handles time ticks for round robin preemption and timer increments. - * @details Decrements the remaining time quantum of the running thread - * and preempts it when the quantum is used up. Increments system - * time and manages the timers. - * - * @note The frequency of the timer determines the system tick granularity - * and, together with the @p CH_TIME_QUANTUM macro, the round robin - * interval. - */ -void chSysTimerHandlerI(void) { - -#if CH_TIME_QUANTUM > 0 - /* Running thread has not used up quantum yet? */ - if (rlist.r_preempt > 0) - /* Decrement remaining quantum.*/ - rlist.r_preempt--; -#endif -#if CH_DBG_THREADS_PROFILING - currp->p_time++; -#endif - chVTDoTickI(); -} - -#if CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED -void chSysLock(void) { - - chDbgAssert(currp->p_locks >= 0, - "chSysLock(), #1", - "negative nesting counter"); - if (currp->p_locks++ == 0) - port_lock(); -} - -void chSysUnlock(void) { - - chDbgAssert(currp->p_locks > 0, - "chSysUnlock(), #1", - "non-positive nesting counter"); - if (--currp->p_locks == 0) - port_unlock(); -} -#endif /* CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED */ - -/** @} */ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chsys.c + * @brief System related code. + * + * @addtogroup system + * @{ + */ + +#include "ch.h" + +static WORKING_AREA(idle_thread_wa, IDLE_THREAD_STACK_SIZE); + +/** + * @brief This function implements the idle thread infinite loop. + * @details The function puts the processor in the lowest power mode capable + * to serve interrupts.
+ * The priority is internally set to the minimum system value so + * that this thread is executed only if there are no other ready + * threads in the system. + * + * @param[in] p the thread parameter, unused in this scenario + */ +static void idle_thread(void *p) { + + (void)p; + while (TRUE) { + port_wait_for_interrupt(); + IDLE_LOOP_HOOK(); + } +} + +/** + * @brief ChibiOS/RT initialization. + * @details After executing this function the current instructions stream + * becomes the main thread. + * @note Interrupts should be still disabled when @p chSysInit() is invoked + * and are internally enabled. + * @note The main thread is created with priority @p NORMALPRIO. + */ +void chSysInit(void) { + static Thread mainthread; + + port_init(); + scheduler_init(); + vt_init(); +#if CH_USE_MEMCORE + core_init(); +#endif +#if CH_USE_HEAP + heap_init(); +#endif +#if CH_DBG_ENABLE_TRACE + trace_init(); +#endif + + /* Now this instructions flow becomes the main thread.*/ + (currp = init_thread(&mainthread, NORMALPRIO))->p_state = THD_STATE_CURRENT; + chSysEnable(); + + /* This thread has the lowest priority in the system, its role is just to + serve interrupts in its context while keeping the lowest energy saving + mode compatible with the system status.*/ + chThdCreateStatic(idle_thread_wa, sizeof(idle_thread_wa), IDLEPRIO, + (tfunc_t)idle_thread, NULL); +} + +/** + * @brief Handles time ticks for round robin preemption and timer increments. + * @details Decrements the remaining time quantum of the running thread + * and preempts it when the quantum is used up. Increments system + * time and manages the timers. + * + * @note The frequency of the timer determines the system tick granularity + * and, together with the @p CH_TIME_QUANTUM macro, the round robin + * interval. + */ +void chSysTimerHandlerI(void) { + +#if CH_TIME_QUANTUM > 0 + /* Running thread has not used up quantum yet? */ + if (rlist.r_preempt > 0) + /* Decrement remaining quantum.*/ + rlist.r_preempt--; +#endif +#if CH_DBG_THREADS_PROFILING + currp->p_time++; +#endif + chVTDoTickI(); +} + +#if CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED +void chSysLock(void) { + + chDbgAssert(currp->p_locks >= 0, + "chSysLock(), #1", + "negative nesting counter"); + if (currp->p_locks++ == 0) + port_lock(); +} + +void chSysUnlock(void) { + + chDbgAssert(currp->p_locks > 0, + "chSysUnlock(), #1", + "non-positive nesting counter"); + if (--currp->p_locks == 0) + port_unlock(); +} +#endif /* CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED */ + +/** @} */ diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 6f67f7093..79ea23f94 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -1,446 +1,446 @@ -/* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT 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. - - ChibiOS/RT 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 chthreads.c - * @brief Threads code. - * - * @addtogroup threads - * @{ - */ - -#include "ch.h" - -/** - * @brief Initializes a thread structure. - * - * @param[in] tp pointer to the thread - * @param[in] prio the priority level for the new thread - * @return The same thread pointer passed as parameter. - */ -Thread *init_thread(Thread *tp, tprio_t prio) { - - tp->p_flags = THD_MEM_MODE_STATIC; - tp->p_prio = prio; - tp->p_state = THD_STATE_SUSPENDED; -#if CH_USE_REGISTRY - REG_INSERT(tp); -#endif -#if CH_USE_DYNAMIC - tp->p_refs = 1; -#endif -#if CH_USE_NESTED_LOCKS - tp->p_locks = 0; -#endif -#if CH_DBG_THREADS_PROFILING - tp->p_time = 0; -#endif -#if CH_USE_MUTEXES - tp->p_realprio = prio; - tp->p_mtxlist = NULL; -#endif -#if CH_USE_WAITEXIT - list_init(&tp->p_waiting); -#endif -#if CH_USE_MESSAGES - queue_init(&tp->p_msgqueue); -#endif -#if CH_USE_EVENTS - tp->p_epending = 0; -#endif - THREAD_EXT_INIT(tp); - return tp; -} - -#if CH_DBG_FILL_THREADS -static void memfill(uint8_t *startp, uint8_t *endp, uint8_t v) { - - while (startp < endp) - *startp++ = v; -} -#endif - -/** - * @brief Initializes a new thread. - * @details The new thread is initialized but not inserted in the ready list, - * the initial state is @p THD_STATE_SUSPENDED. - * @note A thread can terminate by calling @p chThdExit() or by simply - * returning from its main function. - * @note This function can be invoked from within an interrupt handler - * even if it is not an I-Class API because it does not touch - * any critical kernel data structure. - * - * @param[out] wsp pointer to a working area dedicated to the thread stack - * @param[in] size size of the working area - * @param[in] prio the priority level for the new thread - * @param[in] pf the thread function - * @param[in] arg an argument passed to the thread function. It can be - * @p NULL. - * @return The pointer to the @p Thread structure allocated for - * the thread into the working space area. - */ -Thread *chThdInit(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) { - /* Thread structure is layed out in the lower part of the thread workspace */ - Thread *tp = wsp; - - chDbgCheck((wsp != NULL) && (size >= THD_WA_SIZE(0)) && - (prio <= HIGHPRIO) && (pf != NULL), - "chThdInit"); -#if CH_DBG_FILL_THREADS - memfill((uint8_t *)wsp, (uint8_t *)wsp + sizeof(Thread), THREAD_FILL_VALUE); - memfill((uint8_t *)wsp + sizeof(Thread), - (uint8_t *)wsp + size, STACK_FILL_VALUE); -#endif - SETUP_CONTEXT(wsp, size, pf, arg); - return init_thread(tp, prio); -} - -/** - * @brief Creates a new thread into a static memory area. - * @note A thread can terminate by calling @p chThdExit() or by simply - * returning from its main function. - * - * @param[out] wsp pointer to a working area dedicated to the thread stack - * @param[in] size size of the working area - * @param[in] prio the priority level for the new thread - * @param[in] pf the thread function - * @param[in] arg an argument passed to the thread function. It can be - * @p NULL. - * @return The pointer to the @p Thread structure allocated for - * the thread into the working space area. - */ -Thread *chThdCreateStatic(void *wsp, size_t size, - tprio_t prio, tfunc_t pf, void *arg) { - - return chThdResume(chThdInit(wsp, size, prio, pf, arg)); -} - -#if CH_USE_DYNAMIC && CH_USE_HEAP -/** - * @brief Creates a new thread allocating the memory from the heap. - * @note A thread can terminate by calling @p chThdExit() or by simply - * returning from its main function. - * @note The memory allocated for the thread is not released when the thread - * terminates but when a @p chThdWait() is performed. - * @note The function is available only if the @p CH_USE_DYNAMIC, - * @p CH_USE_HEAP and @p CH_USE_WAITEXIT options are enabled - * in @p chconf.h. - * - * @param[in] heapp heap from which allocate the memory or @p NULL for the - * default heap - * @param[in] size size of the working area to be allocated - * @param[in] prio the priority level for the new thread - * @param[in] pf the thread function - * @param[in] arg an argument passed to the thread function. It can be - * @p NULL. - * @return The pointer to the @p Thread structure allocated for - * the thread into the working space area. - * @retval NULL if the memory cannot be allocated. - */ -Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size, - tprio_t prio, tfunc_t pf, void *arg) { - void *wsp; - Thread *tp; - - wsp = chHeapAlloc(heapp, size); - if (wsp == NULL) - return NULL; - tp = chThdInit(wsp, size, prio, pf, arg); - tp->p_flags = THD_MEM_MODE_HEAP; - return chThdResume(tp); -} -#endif /* CH_USE_DYNAMIC && CH_USE_HEAP */ - -#if CH_USE_DYNAMIC && CH_USE_MEMPOOLS -/** - * @brief Creates a new thread allocating the memory from the specified - * Memory Pool. - * @note A thread can terminate by calling @p chThdExit() or by simply - * returning from its main function. - * @note The memory allocated for the thread is not released when the thread - * terminates but when a @p chThdWait() is performed. - * @note The function is available only if the @p CH_USE_DYNAMIC, - * @p CH_USE_MEMPOOLS and @p CH_USE_WAITEXIT options are enabled - * in @p chconf.h. - * - * @param[in] mp pointer to the memory pool object - * @param[in] prio the priority level for the new thread - * @param[in] pf the thread function - * @param[in] arg an argument passed to the thread function. It can be - * @p NULL. - * @return The pointer to the @p Thread structure allocated for - * the thread into the working space area. - * @retval NULL if the memory pool is empty. - */ -Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, - tfunc_t pf, void *arg) { - void *wsp; - Thread *tp; - - chDbgCheck(mp != NULL, "chThdCreateFromMemoryPool"); - - wsp = chPoolAlloc(mp); - if (wsp == NULL) - return NULL; - tp = chThdInit(wsp, mp->mp_object_size, prio, pf, arg); - tp->p_flags = THD_MEM_MODE_MEMPOOL; - tp->p_mpool = mp; - return chThdResume(tp); -} -#endif /* CH_USE_DYNAMIC && CH_USE_MEMPOOLS */ - -/** - * @brief Changes the running thread priority level then reschedules if - * necessary. - * @note The function returns the real thread priority regardless of the - * current priority that could be higher than the real priority - * because the priority inheritance mechanism. - * - * @param[in] newprio the new priority level of the running thread - * @return The old priority level. - */ -tprio_t chThdSetPriority(tprio_t newprio) { - tprio_t oldprio; - - chDbgCheck((newprio >= LOWPRIO) && (newprio <= HIGHPRIO), - "chThdSetPriority"); - - chSysLock(); -#if CH_USE_MUTEXES - oldprio = currp->p_realprio; - if ((currp->p_prio == currp->p_realprio) || (newprio > currp->p_prio)) - currp->p_prio = newprio; - currp->p_realprio = newprio; -#else - oldprio = currp->p_prio; - currp->p_prio = newprio; -#endif - chSchRescheduleS(); - chSysUnlock(); - return oldprio; -} - -/** - * @brief Resumes a suspended thread. - * @note Use this function to resume threads created with @p chThdInit(). - * - * @param[in] tp pointer to the thread - * @return The pointer to the thread. - */ -Thread *chThdResume(Thread *tp) { - - chSysLock(); - chDbgAssert(tp->p_state == THD_STATE_SUSPENDED, - "chThdResume(), #1", - "thread not in THD_STATE_SUSPENDED state"); - chSchWakeupS(tp, RDY_OK); - chSysUnlock(); - return tp; -} - -/** - * @brief Requests a thread termination. - * @note The thread is not terminated but a termination request is added to - * its @p p_flags field. The thread can read this status by - * invoking @p chThdShouldTerminate() and then terminate cleanly. - * - * @param[in] tp pointer to the thread - */ -void chThdTerminate(Thread *tp) { - - chSysLock(); - tp->p_flags |= THD_TERMINATE; - chSysUnlock(); -} - -/** - * @brief Suspends the invoking thread for the specified time. - * - * @param[in] time the delay in system ticks, the special values are - * handled as follow: - * - @a TIME_INFINITE the thread enters an infinite sleep - * state. - * - @a TIME_IMMEDIATE this value is accepted but - * interpreted as a normal time specification not as an - * immediate timeout specification. - * . - */ -void chThdSleep(systime_t time) { - - chDbgCheck(time != TIME_INFINITE, "chThdSleep"); - - chSysLock(); - chThdSleepS(time); - chSysUnlock(); -} - -/** - * @brief Suspends the invoking thread until the system time arrives to the - * specified value. - * - * @param[in] time absolute system time - */ -void chThdSleepUntil(systime_t time) { - - chSysLock(); - if ((time -= chTimeNow()) > 0) - chThdSleepS(time); - chSysUnlock(); -} - -/** - * @brief Yields the time slot. - * @details Yields the CPU control to the next thread in the ready list with - * equal priority, if any. - */ -void chThdYield(void) { - - chSysLock(); - chSchDoYieldS(); - chSysUnlock(); -} - -/** - * @brief Terminates the current thread by specifying an exit status code. - * - * @param[in] msg thread exit code. The code can be retrieved by using - * @p chThdWait(). - */ -void chThdExit(msg_t msg) { - Thread *tp = currp; - - chSysLock(); - tp->p_u.exitcode = msg; - THREAD_EXT_EXIT(tp); -#if CH_USE_WAITEXIT - while (notempty(&tp->p_waiting)) - chSchReadyI(list_remove(&tp->p_waiting)); -#endif -#if CH_USE_REGISTRY - REG_REMOVE(tp); -#endif - chSchGoSleepS(THD_STATE_FINAL); -} - -#if CH_USE_DYNAMIC || defined(__DOXYGEN__) -/** - * @brief Adds a reference to a thread object. - * - * @param[in] tp pointer to the thread - * @return The same thread pointer passed as parameter - * representing the new reference. - */ -Thread *chThdAddRef(Thread *tp) { - - chSysLock(); - chDbgAssert(tp->p_refs < 255, "chThdAddRef(), #1", "too many references"); - tp->p_refs++; - chSysUnlock(); - return tp; -} - -/** - * @brief Releases a reference to a thread object. - * @details If the references counter reaches zero and the thread - * is in the @p THD_STATE_FINAL state then the thread's memory is - * returned to the proper allocator. - * @note Static threads are not affected. - * - * @param[in] tp pointer to the thread - */ -void chThdRelease(Thread *tp) { - trefs_t refs; - - chSysLock(); - chDbgAssert(tp->p_refs > 0, "chThdRelease(), #1", "not referenced"); - refs = --tp->p_refs; - chSysUnlock(); - - /* If the references counter reaches zero then the memory can be returned - to the proper allocator. Of course static threads are not affected.*/ - if (refs == 0) { - switch (tp->p_flags & THD_MEM_MODE_MASK) { -#if CH_USE_HEAP - case THD_MEM_MODE_HEAP: - chHeapFree(tp); - break; -#endif -#if CH_USE_MEMPOOLS - case THD_MEM_MODE_MEMPOOL: - chPoolFree(tp->p_mpool, tp); - break; -#endif - } - } -} -#endif /* CH_USE_DYNAMIC */ - -#if CH_USE_WAITEXIT || defined(__DOXYGEN__) -/** - * @brief Blocks the execution of the invoking thread until the specified - * thread terminates then the exit code is returned. - * @details This function waits for the specified thread to terminate then - * decrements its reference counter, if the counter reaches zero then - * the thread working area is returned to the proper allocator.
- * The memory used by the exited thread is handled in different ways - * depending on the API that spawned the thread: - * - If the thread was spawned by @p chThdCreateStatic() or by - * @p chThdInit() then nothing happens and the thread working area - * is not released or modified in any way. This is the default, - * totally static, behavior. - * - If the thread was spawned by @p chThdCreateFromHeap() then - * the working area is returned to the system heap. - * - If the thread was spawned by @p chThdCreateFromMemoryPool() - * then the working area is returned to the owning memory pool. - * . - * Please read the @ref article_lifecycle article for more details. - * @note After invoking @p chThdWait() the thread pointer becomes invalid - * and must not be used as parameter for further system calls. - * @note The function is available only if the @p CH_USE_WAITEXIT - * option is enabled in @p chconf.h. - * @note If @p CH_USE_DYNAMIC is not specified this function just waits for - * the thread termination, no memory allocators are involved. - * - * @param[in] tp pointer to the thread - * @return The exit code from the terminated thread. - */ -msg_t chThdWait(Thread *tp) { - msg_t msg; - - chDbgCheck(tp != NULL, "chThdWait"); - - chSysLock(); - chDbgAssert(tp != currp, "chThdWait(), #1", "waiting self"); -#if CH_USE_DYNAMIC - chDbgAssert(tp->p_refs > 0, "chThdWait(), #2", "not referenced"); -#endif - if (tp->p_state != THD_STATE_FINAL) { - list_insert(currp, &tp->p_waiting); - chSchGoSleepS(THD_STATE_WTEXIT); - } - msg = tp->p_u.exitcode; - chSysUnlock(); -#if CH_USE_DYNAMIC - chThdRelease(tp); -#endif - return msg; -} -#endif /* CH_USE_WAITEXIT */ - -/** @} */ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chthreads.c + * @brief Threads code. + * + * @addtogroup threads + * @{ + */ + +#include "ch.h" + +/** + * @brief Initializes a thread structure. + * + * @param[in] tp pointer to the thread + * @param[in] prio the priority level for the new thread + * @return The same thread pointer passed as parameter. + */ +Thread *init_thread(Thread *tp, tprio_t prio) { + + tp->p_flags = THD_MEM_MODE_STATIC; + tp->p_prio = prio; + tp->p_state = THD_STATE_SUSPENDED; +#if CH_USE_REGISTRY + REG_INSERT(tp); +#endif +#if CH_USE_DYNAMIC + tp->p_refs = 1; +#endif +#if CH_USE_NESTED_LOCKS + tp->p_locks = 0; +#endif +#if CH_DBG_THREADS_PROFILING + tp->p_time = 0; +#endif +#if CH_USE_MUTEXES + tp->p_realprio = prio; + tp->p_mtxlist = NULL; +#endif +#if CH_USE_WAITEXIT + list_init(&tp->p_waiting); +#endif +#if CH_USE_MESSAGES + queue_init(&tp->p_msgqueue); +#endif +#if CH_USE_EVENTS + tp->p_epending = 0; +#endif + THREAD_EXT_INIT(tp); + return tp; +} + +#if CH_DBG_FILL_THREADS +static void memfill(uint8_t *startp, uint8_t *endp, uint8_t v) { + + while (startp < endp) + *startp++ = v; +} +#endif + +/** + * @brief Initializes a new thread. + * @details The new thread is initialized but not inserted in the ready list, + * the initial state is @p THD_STATE_SUSPENDED. + * @note A thread can terminate by calling @p chThdExit() or by simply + * returning from its main function. + * @note This function can be invoked from within an interrupt handler + * even if it is not an I-Class API because it does not touch + * any critical kernel data structure. + * + * @param[out] wsp pointer to a working area dedicated to the thread stack + * @param[in] size size of the working area + * @param[in] prio the priority level for the new thread + * @param[in] pf the thread function + * @param[in] arg an argument passed to the thread function. It can be + * @p NULL. + * @return The pointer to the @p Thread structure allocated for + * the thread into the working space area. + */ +Thread *chThdInit(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) { + /* Thread structure is layed out in the lower part of the thread workspace */ + Thread *tp = wsp; + + chDbgCheck((wsp != NULL) && (size >= THD_WA_SIZE(0)) && + (prio <= HIGHPRIO) && (pf != NULL), + "chThdInit"); +#if CH_DBG_FILL_THREADS + memfill((uint8_t *)wsp, (uint8_t *)wsp + sizeof(Thread), THREAD_FILL_VALUE); + memfill((uint8_t *)wsp + sizeof(Thread), + (uint8_t *)wsp + size, STACK_FILL_VALUE); +#endif + SETUP_CONTEXT(wsp, size, pf, arg); + return init_thread(tp, prio); +} + +/** + * @brief Creates a new thread into a static memory area. + * @note A thread can terminate by calling @p chThdExit() or by simply + * returning from its main function. + * + * @param[out] wsp pointer to a working area dedicated to the thread stack + * @param[in] size size of the working area + * @param[in] prio the priority level for the new thread + * @param[in] pf the thread function + * @param[in] arg an argument passed to the thread function. It can be + * @p NULL. + * @return The pointer to the @p Thread structure allocated for + * the thread into the working space area. + */ +Thread *chThdCreateStatic(void *wsp, size_t size, + tprio_t prio, tfunc_t pf, void *arg) { + + return chThdResume(chThdInit(wsp, size, prio, pf, arg)); +} + +#if CH_USE_DYNAMIC && CH_USE_HEAP +/** + * @brief Creates a new thread allocating the memory from the heap. + * @note A thread can terminate by calling @p chThdExit() or by simply + * returning from its main function. + * @note The memory allocated for the thread is not released when the thread + * terminates but when a @p chThdWait() is performed. + * @note The function is available only if the @p CH_USE_DYNAMIC, + * @p CH_USE_HEAP and @p CH_USE_WAITEXIT options are enabled + * in @p chconf.h. + * + * @param[in] heapp heap from which allocate the memory or @p NULL for the + * default heap + * @param[in] size size of the working area to be allocated + * @param[in] prio the priority level for the new thread + * @param[in] pf the thread function + * @param[in] arg an argument passed to the thread function. It can be + * @p NULL. + * @return The pointer to the @p Thread structure allocated for + * the thread into the working space area. + * @retval NULL if the memory cannot be allocated. + */ +Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size, + tprio_t prio, tfunc_t pf, void *arg) { + void *wsp; + Thread *tp; + + wsp = chHeapAlloc(heapp, size); + if (wsp == NULL) + return NULL; + tp = chThdInit(wsp, size, prio, pf, arg); + tp->p_flags = THD_MEM_MODE_HEAP; + return chThdResume(tp); +} +#endif /* CH_USE_DYNAMIC && CH_USE_HEAP */ + +#if CH_USE_DYNAMIC && CH_USE_MEMPOOLS +/** + * @brief Creates a new thread allocating the memory from the specified + * Memory Pool. + * @note A thread can terminate by calling @p chThdExit() or by simply + * returning from its main function. + * @note The memory allocated for the thread is not released when the thread + * terminates but when a @p chThdWait() is performed. + * @note The function is available only if the @p CH_USE_DYNAMIC, + * @p CH_USE_MEMPOOLS and @p CH_USE_WAITEXIT options are enabled + * in @p chconf.h. + * + * @param[in] mp pointer to the memory pool object + * @param[in] prio the priority level for the new thread + * @param[in] pf the thread function + * @param[in] arg an argument passed to the thread function. It can be + * @p NULL. + * @return The pointer to the @p Thread structure allocated for + * the thread into the working space area. + * @retval NULL if the memory pool is empty. + */ +Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, + tfunc_t pf, void *arg) { + void *wsp; + Thread *tp; + + chDbgCheck(mp != NULL, "chThdCreateFromMemoryPool"); + + wsp = chPoolAlloc(mp); + if (wsp == NULL) + return NULL; + tp = chThdInit(wsp, mp->mp_object_size, prio, pf, arg); + tp->p_flags = THD_MEM_MODE_MEMPOOL; + tp->p_mpool = mp; + return chThdResume(tp); +} +#endif /* CH_USE_DYNAMIC && CH_USE_MEMPOOLS */ + +/** + * @brief Changes the running thread priority level then reschedules if + * necessary. + * @note The function returns the real thread priority regardless of the + * current priority that could be higher than the real priority + * because the priority inheritance mechanism. + * + * @param[in] newprio the new priority level of the running thread + * @return The old priority level. + */ +tprio_t chThdSetPriority(tprio_t newprio) { + tprio_t oldprio; + + chDbgCheck((newprio >= LOWPRIO) && (newprio <= HIGHPRIO), + "chThdSetPriority"); + + chSysLock(); +#if CH_USE_MUTEXES + oldprio = currp->p_realprio; + if ((currp->p_prio == currp->p_realprio) || (newprio > currp->p_prio)) + currp->p_prio = newprio; + currp->p_realprio = newprio; +#else + oldprio = currp->p_prio; + currp->p_prio = newprio; +#endif + chSchRescheduleS(); + chSysUnlock(); + return oldprio; +} + +/** + * @brief Resumes a suspended thread. + * @note Use this function to resume threads created with @p chThdInit(). + * + * @param[in] tp pointer to the thread + * @return The pointer to the thread. + */ +Thread *chThdResume(Thread *tp) { + + chSysLock(); + chDbgAssert(tp->p_state == THD_STATE_SUSPENDED, + "chThdResume(), #1", + "thread not in THD_STATE_SUSPENDED state"); + chSchWakeupS(tp, RDY_OK); + chSysUnlock(); + return tp; +} + +/** + * @brief Requests a thread termination. + * @note The thread is not terminated but a termination request is added to + * its @p p_flags field. The thread can read this status by + * invoking @p chThdShouldTerminate() and then terminate cleanly. + * + * @param[in] tp pointer to the thread + */ +void chThdTerminate(Thread *tp) { + + chSysLock(); + tp->p_flags |= THD_TERMINATE; + chSysUnlock(); +} + +/** + * @brief Suspends the invoking thread for the specified time. + * + * @param[in] time the delay in system ticks, the special values are + * handled as follow: + * - @a TIME_INFINITE the thread enters an infinite sleep + * state. + * - @a TIME_IMMEDIATE this value is accepted but + * interpreted as a normal time specification not as an + * immediate timeout specification. + * . + */ +void chThdSleep(systime_t time) { + + chDbgCheck(time != TIME_INFINITE, "chThdSleep"); + + chSysLock(); + chThdSleepS(time); + chSysUnlock(); +} + +/** + * @brief Suspends the invoking thread until the system time arrives to the + * specified value. + * + * @param[in] time absolute system time + */ +void chThdSleepUntil(systime_t time) { + + chSysLock(); + if ((time -= chTimeNow()) > 0) + chThdSleepS(time); + chSysUnlock(); +} + +/** + * @brief Yields the time slot. + * @details Yields the CPU control to the next thread in the ready list with + * equal priority, if any. + */ +void chThdYield(void) { + + chSysLock(); + chSchDoYieldS(); + chSysUnlock(); +} + +/** + * @brief Terminates the current thread by specifying an exit status code. + * + * @param[in] msg thread exit code. The code can be retrieved by using + * @p chThdWait(). + */ +void chThdExit(msg_t msg) { + Thread *tp = currp; + + chSysLock(); + tp->p_u.exitcode = msg; + THREAD_EXT_EXIT(tp); +#if CH_USE_WAITEXIT + while (notempty(&tp->p_waiting)) + chSchReadyI(list_remove(&tp->p_waiting)); +#endif +#if CH_USE_REGISTRY + REG_REMOVE(tp); +#endif + chSchGoSleepS(THD_STATE_FINAL); +} + +#if CH_USE_DYNAMIC || defined(__DOXYGEN__) +/** + * @brief Adds a reference to a thread object. + * + * @param[in] tp pointer to the thread + * @return The same thread pointer passed as parameter + * representing the new reference. + */ +Thread *chThdAddRef(Thread *tp) { + + chSysLock(); + chDbgAssert(tp->p_refs < 255, "chThdAddRef(), #1", "too many references"); + tp->p_refs++; + chSysUnlock(); + return tp; +} + +/** + * @brief Releases a reference to a thread object. + * @details If the references counter reaches zero and the thread + * is in the @p THD_STATE_FINAL state then the thread's memory is + * returned to the proper allocator. + * @note Static threads are not affected. + * + * @param[in] tp pointer to the thread + */ +void chThdRelease(Thread *tp) { + trefs_t refs; + + chSysLock(); + chDbgAssert(tp->p_refs > 0, "chThdRelease(), #1", "not referenced"); + refs = --tp->p_refs; + chSysUnlock(); + + /* If the references counter reaches zero then the memory can be returned + to the proper allocator. Of course static threads are not affected.*/ + if (refs == 0) { + switch (tp->p_flags & THD_MEM_MODE_MASK) { +#if CH_USE_HEAP + case THD_MEM_MODE_HEAP: + chHeapFree(tp); + break; +#endif +#if CH_USE_MEMPOOLS + case THD_MEM_MODE_MEMPOOL: + chPoolFree(tp->p_mpool, tp); + break; +#endif + } + } +} +#endif /* CH_USE_DYNAMIC */ + +#if CH_USE_WAITEXIT || defined(__DOXYGEN__) +/** + * @brief Blocks the execution of the invoking thread until the specified + * thread terminates then the exit code is returned. + * @details This function waits for the specified thread to terminate then + * decrements its reference counter, if the counter reaches zero then + * the thread working area is returned to the proper allocator.
+ * The memory used by the exited thread is handled in different ways + * depending on the API that spawned the thread: + * - If the thread was spawned by @p chThdCreateStatic() or by + * @p chThdInit() then nothing happens and the thread working area + * is not released or modified in any way. This is the default, + * totally static, behavior. + * - If the thread was spawned by @p chThdCreateFromHeap() then + * the working area is returned to the system heap. + * - If the thread was spawned by @p chThdCreateFromMemoryPool() + * then the working area is returned to the owning memory pool. + * . + * Please read the @ref article_lifecycle article for more details. + * @note After invoking @p chThdWait() the thread pointer becomes invalid + * and must not be used as parameter for further system calls. + * @note The function is available only if the @p CH_USE_WAITEXIT + * option is enabled in @p chconf.h. + * @note If @p CH_USE_DYNAMIC is not specified this function just waits for + * the thread termination, no memory allocators are involved. + * + * @param[in] tp pointer to the thread + * @return The exit code from the terminated thread. + */ +msg_t chThdWait(Thread *tp) { + msg_t msg; + + chDbgCheck(tp != NULL, "chThdWait"); + + chSysLock(); + chDbgAssert(tp != currp, "chThdWait(), #1", "waiting self"); +#if CH_USE_DYNAMIC + chDbgAssert(tp->p_refs > 0, "chThdWait(), #2", "not referenced"); +#endif + if (tp->p_state != THD_STATE_FINAL) { + list_insert(currp, &tp->p_waiting); + chSchGoSleepS(THD_STATE_WTEXIT); + } + msg = tp->p_u.exitcode; + chSysUnlock(); +#if CH_USE_DYNAMIC + chThdRelease(tp); +#endif + return msg; +} +#endif /* CH_USE_WAITEXIT */ + +/** @} */ diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c index 9558a1cb7..b48e7f4f4 100644 --- a/os/kernel/src/chvt.c +++ b/os/kernel/src/chvt.c @@ -1,5 +1,5 @@ /* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. This file is part of ChibiOS/RT. @@ -28,7 +28,7 @@ #include "ch.h" /** - * @brief Virtual timers delta list header. + * @brief Virtual timers delta list header. */ VTList vtlist; -- cgit v1.2.3 From 947fd0901e98f460d7020990a47e8820595a20d1 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 24 Feb 2010 10:41:11 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1673 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chevents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index e3c0b07ba..bed0def68 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -184,7 +184,7 @@ void chEvtBroadcastI(EventSource *esp) { * @param[in] handlers an array of @p evhandler_t. The array must have size * equal to the number of bits in eventmask_t. */ -void chEvtDispatch(const evhandler_t handlers[], eventmask_t mask) { +void chEvtDispatch(const evhandler_t *handlers, eventmask_t mask) { eventid_t eid; chDbgCheck(handlers != NULL, "chEvtDispatch"); -- cgit v1.2.3 From 59a45f97cae33cf164171a3c9b460dba1f091e4f Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 28 Feb 2010 12:34:11 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1687 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index 7af52d8b6..6327be451 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -172,8 +172,8 @@ msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) { sp->s_cnt++; return RDY_TIMEOUT; } - sem_insert(currp, &sp->s_queue); currp->p_u.wtobjp = sp; + sem_insert(currp, &sp->s_queue); return chSchGoSleepTimeoutS(THD_STATE_WTSEM, time); } return RDY_OK; -- cgit v1.2.3 From 370bbe3477b7f156b5da5b60764e31a0d8c4b4e6 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 28 Feb 2010 12:43:12 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1688 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsem.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index 6327be451..b3f9936b2 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -233,10 +233,11 @@ msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw) { if (sps->s_cnt++ < 0) chSchReadyI(fifo_remove(&sps->s_queue))->p_u.rdymsg = RDY_OK; if (--spw->s_cnt < 0) { - sem_insert(currp, &spw->s_queue); - currp->p_u.wtobjp = spw; + Thread *ctp = currp; + sem_insert(ctp, &spw->s_queue); + ctp->p_u.wtobjp = spw; chSchGoSleepS(THD_STATE_WTSEM); - msg = currp->p_u.rdymsg; + msg = ctp->p_u.rdymsg; } else { chSchRescheduleS(); -- cgit v1.2.3 From 7d9957e5ef13c814dfe08c10502492178a88794f Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 28 Feb 2010 12:47:06 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1689 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index b3f9936b2..9de6571d8 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -118,8 +118,8 @@ msg_t chSemWaitS(Semaphore *sp) { chDbgCheck(sp != NULL, "chSemWaitS"); if (--sp->s_cnt < 0) { - sem_insert(currp, &sp->s_queue); currp->p_u.wtobjp = sp; + sem_insert(currp, &sp->s_queue); chSchGoSleepS(THD_STATE_WTSEM); return currp->p_u.rdymsg; } -- cgit v1.2.3 From ce0845ef81f78144fc4edb5db710bdb1a10d0ba0 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 28 Feb 2010 13:20:38 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1690 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chcond.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c index f0ec50c4f..372b9b2f1 100644 --- a/os/kernel/src/chcond.c +++ b/os/kernel/src/chcond.c @@ -149,8 +149,8 @@ msg_t chCondWaitS(CondVar *cp) { "not owning a mutex"); mp = chMtxUnlockS(); - prio_insert(ctp, &cp->c_queue); ctp->p_u.wtobjp = cp; + prio_insert(ctp, &cp->c_queue); chSchGoSleepS(THD_STATE_WTCOND); msg = ctp->p_u.rdymsg; chMtxLockS(mp); @@ -216,8 +216,8 @@ msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time) { "not owning a mutex"); mp = chMtxUnlockS(); - prio_insert(ctp, &cp->c_queue); ctp->p_u.wtobjp = cp; + prio_insert(ctp, &cp->c_queue); chSchGoSleepTimeoutS(THD_STATE_WTCOND, time); msg = ctp->p_u.rdymsg; chMtxLockS(mp); -- cgit v1.2.3 From 1aad9e4509193ea3726a2d021beb2421adca0a93 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 28 Feb 2010 13:26:02 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1691 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chcond.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c index 372b9b2f1..a78ff4ec5 100644 --- a/os/kernel/src/chcond.c +++ b/os/kernel/src/chcond.c @@ -218,8 +218,8 @@ msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time) { mp = chMtxUnlockS(); ctp->p_u.wtobjp = cp; prio_insert(ctp, &cp->c_queue); - chSchGoSleepTimeoutS(THD_STATE_WTCOND, time); - msg = ctp->p_u.rdymsg; + msg = chSchGoSleepTimeoutS(THD_STATE_WTCOND, time); +// msg = ctp->p_u.rdymsg; chMtxLockS(mp); return msg; } -- cgit v1.2.3 From 15637527154ac52316efcdd81734342fa65718d1 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 28 Feb 2010 13:32:45 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1692 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chcond.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c index a78ff4ec5..33ffe98b1 100644 --- a/os/kernel/src/chcond.c +++ b/os/kernel/src/chcond.c @@ -206,20 +206,18 @@ msg_t chCondWaitTimeout(CondVar *cp, systime_t time) { * timeout. */ msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time) { - Thread *ctp = currp; Mutex *mp; msg_t msg; chDbgCheck(cp != NULL, "chCondWaitTimeoutS"); - chDbgAssert(ctp->p_mtxlist != NULL, + chDbgAssert(currp->p_mtxlist != NULL, "chCondWaitTimeoutS(), #1", "not owning a mutex"); mp = chMtxUnlockS(); - ctp->p_u.wtobjp = cp; - prio_insert(ctp, &cp->c_queue); + currp->p_u.wtobjp = cp; + prio_insert(currp, &cp->c_queue); msg = chSchGoSleepTimeoutS(THD_STATE_WTCOND, time); -// msg = ctp->p_u.rdymsg; chMtxLockS(mp); return msg; } -- cgit v1.2.3 From 917c1b3de8c29b9aab8f745481827db179d3dd7e Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 1 Mar 2010 16:41:24 +0000 Subject: Fixed bug 2961208. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1693 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chevents.c | 1 + 1 file changed, 1 insertion(+) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index bed0def68..898b2c0bb 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -123,6 +123,7 @@ void chEvtSignal(Thread *tp, eventmask_t mask) { chSysLock(); chEvtSignalI(tp, mask); + chSchRescheduleS(); chSysUnlock(); } -- cgit v1.2.3 From b69948bc4883423fde36e63e2ef5d2d16f7ec71c Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 5 Mar 2010 19:01:12 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1713 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmsg.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmsg.c b/os/kernel/src/chmsg.c index 411c5fed3..5030ac809 100644 --- a/os/kernel/src/chmsg.c +++ b/os/kernel/src/chmsg.c @@ -77,7 +77,8 @@ msg_t chMsgWait(void) { chSysLock(); if (!chMsgIsPendingI(currp)) chSchGoSleepS(THD_STATE_WTMSG); - msg = chMsgGetI(currp); +/* msg = chMsgGetI(currp);*/ + msg = chMsgGetI((volatile Thread *)currp); /* Temporary hack.*/ chSysUnlock(); return msg; } -- cgit v1.2.3 From 755c42b99afb7f68428bf43bd31b3ce407cc8f13 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 6 Mar 2010 09:08:30 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1718 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmsg.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmsg.c b/os/kernel/src/chmsg.c index 5030ac809..1e89aa0a3 100644 --- a/os/kernel/src/chmsg.c +++ b/os/kernel/src/chmsg.c @@ -77,8 +77,11 @@ msg_t chMsgWait(void) { chSysLock(); if (!chMsgIsPendingI(currp)) chSchGoSleepS(THD_STATE_WTMSG); -/* msg = chMsgGetI(currp);*/ +#if defined(CH_ARCHITECTURE_STM8) msg = chMsgGetI((volatile Thread *)currp); /* Temporary hack.*/ +#else + msg = chMsgGetI(currp); +#endif chSysUnlock(); return msg; } -- cgit v1.2.3 From 075b89133ec371480bdcf670d3f412b1cf131b0e Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 14 Mar 2010 09:13:21 +0000 Subject: Performance optimization (not complete yet). git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1739 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chdebug.c | 4 ++-- os/kernel/src/chschd.c | 16 ++++++++-------- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index ebe93e8a5..969718082 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -45,10 +45,10 @@ void trace_init(void) { /** * @brief Inserts in the circular debug trace buffer a context switch record. * - * @param[in] otp the thread being switched out * @param[in] ntp the thread to be switched in + * @param[in] otp the thread being switched out */ -void chDbgTrace(Thread *otp, Thread *ntp) { +void chDbgTrace(Thread *ntp, Thread *otp) { trace_buffer.tb_ptr->cse_wtobjp = otp->p_u.wtobjp; trace_buffer.tb_ptr->cse_time = chTimeNow(); diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 8cfd5cd81..441559c36 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -90,8 +90,8 @@ void chSchGoSleepS(tstate_t newstate) { #if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; #endif - chDbgTrace(otp, currp); - chSysSwitchI(otp, currp); + chDbgTrace(currp, otp); + chSysSwitchI(currp, otp); } /* @@ -185,8 +185,8 @@ void chSchWakeupS(Thread *ntp, msg_t msg) { rlist.r_preempt = CH_TIME_QUANTUM; #endif (currp = ntp)->p_state = THD_STATE_CURRENT; - chDbgTrace(otp, ntp); - chSysSwitchI(otp, ntp); + chDbgTrace(ntp, otp); + chSysSwitchI(ntp, otp); } } @@ -204,8 +204,8 @@ void chSchDoRescheduleI(void) { #if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; #endif - chDbgTrace(otp, currp); - chSysSwitchI(otp, currp); + chDbgTrace(currp, otp); + chSysSwitchI(currp, otp); } /** @@ -272,8 +272,8 @@ void chSchDoYieldS(void) { #if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; #endif - chDbgTrace(otp, currp); - chSysSwitchI(otp, currp); + chDbgTrace(currp, otp); + chSysSwitchI(currp, otp); } } -- cgit v1.2.3 From 8cf7b70436de8a93b2a0b3ddaeffbc7bfe4a5666 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 15 Mar 2010 16:04:47 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1743 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 441559c36..412467b65 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -196,16 +196,17 @@ void chSchWakeupS(Thread *ntp, msg_t msg) { * to @p TRUE. */ void chSchDoRescheduleI(void) { + Thread *otp, *ntp; - Thread *otp = currp; - /* Pick the first thread from the ready queue and makes it current.*/ - (currp = fifo_remove(&rlist.r_queue))->p_state = THD_STATE_CURRENT; - chSchReadyI(otp); #if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; #endif - chDbgTrace(currp, otp); - chSysSwitchI(currp, otp); + otp = currp; + /* Pick the first thread from the ready queue and makes it current.*/ + (currp = ntp = fifo_remove(&rlist.r_queue))->p_state = THD_STATE_CURRENT; + chSchReadyI(otp); + chDbgTrace(ntp, otp); + chSysSwitchI(ntp, otp); } /** -- cgit v1.2.3 From 0eed163a696d4b6daab19fd8daf05b980058f5f3 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 16 Mar 2010 15:43:23 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1745 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 56 +++++++++++++++++++---------------------------- os/kernel/src/chthreads.c | 7 +++++- 2 files changed, 28 insertions(+), 35 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 412467b65..023c35d41 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -21,7 +21,13 @@ * @file chschd.c * @brief Scheduler code. * - * @addtogroup scheduler + * @defgroup scheduler Scheduler + * @ingroup base + * @details This module provides the default portable scheduler code, + * scheduler functions can be individually captured by the port + * layer in order to provide architecture optimized equivalents. + * When a function is captured its default code is not built into + * the OS image, the optimized version is included instead. * @{ */ @@ -30,7 +36,9 @@ /** * @brief Ready list header. */ +#if !defined(PORT_OPTIMIZED_RLIST_VAR) || defined(__DOXYGEN__) ReadyList rlist; +#endif /* !defined(PORT_OPTIMIZED_RLIST_VAR) */ /** * @brief Scheduler initialization. @@ -56,6 +64,7 @@ void scheduler_init(void) { * @param[in] tp the Thread to be made ready * @return The Thread pointer. */ +#if !defined(PORT_OPTIMIZED_READYI) || defined(__DOXYGEN__) #if CH_OPTIMIZE_SPEED /* NOTE: it is inlined in this module only.*/ INLINE Thread *chSchReadyI(Thread *tp) { @@ -74,6 +83,7 @@ Thread *chSchReadyI(Thread *tp) { tp->p_prev->p_next = cp->p_prev = tp; return tp; } +#endif /* !defined(PORT_OPTIMIZED_READYI) */ /** * @brief Puts the current thread to sleep into the specified state. @@ -82,6 +92,7 @@ Thread *chSchReadyI(Thread *tp) { * * @param[in] newstate the new thread state */ +#if !defined(PORT_OPTIMIZED_GOSLEEPS) || defined(__DOXYGEN__) void chSchGoSleepS(tstate_t newstate) { Thread *otp; @@ -93,6 +104,7 @@ void chSchGoSleepS(tstate_t newstate) { chDbgTrace(currp, otp); chSysSwitchI(currp, otp); } +#endif /* !defined(PORT_OPTIMIZED_GOSLEEPS) */ /* * Timeout wakeup callback. @@ -169,6 +181,7 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { * @param[in] ntp the Thread to be made ready * @param[in] msg message to the awakened thread */ +#if !defined(PORT_OPTIMIZED_WAKEUPS) || defined(__DOXYGEN__) void chSchWakeupS(Thread *ntp, msg_t msg) { ntp->p_u.rdymsg = msg; @@ -189,12 +202,14 @@ void chSchWakeupS(Thread *ntp, msg_t msg) { chSysSwitchI(ntp, otp); } } +#endif /* !defined(PORT_OPTIMIZED_WAKEUPS) */ /** * @brief Switches to the first thread on the runnable queue. * @note It is intended to be called if @p chSchRescRequiredI() evaluates * to @p TRUE. */ +#if !defined(PORT_OPTIMIZED_DORESCHEDULEI) || defined(__DOXYGEN__) void chSchDoRescheduleI(void) { Thread *otp, *ntp; @@ -202,23 +217,26 @@ void chSchDoRescheduleI(void) { rlist.r_preempt = CH_TIME_QUANTUM; #endif otp = currp; - /* Pick the first thread from the ready queue and makes it current.*/ + /* Picks the first thread from the ready queue and makes it current.*/ (currp = ntp = fifo_remove(&rlist.r_queue))->p_state = THD_STATE_CURRENT; chSchReadyI(otp); chDbgTrace(ntp, otp); chSysSwitchI(ntp, otp); } +#endif /* !defined(PORT_OPTIMIZED_DORESCHEDULEI) */ /** * @brief Performs a reschedulation if a higher priority thread is runnable. * @details If a thread with a higher priority than the current thread is in * the ready list then make the higher priority thread running. */ +#if !defined(PORT_OPTIMIZED_RESCHEDULES) || defined(__DOXYGEN__) void chSchRescheduleS(void) { if (chSchIsRescRequiredI()) chSchDoRescheduleI(); } +#endif /* !defined(PORT_OPTIMIZED_RESCHEDULES) */ /** * @brief Evaluates if a reschedulation is required. @@ -230,6 +248,7 @@ void chSchRescheduleS(void) { * @retval TRUE if there is a thread that should go in running state. * @retval FALSE if a reschedulation is not required. */ +#if !defined(PORT_OPTIMIZED_ISRESCHREQUIREDEXI) || defined(__DOXYGEN__) bool_t chSchIsRescRequiredExI(void) { tprio_t p1 = firstprio(&rlist.r_queue); tprio_t p2 = currp->p_prio; @@ -245,37 +264,6 @@ bool_t chSchIsRescRequiredExI(void) { return p1 > p2; #endif } - -/** - * @brief Yields the time slot. - * @details Yields the CPU control to the next thread in the ready list with - * equal priority, if any. - */ -void chSchDoYieldS(void) { - - if (chSchCanYieldS()) { - Thread *cp = (Thread *)&rlist.r_queue; - Thread *otp = currp; - - /* Note, the following insertion code works because we know that on the - ready list there is at least one thread with priority equal or higher - than the current one.*/ - otp->p_state = THD_STATE_READY; - do { - cp = cp->p_prev; - } while (cp->p_prio < otp->p_prio); - /* Insertion on p_next.*/ - otp->p_next = (otp->p_prev = cp)->p_next; - otp->p_next->p_prev = cp->p_next = otp; - - /* Pick the first thread from the ready queue and makes it current.*/ - (currp = fifo_remove(&rlist.r_queue))->p_state = THD_STATE_CURRENT; -#if CH_TIME_QUANTUM > 0 - rlist.r_preempt = CH_TIME_QUANTUM; -#endif - chDbgTrace(currp, otp); - chSysSwitchI(currp, otp); - } -} +#endif /* !defined(PORT_OPTIMIZED_ISRESCHREQUIREDEXI) */ /** @} */ diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 79ea23f94..a2745b94c 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -21,7 +21,12 @@ * @file chthreads.c * @brief Threads code. * - * @addtogroup threads + * @defgroup threads Threads + * @ingroup base + * @details This module contains all the threads related APIs, creation, + * termination, synchronization, delay etc. Dynamic variants of + * the base static API are also included. + * * @{ */ -- cgit v1.2.3 From ad3d21e81592481539a56e93234f5bf1fa2c0504 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 16 Mar 2010 19:36:21 +0000 Subject: Documentation reorganization. Moved the description from kernel.dox into the source code for ease of editing and reference. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1746 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chcond.c | 52 +++++++++++++++++++++++++++++++--------------- os/kernel/src/chdebug.c | 5 +++++ os/kernel/src/chevents.c | 27 ++++++++++++++++++++++++ os/kernel/src/chheap.c | 12 +++++++++++ os/kernel/src/chlists.c | 6 +++--- os/kernel/src/chmboxes.c | 24 +++++++++++++++++++++ os/kernel/src/chmemcore.c | 16 ++++++++++++++ os/kernel/src/chmempools.c | 7 +++++++ os/kernel/src/chmsg.c | 16 ++++++++++++++ os/kernel/src/chmtx.c | 37 +++++++++++++++++++++++++++++++++ os/kernel/src/chqueues.c | 17 +++++++++++++++ os/kernel/src/chregistry.c | 3 +++ os/kernel/src/chschd.c | 3 +-- os/kernel/src/chsem.c | 22 ++++++++++++++++++++ os/kernel/src/chsys.c | 7 +++++++ os/kernel/src/chthreads.c | 15 +++++++------ os/kernel/src/chvt.c | 1 + 17 files changed, 242 insertions(+), 28 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c index 33ffe98b1..c450b0c32 100644 --- a/os/kernel/src/chcond.c +++ b/os/kernel/src/chcond.c @@ -26,6 +26,15 @@ * @brief Condition Variables code. * * @addtogroup condvars Condition Variables + * @details This module implements the Condition Variables mechanism. Condition + * variables are an extensions to the Mutex subsystem and cannot + * work alone. + *

Operation mode

+ * The condition variable is a synchronization object meant to be + * used inside a zone protected by a @p Mutex. Mutexes and CondVars + * together can implement a Monitor construct.
+ * In order to use the Condition Variables APIs the @p CH_USE_CONDVARS + * option must be enabled in @p chconf.h. * @{ */ @@ -107,10 +116,11 @@ void chCondBroadcastI(CondVar *cp) { /** * @brief Waits on the condition variable releasing the mutex lock. - * @details Releases the mutex, waits on the condition variable, and finally - * acquires the mutex again. This is done atomically. - * @note The thread MUST already have locked the mutex when calling - * @p chCondWait(). + * @details Releases the currently owned mutex, waits on the condition + * variable, and finally acquires the mutex again. All the sequence + * is performed atomically. + * @note The invoking thread must have at least one owned mutex on + * entry. * * @param[in] cp pointer to the @p CondVar structure * @return The wakep mode. @@ -128,10 +138,11 @@ msg_t chCondWait(CondVar *cp) { /** * @brief Waits on the condition variable releasing the mutex lock. - * @details Releases the mutex, waits on the condition variable, and finally - * acquires the mutex again. This is done atomically. - * @note The thread MUST already have locked the mutex when calling - * @p chCondWaitS(). + * @details Releases the currently owned mutex, waits on the condition + * variable, and finally acquires the mutex again. All the sequence + * is performed atomically. + * @note The invoking thread must have at least one owned mutex on + * entry. * * @param[in] cp pointer to the @p CondVar structure * @return The wakep mode. @@ -160,10 +171,13 @@ msg_t chCondWaitS(CondVar *cp) { #if CH_USE_CONDVARS_TIMEOUT /** * @brief Waits on the condition variable releasing the mutex lock. - * @details Releases the mutex, waits on the condition variable, and finally - * acquires the mutex again. This is done atomically. - * @note The thread MUST already have locked the mutex when calling - * @p chCondWaitTimeout(). + * @details Releases the currently owned mutex, waits on the condition + * variable, and finally acquires the mutex again. All the sequence + * is performed atomically. + * @note The invoking thread must have at least one owned mutex on + * entry. + * @note Exiting the function because a timeout does not re-acquire the + * mutex, the mutex ownership is lost. * * @param[in] cp pointer to the @p CondVar structure * @param[in] time the number of ticks before the operation timeouts, @@ -188,10 +202,13 @@ msg_t chCondWaitTimeout(CondVar *cp, systime_t time) { /** * @brief Waits on the condition variable releasing the mutex lock. - * @details Releases the mutex, waits on the condition variable, and finally - * acquires the mutex again. This is done atomically. - * @note The thread MUST already have locked the mutex when calling - * @p chCondWaitTimeoutS(). + * @details Releases the currently owned mutex, waits on the condition + * variable, and finally acquires the mutex again. All the sequence + * is performed atomically. + * @note The invoking thread must have at least one owned mutex on + * entry. + * @note Exiting the function because a timeout does not re-acquire the + * mutex, the mutex ownership is lost. * * @param[in] cp pointer to the @p CondVar structure * @param[in] time the number of ticks before the operation timeouts, @@ -218,7 +235,8 @@ msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time) { currp->p_u.wtobjp = cp; prio_insert(currp, &cp->c_queue); msg = chSchGoSleepTimeoutS(THD_STATE_WTCOND, time); - chMtxLockS(mp); + if (msg != RDY_TIMEOUT) + chMtxLockS(mp); return msg; } #endif /* CH_USE_CONDVARS_TIMEOUT */ diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index 969718082..462f2559e 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -22,6 +22,11 @@ * @brief ChibiOS/RT Debug code. * * @addtogroup debug + * @details Debug APIs and services: + * - Trace buffer. + * - Parameters check. + * - Kernel assertions. + * . * @{ */ diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index 898b2c0bb..6a0ed1755 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -22,6 +22,33 @@ * @brief Events code. * * @addtogroup events + * @details Event Flags, Event Sources and Event Listeners. + *

Operation mode

+ * Each thread has a mask of pending event flags inside its @p Thread + * structure. + * Several operations are defined: + * - Wait, the invoking thread goes to sleep until a certain + * AND/OR combination of event flags becomes pending. + * - Clear, a mask of event flags is cleared from the pending + * events mask, the cleared event flags mask is returned (only the + * flags that were actually pending and then cleared). + * - Signal, an event mask is directly ORed to the mask of the + * signaled thread. + * - Broadcast, each thread registered on an Event Source is + * signaled with the event flags specified in its Event Listener. + * - Dispatch, an events mask is scanned and for each bit set + * to one an associated handler function is invoked. Bit masks are + * scanned from bit zero upward. + * . + * An Event Source is a special object that can be "broadcasted" by + * a thread or an interrupt service routine. Broadcasting an Event + * Source has the effect that all the threads registered on the + * Event Source will be signaled with an events mask.
+ * An unlimited number of Event Sources can exists in a system and + * each thread can be listening on an unlimited number of + * them.

+ * In order to use the Events APIs the @p CH_USE_EVENTS option must be + * enabled in @p chconf.h. * @{ */ #include "ch.h" diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c index ce8ce385b..ede326b59 100644 --- a/os/kernel/src/chheap.c +++ b/os/kernel/src/chheap.c @@ -22,6 +22,18 @@ * @brief Heaps code. * * @addtogroup heaps + * @details Heap Allocator related APIs. + *

Operation mode

+ * The heap allocator implements a first-fit strategy and its APIs + * are functionally equivalent to the usual @p malloc() and @p free() + * library functions. The main difference is that the OS heap APIs + * are guaranteed to be thread safe.
+ * By enabling the @p CH_USE_MALLOC_HEAP option the heap manager + * will use the runtime-provided @p malloc() and @p free() as + * backend for the heap APIs instead of the system provided + * allocator.
+ * In order to use the heap APIs the @p CH_USE_HEAP option must + * be enabled in @p chconf.h. * @{ */ diff --git a/os/kernel/src/chlists.c b/os/kernel/src/chlists.c index f722f94cb..2d973e771 100644 --- a/os/kernel/src/chlists.c +++ b/os/kernel/src/chlists.c @@ -20,11 +20,11 @@ /** * @file chlists.c * @brief Thread queues/lists code. - * @note All the functions present in this module, while public, are not - * an OS API and should not be directly used in the user applications - * code. * * @addtogroup internals + * @details All the functions present in this module, while public, are not + * an OS API and should not be directly used in the user applications + * code. * @{ */ #include "ch.h" diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c index 3811fc5da..ce4ecae67 100644 --- a/os/kernel/src/chmboxes.c +++ b/os/kernel/src/chmboxes.c @@ -22,6 +22,30 @@ * @brief Mailboxes code. * * @addtogroup mailboxes + * @details Asynchronous messages. + *

Operation mode

+ * A mailbox is an asynchronous communication mechanism.
+ * The following operations are possible on a mailbox: + * - Post: Posts a message on the mailbox in FIFO order. + * - Post Ahead: Posts a message on the mailbox with urgent + * priority. + * - Fetch: A message is fetched from the mailbox and removed + * from the queue. + * - Reset: The mailbox is emptied and all the stored messages + * are lost. + * . + * A message is a variable of type msg_t that is guaranteed to have + * the same size of and be compatible with (data) pointers (anyway an + * explicit cast is needed). + * If larger messages need to be exchanged then a pointer to a + * structure can be posted in the mailbox but the posting side has + * no predefined way to know when the message has been processed. A + * possible approach is to allocate memory (from a memory pool as + * example) from the posting side and free it on the fetching side. + * Another approach is to set a "done" flag into the structure pointed + * by the message.
+ * In order to use the mailboxes APIs the @p CH_USE_MAILBOXES option + * must be enabled in @p chconf.h. * @{ */ diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index 435120a33..d0c657a48 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -22,6 +22,22 @@ * @brief Core memory manager code. * * @addtogroup memcore + * @details Core Memory Manager related APIs and services. + *

Operation mode

+ * The core memory manager is a simplified allocator that only allows + * to allocate memory blocks without the possibility to free them.
+ * This allocator is meant as a memory blocks provider for the other + * allocators such as: + * - C-Runtime allocator (through a compiler specific adapter module). + * - Heap allocator (see @ref heaps). + * - Memory pools allocator (see @ref pools). + * . + * By having a centralized memory provider the various allocators can + * coexist and share the main memory.
+ * This allocator, alone, is also useful for very simple applications + * that just require a simple way to get memory blocks.
+ * In order to use the core memory manager APIs the @p CH_USE_MEMCORE + * option must be enabled in @p chconf.h. * @{ */ diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c index f79e20353..31e4682fb 100644 --- a/os/kernel/src/chmempools.c +++ b/os/kernel/src/chmempools.c @@ -22,6 +22,13 @@ * @brief Memory Pools code. * * @addtogroup pools + * @details Memory Pools related APIs and services. + *

Operation mode

+ * The Memory Pools APIs allow to allocate/free fixed size objects in + * constant time and reliably without memory fragmentation + * problems.
+ * In order to use the memory pools APIs the @p CH_USE_MEMPOOLS option + * must be enabled in @p chconf.h. * @{ */ diff --git a/os/kernel/src/chmsg.c b/os/kernel/src/chmsg.c index 1e89aa0a3..96bf61452 100644 --- a/os/kernel/src/chmsg.c +++ b/os/kernel/src/chmsg.c @@ -22,6 +22,22 @@ * @brief Messages code. * * @addtogroup messages + * @details Synchronous inter-thread messages APIs and services. + *

Operation Mode

+ * Synchronous messages are an easy to use and fast IPC mechanism, + * threads can both act as message servers and/or message clients, + * the mechanism allows data to be carried in both directions. Note + * that messages are not copied between the client and server threads + * but just a pointer passed so the exchange is very time + * efficient.
+ * Messages are usually processed in FIFO order but it is possible to + * process them in priority order by enabling the + * @p CH_USE_MESSAGES_PRIORITY option in @p chconf.h.
+ * Applications do not need to allocate buffers for synchronous + * message queues, the mechanism just requires two extra pointers in + * the @p Thread structure (the message queue header).
+ * In order to use the Messages APIs the @p CH_USE_MESSAGES option + * must be enabled in @p chconf.h. * @{ */ diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 336df8a6e..cc179eb20 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -22,6 +22,43 @@ * @brief Mutexes code. * * @addtogroup mutexes + * @details Mutexes related APIs and services. + * + *

Operation mode

+ * A mutex is a threads synchronization object that can be in two + * distinct states: + * - Not owned. + * - Owned by a thread. + * . + * Some operations are defined on mutexes: + * - Lock: The mutex is checked, if the mutex is not owned by + * some other thread then it is associated to the locking thread + * else the thread is queued on the mutex in a list ordered by + * priority. + * - Unlock: The mutex is released by the owner and the highest + * priority thread waiting in the queue, if any, is resumed and made + * owner of the mutex. + * . + * In order to use the Mutexes APIs the @p CH_USE_MUTEXES option must + * be enabled in @p chconf.h. + *

Constraints

+ * In ChibiOS/RT the Unlock operations are always performed in + * lock-reverse order. The unlock API does not even have a parameter, + * the mutex to unlock is selected from an internal, per-thread, stack + * of owned mutexes. This both improves the performance and is + * required for an efficient implementation of the priority + * inheritance mechanism. + * + *

The priority inversion problem

+ * The mutexes in ChibiOS/RT implements the full priority + * inheritance mechanism in order handle the priority inversion + * problem.
+ * When a thread is queued on a mutex, any thread, directly or + * indirectly, holding the mutex gains the same priority of the + * waiting thread (if their priority was not already equal or higher). + * The mechanism works with any number of nested mutexes and any + * number of involved threads. The algorithm complexity (worst case) + * is N with N equal to the number of nested mutexes. * @{ */ diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index 2f8d1b569..acc7494c2 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -22,6 +22,23 @@ * @brief I/O Queues code. * * @addtogroup io_queues + * @details ChibiOS/RT queues are mostly used in serial-like device drivers. + * The device drivers are usually designed to have a lower side + * (lower driver, it is usually an interrupt service routine) and an + * upper side (upper driver, accessed by the application threads).
+ * There are several kind of queues:
+ * - Input queue, unidirectional queue where the writer is the + * lower side and the reader is the upper side. + * - Output queue, unidirectional queue where the writer is the + * upper side and the reader is the lower side. + * - Full duplex queue, bidirectional queue. Full duplex queues + * are implemented by pairing an input queue and an output queue + * together. + * . + * In order to use the I/O queues the @p CH_USE_QUEUES option must + * be enabled in @p chconf.h.
+ * I/O queues are usually used as an implementation layer for the I/O + * channels interface, also see @ref io_channels. * @{ */ diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c index 8d4ffa4e8..4dca52534 100644 --- a/os/kernel/src/chregistry.c +++ b/os/kernel/src/chregistry.c @@ -22,6 +22,9 @@ * @brief Threads registry code. * * @addtogroup registry + * @details Threads Registry related APIs and services.
+ * In order to use the threads registry the @p CH_USE_REGISTRY option + * must be enabled in @p chconf.h. * @{ */ #include "ch.h" diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 023c35d41..9bf34d43a 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -21,8 +21,7 @@ * @file chschd.c * @brief Scheduler code. * - * @defgroup scheduler Scheduler - * @ingroup base + * @addtogroup scheduler * @details This module provides the default portable scheduler code, * scheduler functions can be individually captured by the port * layer in order to provide architecture optimized equivalents. diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index 9de6571d8..439412d7c 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -22,6 +22,28 @@ * @brief Semaphores code. * * @addtogroup semaphores + * @details Semaphores and threads synchronization. + * + *

Operation mode

+ * A semaphore is a threads synchronization object, some operations + * are defined on semaphores: + * - Signal: The semaphore counter is increased and if the + * result is non-positive then a waiting thread is removed from + * the semaphore queue and made ready for execution. + * - Wait: The semaphore counter is decreased and if the result + * becomes negative the thread is queued in the semaphore and + * suspended. + * - Reset: The semaphore counter is reset to a non-negative + * value and all the threads in the queue are released. + * . + * Semaphores can be used as guards for mutual exclusion code zones + * (note that mutexes are recommended for this kind of use) but also + * have other uses, queues guards and counters as example.
+ * Semaphores usually use a FIFO queuing strategy but it is possible + * to make them order threads by priority by enabling + * @p CH_USE_SEMAPHORES_PRIORITY in @p chconf.h.
+ * In order to use the Semaphores APIs the @p CH_USE_SEMAPHORES + * option must be enabled in @p chconf.h. * @{ */ diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 2003f690b..eeed4a998 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -22,6 +22,13 @@ * @brief System related code. * * @addtogroup system + * @details System related APIs and services: + * - Initialization. + * - Locks. + * - Interrupt Handling. + * - Power Management. + * - Abnormal Termination. + * . * @{ */ diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index a2745b94c..3ba5702f5 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -21,12 +21,15 @@ * @file chthreads.c * @brief Threads code. * - * @defgroup threads Threads - * @ingroup base - * @details This module contains all the threads related APIs, creation, - * termination, synchronization, delay etc. Dynamic variants of - * the base static API are also included. - * + * @addtogroup threads + * @details This module contains all the threads related APIs and services: + * - Creation. + * - Termination. + * - Synchronization. + * - Delays. + * - References. + * . + * Dynamic variants of the base static API are also included. * @{ */ diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c index b48e7f4f4..8be1926ca 100644 --- a/os/kernel/src/chvt.c +++ b/os/kernel/src/chvt.c @@ -22,6 +22,7 @@ * @brief Time and Virtual Timers related code. * * @addtogroup time + * @details Time and Virtual Timers related APIs and services. * @{ */ -- cgit v1.2.3 From 392c2fe70d224c4f564ebab5dcd3f0d607a546f0 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 17 Mar 2010 13:04:42 +0000 Subject: Fixed bug 2971878 . git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1747 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chregistry.c | 35 ++++++++++++++++++++++------------- 1 file changed, 22 insertions(+), 13 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c index 4dca52534..5ed8ace2e 100644 --- a/os/kernel/src/chregistry.c +++ b/os/kernel/src/chregistry.c @@ -23,6 +23,16 @@ * * @addtogroup registry * @details Threads Registry related APIs and services.
+ * The threads Threads Registry is a double linked list that holds + * all the active threads in the system.
+ * The registry is meant to be mainly a debug feature, as example + * through the registry a debugger can enumerate the active threads + * in any given moment or the shell can print the active threads and + * their state.
+ * Another possible use is for centralized threads memory management, + * terminating threads can pulse an event source and an event handler + * can perform a scansion of the registry in order to recover the + * memory.
* In order to use the threads registry the @p CH_USE_REGISTRY option * must be enabled in @p chconf.h. * @{ @@ -64,25 +74,24 @@ Thread *chRegFirstThread(void) { * @retval NULL if there is no next thread. */ Thread *chRegNextThread(Thread *tp) { + Thread *ntp; chSysLock(); + ntp = tp->p_newer; + if (ntp == (Thread *)&rlist) + ntp = NULL; #if CH_USE_DYNAMIC - chDbgAssert(tp->p_refs > 0, "chRegNextThread(), #1", - "not referenced"); - tp->p_refs--; -#endif - if (tp->p_newer != (Thread *)&rlist) { - tp = tp->p_newer; -#if CH_USE_DYNAMIC - chDbgAssert(tp->p_refs < 255, "chRegNextThread(), #2", + else { + chDbgAssert(ntp->p_refs < 255, "chRegNextThread(), #1", "too many references"); - tp->p_refs++; -#endif + ntp->p_refs++; } - else - tp = NULL; +#endif chSysUnlock(); - return tp; +#if CH_USE_DYNAMIC + chThdRelease(tp); +#endif + return ntp; } #endif /* CH_USE_REGISTRY */ -- cgit v1.2.3 From 7ae3e3227ee895c3ed5ac3358411b07276c7838e Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 17 Mar 2010 16:24:43 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1748 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chevents.c | 2 +- os/kernel/src/chmboxes.c | 2 +- os/kernel/src/chmtx.c | 2 +- os/kernel/src/chregistry.c | 22 +++++++++++++++------- os/kernel/src/chsem.c | 21 +++++++++++++++------ os/kernel/src/chthreads.c | 36 +++++++++++++++++++++++++++++------- 6 files changed, 62 insertions(+), 23 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index 6a0ed1755..2bc145cac 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -26,7 +26,7 @@ *

Operation mode

* Each thread has a mask of pending event flags inside its @p Thread * structure. - * Several operations are defined: + * Operations defined for event flags: * - Wait, the invoking thread goes to sleep until a certain * AND/OR combination of event flags becomes pending. * - Clear, a mask of event flags is cleared from the pending diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c index ce4ecae67..717246b88 100644 --- a/os/kernel/src/chmboxes.c +++ b/os/kernel/src/chmboxes.c @@ -25,7 +25,7 @@ * @details Asynchronous messages. *

Operation mode

* A mailbox is an asynchronous communication mechanism.
- * The following operations are possible on a mailbox: + * Operations defined for mailboxes: * - Post: Posts a message on the mailbox in FIFO order. * - Post Ahead: Posts a message on the mailbox with urgent * priority. diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index cc179eb20..c3076163a 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -30,7 +30,7 @@ * - Not owned. * - Owned by a thread. * . - * Some operations are defined on mutexes: + * Operations defined for mutexes: * - Lock: The mutex is checked, if the mutex is not owned by * some other thread then it is associated to the locking thread * else the thread is queued on the mutex in a list ordered by diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c index 5ed8ace2e..ad5cd7fc1 100644 --- a/os/kernel/src/chregistry.c +++ b/os/kernel/src/chregistry.c @@ -22,13 +22,21 @@ * @brief Threads registry code. * * @addtogroup registry - * @details Threads Registry related APIs and services.
- * The threads Threads Registry is a double linked list that holds - * all the active threads in the system.
- * The registry is meant to be mainly a debug feature, as example - * through the registry a debugger can enumerate the active threads - * in any given moment or the shell can print the active threads and - * their state.
+ * @details Threads Registry related APIs and services. + * + *

Operation mode

+ * The Threads Registry is a double linked list that holds all the + * active threads in the system.
+ * Operations defined for the registry: + * - First, returns the first, in creation order, active thread + * in the system. + * - Next, returns the next, in creation order, active thread + * in the system. + * . + * The registry is meant to be mainly a debug feature, as example, + * using the registry a debugger can enumerate the active threads + * in any given moment or the shell can print the active threads + * and their state.
* Another possible use is for centralized threads memory management, * terminating threads can pulse an event source and an event handler * can perform a scansion of the registry in order to recover the diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index 439412d7c..2a86a14f6 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -22,11 +22,20 @@ * @brief Semaphores code. * * @addtogroup semaphores - * @details Semaphores and threads synchronization. + * @details Semaphores related APIs and services. * *

Operation mode

- * A semaphore is a threads synchronization object, some operations - * are defined on semaphores: + * Semaphores are a flexible synchronization primitive, ChibiOS/RT + * implements semaphores in their "counting semaphores" variant as + * defined by Edsger Dijkstra plus several enhancements like: + * - Wait operation with timeout. + * - Reset operation. + * - Atomic wait+signal operation. + * - Return message from the wait operation (OK, RESET, TIMEOUT). + * . + * The binary semaphores variant can be easily implemented using + * counting semaphores.
+ * Operations defined for semaphores: * - Signal: The semaphore counter is increased and if the * result is non-positive then a waiting thread is removed from * the semaphore queue and made ready for execution. @@ -36,9 +45,9 @@ * - Reset: The semaphore counter is reset to a non-negative * value and all the threads in the queue are released. * . - * Semaphores can be used as guards for mutual exclusion code zones - * (note that mutexes are recommended for this kind of use) but also - * have other uses, queues guards and counters as example.
+ * Semaphores can be used as guards for mutual exclusion zones + * (note that mutexes are recommended for this kind of use) but + * also have other uses, queues guards and counters as example.
* Semaphores usually use a FIFO queuing strategy but it is possible * to make them order threads by priority by enabling * @p CH_USE_SEMAPHORES_PRIORITY in @p chconf.h.
diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 3ba5702f5..3f2f88899 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -22,14 +22,36 @@ * @brief Threads code. * * @addtogroup threads - * @details This module contains all the threads related APIs and services: - * - Creation. - * - Termination. - * - Synchronization. - * - Delays. - * - References. + * @details Threads related APIs and services. + * + *

Operation mode

+ * A thread is an abstraction of an independent instructions flow. + * In ChibiOS/RT a thread is represented by a "C" function owning + * a processor context, state informations and a dedicated stack + * area. In this scenario static variables are shared among all + * threads while automatic variables are local to the thread.
+ * Operations defined for threads: + * - Init, a thread is prepared and put in the suspended + * state. + * - Create, a thread is started on the specified thread + * function. This operation is available in multiple variants, + * both static and dynamic. + * - Exit, a thread terminates by returning from its top + * level function or invoking a specific API, the thread can + * return a value that can be retrieved by other threads. + * - Wait, a thread waits for the termination of another + * thread and retrieves its return value. + * - Resume, a thread created in suspended state is started. + * - Sleep, the execution of a thread is suspended for the + * specified amount of time or the specified future absolute time + * is reached. + * - SetPriority, a thread changes its own priority level. + * - Yield, a thread voluntarily renounces to its time slot. * . - * Dynamic variants of the base static API are also included. + * The threads subsystem is implicitly included in kernel however + * some of its part may be excluded by disabling them in @p chconf.h, + * see the @p CH_USE_WAITEXIT and @p CH_USE_DYNAMIC configuration + * options. * @{ */ -- cgit v1.2.3 From cf1b70f486a2696d523d585e91d0e4e5c7b8021c Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 18 Mar 2010 16:01:11 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1749 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 9bf34d43a..ac69c6661 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -105,23 +105,21 @@ void chSchGoSleepS(tstate_t newstate) { } #endif /* !defined(PORT_OPTIMIZED_GOSLEEPS) */ +#if !defined(PORT_OPTIMIZED_GOSLEEPTIMEOUTS) || defined(__DOXYGEN__) /* * Timeout wakeup callback. */ static void wakeup(void *p) { Thread *tp = (Thread *)p; -#if CH_USE_SEMAPHORES || CH_USE_MUTEXES || CH_USE_CONDVARS +#if CH_USE_SEMAPHORES || (CH_USE_CONDVARS && CH_USE_CONDVARS_TIMEOUT) switch (tp->p_state) { #if CH_USE_SEMAPHORES case THD_STATE_WTSEM: chSemFastSignalI((Semaphore *)tp->p_u.wtobjp); /* Falls into, intentional. */ #endif -#if CH_USE_MUTEXES - case THD_STATE_WTMTX: -#endif -#if CH_USE_CONDVARS +#if CH_USE_CONDVARS && CH_USE_CONDVARS_TIMEOUT case THD_STATE_WTCOND: #endif /* States requiring dequeuing.*/ @@ -166,6 +164,7 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { chSchGoSleepS(newstate); return currp->p_u.rdymsg; } +#endif /* !defined(PORT_OPTIMIZED_GOSLEEPTIMEOUTS) */ /** * @brief Wakes up a thread. @@ -191,8 +190,7 @@ void chSchWakeupS(Thread *ntp, msg_t msg) { if (ntp->p_prio <= currp->p_prio) chSchReadyI(ntp); else { - Thread *otp = currp; - chSchReadyI(otp); + Thread *otp = chSchReadyI(currp); #if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; #endif @@ -225,7 +223,7 @@ void chSchDoRescheduleI(void) { #endif /* !defined(PORT_OPTIMIZED_DORESCHEDULEI) */ /** - * @brief Performs a reschedulation if a higher priority thread is runnable. + * @brief Performs a reschedule if a higher priority thread is runnable. * @details If a thread with a higher priority than the current thread is in * the ready list then make the higher priority thread running. */ @@ -238,14 +236,14 @@ void chSchRescheduleS(void) { #endif /* !defined(PORT_OPTIMIZED_RESCHEDULES) */ /** - * @brief Evaluates if a reschedulation is required. + * @brief Evaluates if a reschedule is required. * @details The decision is taken by comparing the relative priorities and * depending on the state of the round robin timeout counter. * @note This function is meant to be used in the timer interrupt handler * where @p chVTDoTickI() is invoked. * * @retval TRUE if there is a thread that should go in running state. - * @retval FALSE if a reschedulation is not required. + * @retval FALSE if a reschedule is not required. */ #if !defined(PORT_OPTIMIZED_ISRESCHREQUIREDEXI) || defined(__DOXYGEN__) bool_t chSchIsRescRequiredExI(void) { -- cgit v1.2.3 From 7370e125969d1f5a9808280c507d7ac38d2fc1bc Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 18 Mar 2010 18:36:27 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1751 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index ac69c6661..c561cbd41 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -112,6 +112,7 @@ void chSchGoSleepS(tstate_t newstate) { static void wakeup(void *p) { Thread *tp = (Thread *)p; + tp->p_u.rdymsg = RDY_TIMEOUT; #if CH_USE_SEMAPHORES || (CH_USE_CONDVARS && CH_USE_CONDVARS_TIMEOUT) switch (tp->p_state) { #if CH_USE_SEMAPHORES @@ -126,7 +127,7 @@ static void wakeup(void *p) { dequeue(tp); } #endif - chSchReadyI(tp)->p_u.rdymsg = RDY_TIMEOUT; + chSchReadyI(tp); } /** -- cgit v1.2.3 From 55e8eabccb4f0c5fe448055a16b4dfa916977477 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 18 Mar 2010 21:41:33 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1753 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index c561cbd41..d5c8a0a5a 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -112,7 +112,6 @@ void chSchGoSleepS(tstate_t newstate) { static void wakeup(void *p) { Thread *tp = (Thread *)p; - tp->p_u.rdymsg = RDY_TIMEOUT; #if CH_USE_SEMAPHORES || (CH_USE_CONDVARS && CH_USE_CONDVARS_TIMEOUT) switch (tp->p_state) { #if CH_USE_SEMAPHORES @@ -127,6 +126,8 @@ static void wakeup(void *p) { dequeue(tp); } #endif + /* Done this way in order to allow a tail call.*/ + tp->p_u.rdymsg = RDY_TIMEOUT; chSchReadyI(tp); } -- cgit v1.2.3 From 79075f9e81d9d56be5da3bf6cdae56f4ace950de Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 19 Mar 2010 12:48:54 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1755 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 9 ++++++--- os/kernel/src/chsys.c | 3 ++- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index d5c8a0a5a..7170fb0ec 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -96,7 +96,8 @@ void chSchGoSleepS(tstate_t newstate) { Thread *otp; (otp = currp)->p_state = newstate; - (currp = fifo_remove(&rlist.r_queue))->p_state = THD_STATE_CURRENT; + setcurrp(fifo_remove(&rlist.r_queue)); + currp->p_state = THD_STATE_CURRENT; #if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; #endif @@ -196,7 +197,8 @@ void chSchWakeupS(Thread *ntp, msg_t msg) { #if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; #endif - (currp = ntp)->p_state = THD_STATE_CURRENT; + setcurrp(ntp); + ntp->p_state = THD_STATE_CURRENT; chDbgTrace(ntp, otp); chSysSwitchI(ntp, otp); } @@ -217,7 +219,8 @@ void chSchDoRescheduleI(void) { #endif otp = currp; /* Picks the first thread from the ready queue and makes it current.*/ - (currp = ntp = fifo_remove(&rlist.r_queue))->p_state = THD_STATE_CURRENT; + (ntp = fifo_remove(&rlist.r_queue))->p_state = THD_STATE_CURRENT; + setcurrp(ntp); chSchReadyI(otp); chDbgTrace(ntp, otp); chSysSwitchI(ntp, otp); diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index eeed4a998..1a66c8e98 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -80,7 +80,8 @@ void chSysInit(void) { #endif /* Now this instructions flow becomes the main thread.*/ - (currp = init_thread(&mainthread, NORMALPRIO))->p_state = THD_STATE_CURRENT; + setcurrp(init_thread(&mainthread, NORMALPRIO)); + currp->p_state = THD_STATE_CURRENT; chSysEnable(); /* This thread has the lowest priority in the system, its role is just to -- cgit v1.2.3 From b61fb43e6cc681f9fc53a5efb116accc13e0d35d Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 19 Mar 2010 15:45:25 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1756 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chregistry.c | 2 +- os/kernel/src/chschd.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c index ad5cd7fc1..c561d8ca6 100644 --- a/os/kernel/src/chregistry.c +++ b/os/kernel/src/chregistry.c @@ -64,7 +64,7 @@ Thread *chRegFirstThread(void) { Thread *tp; chSysLock(); - tp = rlist.p_newer; + tp = rlist.r_newer; #if CH_USE_DYNAMIC tp->p_refs++; #endif diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 7170fb0ec..cee046af2 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -51,7 +51,7 @@ void scheduler_init(void) { rlist.r_preempt = CH_TIME_QUANTUM; #endif #if CH_USE_REGISTRY - rlist.p_newer = rlist.p_older = (Thread *)&rlist; + rlist.r_newer = rlist.r_older = (Thread *)&rlist; #endif } @@ -96,11 +96,11 @@ void chSchGoSleepS(tstate_t newstate) { Thread *otp; (otp = currp)->p_state = newstate; - setcurrp(fifo_remove(&rlist.r_queue)); - currp->p_state = THD_STATE_CURRENT; #if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; #endif + setcurrp(fifo_remove(&rlist.r_queue)); + currp->p_state = THD_STATE_CURRENT; chDbgTrace(currp, otp); chSysSwitchI(currp, otp); } -- cgit v1.2.3 From 295f370672c3238bc166743261f067bd8fe80cc4 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 19 Mar 2010 20:27:40 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1758 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index cee046af2..c75f099f6 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -212,18 +212,18 @@ void chSchWakeupS(Thread *ntp, msg_t msg) { */ #if !defined(PORT_OPTIMIZED_DORESCHEDULEI) || defined(__DOXYGEN__) void chSchDoRescheduleI(void) { - Thread *otp, *ntp; + Thread *otp; #if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; #endif otp = currp; /* Picks the first thread from the ready queue and makes it current.*/ - (ntp = fifo_remove(&rlist.r_queue))->p_state = THD_STATE_CURRENT; - setcurrp(ntp); + setcurrp(fifo_remove(&rlist.r_queue)); + currp->p_state = THD_STATE_CURRENT; chSchReadyI(otp); - chDbgTrace(ntp, otp); - chSysSwitchI(ntp, otp); + chDbgTrace(currp, otp); + chSysSwitchI(currp, otp); } #endif /* !defined(PORT_OPTIMIZED_DORESCHEDULEI) */ -- cgit v1.2.3 From e55b9dfdcb1a285aed416fc49d702b01e18de03f Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 19 Mar 2010 20:39:23 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1759 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chdebug.c | 5 ++--- os/kernel/src/chschd.c | 6 +++--- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index 462f2559e..15a2f3e92 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -50,15 +50,14 @@ void trace_init(void) { /** * @brief Inserts in the circular debug trace buffer a context switch record. * - * @param[in] ntp the thread to be switched in * @param[in] otp the thread being switched out */ -void chDbgTrace(Thread *ntp, Thread *otp) { +void chDbgTrace(Thread *otp) { trace_buffer.tb_ptr->cse_wtobjp = otp->p_u.wtobjp; trace_buffer.tb_ptr->cse_time = chTimeNow(); trace_buffer.tb_ptr->cse_state = otp->p_state; - trace_buffer.tb_ptr->cse_tid = (unsigned)ntp >> 4; + trace_buffer.tb_ptr->cse_tid = (unsigned)currp >> 6; if (++trace_buffer.tb_ptr >= &trace_buffer.tb_buffer[TRACE_BUFFER_SIZE]) trace_buffer.tb_ptr = &trace_buffer.tb_buffer[0]; } diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index c75f099f6..d412798c0 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -101,7 +101,7 @@ void chSchGoSleepS(tstate_t newstate) { #endif setcurrp(fifo_remove(&rlist.r_queue)); currp->p_state = THD_STATE_CURRENT; - chDbgTrace(currp, otp); + chDbgTrace(otp); chSysSwitchI(currp, otp); } #endif /* !defined(PORT_OPTIMIZED_GOSLEEPS) */ @@ -199,7 +199,7 @@ void chSchWakeupS(Thread *ntp, msg_t msg) { #endif setcurrp(ntp); ntp->p_state = THD_STATE_CURRENT; - chDbgTrace(ntp, otp); + chDbgTrace(otp); chSysSwitchI(ntp, otp); } } @@ -222,7 +222,7 @@ void chSchDoRescheduleI(void) { setcurrp(fifo_remove(&rlist.r_queue)); currp->p_state = THD_STATE_CURRENT; chSchReadyI(otp); - chDbgTrace(currp, otp); + chDbgTrace(otp); chSysSwitchI(currp, otp); } #endif /* !defined(PORT_OPTIMIZED_DORESCHEDULEI) */ -- cgit v1.2.3 From 0074052e3f64b2166258f2d117faf8acdf5d4566 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 27 Apr 2010 11:53:03 +0000 Subject: Documented test runtime code. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1895 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chevents.c | 1 + 1 file changed, 1 insertion(+) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index 2bc145cac..22739443f 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -51,6 +51,7 @@ * enabled in @p chconf.h. * @{ */ + #include "ch.h" #if CH_USE_EVENTS -- cgit v1.2.3 From bc9d319ddb279f973404c2b1abf15ec1091bd891 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 4 May 2010 12:31:05 +0000 Subject: Improved code coverage. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1902 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmemcore.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index d0c657a48..f835e2111 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -109,11 +109,11 @@ void *chCoreAllocI(size_t size) { } /** - * @brief Core memory left. + * @brief Core memory status. * * @return The size, in bytes, of the free core memory. */ -size_t chCoreFree(void) { +size_t chCoreStatus(void) { return (size_t)(endmem - nextmem); } -- cgit v1.2.3 From 4ee79187645d1a2687f81de3f19320acbce733c8 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 2 Jun 2010 11:17:33 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1982 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsem.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index 2a86a14f6..2959b4d63 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -117,7 +117,7 @@ void chSemResetI(Semaphore *sp, cnt_t n) { cnt = sp->s_cnt; sp->s_cnt = n; - while (cnt++ < 0) + while (++cnt <= 0) chSchReadyI(lifo_remove(&sp->s_queue))->p_u.rdymsg = RDY_RESET; } @@ -220,7 +220,7 @@ void chSemSignal(Semaphore *sp) { chDbgCheck(sp != NULL, "chSemSignal"); chSysLock(); - if (sp->s_cnt++ < 0) + if (++sp->s_cnt <= 0) chSchWakeupS(fifo_remove(&sp->s_queue), RDY_OK); chSysUnlock(); } @@ -235,7 +235,7 @@ void chSemSignalI(Semaphore *sp) { chDbgCheck(sp != NULL, "chSemSignalI"); - if (sp->s_cnt++ < 0) { + if (++sp->s_cnt <= 0) { /* note, it is done this way in order to allow a tail call on chSchReadyI().*/ Thread *tp = fifo_remove(&sp->s_queue); @@ -261,7 +261,7 @@ msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw) { chDbgCheck((sps != NULL) && (spw != NULL), "chSemSignalWait"); chSysLock(); - if (sps->s_cnt++ < 0) + if (++sps->s_cnt <= 0) chSchReadyI(fifo_remove(&sps->s_queue))->p_u.rdymsg = RDY_OK; if (--spw->s_cnt < 0) { Thread *ctp = currp; -- cgit v1.2.3 From d9578ad0dbbb3cad59073de52cf258497acb5778 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 2 Jun 2010 17:27:31 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1990 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chqueues.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index acc7494c2..651b79f4e 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -215,7 +215,7 @@ void chOQInit(OutputQueue *oqp, uint8_t *bp, size_t size, qnotify_t onfy) { oqp->q_buffer = oqp->q_rdptr = oqp->q_wrptr = bp; oqp->q_top = bp + size; oqp->q_notify = onfy; - chSemInit(&oqp->q_sem, size); + chSemInit(&oqp->q_sem, (cnt_t)size); } /** -- cgit v1.2.3 From fe292af06d48b5d42b0dd8fcb594b5a9c4668144 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 21 Jun 2010 16:52:51 +0000 Subject: Fixed bug 3019099. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2027 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 58 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 15 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index c3076163a..88b6f4ecd 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -145,12 +145,17 @@ void chMtxLockS(Mutex *mp) { prio_insert(ctp, &mp->m_queue); ctp->p_u.wtobjp = mp; chSchGoSleepS(THD_STATE_WTMTX); - chDbgAssert(mp->m_owner == NULL, "chMtxLockS(), #1", "still owned"); + /* It is assumed that the thread performing the unlock operation assigns + the mutex to this thread.*/ + chDbgAssert(mp->m_owner == ctp, "chMtxLockS(), #1", "not owner"); + chDbgAssert(ctp->p_mtxlist == mp, "chMtxLockS(), #2", "not owned"); + } + else { + /* It was not owned, inserted in the owned mutexes list.*/ + mp->m_owner = ctp; + mp->m_next = ctp->p_mtxlist; + ctp->p_mtxlist = mp; } - /* The mutex is now inserted in the owned mutexes list.*/ - mp->m_owner = ctp; - mp->m_next = ctp->p_mtxlist; - ctp->p_mtxlist = mp; } /** @@ -216,9 +221,10 @@ Mutex *chMtxUnlock(void) { as not owned.*/ ump = ctp->p_mtxlist; ctp->p_mtxlist = ump->m_next; - ump->m_owner = NULL; /* If a thread is waiting on the mutex then the fun part begins.*/ if (chMtxQueueNotEmptyS(ump)) { + Thread *tp; + /* Recalculates the optimal thread priority by scanning the owned mutexes list.*/ tprio_t newprio = ctp->p_realprio; @@ -234,9 +240,16 @@ Mutex *chMtxUnlock(void) { /* Assigns to the current thread the highest priority among all the waiting threads.*/ ctp->p_prio = newprio; - /* Awakens the highest priority thread waiting for the unlocked mutex.*/ - chSchWakeupS(fifo_remove(&ump->m_queue), RDY_OK); + /* Awakens the highest priority thread waiting for the unlocked mutex and + assigns the mutex to it.*/ + tp = fifo_remove(&ump->m_queue); + ump->m_owner = tp; + ump->m_next = tp->p_mtxlist; + tp->p_mtxlist = ump; + chSchWakeupS(tp, RDY_OK); } + else + ump->m_owner = NULL; chSysUnlock(); return ump; } @@ -262,9 +275,10 @@ Mutex *chMtxUnlockS(void) { owned.*/ ump = ctp->p_mtxlist; ctp->p_mtxlist = ump->m_next; - ump->m_owner = NULL; /* If a thread is waiting on the mutex then the fun part begins.*/ if (chMtxQueueNotEmptyS(ump)) { + Thread *tp; + /* Recalculates the optimal thread priority by scanning the owned mutexes list.*/ tprio_t newprio = ctp->p_realprio; @@ -278,8 +292,16 @@ Mutex *chMtxUnlockS(void) { mp = mp->m_next; } ctp->p_prio = newprio; - chSchReadyI(fifo_remove(&ump->m_queue)); + /* Awakens the highest priority thread waiting for the unlocked mutex and + assigns the mutex to it.*/ + tp = fifo_remove(&ump->m_queue); + ump->m_owner = tp; + ump->m_next = tp->p_mtxlist; + tp->p_mtxlist = ump; + chSchReadyI(tp); } + else + ump->m_owner = NULL; return ump; } @@ -296,11 +318,17 @@ void chMtxUnlockAll(void) { chSysLock(); if (ctp->p_mtxlist != NULL) { do { - Mutex *mp = ctp->p_mtxlist; - ctp->p_mtxlist = mp->m_next; - mp->m_owner = NULL; - if (chMtxQueueNotEmptyS(mp)) - chSchReadyI(fifo_remove(&mp->m_queue)); + Mutex *ump = ctp->p_mtxlist; + ctp->p_mtxlist = ump->m_next; + if (chMtxQueueNotEmptyS(ump)) { + Thread *tp = fifo_remove(&ump->m_queue); + ump->m_owner = tp; + ump->m_next = tp->p_mtxlist; + tp->p_mtxlist = ump; + chSchReadyI(tp); + } + else + ump->m_owner = NULL; } while (ctp->p_mtxlist != NULL); ctp->p_prio = ctp->p_realprio; chSchRescheduleS(); -- cgit v1.2.3 From d0d72baa87964a4f76f34949b16a02736ca04bdf Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 21 Jun 2010 17:05:53 +0000 Subject: Fixed bug 3019158. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2028 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chqueues.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index 651b79f4e..84cbbed94 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -154,7 +154,8 @@ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) { * * @param[in] iqp pointer to an @p InputQueue structure * @param[out] bp pointer to the data buffer - * @param[in] n the maximum amount of data to be transferred + * @param[in] n the maximum amount of data to be transferred, the + * value 0 is reserved * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. @@ -167,6 +168,8 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, qnotify_t nfy = iqp->q_notify; size_t r = 0; + chDbgCheck(n > 0, "chIQReadTimeout"); + chSysLock(); while (TRUE) { if (chIQIsEmpty(iqp)) { @@ -304,7 +307,8 @@ msg_t chOQGetI(OutputQueue *oqp) { * * @param[in] oqp pointer to an @p OutputQueue structure * @param[out] bp pointer to the data buffer - * @param[in] n the maximum amount of data to be transferred + * @param[in] n the maximum amount of data to be transferred, the + * value 0 is reserved * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. @@ -317,6 +321,8 @@ size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp, qnotify_t nfy = oqp->q_notify; size_t w = 0; + chDbgCheck(n > 0, "chOQWriteTimeout"); + chSysLock(); while (TRUE) { if (chOQIsFull(oqp)) { -- cgit v1.2.3 From 62f4b7f471a4b1037468d382f927c5061e5fa9ed Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 24 Jun 2010 14:19:52 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2036 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chcond.c | 3 +-- os/kernel/src/chqueues.c | 7 ++++--- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c index c450b0c32..92e1a4eb4 100644 --- a/os/kernel/src/chcond.c +++ b/os/kernel/src/chcond.c @@ -17,8 +17,7 @@ along with this program. If not, see . */ /* - Concepts and parts of this file are contributed by and Copyright (C) 2008 - of Leon Woestenberg. + Concepts and parts of this file have been contributed by Leon Woestenberg. */ /** diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index 84cbbed94..d1aa03cc6 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -126,6 +126,10 @@ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) { msg_t msg; chSysLock(); + + if (iqp->q_notify) + iqp->q_notify(); + if ((msg = chSemWaitTimeoutS(&iqp->q_sem, time)) < RDY_OK) { chSysUnlock(); return msg; @@ -134,9 +138,6 @@ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) { if (iqp->q_rdptr >= iqp->q_top) iqp->q_rdptr = iqp->q_buffer; - if (iqp->q_notify) - iqp->q_notify(); - chSysUnlock(); return b; } -- cgit v1.2.3 From e3a5e25315231a31932e865d3f6be9c1cd1f159b Mon Sep 17 00:00:00 2001 From: ecarusi Date: Mon, 5 Jul 2010 17:47:44 +0000 Subject: CH_USE_MALLOC_HEAP and H_(UN)LOCK redefinition fix git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2055 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chheap.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c index ede326b59..820f15362 100644 --- a/os/kernel/src/chheap.c +++ b/os/kernel/src/chheap.c @@ -41,6 +41,8 @@ #if CH_USE_HEAP +#if !CH_USE_MALLOC_HEAP + /* * Defaults on the best synchronization mechanism available. */ @@ -52,8 +54,6 @@ #define H_UNLOCK(h) chSemSignal(&(h)->h_sem) #endif -#if !CH_USE_MALLOC_HEAP - /** * @brief Default heap descriptor. */ @@ -253,7 +253,7 @@ size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep) { #if CH_USE_MUTEXES #define H_LOCK() chMtxLock(&hmtx) -#define H_UNLOCK() chMtxUnock() +#define H_UNLOCK() chMtxUnlock() static Mutex hmtx; #elif CH_USE_SEMAPHORES #define H_LOCK() chSemWait(&hsem) -- cgit v1.2.3 From fef1911a8f6329ad97e4112965e004d21bffef73 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 20 Aug 2010 07:15:55 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2134 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsys.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 1a66c8e98..80d037dd6 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -34,7 +34,7 @@ #include "ch.h" -static WORKING_AREA(idle_thread_wa, IDLE_THREAD_STACK_SIZE); +WORKING_AREA(_idle_thread_wa, IDLE_THREAD_STACK_SIZE); /** * @brief This function implements the idle thread infinite loop. @@ -46,7 +46,7 @@ static WORKING_AREA(idle_thread_wa, IDLE_THREAD_STACK_SIZE); * * @param[in] p the thread parameter, unused in this scenario */ -static void idle_thread(void *p) { +void _idle_thread(void *p) { (void)p; while (TRUE) { @@ -87,8 +87,8 @@ void chSysInit(void) { /* This thread has the lowest priority in the system, its role is just to serve interrupts in its context while keeping the lowest energy saving mode compatible with the system status.*/ - chThdCreateStatic(idle_thread_wa, sizeof(idle_thread_wa), IDLEPRIO, - (tfunc_t)idle_thread, NULL); + chThdCreateStatic(idle_thread_wa, sizeof(_idle_thread_wa), IDLEPRIO, + (tfunc_t)_idle_thread, NULL); } /** -- cgit v1.2.3 From 29226ecec7052b72ba82e8ba2eedb4c91d27ff28 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 20 Aug 2010 07:40:01 +0000 Subject: Small fix to the SPI demo. SPI I/O pins were no initialized as alternate. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2135 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsys.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 80d037dd6..d34e7e73a 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -34,6 +34,10 @@ #include "ch.h" +/** + * @brief Idle thread working area. + * @see IDLE_THREAD_STACK_SIZE + */ WORKING_AREA(_idle_thread_wa, IDLE_THREAD_STACK_SIZE); /** @@ -87,7 +91,7 @@ void chSysInit(void) { /* This thread has the lowest priority in the system, its role is just to serve interrupts in its context while keeping the lowest energy saving mode compatible with the system status.*/ - chThdCreateStatic(idle_thread_wa, sizeof(_idle_thread_wa), IDLEPRIO, + chThdCreateStatic(_idle_thread_wa, sizeof(_idle_thread_wa), IDLEPRIO, (tfunc_t)_idle_thread, NULL); } -- cgit v1.2.3 From 138c0f900d823b2c953038048bc40b14610f958a Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 21 Aug 2010 08:38:14 +0000 Subject: Added new kernel hooks (on halt and on systick). git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2136 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsys.c | 3 +++ os/kernel/src/chthreads.c | 8 ++++++-- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index d34e7e73a..22860b317 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -117,6 +117,9 @@ void chSysTimerHandlerI(void) { currp->p_time++; #endif chVTDoTickI(); +#if defined(SYSTEM_TICK_EVENT_HOOK) + SYSTEM_TICK_EVENT_HOOK(); +#endif } #if CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 3f2f88899..ae38dc11a 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -94,7 +94,9 @@ Thread *init_thread(Thread *tp, tprio_t prio) { #if CH_USE_EVENTS tp->p_epending = 0; #endif - THREAD_EXT_INIT(tp); +#if defined(THREAD_EXT_EXIT_HOOK) + THREAD_EXT_INIT_HOOK(tp); +#endif return tp; } @@ -357,7 +359,9 @@ void chThdExit(msg_t msg) { chSysLock(); tp->p_u.exitcode = msg; - THREAD_EXT_EXIT(tp); +#if defined(THREAD_EXT_EXIT_HOOK) + THREAD_EXT_EXIT_HOOK(tp); +#endif #if CH_USE_WAITEXIT while (notempty(&tp->p_waiting)) chSchReadyI(list_remove(&tp->p_waiting)); -- cgit v1.2.3 From ece6ef6bf70d1b3033687dedd23a9ce4cfc4f59b Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 28 Aug 2010 14:32:56 +0000 Subject: Added assertions to the semaphores subsystem. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2138 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsem.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index 2959b4d63..e5ec9afde 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -115,6 +115,11 @@ void chSemResetI(Semaphore *sp, cnt_t n) { chDbgCheck((sp != NULL) && (n >= 0), "chSemResetI"); + chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) || + ((sp->s_cnt < 0) && notempty(&sp->s_queue)), + "chSemResetI(), #1", + "inconsistent semaphore"); + cnt = sp->s_cnt; sp->s_cnt = n; while (++cnt <= 0) @@ -148,6 +153,11 @@ msg_t chSemWaitS(Semaphore *sp) { chDbgCheck(sp != NULL, "chSemWaitS"); + chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) || + ((sp->s_cnt < 0) && notempty(&sp->s_queue)), + "chSemWaitS(), #1", + "inconsistent semaphore"); + if (--sp->s_cnt < 0) { currp->p_u.wtobjp = sp; sem_insert(currp, &sp->s_queue); @@ -198,6 +208,11 @@ msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) { chDbgCheck(sp != NULL, "chSemWaitTimeoutS"); + chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) || + ((sp->s_cnt < 0) && notempty(&sp->s_queue)), + "chSemWaitTimeoutS(), #1", + "inconsistent semaphore"); + if (--sp->s_cnt < 0) { if (TIME_IMMEDIATE == time) { sp->s_cnt++; @@ -219,6 +234,11 @@ void chSemSignal(Semaphore *sp) { chDbgCheck(sp != NULL, "chSemSignal"); + chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) || + ((sp->s_cnt < 0) && notempty(&sp->s_queue)), + "chSemSignal(), #1", + "inconsistent semaphore"); + chSysLock(); if (++sp->s_cnt <= 0) chSchWakeupS(fifo_remove(&sp->s_queue), RDY_OK); @@ -235,6 +255,11 @@ void chSemSignalI(Semaphore *sp) { chDbgCheck(sp != NULL, "chSemSignalI"); + chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) || + ((sp->s_cnt < 0) && notempty(&sp->s_queue)), + "chSemSignalI(), #1", + "inconsistent semaphore"); + if (++sp->s_cnt <= 0) { /* note, it is done this way in order to allow a tail call on chSchReadyI().*/ @@ -260,6 +285,16 @@ msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw) { chDbgCheck((sps != NULL) && (spw != NULL), "chSemSignalWait"); + chDbgAssert(((sps->s_cnt >= 0) && isempty(&sps->s_queue)) || + ((sps->s_cnt < 0) && notempty(&sps->s_queue)), + "chSemSignalWait(), #1", + "inconsistent semaphore"); + + chDbgAssert(((spw->s_cnt >= 0) && isempty(&spw->s_queue)) || + ((spw->s_cnt < 0) && notempty(&spw->s_queue)), + "chSemSignalWait(), #2", + "inconsistent semaphore"); + chSysLock(); if (++sps->s_cnt <= 0) chSchReadyI(fifo_remove(&sps->s_queue))->p_u.rdymsg = RDY_OK; -- cgit v1.2.3 From 0ea17958535e56f50064ae47a50a3cd742f88163 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 29 Aug 2010 06:29:01 +0000 Subject: Fixed bug 3055329. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2139 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chlists.c | 9 +++++---- os/kernel/src/chschd.c | 3 ++- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chlists.c b/os/kernel/src/chlists.c index 2d973e771..83bdf8b35 100644 --- a/os/kernel/src/chlists.c +++ b/os/kernel/src/chlists.c @@ -48,9 +48,9 @@ void prio_insert(Thread *tp, ThreadsQueue *tqp) { cp = cp->p_next; /* Not end of queue? and cp has equal or higher priority than tp?.*/ } while ((cp != (Thread *)tqp) && (cp->p_prio >= tp->p_prio)); - /* Insert before cp, point tp to next and prev in queue.*/ - tp->p_prev = (tp->p_next = cp)->p_prev; - /* Make prev point to tp, and cp point back to tp.*/ + /* Insertion on p_prev.*/ + tp->p_next = cp; + tp->p_prev = cp->p_prev; tp->p_prev->p_next = cp->p_prev = tp; } @@ -63,7 +63,8 @@ void prio_insert(Thread *tp, ThreadsQueue *tqp) { */ void queue_insert(Thread *tp, ThreadsQueue *tqp) { - tp->p_prev = (tp->p_next = (Thread *)tqp)->p_prev; + tp->p_next = (Thread *)tqp; + tp->p_prev = tqp->p_prev; tp->p_prev->p_next = tqp->p_prev = tp; } diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index d412798c0..51987749f 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -78,7 +78,8 @@ Thread *chSchReadyI(Thread *tp) { cp = cp->p_next; } while (cp->p_prio >= tp->p_prio); /* Insertion on p_prev.*/ - tp->p_prev = (tp->p_next = cp)->p_prev; + tp->p_next = cp; + tp->p_prev = cp->p_prev; tp->p_prev->p_next = cp->p_prev = tp; return tp; } -- cgit v1.2.3 From 1a0fead19b521501ec5b7ff7532d6a7b435fdaa6 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 3 Sep 2010 18:23:37 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2162 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 6 +++++- os/kernel/src/chschd.c | 6 ++++++ 2 files changed, 11 insertions(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 88b6f4ecd..93943bba0 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -136,7 +136,11 @@ void chMtxLockS(Mutex *mp) { break; #endif case THD_STATE_READY: - /* Re-enqueues tp with its new priority on the ready list.*/ +#if CH_DBG_ENABLE_ASSERTS + /* Prevents an assertion in chSchReadyI().*/ + tp->p_state = THD_STATE_CURRENT; +#endif + /* Re-enqueues tp with its new priority on the ready list.*/ chSchReadyI(dequeue(tp)); } break; diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 51987749f..c4a6a3fd0 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -72,6 +72,12 @@ Thread *chSchReadyI(Thread *tp) { #endif Thread *cp; + /* Integrity check.*/ + chDbgAssert((tp->p_state != THD_STATE_READY) && + (tp->p_state != THD_STATE_FINAL), + "chSchReadyI(), #1", + "invalid state"); + tp->p_state = THD_STATE_READY; cp = (Thread *)&rlist.r_queue; do { -- cgit v1.2.3 From 9ffea7e261ec4016d788abbbf7c4a6d3a78e0a04 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 18 Sep 2010 06:48:56 +0000 Subject: Documentation improvements, renamed some event APIs. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2179 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chcond.c | 85 ++++++++++++++++++++++++++++------------------ os/kernel/src/chdebug.c | 9 +++-- os/kernel/src/chevents.c | 73 +++++++++++++++++++++++---------------- os/kernel/src/chheap.c | 20 +++++------ os/kernel/src/chmboxes.c | 44 ++++++++++++------------ os/kernel/src/chmemcore.c | 7 ++-- os/kernel/src/chmempools.c | 22 +++++++----- os/kernel/src/chmsg.c | 48 ++++++++++++-------------- os/kernel/src/chmtx.c | 61 +++++++++++++++++++++++---------- os/kernel/src/chqueues.c | 18 ++++++---- os/kernel/src/chregistry.c | 13 ++++--- os/kernel/src/chschd.c | 22 +++++++----- os/kernel/src/chsem.c | 71 ++++++++++++++++++++++++++------------ os/kernel/src/chsys.c | 4 +-- os/kernel/src/chthreads.c | 49 ++++++++++++++++---------- 15 files changed, 333 insertions(+), 213 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c index 92e1a4eb4..71729139f 100644 --- a/os/kernel/src/chcond.c +++ b/os/kernel/src/chcond.c @@ -31,21 +31,20 @@ *

Operation mode

* The condition variable is a synchronization object meant to be * used inside a zone protected by a @p Mutex. Mutexes and CondVars - * together can implement a Monitor construct.
- * In order to use the Condition Variables APIs the @p CH_USE_CONDVARS + * together can implement a Monitor construct. + * @pre In order to use the condition variable APIs the @p CH_USE_CONDVARS * option must be enabled in @p chconf.h. * @{ */ #include "ch.h" -#if CH_USE_CONDVARS && CH_USE_MUTEXES +#if (CH_USE_CONDVARS && CH_USE_MUTEXES) || defined(__DOXYGEN__) /** * @brief Initializes s @p CondVar structure. - * @note This function can be invoked from within an interrupt handler even - * if it is not an I-Class API because it does not touch any critical - * kernel data structure. + * @note This function can be invoked before the kernel is initialized + * because it just prepares a @p CondVar structure. * * @param[out] cp pointer to a @p CondVar structure */ @@ -73,6 +72,10 @@ void chCondSignal(CondVar *cp) { /** * @brief Signals one thread that is waiting on the condition variable. + * @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] cp pointer to the @p CondVar structure */ @@ -99,6 +102,10 @@ void chCondBroadcast(CondVar *cp) { /** * @brief Signals all threads that are waiting on the condition variable. + * @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] cp pointer to the @p CondVar structure */ @@ -118,13 +125,15 @@ void chCondBroadcastI(CondVar *cp) { * @details Releases the currently owned mutex, waits on the condition * variable, and finally acquires the mutex again. All the sequence * is performed atomically. - * @note The invoking thread must have at least one owned mutex on - * entry. + * @pre The invoking thread must have at least one owned mutex. * * @param[in] cp pointer to the @p CondVar structure - * @return The wakep mode. - * @retval RDY_OK if the condvar was signaled using @p chCondSignal(). - * @retval RDY_RESET if the condvar was signaled using @p chCondBroadcast(). + * @return A message specifying how the invoking thread has been + * released from the condition variable. + * @retval RDY_OK if the condvar has been signaled using + * @p chCondSignal(). + * @retval RDY_RESET if the condvar has been signaled using + * @p chCondBroadcast(). */ msg_t chCondWait(CondVar *cp) { msg_t msg; @@ -140,13 +149,15 @@ msg_t chCondWait(CondVar *cp) { * @details Releases the currently owned mutex, waits on the condition * variable, and finally acquires the mutex again. All the sequence * is performed atomically. - * @note The invoking thread must have at least one owned mutex on - * entry. + * @pre The invoking thread must have at least one owned mutex. * * @param[in] cp pointer to the @p CondVar structure - * @return The wakep mode. - * @retval RDY_OK if the condvar was signaled using @p chCondSignal(). - * @retval RDY_RESET if the condvar was signaled using @p chCondBroadcast(). + * @return A message specifying how the invoking thread has been + * released from the condition variable. + * @retval RDY_OK if the condvar has been signaled using + * @p chCondSignal(). + * @retval RDY_RESET if the condvar has been signaled using + * @p chCondBroadcast(). */ msg_t chCondWaitS(CondVar *cp) { Thread *ctp = currp; @@ -167,15 +178,16 @@ msg_t chCondWaitS(CondVar *cp) { return msg; } -#if CH_USE_CONDVARS_TIMEOUT +#if CH_USE_CONDVARS_TIMEOUT || defined(__DOXYGEN__) /** * @brief Waits on the condition variable releasing the mutex lock. * @details Releases the currently owned mutex, waits on the condition * variable, and finally acquires the mutex again. All the sequence * is performed atomically. - * @note The invoking thread must have at least one owned mutex on - * entry. - * @note Exiting the function because a timeout does not re-acquire the + * @pre The invoking thread must have at least one owned mutex. + * @pre The configuration option @p CH_USE_CONDVARS_TIMEOUT must be enabled + * in order to use this function. + * @post Exiting the function because a timeout does not re-acquire the * mutex, the mutex ownership is lost. * * @param[in] cp pointer to the @p CondVar structure @@ -184,11 +196,14 @@ msg_t chCondWaitS(CondVar *cp) { * It is not possible to specify zero @p TIME_IMMEDIATE * as timeout specification because it would make no sense * in this function. - * @return The wakep mode. - * @retval RDY_OK if the condvar was signaled using @p chCondSignal(). - * @retval RDY_RESET if the condvar was signaled using @p chCondBroadcast(). - * @retval RDY_TIMEOUT if the condvar was not signaled @p within the specified - * timeout. + * @return A message specifying how the invoking thread has been + * released from the condition variable. + * @retval RDY_OK if the condvar has been signaled using + * @p chCondSignal(). + * @retval RDY_RESET if the condvar has been signaled using + * @p chCondBroadcast(). + * @retval RDY_TIMEOUT if the condvar has not been signaled within the + * specified timeout. */ msg_t chCondWaitTimeout(CondVar *cp, systime_t time) { msg_t msg; @@ -204,9 +219,10 @@ msg_t chCondWaitTimeout(CondVar *cp, systime_t time) { * @details Releases the currently owned mutex, waits on the condition * variable, and finally acquires the mutex again. All the sequence * is performed atomically. - * @note The invoking thread must have at least one owned mutex on - * entry. - * @note Exiting the function because a timeout does not re-acquire the + * @pre The invoking thread must have at least one owned mutex. + * @pre The configuration option @p CH_USE_CONDVARS_TIMEOUT must be enabled + * in order to use this function. + * @post Exiting the function because a timeout does not re-acquire the * mutex, the mutex ownership is lost. * * @param[in] cp pointer to the @p CondVar structure @@ -215,11 +231,14 @@ msg_t chCondWaitTimeout(CondVar *cp, systime_t time) { * It is not possible to specify zero @p TIME_IMMEDIATE * as timeout specification because it would make no sense * in this function. - * @return The wakep mode. - * @retval RDY_OK if the condvar was signaled using @p chCondSignal(). - * @retval RDY_RESET if the condvar was signaled using @p chCondBroadcast(). - * @retval RDY_TIMEOUT if the condvar was not signaled within the specified - * timeout. + * @return A message specifying how the invoking thread has been + * released from the condition variable. + * @retval RDY_OK if the condvar has been signaled using + * @p chCondSignal(). + * @retval RDY_RESET if the condvar has been signaled using + * @p chCondBroadcast(). + * @retval RDY_TIMEOUT if the condvar has not been signaled within the + * specified timeout. */ msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time) { Mutex *mp; diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index 15a2f3e92..dcf42c2b3 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -27,12 +27,15 @@ * - Parameters check. * - Kernel assertions. * . + * @pre In order to use the debug APIs the @p CH_DBG_ENABLE_TRACE, + * @p CH_DBG_ENABLE_ASSERTS, @p CH_DBG_ENABLE_CHECKS options must + * be enabled in @p chconf.h. * @{ */ #include "ch.h" -#if CH_DBG_ENABLE_TRACE +#if CH_DBG_ENABLE_TRACE || defined(__DOXYGEN__) /** * @brief Public trace buffer. */ @@ -40,6 +43,7 @@ TraceBuffer trace_buffer; /** * @brief Trace circular buffer subsystem initialization. + * @note Internal use only. */ void trace_init(void) { @@ -63,7 +67,8 @@ void chDbgTrace(Thread *otp) { } #endif /* CH_DBG_ENABLE_TRACE */ -#if CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK +#if CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || \ + CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__) /** * @brief Pointer to the panic message. * @details This pointer is meant to be accessed through the debugger, it is diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index 22739443f..aac3a22af 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -46,22 +46,27 @@ * Event Source will be signaled with an events mask.
* An unlimited number of Event Sources can exists in a system and * each thread can be listening on an unlimited number of - * them.

- * In order to use the Events APIs the @p CH_USE_EVENTS option must be + * them. + * @pre In order to use the Events APIs the @p CH_USE_EVENTS option must be * enabled in @p chconf.h. + * @post Enabling events requires 1-4 (depending on the architecture) + * extra bytes in the @p Thread structure. * @{ */ #include "ch.h" -#if CH_USE_EVENTS +#if CH_USE_EVENTS || defined(__DOXYGEN__) /** * @brief Registers an Event Listener on an Event Source. - * @note Multiple Event Listeners can specify the same bits to be pended. + * @details Once a thread has registered as listener on an event source it + * will be notified of all events broadcasted there. + * @note Multiple Event Listeners can specify the same bits to be ORed to + * different threads. * * @param[in] esp pointer to the @p EventSource structure * @param[in] elp pointer to the @p EventListener structure - * @param[in] mask the mask of event flags to be pended to the thread when + * @param[in] mask the mask of event flags to be ORed to the thread when * the event source is broadcasted */ void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t mask) { @@ -110,7 +115,7 @@ void chEvtUnregister(EventSource *esp, EventListener *elp) { * @param[in] mask the events to be cleared * @return The pending events that were cleared. */ -eventmask_t chEvtClear(eventmask_t mask) { +eventmask_t chEvtClearFlags(eventmask_t mask) { eventmask_t m; chSysLock(); @@ -123,13 +128,13 @@ eventmask_t chEvtClear(eventmask_t mask) { } /** - * @brief Pends a set of event flags on the current thread, this is @b much - * faster than using @p chEvtBroadcast() or @p chEvtSignal(). + * @brief Adds (OR) a set of event flags on the current thread, this is + * @b much faster than using @p chEvtBroadcast() or @p chEvtSignal(). * - * @param[in] mask the events to be pended + * @param[in] mask the event flags to be ORed * @return The current pending events mask. */ -eventmask_t chEvtPend(eventmask_t mask) { +eventmask_t chEvtAddFlags(eventmask_t mask) { chSysLock(); @@ -140,10 +145,10 @@ eventmask_t chEvtPend(eventmask_t mask) { } /** - * @brief Pends a set of event flags on the specified @p Thread. + * @brief Adds (OR) a set of event flags on the specified @p Thread. * * @param[in] tp the thread to be signaled - * @param[in] mask the event flags set to be pended + * @param[in] mask the event flags set to be ORed */ void chEvtSignal(Thread *tp, eventmask_t mask) { @@ -156,10 +161,14 @@ void chEvtSignal(Thread *tp, eventmask_t mask) { } /** - * @brief Pends a set of event flags on the specified @p Thread. + * @brief Adds (OR) a set of event flags on the specified @p Thread. + * @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 pended + * @param[in] mask the event flags set to be ORed */ void chEvtSignalI(Thread *tp, eventmask_t mask) { @@ -191,6 +200,10 @@ void chEvtBroadcast(EventSource *esp) { /** * @brief Signals all the Event Listeners registered on the specified Event * Source. + * @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] esp pointer to the @p EventSource structure */ @@ -209,7 +222,7 @@ void chEvtBroadcastI(EventSource *esp) { /** * @brief Invokes the event handlers associated to an event flags mask. * - * @param[in] mask mask of the events to be dispatched + * @param[in] mask mask of the event flags to be dispatched * @param[in] handlers an array of @p evhandler_t. The array must have size * equal to the number of bits in eventmask_t. */ @@ -242,8 +255,8 @@ void chEvtDispatch(const evhandler_t *handlers, eventmask_t mask) { * This means that Event Listeners with a lower event identifier have * an higher priority. * - * @param[in] mask mask of the events that the function should wait for, - * @p ALL_EVENTS enables all the events + * @param[in] mask mask of the event flags that the function should wait + * for, @p ALL_EVENTS enables all the events * @return The mask of the lowest id served and cleared event. */ eventmask_t chEvtWaitOne(eventmask_t mask) { @@ -269,8 +282,8 @@ eventmask_t chEvtWaitOne(eventmask_t mask) { * @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 events that the function should wait for, - * @p ALL_EVENTS enables all the events + * @param[in] mask mask of the event flags that the function should wait + * for, @p ALL_EVENTS enables all the events * @return The mask of the served and cleared events. */ eventmask_t chEvtWaitAny(eventmask_t mask) { @@ -295,7 +308,8 @@ eventmask_t chEvtWaitAny(eventmask_t mask) { * @details The function waits for all the events specified in @p mask to * become pending then the events are cleared and returned. * - * @param[in] mask mask of the event ids that the function should wait for + * @param[in] mask mask of the event flags that the function should wait + * for, @p ALL_EVENTS requires all the events * @return The mask of the served and cleared events. */ eventmask_t chEvtWaitAll(eventmask_t mask) { @@ -314,7 +328,7 @@ eventmask_t chEvtWaitAll(eventmask_t mask) { } #endif /* CH_OPTIMIZE_SPEED || !CH_USE_EVENTS_TIMEOUT */ -#if CH_USE_EVENTS_TIMEOUT +#if CH_USE_EVENTS_TIMEOUT || defined(__DOXYGEN__) /** * @brief Waits for exactly one of the specified events. * @details The function waits for one event among those specified in @@ -325,15 +339,15 @@ eventmask_t chEvtWaitAll(eventmask_t mask) { * This means that Event Listeners with a lower event identifier have * an higher priority. * - * @param[in] mask mask of the events that the function should wait for, - * @p ALL_EVENTS enables all the events + * @param[in] mask mask of the event flagss that the function should wait + * for, @p ALL_EVENTS enables all the events * @param[in] time 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 lowest id served and cleared event. - * @retval 0 if the specified timeout expired. + * @retval 0 if the operation has timed out. */ eventmask_t chEvtWaitOneTimeout(eventmask_t mask, systime_t time) { Thread *ctp = currp; @@ -362,15 +376,15 @@ eventmask_t chEvtWaitOneTimeout(eventmask_t mask, systime_t time) { * @p mask to become pending then the events are cleared and * returned. * - * @param[in] mask mask of the events that the function should wait for, - * @p ALL_EVENTS enables all the events + * @param[in] mask mask of the event flags that the function should wait + * for, @p ALL_EVENTS enables all the events * @param[in] time 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 specified timeout expired. + * @retval 0 if the operation has timed out. */ eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t time) { Thread *ctp = currp; @@ -397,14 +411,15 @@ eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t time) { * @details The function waits for all the events specified in @p mask to * become pending then the events are cleared and returned. * - * @param[in] mask mask of the event ids that the function should wait for + * @param[in] mask mask of the event flags that the function should wait + * for, @p ALL_EVENTS requires all the events * @param[in] time 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 specified timeout expired. + * @retval 0 if the operation has timed out. */ eventmask_t chEvtWaitAllTimeout(eventmask_t mask, systime_t time) { Thread *ctp = currp; diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c index 820f15362..fc92e3c18 100644 --- a/os/kernel/src/chheap.c +++ b/os/kernel/src/chheap.c @@ -31,22 +31,22 @@ * By enabling the @p CH_USE_MALLOC_HEAP option the heap manager * will use the runtime-provided @p malloc() and @p free() as * backend for the heap APIs instead of the system provided - * allocator.
- * In order to use the heap APIs the @p CH_USE_HEAP option must + * allocator. + * @pre In order to use the heap APIs the @p CH_USE_HEAP option must * be enabled in @p chconf.h. * @{ */ #include "ch.h" -#if CH_USE_HEAP +#if CH_USE_HEAP || defined(__DOXYGEN__) -#if !CH_USE_MALLOC_HEAP +#if !CH_USE_MALLOC_HEAP || defined(__DOXYGEN__) /* * Defaults on the best synchronization mechanism available. */ -#if CH_USE_MUTEXES +#if CH_USE_MUTEXES || defined(__DOXYGEN__) #define H_LOCK(h) chMtxLock(&(h)->h_mtx) #define H_UNLOCK(h) chMtxUnlock() #else @@ -67,7 +67,7 @@ void heap_init(void) { default_heap.h_provider = chCoreAlloc; default_heap.h_free.h.u.next = (union heap_header *)NULL; default_heap.h_free.h.size = 0; -#if CH_USE_MUTEXES +#if CH_USE_MUTEXES || defined(__DOXYGEN__) chMtxInit(&default_heap.h_mtx); #else chSemInit(&default_heap.h_sem, 1); @@ -76,8 +76,8 @@ void heap_init(void) { /** * @brief Initializes a memory heap from a static memory area. - * @note Both the heap buffer base and the heap size must be aligned to - * the @p align_t type size. + * @pre Both the heap buffer base and the heap size must be aligned to + * the @p stkalign_t type size. * * @param[out] heapp pointer to the memory heap descriptor to be initialized * @param[in] buf heap buffer base @@ -93,7 +93,7 @@ void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) { heapp->h_free.h.size = 0; hp->h.u.next = NULL; hp->h.size = size - sizeof(union heap_header); -#if CH_USE_MUTEXES +#if CH_USE_MUTEXES || defined(__DOXYGEN__) chMtxInit(&heapp->h_mtx); #else chSemInit(&heapp->h_sem, 1); @@ -104,7 +104,7 @@ void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) { * @brief Allocates a block of memory from the heap by using the first-fit * algorithm. * @details The allocated block is guaranteed to be properly aligned for a - * pointer data type (@p align_t). + * pointer data type (@p stkalign_t). * * @param[in] heapp pointer to a heap descriptor or @p NULL in order to * access the default heap. diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c index 717246b88..279778e48 100644 --- a/os/kernel/src/chmboxes.c +++ b/os/kernel/src/chmboxes.c @@ -43,17 +43,19 @@ * possible approach is to allocate memory (from a memory pool as * example) from the posting side and free it on the fetching side. * Another approach is to set a "done" flag into the structure pointed - * by the message.
- * In order to use the mailboxes APIs the @p CH_USE_MAILBOXES option + * by the message. + * @pre In order to use the mailboxes APIs the @p CH_USE_MAILBOXES option * must be enabled in @p chconf.h. * @{ */ #include "ch.h" -#if CH_USE_MAILBOXES +#if CH_USE_MAILBOXES || defined(__DOXYGEN__) /** * @brief Initializes a Mailbox object. + * @note This function can be invoked before the kernel is initialized + * because it just prepares a @p Mailbox structure. * * @param[out] mbp the pointer to the Mailbox structure to be initialized * @param[in] buf the circular messages buffer @@ -101,9 +103,9 @@ void chMBReset(Mailbox *mbp) { * - @a TIME_INFINITE no timeout. * . * @return The operation status. - * @retval RDY_OK if the message was correctly posted. - * @retval RDY_RESET if the mailbox was reset while waiting. - * @retval RDY_TIMEOUT if the operation timed out. + * @retval RDY_OK if a message has been correctly posted. + * @retval RDY_RESET if the mailbox has been reset while waiting. + * @retval RDY_TIMEOUT if the operation has timed out. */ msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t time) { msg_t rdymsg; @@ -127,9 +129,9 @@ msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t time) { * - @a TIME_INFINITE no timeout. * . * @return The operation status. - * @retval RDY_OK if the message was correctly posted. - * @retval RDY_RESET if the mailbox was reset while waiting. - * @retval RDY_TIMEOUT if the operation timed out. + * @retval RDY_OK if a message has been correctly posted. + * @retval RDY_RESET if the mailbox has been reset while waiting. + * @retval RDY_TIMEOUT if the operation has timed out. */ msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) { msg_t rdymsg; @@ -160,9 +162,9 @@ msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) { * - @a TIME_INFINITE no timeout. * . * @return The operation status. - * @retval RDY_OK if the message was correctly posted. - * @retval RDY_RESET if the mailbox was reset while waiting. - * @retval RDY_TIMEOUT if the operation timed out. + * @retval RDY_OK if a message has been correctly posted. + * @retval RDY_RESET if the mailbox has been reset while waiting. + * @retval RDY_TIMEOUT if the operation has timed out. */ msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t time) { msg_t rdymsg; @@ -186,9 +188,9 @@ msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t time) { * - @a TIME_INFINITE no timeout. * . * @return The operation status. - * @retval RDY_OK if the message was correctly posted. - * @retval RDY_RESET if the mailbox was reset while waiting. - * @retval RDY_TIMEOUT if the operation timed out. + * @retval RDY_OK if a message has been correctly posted. + * @retval RDY_RESET if the mailbox has been reset while waiting. + * @retval RDY_TIMEOUT if the operation has timed out. */ msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) { msg_t rdymsg; @@ -219,9 +221,9 @@ msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) { * - @a TIME_INFINITE no timeout. * . * @return The operation status. - * @retval RDY_OK if a message was correctly fetched. - * @retval RDY_RESET if the mailbox was reset while waiting. - * @retval RDY_TIMEOUT if the operation timed out. + * @retval RDY_OK if a message has been correctly fetched. + * @retval RDY_RESET if the mailbox has been reset while waiting. + * @retval RDY_TIMEOUT if the operation has timed out. */ msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t time) { msg_t rdymsg; @@ -245,9 +247,9 @@ msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t time) { * - @a TIME_INFINITE no timeout. * . * @return The operation status. - * @retval RDY_OK if a message was correctly fetched. - * @retval RDY_RESET if the mailbox was reset while waiting. - * @retval RDY_TIMEOUT if the operation timed out. + * @retval RDY_OK if a message has been correctly fetched. + * @retval RDY_RESET if the mailbox has been reset while waiting. + * @retval RDY_TIMEOUT if the operation has timed out. */ msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t time) { msg_t rdymsg; diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index f835e2111..04edb7dae 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -35,15 +35,15 @@ * By having a centralized memory provider the various allocators can * coexist and share the main memory.
* This allocator, alone, is also useful for very simple applications - * that just require a simple way to get memory blocks.
- * In order to use the core memory manager APIs the @p CH_USE_MEMCORE + * that just require a simple way to get memory blocks. + * @pre In order to use the core memory manager APIs the @p CH_USE_MEMCORE * option must be enabled in @p chconf.h. * @{ */ #include "ch.h" -#if CH_USE_MEMCORE +#if CH_USE_MEMCORE || defined(__DOXYGEN__) static uint8_t *nextmem; static uint8_t *endmem; @@ -73,7 +73,6 @@ void core_init(void) { * type @p stkalign_t so it is not possible to allocate less * than sizeof(stkalign_t). * - * * @param[in] size the size of the block to be allocated * @return A pointer to the allocated memory block. * @retval NULL allocation failed, core memory exhausted. diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c index 31e4682fb..e1817aa60 100644 --- a/os/kernel/src/chmempools.c +++ b/os/kernel/src/chmempools.c @@ -26,19 +26,21 @@ *

Operation mode

* The Memory Pools APIs allow to allocate/free fixed size objects in * constant time and reliably without memory fragmentation - * problems.
- * In order to use the memory pools APIs the @p CH_USE_MEMPOOLS option + * problems. + * @pre In order to use the memory pools APIs the @p CH_USE_MEMPOOLS option * must be enabled in @p chconf.h. * @{ */ #include "ch.h" -#if CH_USE_MEMPOOLS +#if CH_USE_MEMPOOLS || defined(__DOXYGEN__) /** * @brief Initializes an empty memory pool. - * @note The size is internally aligned to be a multiple of the @p align_t - * type size. + * @note This function can be invoked before the kernel is initialized + * because it just prepares a @p MemoryPool structure. + * @note The size is internally aligned to be a multiple of the + * @p stkalign_t type size. * * @param[out] mp pointer to a @p MemoryPool structure * @param[in] size the size of the objects contained in this memory pool, @@ -96,10 +98,10 @@ void *chPoolAlloc(MemoryPool *mp) { /** * @brief Releases (or adds) an object into (to) a memory pool. - * @note The object is assumed to be of the right size for the specified + * @pre The freed object must be of the right size for the specified * memory pool. - * @note The object is assumed to be memory aligned to the size of @p align_t - * type. + * @pre The freed object must be memory aligned to the size of + * @p stkalign_t type. * * @param[in] mp pointer to a @p MemoryPool structure * @param[in] objp the pointer to the object to be released or added @@ -116,8 +118,10 @@ void chPoolFreeI(MemoryPool *mp, void *objp) { /** * @brief Releases (or adds) an object into (to) a memory pool. - * @note The object is assumed to be of the right size for the specified + * @pre The freed object must be of the right size for the specified * memory pool. + * @pre The freed object must be memory aligned to the size of + * @p stkalign_t type. * * @param[in] mp pointer to a @p MemoryPool structure * @param[in] objp the pointer to the object to be released or added diff --git a/os/kernel/src/chmsg.c b/os/kernel/src/chmsg.c index 96bf61452..09acf7b42 100644 --- a/os/kernel/src/chmsg.c +++ b/os/kernel/src/chmsg.c @@ -30,20 +30,22 @@ * that messages are not copied between the client and server threads * but just a pointer passed so the exchange is very time * efficient.
+ * Messages are scalar data types of type @p msg_t that are guaranteed + * to be size compatible with data pointers. Note that on some + * architectures function pointers can be larger that @p msg_t.
* Messages are usually processed in FIFO order but it is possible to * process them in priority order by enabling the * @p CH_USE_MESSAGES_PRIORITY option in @p chconf.h.
- * Applications do not need to allocate buffers for synchronous - * message queues, the mechanism just requires two extra pointers in - * the @p Thread structure (the message queue header).
- * In order to use the Messages APIs the @p CH_USE_MESSAGES option + * @pre In order to use the message APIs the @p CH_USE_MESSAGES option * must be enabled in @p chconf.h. + * @post Enabling messages requires 6-12 (depending on the architecture) + * extra bytes in the @p Thread structure. * @{ */ #include "ch.h" -#if CH_USE_MESSAGES +#if CH_USE_MESSAGES || defined(__DOXYGEN__) #if CH_USE_MESSAGES_PRIORITY #define msg_insert(tp, qp) prio_insert(tp, qp) @@ -79,13 +81,13 @@ msg_t chMsgSend(Thread *tp, msg_t msg) { /** * @brief Suspends the thread and waits for an incoming message. - * @note You can assume that the data contained in the message is stable - * until you invoke @p chMsgRelease() because the sending thread is - * suspended until then. + * @post After receiving a message the function @p chMsgRelease() must be + * invoked in order to acknowledge the reception and send the answer. + * @note If the message is a pointer then you can assume that the data + * pointed by the message is stable until you invoke @p chMsgRelease() + * because the sending thread is suspended until then. * - * @return The pointer to the message structure. Note, it is - * always the message associated to the thread on the - * top of the messages queue. + * @return The message. */ msg_t chMsgWait(void) { msg_t msg; @@ -104,16 +106,14 @@ msg_t chMsgWait(void) { /** * @brief Returns the next message in the queue. - * @note You can assume that the data pointed by the message is stable until - * you invoke @p chMsgRelease() because the sending thread is - * suspended until then. Always remember that the message data is not - * copied between the sender and the receiver, just a pointer is - * passed. + * @post After receiving a message the function @p chMsgRelease() must be + * invoked in order to acknowledge the reception and send the answer. + * @note If the message is a pointer then you can assume that the data + * pointed by the message is stable until you invoke @p chMsgRelease() + * because the sending thread is suspended until then. * - * @return The pointer to the message structure. Note, it is - * always the message associated to the thread on the - * top of the messages queue. - * @retval NULL if the queue is empty. + * @return The message. + * @retval 0 if the queue is empty. */ msg_t chMsgGet(void) { msg_t msg; @@ -126,12 +126,8 @@ msg_t chMsgGet(void) { /** * @brief Releases the thread waiting on top of the messages queue. - * @note You can call this function only if there is a message already in - * the queue else the result will be unpredictable (a crash most likely). - * Exiting from the @p chMsgWait() ensures you have at least one - * message in the queue so it is not a big deal.
- * The condition is only tested in debug mode in order to make this - * code as fast as possible. + * @pre Invoke this function only after a message has been received + * using @p chMsgWait() or @p chMsgGet(). * * @param[in] msg the message returned to the message sender */ diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 93943bba0..9698d3cd8 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -27,8 +27,8 @@ *

Operation mode

* A mutex is a threads synchronization object that can be in two * distinct states: - * - Not owned. - * - Owned by a thread. + * - Not owned (unlocked). + * - Owned by a thread (locked). * . * Operations defined for mutexes: * - Lock: The mutex is checked, if the mutex is not owned by @@ -39,8 +39,6 @@ * priority thread waiting in the queue, if any, is resumed and made * owner of the mutex. * . - * In order to use the Mutexes APIs the @p CH_USE_MUTEXES option must - * be enabled in @p chconf.h. *

Constraints

* In ChibiOS/RT the Unlock operations are always performed in * lock-reverse order. The unlock API does not even have a parameter, @@ -59,15 +57,21 @@ * The mechanism works with any number of nested mutexes and any * number of involved threads. The algorithm complexity (worst case) * is N with N equal to the number of nested mutexes. + * @pre In order to use the mutex APIs the @p CH_USE_MUTEXES option + * must be enabled in @p chconf.h. + * @post Enabling mutexes requires 5-12 (depending on the architecture) + * extra bytes in the @p Thread structure. * @{ */ #include "ch.h" -#if CH_USE_MUTEXES +#if CH_USE_MUTEXES || defined(__DOXYGEN__) /** * @brief Initializes s @p Mutex structure. + * @note This function can be invoked before the kernel is initialized + * because it just prepares a @p Mutex structure. * * @param[out] mp pointer to a @p Mutex structure */ @@ -81,6 +85,8 @@ void chMtxInit(Mutex *mp) { /** * @brief Locks the specified mutex. + * @post The mutex is locked and inserted in the per-thread stack of owned + * mutexes. * * @param[in] mp pointer to the @p Mutex structure */ @@ -95,6 +101,8 @@ void chMtxLock(Mutex *mp) { /** * @brief Locks the specified mutex. + * @post The mutex is locked and inserted in the per-thread stack of owned + * mutexes. * * @param[in] mp pointer to the @p Mutex structure */ @@ -164,12 +172,17 @@ void chMtxLockS(Mutex *mp) { /** * @brief Tries to lock a mutex. - * @details This function does not have any overhead related to - * the priority inheritance mechanism because it does not try to - * enter a sleep state on the mutex. + * @details This function attempts to lock a mutex, if the mutex is already + * locked by another thread then the function exits without waiting. + * @post The mutex is locked and inserted in the per-thread stack of owned + * mutexes. + * @note This function does not have any overhead related to the + * priority inheritance mechanism because it does not try to + * enter a sleep state. * * @param[in] mp pointer to the @p Mutex structure - * @retval TRUE if the mutex was successfully acquired + * @return The operation status. + * @retval TRUE if the mutex has been successfully acquired * @retval FALSE if the lock attempt failed. */ bool_t chMtxTryLock(Mutex *mp) { @@ -185,12 +198,17 @@ bool_t chMtxTryLock(Mutex *mp) { /** * @brief Tries to lock a mutex. - * @details This function does not have any overhead related to - * the priority inheritance mechanism because it does not try to - * enter a sleep state on the mutex. + * @details This function attempts to lock a mutex, if the mutex is already + * taken by another thread then the function exits without waiting. + * @post The mutex is locked and inserted in the per-thread stack of owned + * mutexes. + * @note This function does not have any overhead related to the + * priority inheritance mechanism because it does not try to + * enter a sleep state. * * @param[in] mp pointer to the @p Mutex structure - * @retval TRUE if the mutex was successfully acquired + * @return The operation status. + * @retval TRUE if the mutex has been successfully acquired * @retval FALSE if the lock attempt failed. */ bool_t chMtxTryLockS(Mutex *mp) { @@ -207,8 +225,11 @@ bool_t chMtxTryLockS(Mutex *mp) { /** * @brief Unlocks the next owned mutex in reverse lock order. + * @pre The invoking thread must have at least one owned mutex. + * @post The mutex is unlocked and removed from the per-thread stack of + * owned mutexes. * - * @return The pointer to the unlocked mutex. + * @return A pointer to the unlocked mutex. */ Mutex *chMtxUnlock(void) { Thread *ctp = currp; @@ -260,9 +281,13 @@ Mutex *chMtxUnlock(void) { /** * @brief Unlocks the next owned mutex in reverse lock order. - * @note This function does not reschedule internally. + * @pre The invoking thread must have at least one owned mutex. + * @post The mutex is unlocked and removed from the per-thread stack of + * owned mutexes. + * @post This function does not reschedule so a call to a rescheduling + * function must be performed before unlocking the kernel. * - * @return The pointer to the unlocked mutex. + * @return A pointer to the unlocked mutex. */ Mutex *chMtxUnlockS(void) { Thread *ctp = currp; @@ -311,7 +336,9 @@ Mutex *chMtxUnlockS(void) { /** * @brief Unlocks all the mutexes owned by the invoking thread. - * @details This function is MUCH MORE efficient than releasing the + * @post The stack of owned mutexes is emptied and all the found + * mutexes are unlocked. + * @note This function is MUCH MORE efficient than releasing the * mutexes one by one and not just because the call overhead, * this function does not have any overhead related to the priority * inheritance mechanism. diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index d1aa03cc6..485984fdf 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -35,21 +35,23 @@ * are implemented by pairing an input queue and an output queue * together. * . - * In order to use the I/O queues the @p CH_USE_QUEUES option must - * be enabled in @p chconf.h.
* I/O queues are usually used as an implementation layer for the I/O * channels interface, also see @ref io_channels. + * @pre In order to use the I/O queues the @p CH_USE_QUEUES option must + * be enabled in @p chconf.h. * @{ */ #include "ch.h" -#if CH_USE_QUEUES +#if CH_USE_QUEUES || defined(__DOXYGEN__) /** * @brief Initializes an input queue. * @details A Semaphore is internally initialized and works as a counter of * the bytes contained in the queue. + * @note This function can be invoked before the kernel is initialized + * because it just prepares a @p InputQueue structure. * @note The callback is invoked from within the S-Locked system state, * see @ref system_states. * @@ -88,7 +90,7 @@ void chIQResetI(InputQueue *iqp) { * * @param[in] iqp pointer to an @p InputQueue structure * @param[in] b the byte value to be written in the queue - * @return The operation status, it can be one of: + * @return The operation status. * @retval Q_OK if the operation has been completed with success. * @retval Q_FULL if the queue is full and the operation cannot be * completed. @@ -117,7 +119,7 @@ msg_t chIQPutI(InputQueue *iqp, uint8_t b) { * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . - * @return A byte value from the queue or: + * @return A byte value from the queue. * @retval Q_TIMEOUT if the specified time expired. * @retval Q_RESET if the queue was reset. */ @@ -205,6 +207,8 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, * @brief Initializes an output queue. * @details A Semaphore is internally initialized and works as a counter of * the free bytes in the queue. + * @note This function can be invoked before the kernel is initialized + * because it just prepares a @p OutputQueue structure. * @note The callback is invoked from within the S-Locked system state, * see @ref system_states. * @@ -250,7 +254,7 @@ void chOQResetI(OutputQueue *oqp) { * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . - * @return The operation status: + * @return The operation status. * @retval Q_OK if the operation succeeded. * @retval Q_TIMEOUT if the specified time expired. * @retval Q_RESET if the queue was reset. @@ -279,7 +283,7 @@ msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t time) { * @details A byte value is read from the low end of an output queue. * * @param[in] oqp pointer to an @p OutputQueue structure - * @return The byte value from the queue or: + * @return The byte value from the queue. * @retval Q_EMPTY if the queue is empty. */ msg_t chOQGetI(OutputQueue *oqp) { diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c index c561d8ca6..216758c85 100644 --- a/os/kernel/src/chregistry.c +++ b/os/kernel/src/chregistry.c @@ -40,25 +40,24 @@ * Another possible use is for centralized threads memory management, * terminating threads can pulse an event source and an event handler * can perform a scansion of the registry in order to recover the - * memory.
- * In order to use the threads registry the @p CH_USE_REGISTRY option + * memory. + * @pre In order to use the threads registry the @p CH_USE_REGISTRY option * must be enabled in @p chconf.h. * @{ */ #include "ch.h" -#if CH_USE_REGISTRY +#if CH_USE_REGISTRY || defined(__DOXYGEN__) /** * @brief Returns the first thread in the system. * @details Returns the most ancient thread in the system, usually this is - * the main thread unless it terminated. - * @note A reference is added to the returned thread in order to make sure - * it status is not lost. + * the main thread unless it terminated. A reference is added to the + * returned thread in order to make sure its status is not lost. * @note This function cannot return @p NULL because there is always at * least one thread in the system. * - * @return A reference to the first thread. + * @return A reference to the most ancient thread. */ Thread *chRegFirstThread(void) { Thread *tp; diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index c4a6a3fd0..213d999ce 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -57,11 +57,15 @@ void scheduler_init(void) { /** * @brief Inserts a thread in the Ready List. - * @note The function does not reschedule, the @p chSchRescheduleS() should - * be called soon after. + * @pre The thread must not be already inserted in any list through its + * @p p_next and @p p_prev or list corruption would occur. + * @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 made ready - * @return The Thread pointer. + * @param[in] tp the thread to be made ready + * @return The thread pointer. */ #if !defined(PORT_OPTIMIZED_READYI) || defined(__DOXYGEN__) #if CH_OPTIMIZE_SPEED @@ -93,8 +97,8 @@ Thread *chSchReadyI(Thread *tp) { /** * @brief Puts the current thread to sleep into the specified state. - * @details The thread goes into a sleeping state. The @ref thread_states are - * described into @p threads.h. + * @details The thread goes into a sleeping state. The possible + * @ref thread_states are defined into @p threads.h. * * @param[in] newstate the new thread state */ @@ -144,8 +148,8 @@ static void wakeup(void *p) { * timeout specification. * @details The thread goes into a sleeping state, if it is not awakened * explicitly within the specified timeout then it is forcibly - * awakened with a @p RDY_TIMEOUT low level message. The @ref - * thread_states are described into @p threads.h. + * awakened with a @p RDY_TIMEOUT low level message. The possible + * @ref thread_states are defined into @p threads.h. * * @param[in] newstate the new thread state * @param[in] time the number of ticks before the operation timeouts, the @@ -181,6 +185,8 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { * @details The thread is inserted into the ready list or immediately made * running depending on its relative priority compared to the current * thread. + * @pre The thread must not be already inserted in any list through its + * @p p_next and @p p_prev or list corruption would occur. * @note It is equivalent to a @p chSchReadyI() followed by a * @p chSchRescheduleS() but much more efficient. * @note The function assumes that the current thread has the highest diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index e5ec9afde..750402266 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -50,15 +50,15 @@ * also have other uses, queues guards and counters as example.
* Semaphores usually use a FIFO queuing strategy but it is possible * to make them order threads by priority by enabling - * @p CH_USE_SEMAPHORES_PRIORITY in @p chconf.h.
- * In order to use the Semaphores APIs the @p CH_USE_SEMAPHORES + * @p CH_USE_SEMAPHORES_PRIORITY in @p chconf.h. + * @pre In order to use the semaphore APIs the @p CH_USE_SEMAPHORES * option must be enabled in @p chconf.h. * @{ */ #include "ch.h" -#if CH_USE_SEMAPHORES +#if CH_USE_SEMAPHORES || defined(__DOXYGEN__) #if CH_USE_SEMAPHORES_PRIORITY #define sem_insert(tp, qp) prio_insert(tp, qp) @@ -68,6 +68,8 @@ /** * @brief Initializes a semaphore with the specified counter value. + * @note This function can be invoked before the kernel is initialized + * because it just prepares a @p Semaphore structure. * * @param[out] sp pointer to a @p Semaphore structure * @param[in] n initial value of the semaphore counter. Must be @@ -83,6 +85,9 @@ void chSemInit(Semaphore *sp, cnt_t n) { /** * @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. * @note The released threads can recognize they were waked up by a reset * rather than a signal because the @p chSemWait() will return * @p RDY_RESET instead of @p RDY_OK. @@ -101,10 +106,16 @@ void chSemReset(Semaphore *sp, cnt_t n) { /** * @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. * @note The released threads can recognize they were waked up by a reset * rather than a signal because the @p chSemWait() will return * @p RDY_RESET instead of @p RDY_OK. - * @note This function does not reschedule. * * @param[in] sp pointer to a @p Semaphore structure * @param[in] n the new value of the semaphore counter. The value must @@ -130,8 +141,11 @@ void chSemResetI(Semaphore *sp, cnt_t n) { * @brief Performs a wait operation on a semaphore. * * @param[in] sp pointer to a @p Semaphore structure - * @retval RDY_OK if the semaphore was signaled or not taken. - * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). + * @return A message specifying how the invoking thread has been + * released from the semaphore. + * @retval RDY_OK if the thread has not stopped on the semaphore or the + * semaphore has been signaled. + * @retval RDY_RESET if the semaphore has been reset using @p chSemReset(). */ msg_t chSemWait(Semaphore *sp) { msg_t msg; @@ -146,8 +160,11 @@ msg_t chSemWait(Semaphore *sp) { * @brief Performs a wait operation on a semaphore. * * @param[in] sp pointer to a @p Semaphore structure - * @retval RDY_OK if the semaphore was signaled or not taken. - * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). + * @return A message specifying how the invoking thread has been + * released from the semaphore. + * @retval RDY_OK if the thread has not stopped on the semaphore or the + * semaphore has been signaled. + * @retval RDY_RESET if the semaphore has been reset using @p chSemReset(). */ msg_t chSemWaitS(Semaphore *sp) { @@ -176,10 +193,13 @@ msg_t chSemWaitS(Semaphore *sp) { * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . - * @retval RDY_OK if the semaphore was signaled or not taken. - * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). - * @retval RDY_TIMEOUT if the semaphore was not signaled or reset within the - * specified timeout. + * @return A message specifying how the invoking thread has been + * released from the semaphore. + * @retval RDY_OK if the thread has not stopped on the semaphore or the + * semaphore has been signaled. + * @retval RDY_RESET if the semaphore has been reset using @p chSemReset(). + * @retval RDY_TIMEOUT if the semaphore has not been signaled or reset within + * the specified timeout. */ msg_t chSemWaitTimeout(Semaphore *sp, systime_t time) { msg_t msg; @@ -199,10 +219,13 @@ msg_t chSemWaitTimeout(Semaphore *sp, systime_t time) { * - @a TIME_IMMEDIATE immediate timeout. * - @a TIME_INFINITE no timeout. * . - * @retval RDY_OK if the semaphore was signaled or not taken. - * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). - * @retval RDY_TIMEOUT if the semaphore was not signaled or reset within the - * specified timeout. + * @return A message specifying how the invoking thread has been + * released from the semaphore. + * @retval RDY_OK if the thread has not stopped on the semaphore or the + * semaphore has been signaled. + * @retval RDY_RESET if the semaphore has been reset using @p chSemReset(). + * @retval RDY_TIMEOUT if the semaphore has not been signaled or reset within + * the specified timeout. */ msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) { @@ -247,7 +270,10 @@ void chSemSignal(Semaphore *sp) { /** * @brief Performs a signal operation on a semaphore. - * @note This function does not reschedule. + * @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 structure */ @@ -272,13 +298,16 @@ void chSemSignalI(Semaphore *sp) { #if CH_USE_SEMSW /** * @brief Performs atomic signal and wait operations on two semaphores. - * @note The function is available only if the @p CH_USE_SEMSW - * option is enabled in @p chconf.h. + * @pre The configuration option @p CH_USE_SEMSW must be enabled in order + * to use this function. * * @param[in] sps pointer to a @p Semaphore structure to be signaled * @param[in] spw pointer to a @p Semaphore structure to be wait on - * @retval RDY_OK if the semaphore was signaled or not taken. - * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). + * @return A message specifying how the invoking thread has been + * released from the semaphore. + * @retval RDY_OK if the thread has not stopped on the semaphore or the + * semaphore has been signaled. + * @retval RDY_RESET if the semaphore has been reset using @p chSemReset(). */ msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw) { msg_t msg; diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 22860b317..809212a7b 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -63,9 +63,9 @@ void _idle_thread(void *p) { * @brief ChibiOS/RT initialization. * @details After executing this function the current instructions stream * becomes the main thread. - * @note Interrupts should be still disabled when @p chSysInit() is invoked + * @pre Interrupts must be still disabled when @p chSysInit() is invoked * and are internally enabled. - * @note The main thread is created with priority @p NORMALPRIO. + * @post The main thread is created with priority @p NORMALPRIO. */ void chSysInit(void) { static Thread mainthread; diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index ae38dc11a..33ba3741e 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -59,6 +59,7 @@ /** * @brief Initializes a thread structure. + * @note This is an internal functions, do not use it in application code. * * @param[in] tp pointer to the thread * @param[in] prio the priority level for the new thread @@ -112,6 +113,8 @@ static void memfill(uint8_t *startp, uint8_t *endp, uint8_t v) { * @brief Initializes a new thread. * @details The new thread is initialized but not inserted in the ready list, * the initial state is @p THD_STATE_SUSPENDED. + * @post The initialized thread can be subsequently started by invoking + * @p chThdResume(). * @note A thread can terminate by calling @p chThdExit() or by simply * returning from its main function. * @note This function can be invoked from within an interrupt handler @@ -166,13 +169,12 @@ Thread *chThdCreateStatic(void *wsp, size_t size, #if CH_USE_DYNAMIC && CH_USE_HEAP /** * @brief Creates a new thread allocating the memory from the heap. + * @pre The configuration options @p CH_USE_DYNAMIC and @p CH_USE_HEAP + * must be enabled in order to use this function. * @note A thread can terminate by calling @p chThdExit() or by simply * returning from its main function. * @note The memory allocated for the thread is not released when the thread * terminates but when a @p chThdWait() is performed. - * @note The function is available only if the @p CH_USE_DYNAMIC, - * @p CH_USE_HEAP and @p CH_USE_WAITEXIT options are enabled - * in @p chconf.h. * * @param[in] heapp heap from which allocate the memory or @p NULL for the * default heap @@ -202,14 +204,13 @@ Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size, #if CH_USE_DYNAMIC && CH_USE_MEMPOOLS /** * @brief Creates a new thread allocating the memory from the specified - * Memory Pool. + * memory pool. + * @pre The configuration options @p CH_USE_DYNAMIC and @p CH_USE_MEMPOOLS + * must be enabled in order to use this function. * @note A thread can terminate by calling @p chThdExit() or by simply * returning from its main function. * @note The memory allocated for the thread is not released when the thread * terminates but when a @p chThdWait() is performed. - * @note The function is available only if the @p CH_USE_DYNAMIC, - * @p CH_USE_MEMPOOLS and @p CH_USE_WAITEXIT options are enabled - * in @p chconf.h. * * @param[in] mp pointer to the memory pool object * @param[in] prio the priority level for the new thread @@ -270,7 +271,11 @@ tprio_t chThdSetPriority(tprio_t newprio) { /** * @brief Resumes a suspended thread. - * @note Use this function to resume threads created with @p chThdInit(). + * @pre The specified thread pointer must refer to an initialized thread + * in the @p THD_STATE_SUSPENDED state. + * @post The specified thread is immediately started or put in the ready + * list depending on the relative priority levels. + * @note Use this function to start threads created with @p chThdInit(). * * @param[in] tp pointer to the thread * @return The pointer to the thread. @@ -288,9 +293,11 @@ Thread *chThdResume(Thread *tp) { /** * @brief Requests a thread termination. - * @note The thread is not terminated but a termination request is added to - * its @p p_flags field. The thread can read this status by - * invoking @p chThdShouldTerminate() and then terminate cleanly. + * @pre The target thread must be written to invoke periodically + * @p chThdShouldTerminate() and terminate cleanly if it returns + * @p TRUE. + * @post The specified thread will terminate after detecting the termination + * condition. * * @param[in] tp pointer to the thread */ @@ -349,10 +356,14 @@ void chThdYield(void) { } /** - * @brief Terminates the current thread by specifying an exit status code. + * @brief Terminates the current thread. + * @details The thread goes in the @p THD_STATE_FINAL state holding the + * specified exit status code, other threads can retrieve the + * exit status code by invoking the function @p chThdWait(). + * @post Eventual code after this function will never be executed, + * this function never returns. * - * @param[in] msg thread exit code. The code can be retrieved by using - * @p chThdWait(). + * @param[in] msg thread exit code */ void chThdExit(msg_t msg) { Thread *tp = currp; @@ -375,6 +386,8 @@ void chThdExit(msg_t msg) { #if CH_USE_DYNAMIC || defined(__DOXYGEN__) /** * @brief Adds a reference to a thread object. + * @pre The configuration option @p CH_USE_DYNAMIC must be enabled in order + * to use this function. * * @param[in] tp pointer to the thread * @return The same thread pointer passed as parameter @@ -394,6 +407,8 @@ Thread *chThdAddRef(Thread *tp) { * @details If the references counter reaches zero and the thread * is in the @p THD_STATE_FINAL state then the thread's memory is * returned to the proper allocator. + * @pre The configuration option @p CH_USE_DYNAMIC must be enabled in order + * to use this function. * @note Static threads are not affected. * * @param[in] tp pointer to the thread @@ -444,10 +459,10 @@ void chThdRelease(Thread *tp) { * then the working area is returned to the owning memory pool. * . * Please read the @ref article_lifecycle article for more details. - * @note After invoking @p chThdWait() the thread pointer becomes invalid + * @pre The configuration option @p CH_USE_WAITEXIT must be enabled in + * order to use this function. + * @post After invoking @p chThdWait() the thread pointer becomes invalid * and must not be used as parameter for further system calls. - * @note The function is available only if the @p CH_USE_WAITEXIT - * option is enabled in @p chconf.h. * @note If @p CH_USE_DYNAMIC is not specified this function just waits for * the thread termination, no memory allocators are involved. * -- cgit v1.2.3 From 6c3bddd257cc521db0d5bf5fb9524fdd234e038e Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 18 Sep 2010 08:31:12 +0000 Subject: Fixed bug 3069854, fixed documentation article about events. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2180 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chthreads.c | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 33ba3741e..5bcadb96d 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -67,14 +67,15 @@ */ Thread *init_thread(Thread *tp, tprio_t prio) { - tp->p_flags = THD_MEM_MODE_STATIC; tp->p_prio = prio; tp->p_state = THD_STATE_SUSPENDED; -#if CH_USE_REGISTRY - REG_INSERT(tp); + tp->p_flags = THD_MEM_MODE_STATIC; +#if CH_USE_MUTEXES + tp->p_realprio = prio; + tp->p_mtxlist = NULL; #endif -#if CH_USE_DYNAMIC - tp->p_refs = 1; +#if CH_USE_EVENTS + tp->p_epending = 0; #endif #if CH_USE_NESTED_LOCKS tp->p_locks = 0; @@ -82,9 +83,8 @@ Thread *init_thread(Thread *tp, tprio_t prio) { #if CH_DBG_THREADS_PROFILING tp->p_time = 0; #endif -#if CH_USE_MUTEXES - tp->p_realprio = prio; - tp->p_mtxlist = NULL; +#if CH_USE_DYNAMIC + tp->p_refs = 1; #endif #if CH_USE_WAITEXIT list_init(&tp->p_waiting); @@ -92,8 +92,10 @@ Thread *init_thread(Thread *tp, tprio_t prio) { #if CH_USE_MESSAGES queue_init(&tp->p_msgqueue); #endif -#if CH_USE_EVENTS - tp->p_epending = 0; +#if CH_USE_REGISTRY + chSysLock(); + REG_INSERT(tp); + chSysUnlock(); #endif #if defined(THREAD_EXT_EXIT_HOOK) THREAD_EXT_INIT_HOOK(tp); @@ -117,9 +119,6 @@ static void memfill(uint8_t *startp, uint8_t *endp, uint8_t v) { * @p chThdResume(). * @note A thread can terminate by calling @p chThdExit() or by simply * returning from its main function. - * @note This function can be invoked from within an interrupt handler - * even if it is not an I-Class API because it does not touch - * any critical kernel data structure. * * @param[out] wsp pointer to a working area dedicated to the thread stack * @param[in] size size of the working area @@ -461,6 +460,8 @@ void chThdRelease(Thread *tp) { * Please read the @ref article_lifecycle article for more details. * @pre The configuration option @p CH_USE_WAITEXIT must be enabled in * order to use this function. + * @post Enabling @p chThdWait() requires 2-4 (depending on the + * architecture) extra bytes in the @p Thread structure. * @post After invoking @p chThdWait() the thread pointer becomes invalid * and must not be used as parameter for further system calls. * @note If @p CH_USE_DYNAMIC is not specified this function just waits for -- cgit v1.2.3 From 16855e1a4e43b4b45e5b5a595628ab1d8c108093 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 20 Sep 2010 10:02:19 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2183 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chvt.c | 1 - 1 file changed, 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c index 8be1926ca..058433c09 100644 --- a/os/kernel/src/chvt.c +++ b/os/kernel/src/chvt.c @@ -40,7 +40,6 @@ VTList vtlist; void vt_init(void) { vtlist.vt_next = vtlist.vt_prev = (void *)&vtlist; - vtlist.vt_time = (systime_t)-1; vtlist.vt_systime = 0; } -- cgit v1.2.3 From 07351222e6d0b6b3dcd4f50ecb18bc09e7402d1c Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 21 Sep 2010 10:22:06 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2184 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chcond.c | 20 ++++++++++++++++++-- os/kernel/src/chdebug.c | 2 ++ os/kernel/src/chevents.c | 30 ++++++++++++++++++++++++++++++ os/kernel/src/chheap.c | 11 ++++++++++- os/kernel/src/chlists.c | 29 ++++++++++++++++++----------- os/kernel/src/chmboxes.c | 18 ++++++++++++++++-- os/kernel/src/chmemcore.c | 9 ++++++++- os/kernel/src/chmempools.c | 12 ++++++++++-- os/kernel/src/chmsg.c | 8 ++++++++ os/kernel/src/chmtx.c | 18 ++++++++++++++++-- os/kernel/src/chqueues.c | 32 ++++++++++++++++++++++++-------- os/kernel/src/chregistry.c | 4 ++++ os/kernel/src/chschd.c | 17 ++++++++++++++++- os/kernel/src/chsem.c | 22 ++++++++++++++++++++-- os/kernel/src/chsys.c | 7 ++++++- os/kernel/src/chthreads.c | 34 +++++++++++++++++++++++++++++++++- os/kernel/src/chvt.c | 8 ++++++++ 17 files changed, 247 insertions(+), 34 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c index 71729139f..0ad9d459d 100644 --- a/os/kernel/src/chcond.c +++ b/os/kernel/src/chcond.c @@ -43,10 +43,10 @@ /** * @brief Initializes s @p CondVar structure. - * @note This function can be invoked before the kernel is initialized - * because it just prepares a @p CondVar structure. * * @param[out] cp pointer to a @p CondVar structure + * + * @init */ void chCondInit(CondVar *cp) { @@ -59,6 +59,8 @@ void chCondInit(CondVar *cp) { * @brief Signals one thread that is waiting on the condition variable. * * @param[in] cp pointer to the @p CondVar structure + * + * @api */ void chCondSignal(CondVar *cp) { @@ -78,6 +80,8 @@ void chCondSignal(CondVar *cp) { * reschedule must not be performed in ISRs. * * @param[in] cp pointer to the @p CondVar structure + * + * @iclass */ void chCondSignalI(CondVar *cp) { @@ -91,6 +95,8 @@ void chCondSignalI(CondVar *cp) { * @brief Signals all threads that are waiting on the condition variable. * * @param[in] cp pointer to the @p CondVar structure + * + * @api */ void chCondBroadcast(CondVar *cp) { @@ -108,6 +114,8 @@ void chCondBroadcast(CondVar *cp) { * reschedule must not be performed in ISRs. * * @param[in] cp pointer to the @p CondVar structure + * + * @iclass */ void chCondBroadcastI(CondVar *cp) { @@ -134,6 +142,8 @@ void chCondBroadcastI(CondVar *cp) { * @p chCondSignal(). * @retval RDY_RESET if the condvar has been signaled using * @p chCondBroadcast(). + * + * @api */ msg_t chCondWait(CondVar *cp) { msg_t msg; @@ -158,6 +168,8 @@ msg_t chCondWait(CondVar *cp) { * @p chCondSignal(). * @retval RDY_RESET if the condvar has been signaled using * @p chCondBroadcast(). + * + * @sclass */ msg_t chCondWaitS(CondVar *cp) { Thread *ctp = currp; @@ -204,6 +216,8 @@ msg_t chCondWaitS(CondVar *cp) { * @p chCondBroadcast(). * @retval RDY_TIMEOUT if the condvar has not been signaled within the * specified timeout. + * + * @api */ msg_t chCondWaitTimeout(CondVar *cp, systime_t time) { msg_t msg; @@ -239,6 +253,8 @@ msg_t chCondWaitTimeout(CondVar *cp, systime_t time) { * @p chCondBroadcast(). * @retval RDY_TIMEOUT if the condvar has not been signaled within the * specified timeout. + * + * @sclass */ msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time) { Mutex *mp; diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index dcf42c2b3..80323e183 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -55,6 +55,8 @@ void trace_init(void) { * @brief Inserts in the circular debug trace buffer a context switch record. * * @param[in] otp the thread being switched out + * + * @notapi */ void chDbgTrace(Thread *otp) { diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index aac3a22af..a66a7fa28 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -68,6 +68,8 @@ * @param[in] elp pointer to the @p EventListener structure * @param[in] mask the mask of event flags to be ORed to the thread when * the event source is broadcasted + * + * @api */ void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t mask) { @@ -91,6 +93,8 @@ void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t mask) { * * @param[in] esp pointer to the @p EventSource structure * @param[in] elp pointer to the @p EventListener structure + * + * @api */ void chEvtUnregister(EventSource *esp, EventListener *elp) { EventListener *p; @@ -114,6 +118,8 @@ void chEvtUnregister(EventSource *esp, EventListener *elp) { * * @param[in] mask the events to be cleared * @return The pending events that were cleared. + * + * @api */ eventmask_t chEvtClearFlags(eventmask_t mask) { eventmask_t m; @@ -133,6 +139,8 @@ eventmask_t chEvtClearFlags(eventmask_t mask) { * * @param[in] mask the event flags to be ORed * @return The current pending events mask. + * + * @api */ eventmask_t chEvtAddFlags(eventmask_t mask) { @@ -149,6 +157,8 @@ eventmask_t chEvtAddFlags(eventmask_t mask) { * * @param[in] tp the thread to be signaled * @param[in] mask the event flags set to be ORed + * + * @api */ void chEvtSignal(Thread *tp, eventmask_t mask) { @@ -169,6 +179,8 @@ void chEvtSignal(Thread *tp, eventmask_t mask) { * * @param[in] tp the thread to be signaled * @param[in] mask the event flags set to be ORed + * + * @iclass */ void chEvtSignalI(Thread *tp, eventmask_t mask) { @@ -188,6 +200,8 @@ void chEvtSignalI(Thread *tp, eventmask_t mask) { * Source. * * @param[in] esp pointer to the @p EventSource structure + * + * @api */ void chEvtBroadcast(EventSource *esp) { @@ -206,6 +220,8 @@ void chEvtBroadcast(EventSource *esp) { * reschedule must not be performed in ISRs. * * @param[in] esp pointer to the @p EventSource structure + * + * @iclass */ void chEvtBroadcastI(EventSource *esp) { EventListener *elp; @@ -225,6 +241,8 @@ void chEvtBroadcastI(EventSource *esp) { * @param[in] mask mask of the event flags to be dispatched * @param[in] handlers an array of @p evhandler_t. The array must have size * equal to the number of bits in eventmask_t. + * + * @api */ void chEvtDispatch(const evhandler_t *handlers, eventmask_t mask) { eventid_t eid; @@ -258,6 +276,8 @@ void chEvtDispatch(const evhandler_t *handlers, eventmask_t mask) { * @param[in] mask mask of the event flags that the function should wait * for, @p ALL_EVENTS enables all the events * @return The mask of the lowest id served and cleared event. + * + * @api */ eventmask_t chEvtWaitOne(eventmask_t mask) { Thread *ctp = currp; @@ -285,6 +305,8 @@ eventmask_t chEvtWaitOne(eventmask_t mask) { * @param[in] mask mask of the event flags that the function should wait * for, @p ALL_EVENTS enables all the events * @return The mask of the served and cleared events. + * + * @api */ eventmask_t chEvtWaitAny(eventmask_t mask) { Thread *ctp = currp; @@ -311,6 +333,8 @@ eventmask_t chEvtWaitAny(eventmask_t mask) { * @param[in] mask mask of the event flags that the function should wait * for, @p ALL_EVENTS requires all the events * @return The mask of the served and cleared events. + * + * @api */ eventmask_t chEvtWaitAll(eventmask_t mask) { Thread *ctp = currp; @@ -348,6 +372,8 @@ eventmask_t chEvtWaitAll(eventmask_t mask) { * . * @return The mask of the lowest id served and cleared event. * @retval 0 if the operation has timed out. + * + * @api */ eventmask_t chEvtWaitOneTimeout(eventmask_t mask, systime_t time) { Thread *ctp = currp; @@ -385,6 +411,8 @@ eventmask_t chEvtWaitOneTimeout(eventmask_t mask, systime_t time) { * . * @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 time) { Thread *ctp = currp; @@ -420,6 +448,8 @@ eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t time) { * . * @return The mask of the served and cleared events. * @retval 0 if the operation has timed out. + * + * @api */ eventmask_t chEvtWaitAllTimeout(eventmask_t mask, systime_t time) { Thread *ctp = currp; diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c index fc92e3c18..13db7cf6b 100644 --- a/os/kernel/src/chheap.c +++ b/os/kernel/src/chheap.c @@ -61,7 +61,8 @@ static MemoryHeap default_heap; /** * @brief Initializes the default heap. - * @note Internal use only. + * + * @notapi */ void heap_init(void) { default_heap.h_provider = chCoreAlloc; @@ -82,6 +83,8 @@ void heap_init(void) { * @param[out] heapp pointer to the memory heap descriptor to be initialized * @param[in] buf heap buffer base * @param[in] size heap size + * + * @init */ void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) { union heap_header *hp; @@ -113,6 +116,8 @@ void chHeapInit(MemoryHeap *heapp, void *buf, size_t size) { * size for alignment and fragmentation reasons. * @return A pointer to the allocated block. * @retval NULL if the block cannot be allocated. + * + * @api */ void *chHeapAlloc(MemoryHeap *heapp, size_t size) { union heap_header *qp, *hp, *fp; @@ -173,6 +178,8 @@ void *chHeapAlloc(MemoryHeap *heapp, size_t size) { * @brief Frees a previously allocated memory block. * * @param[in] p pointer to the memory block to be freed + * + * @api */ void chHeapFree(void *p) { union heap_header *qp, *hp; @@ -227,6 +234,8 @@ void chHeapFree(void *p) { * @param[in] sizep pointer to a variable that will receive the total * fragmented free space * @return The number of fragments in the heap. + * + * @api */ size_t chHeapStatus(MemoryHeap *heapp, size_t *sizep) { union heap_header *qp; diff --git a/os/kernel/src/chlists.c b/os/kernel/src/chlists.c index 83bdf8b35..878f1360c 100644 --- a/os/kernel/src/chlists.c +++ b/os/kernel/src/chlists.c @@ -23,7 +23,7 @@ * * @addtogroup internals * @details All the functions present in this module, while public, are not - * an OS API and should not be directly used in the user applications + * OS APIs and should not be directly used in the user applications * code. * @{ */ @@ -32,12 +32,13 @@ #if !CH_OPTIMIZE_SPEED || defined(__DOXYGEN__) /** * @brief Inserts a thread into a priority ordered queue. - * @note The insertion is done by scanning the list from the highest priority - * toward the lowest. - * @note This function is @b not an API. + * @note The insertion is done by scanning the list from the highest + * priority toward the lowest. * * @param[in] tp the pointer to the thread to be inserted in the list * @param[in] tqp the pointer to the threads list header + * + * @notapi */ void prio_insert(Thread *tp, ThreadsQueue *tqp) { @@ -56,10 +57,11 @@ void prio_insert(Thread *tp, ThreadsQueue *tqp) { /** * @brief Inserts a Thread into a queue. - * @note This function is @b not an API. * * @param[in] tp the pointer to the thread to be inserted in the list * @param[in] tqp the pointer to the threads list header + * + * @notapi */ void queue_insert(Thread *tp, ThreadsQueue *tqp) { @@ -72,10 +74,11 @@ void queue_insert(Thread *tp, ThreadsQueue *tqp) { * @brief Removes the first-out Thread from a queue and returns it. * @note If the queue is priority ordered then this function returns the * thread with the highest priority. - * @note This function is @b not an API. * * @param[in] tqp the pointer to the threads list header * @return The removed thread pointer. + * + * @notapi */ Thread *fifo_remove(ThreadsQueue *tqp) { Thread *tp = tqp->p_next; @@ -88,10 +91,11 @@ Thread *fifo_remove(ThreadsQueue *tqp) { * @brief Removes the last-out Thread from a queue and returns it. * @note If the queue is priority ordered then this function returns the * thread with the lowest priority. - * @note This function is @b not an API. * * @param[in] tqp the pointer to the threads list header * @return The removed thread pointer. + * + * @notapi */ Thread *lifo_remove(ThreadsQueue *tqp) { Thread *tp = tqp->p_prev; @@ -104,10 +108,11 @@ Thread *lifo_remove(ThreadsQueue *tqp) { * @brief Removes a Thread from a queue and returns it. * @details The thread is removed from the queue regardless of its relative * position and regardless the used insertion method. - * @note This function is @b not an API. * * @param[in] tp the pointer to the thread to be removed from the queue * @return The removed thread pointer. + * + * @notapi */ Thread *dequeue(Thread *tp) { @@ -118,10 +123,11 @@ Thread *dequeue(Thread *tp) { /** * @brief Pushes a Thread on top of a stack list. - * @note This function is @b not an API. * * @param[in] tp the pointer to the thread to be inserted in the list * @param[in] tlp the pointer to the threads list header + * + * @notapi */ void list_insert(Thread *tp, ThreadsList *tlp) { @@ -131,11 +137,12 @@ void list_insert(Thread *tp, ThreadsList *tlp) { /** * @brief Pops a Thread from the top of a stack list and returns it. - * @note The list must be non-empty before calling this function. - * @note This function is @b not an API. + * @pre The list must be non-empty before calling this function. * * @param[in] tlp the pointer to the threads list header * @return The removed thread pointer. + * + * @notapi */ Thread *list_remove(ThreadsList *tlp) { diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c index 279778e48..b2cef2470 100644 --- a/os/kernel/src/chmboxes.c +++ b/os/kernel/src/chmboxes.c @@ -54,12 +54,12 @@ #if CH_USE_MAILBOXES || defined(__DOXYGEN__) /** * @brief Initializes a Mailbox object. - * @note This function can be invoked before the kernel is initialized - * because it just prepares a @p Mailbox structure. * * @param[out] mbp the pointer to the Mailbox structure to be initialized * @param[in] buf the circular messages buffer * @param[in] n the buffer size as number of @p msg_t + * + * @init */ void chMBInit(Mailbox *mbp, msg_t *buf, cnt_t n) { @@ -77,6 +77,8 @@ void chMBInit(Mailbox *mbp, msg_t *buf, cnt_t n) { * the queued messages are lost. * * @param[in] mbp the pointer to an initialized Mailbox object + * + * @api */ void chMBReset(Mailbox *mbp) { @@ -106,6 +108,8 @@ void chMBReset(Mailbox *mbp) { * @retval RDY_OK if a message has been correctly posted. * @retval RDY_RESET if the mailbox has been reset while waiting. * @retval RDY_TIMEOUT if the operation has timed out. + * + * @api */ msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t time) { msg_t rdymsg; @@ -132,6 +136,8 @@ msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t time) { * @retval RDY_OK if a message has been correctly posted. * @retval RDY_RESET if the mailbox has been reset while waiting. * @retval RDY_TIMEOUT if the operation has timed out. + * + * @sclass */ msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) { msg_t rdymsg; @@ -165,6 +171,8 @@ msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) { * @retval RDY_OK if a message has been correctly posted. * @retval RDY_RESET if the mailbox has been reset while waiting. * @retval RDY_TIMEOUT if the operation has timed out. + * + * @api */ msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t time) { msg_t rdymsg; @@ -191,6 +199,8 @@ msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t time) { * @retval RDY_OK if a message has been correctly posted. * @retval RDY_RESET if the mailbox has been reset while waiting. * @retval RDY_TIMEOUT if the operation has timed out. + * + * @sclass */ msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) { msg_t rdymsg; @@ -224,6 +234,8 @@ msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) { * @retval RDY_OK if a message has been correctly fetched. * @retval RDY_RESET if the mailbox has been reset while waiting. * @retval RDY_TIMEOUT if the operation has timed out. + * + * @api */ msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t time) { msg_t rdymsg; @@ -250,6 +262,8 @@ msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t time) { * @retval RDY_OK if a message has been correctly fetched. * @retval RDY_RESET if the mailbox has been reset while waiting. * @retval RDY_TIMEOUT if the operation has timed out. + * + * @sclass */ msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t time) { msg_t rdymsg; diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index 04edb7dae..69d3014a5 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -50,7 +50,8 @@ static uint8_t *endmem; /** * @brief Low level memory manager initialization. - * @note Internal use only. + * + * @notapi */ void core_init(void) { #if CH_MEMCORE_SIZE == 0 @@ -76,6 +77,8 @@ void core_init(void) { * @param[in] size the size of the block to be allocated * @return A pointer to the allocated memory block. * @retval NULL allocation failed, core memory exhausted. + * + * @api */ void *chCoreAlloc(size_t size) { void *p; @@ -95,6 +98,8 @@ void *chCoreAlloc(size_t size) { * @param[in] size the size of the block to be allocated. * @return A pointer to the allocated memory block. * @retval NULL allocation failed, core memory exhausted. + * + * @iclass */ void *chCoreAllocI(size_t size) { void *p; @@ -111,6 +116,8 @@ void *chCoreAllocI(size_t size) { * @brief Core memory status. * * @return The size, in bytes, of the free core memory. + * + * @api */ size_t chCoreStatus(void) { diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c index e1817aa60..092944b59 100644 --- a/os/kernel/src/chmempools.c +++ b/os/kernel/src/chmempools.c @@ -37,8 +37,6 @@ #if CH_USE_MEMPOOLS || defined(__DOXYGEN__) /** * @brief Initializes an empty memory pool. - * @note This function can be invoked before the kernel is initialized - * because it just prepares a @p MemoryPool structure. * @note The size is internally aligned to be a multiple of the * @p stkalign_t type size. * @@ -49,6 +47,8 @@ * @param[in] provider memory provider function for the memory pool or * @p NULL if the pool is not allowed to grow * automatically + * + * @init */ void chPoolInit(MemoryPool *mp, size_t size, memgetfunc_t provider) { @@ -65,6 +65,8 @@ void chPoolInit(MemoryPool *mp, size_t size, memgetfunc_t provider) { * @param[in] mp pointer to a @p MemoryPool structure * @return The pointer to the allocated object. * @retval NULL if pool is empty. + * + * @iclass */ void *chPoolAllocI(MemoryPool *mp) { void *objp; @@ -86,6 +88,8 @@ void *chPoolAllocI(MemoryPool *mp) { * @param[in] mp pointer to a @p MemoryPool structure * @return The pointer to the allocated object. * @retval NULL if pool is empty. + * + * @api */ void *chPoolAlloc(MemoryPool *mp) { void *objp; @@ -105,6 +109,8 @@ void *chPoolAlloc(MemoryPool *mp) { * * @param[in] mp pointer to a @p MemoryPool structure * @param[in] objp the pointer to the object to be released or added + * + * @iclass */ void chPoolFreeI(MemoryPool *mp, void *objp) { struct pool_header *php = objp; @@ -125,6 +131,8 @@ void chPoolFreeI(MemoryPool *mp, void *objp) { * * @param[in] mp pointer to a @p MemoryPool structure * @param[in] objp the pointer to the object to be released or added + * + * @api */ void chPoolFree(MemoryPool *mp, void *objp) { diff --git a/os/kernel/src/chmsg.c b/os/kernel/src/chmsg.c index 09acf7b42..c3b4848b0 100644 --- a/os/kernel/src/chmsg.c +++ b/os/kernel/src/chmsg.c @@ -61,6 +61,8 @@ * @param[in] tp the pointer to the thread * @param[in] msg the message * @return The answer message from @p chMsgRelease(). + * + * @api */ msg_t chMsgSend(Thread *tp, msg_t msg) { Thread *ctp = currp; @@ -88,6 +90,8 @@ msg_t chMsgSend(Thread *tp, msg_t msg) { * because the sending thread is suspended until then. * * @return The message. + * + * @api */ msg_t chMsgWait(void) { msg_t msg; @@ -114,6 +118,8 @@ msg_t chMsgWait(void) { * * @return The message. * @retval 0 if the queue is empty. + * + * @api */ msg_t chMsgGet(void) { msg_t msg; @@ -130,6 +136,8 @@ msg_t chMsgGet(void) { * using @p chMsgWait() or @p chMsgGet(). * * @param[in] msg the message returned to the message sender + * + * @api */ void chMsgRelease(msg_t msg) { diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 9698d3cd8..b84c4d57e 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -70,10 +70,10 @@ /** * @brief Initializes s @p Mutex structure. - * @note This function can be invoked before the kernel is initialized - * because it just prepares a @p Mutex structure. * * @param[out] mp pointer to a @p Mutex structure + * + * @init */ void chMtxInit(Mutex *mp) { @@ -89,6 +89,8 @@ void chMtxInit(Mutex *mp) { * mutexes. * * @param[in] mp pointer to the @p Mutex structure + * + * @api */ void chMtxLock(Mutex *mp) { @@ -105,6 +107,8 @@ void chMtxLock(Mutex *mp) { * mutexes. * * @param[in] mp pointer to the @p Mutex structure + * + * @sclass */ void chMtxLockS(Mutex *mp) { Thread *ctp = currp; @@ -184,6 +188,8 @@ void chMtxLockS(Mutex *mp) { * @return The operation status. * @retval TRUE if the mutex has been successfully acquired * @retval FALSE if the lock attempt failed. + * + * @api */ bool_t chMtxTryLock(Mutex *mp) { bool_t b; @@ -210,6 +216,8 @@ bool_t chMtxTryLock(Mutex *mp) { * @return The operation status. * @retval TRUE if the mutex has been successfully acquired * @retval FALSE if the lock attempt failed. + * + * @sclass */ bool_t chMtxTryLockS(Mutex *mp) { @@ -230,6 +238,8 @@ bool_t chMtxTryLockS(Mutex *mp) { * owned mutexes. * * @return A pointer to the unlocked mutex. + * + * @api */ Mutex *chMtxUnlock(void) { Thread *ctp = currp; @@ -288,6 +298,8 @@ Mutex *chMtxUnlock(void) { * function must be performed before unlocking the kernel. * * @return A pointer to the unlocked mutex. + * + * @sclass */ Mutex *chMtxUnlockS(void) { Thread *ctp = currp; @@ -342,6 +354,8 @@ Mutex *chMtxUnlockS(void) { * mutexes one by one and not just because the call overhead, * this function does not have any overhead related to the priority * inheritance mechanism. + * + * @api */ void chMtxUnlockAll(void) { Thread *ctp = currp; diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index 485984fdf..b02fa6a64 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -50,8 +50,6 @@ * @brief Initializes an input queue. * @details A Semaphore is internally initialized and works as a counter of * the bytes contained in the queue. - * @note This function can be invoked before the kernel is initialized - * because it just prepares a @p InputQueue structure. * @note The callback is invoked from within the S-Locked system state, * see @ref system_states. * @@ -60,6 +58,8 @@ * @param[in] size size of the queue buffer * @param[in] infy pointer to a callback function that is invoked when * data is read from the queue. The value can be @p NULL. + * + * @init */ void chIQInit(InputQueue *iqp, uint8_t *bp, size_t size, qnotify_t infy) { @@ -77,6 +77,8 @@ void chIQInit(InputQueue *iqp, uint8_t *bp, size_t size, qnotify_t infy) { * obtain immediate attention from the high level layers. * * @param[in] iqp pointer to an @p InputQueue structure + * + * @iclass */ void chIQResetI(InputQueue *iqp) { @@ -94,10 +96,12 @@ void chIQResetI(InputQueue *iqp) { * @retval Q_OK if the operation has been completed with success. * @retval Q_FULL if the queue is full and the operation cannot be * completed. + * + * @iclass */ msg_t chIQPutI(InputQueue *iqp, uint8_t b) { - if (chIQIsFull(iqp)) + if (chIQIsFullI(iqp)) return Q_FULL; *iqp->q_wrptr++ = b; @@ -122,6 +126,8 @@ msg_t chIQPutI(InputQueue *iqp, uint8_t b) { * @return A byte value from the queue. * @retval Q_TIMEOUT if the specified time expired. * @retval Q_RESET if the queue was reset. + * + * @api */ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) { uint8_t b; @@ -165,6 +171,8 @@ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) { * - @a TIME_INFINITE no timeout. * . * @return The number of bytes effectively transferred. + * + * @api */ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, size_t n, systime_t time) { @@ -175,7 +183,7 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, chSysLock(); while (TRUE) { - if (chIQIsEmpty(iqp)) { + if (chIQIsEmptyI(iqp)) { if (nfy) nfy(); if ((chSemWaitTimeoutS(&iqp->q_sem, time) != RDY_OK)) { @@ -207,8 +215,6 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, * @brief Initializes an output queue. * @details A Semaphore is internally initialized and works as a counter of * the free bytes in the queue. - * @note This function can be invoked before the kernel is initialized - * because it just prepares a @p OutputQueue structure. * @note The callback is invoked from within the S-Locked system state, * see @ref system_states. * @@ -217,6 +223,8 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, * @param[in] size size of the queue buffer * @param[in] onfy pointer to a callback function that is invoked when * data is written to the queue. The value can be @p NULL. + * + * @init */ void chOQInit(OutputQueue *oqp, uint8_t *bp, size_t size, qnotify_t onfy) { @@ -234,6 +242,8 @@ void chOQInit(OutputQueue *oqp, uint8_t *bp, size_t size, qnotify_t onfy) { * obtain immediate attention from the high level layers. * * @param[in] oqp pointer to an @p OutputQueue structure + * + * @iclass */ void chOQResetI(OutputQueue *oqp) { @@ -258,6 +268,8 @@ void chOQResetI(OutputQueue *oqp) { * @retval Q_OK if the operation succeeded. * @retval Q_TIMEOUT if the specified time expired. * @retval Q_RESET if the queue was reset. + * + * @api */ msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t time) { msg_t msg; @@ -285,11 +297,13 @@ msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t time) { * @param[in] oqp pointer to an @p OutputQueue structure * @return The byte value from the queue. * @retval Q_EMPTY if the queue is empty. + * + * @iclass */ msg_t chOQGetI(OutputQueue *oqp) { uint8_t b; - if (chOQIsEmpty(oqp)) + if (chOQIsEmptyI(oqp)) return Q_EMPTY; b = *oqp->q_rdptr++; @@ -320,6 +334,8 @@ msg_t chOQGetI(OutputQueue *oqp) { * - @a TIME_INFINITE no timeout. * . * @return The number of bytes effectively transferred. + * + * @api */ size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp, size_t n, systime_t time) { @@ -330,7 +346,7 @@ size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp, chSysLock(); while (TRUE) { - if (chOQIsFull(oqp)) { + if (chOQIsFullI(oqp)) { if (nfy) nfy(); if ((chSemWaitTimeoutS(&oqp->q_sem, time) != RDY_OK)) { diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c index 216758c85..95893de85 100644 --- a/os/kernel/src/chregistry.c +++ b/os/kernel/src/chregistry.c @@ -58,6 +58,8 @@ * least one thread in the system. * * @return A reference to the most ancient thread. + * + * @api */ Thread *chRegFirstThread(void) { Thread *tp; @@ -79,6 +81,8 @@ Thread *chRegFirstThread(void) { * @param[in] tp pointer to the thread * @return A reference to the next thread. * @retval NULL if there is no next thread. + * + * @api */ Thread *chRegNextThread(Thread *tp) { Thread *ntp; diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 213d999ce..c7db9ad60 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -41,7 +41,8 @@ ReadyList rlist; /** * @brief Scheduler initialization. - * @note Internally invoked by the @p chSysInit(), not an API. + * + * @notapi */ void scheduler_init(void) { @@ -66,6 +67,8 @@ void scheduler_init(void) { * * @param[in] tp the thread to be made ready * @return The thread pointer. + * + * @iclass */ #if !defined(PORT_OPTIMIZED_READYI) || defined(__DOXYGEN__) #if CH_OPTIMIZE_SPEED @@ -101,6 +104,8 @@ Thread *chSchReadyI(Thread *tp) { * @ref thread_states are defined into @p threads.h. * * @param[in] newstate the new thread state + * + * @sclass */ #if !defined(PORT_OPTIMIZED_GOSLEEPS) || defined(__DOXYGEN__) void chSchGoSleepS(tstate_t newstate) { @@ -163,6 +168,8 @@ static void wakeup(void *p) { * . * @return The wakeup message. * @retval RDY_TIMEOUT if a timeout occurs. + * + * @sclass */ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { @@ -194,6 +201,8 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { * * @param[in] ntp the Thread to be made ready * @param[in] msg message to the awakened thread + * + * @sclass */ #if !defined(PORT_OPTIMIZED_WAKEUPS) || defined(__DOXYGEN__) void chSchWakeupS(Thread *ntp, msg_t msg) { @@ -222,6 +231,8 @@ void chSchWakeupS(Thread *ntp, msg_t msg) { * @brief Switches to the first thread on the runnable queue. * @note It is intended to be called if @p chSchRescRequiredI() evaluates * to @p TRUE. + * + * @iclass */ #if !defined(PORT_OPTIMIZED_DORESCHEDULEI) || defined(__DOXYGEN__) void chSchDoRescheduleI(void) { @@ -244,6 +255,8 @@ void chSchDoRescheduleI(void) { * @brief Performs a reschedule if a higher priority thread is runnable. * @details If a thread with a higher priority than the current thread is in * the ready list then make the higher priority thread running. + * + * @iclass */ #if !defined(PORT_OPTIMIZED_RESCHEDULES) || defined(__DOXYGEN__) void chSchRescheduleS(void) { @@ -262,6 +275,8 @@ void chSchRescheduleS(void) { * * @retval TRUE if there is a thread that should go in running state. * @retval FALSE if a reschedule is not required. + * + * @iclass */ #if !defined(PORT_OPTIMIZED_ISRESCHREQUIREDEXI) || defined(__DOXYGEN__) bool_t chSchIsRescRequiredExI(void) { diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index 750402266..58cd94808 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -68,12 +68,12 @@ /** * @brief Initializes a semaphore with the specified counter value. - * @note This function can be invoked before the kernel is initialized - * because it just prepares a @p Semaphore structure. * * @param[out] sp pointer to a @p Semaphore structure * @param[in] n initial value of the semaphore counter. Must be * non-negative. + * + * @init */ void chSemInit(Semaphore *sp, cnt_t n) { @@ -95,6 +95,8 @@ void chSemInit(Semaphore *sp, cnt_t n) { * @param[in] sp pointer to a @p Semaphore structure * @param[in] n the new value of the semaphore counter. The value must * be non-negative. + * + * @api */ void chSemReset(Semaphore *sp, cnt_t n) { @@ -120,6 +122,8 @@ void chSemReset(Semaphore *sp, cnt_t n) { * @param[in] sp pointer to a @p Semaphore structure * @param[in] n the new value of the semaphore counter. The value must * be non-negative. + * + * @iclass */ void chSemResetI(Semaphore *sp, cnt_t n) { cnt_t cnt; @@ -146,6 +150,8 @@ void chSemResetI(Semaphore *sp, cnt_t n) { * @retval RDY_OK if the thread has not stopped on the semaphore or the * semaphore has been signaled. * @retval RDY_RESET if the semaphore has been reset using @p chSemReset(). + * + * @api */ msg_t chSemWait(Semaphore *sp) { msg_t msg; @@ -165,6 +171,8 @@ msg_t chSemWait(Semaphore *sp) { * @retval RDY_OK if the thread has not stopped on the semaphore or the * semaphore has been signaled. * @retval RDY_RESET if the semaphore has been reset using @p chSemReset(). + * + * @sclass */ msg_t chSemWaitS(Semaphore *sp) { @@ -200,6 +208,8 @@ msg_t chSemWaitS(Semaphore *sp) { * @retval RDY_RESET if the semaphore has been reset using @p chSemReset(). * @retval RDY_TIMEOUT if the semaphore has not been signaled or reset within * the specified timeout. + * + * @api */ msg_t chSemWaitTimeout(Semaphore *sp, systime_t time) { msg_t msg; @@ -226,6 +236,8 @@ msg_t chSemWaitTimeout(Semaphore *sp, systime_t time) { * @retval RDY_RESET if the semaphore has been reset using @p chSemReset(). * @retval RDY_TIMEOUT if the semaphore has not been signaled or reset within * the specified timeout. + * + * @sclass */ msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) { @@ -252,6 +264,8 @@ msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) { * @brief Performs a signal operation on a semaphore. * * @param[in] sp pointer to a @p Semaphore structure + * + * @api */ void chSemSignal(Semaphore *sp) { @@ -276,6 +290,8 @@ void chSemSignal(Semaphore *sp) { * reschedule must not be performed in ISRs. * * @param[in] sp pointer to a @p Semaphore structure + * + * @iclass */ void chSemSignalI(Semaphore *sp) { @@ -308,6 +324,8 @@ void chSemSignalI(Semaphore *sp) { * @retval RDY_OK if the thread has not stopped on the semaphore or the * semaphore has been signaled. * @retval RDY_RESET if the semaphore has been reset using @p chSemReset(). + * + * @api */ msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw) { msg_t msg; diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 809212a7b..a567b73da 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -66,6 +66,10 @@ void _idle_thread(void *p) { * @pre Interrupts must be still disabled when @p chSysInit() is invoked * and are internally enabled. * @post The main thread is created with priority @p NORMALPRIO. + * @note This function has special, architecture-dependent, requirements, + * see the notes into the various port reference manuals. + * + * @special */ void chSysInit(void) { static Thread mainthread; @@ -100,10 +104,11 @@ void chSysInit(void) { * @details Decrements the remaining time quantum of the running thread * and preempts it when the quantum is used up. Increments system * time and manages the timers. - * * @note The frequency of the timer determines the system tick granularity * and, together with the @p CH_TIME_QUANTUM macro, the round robin * interval. + * + * @iclass */ void chSysTimerHandlerI(void) { diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 5bcadb96d..c4aa7437c 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -64,6 +64,8 @@ * @param[in] tp pointer to the thread * @param[in] prio the priority level for the new thread * @return The same thread pointer passed as parameter. + * + * @notapi */ Thread *init_thread(Thread *tp, tprio_t prio) { @@ -128,6 +130,8 @@ static void memfill(uint8_t *startp, uint8_t *endp, uint8_t v) { * @p NULL. * @return The pointer to the @p Thread structure allocated for * the thread into the working space area. + * + * @api */ Thread *chThdInit(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) { /* Thread structure is layed out in the lower part of the thread workspace */ @@ -158,6 +162,8 @@ Thread *chThdInit(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) { * @p NULL. * @return The pointer to the @p Thread structure allocated for * the thread into the working space area. + * + * @api */ Thread *chThdCreateStatic(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) { @@ -185,6 +191,8 @@ Thread *chThdCreateStatic(void *wsp, size_t size, * @return The pointer to the @p Thread structure allocated for * the thread into the working space area. * @retval NULL if the memory cannot be allocated. + * + * @api */ Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size, tprio_t prio, tfunc_t pf, void *arg) { @@ -219,6 +227,8 @@ Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size, * @return The pointer to the @p Thread structure allocated for * the thread into the working space area. * @retval NULL if the memory pool is empty. + * + * @api */ Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, tfunc_t pf, void *arg) { @@ -246,6 +256,8 @@ Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, * * @param[in] newprio the new priority level of the running thread * @return The old priority level. + * + * @api */ tprio_t chThdSetPriority(tprio_t newprio) { tprio_t oldprio; @@ -278,6 +290,8 @@ tprio_t chThdSetPriority(tprio_t newprio) { * * @param[in] tp pointer to the thread * @return The pointer to the thread. + * + * @api */ Thread *chThdResume(Thread *tp) { @@ -299,6 +313,8 @@ Thread *chThdResume(Thread *tp) { * condition. * * @param[in] tp pointer to the thread + * + * @api */ void chThdTerminate(Thread *tp) { @@ -318,6 +334,8 @@ void chThdTerminate(Thread *tp) { * interpreted as a normal time specification not as an * immediate timeout specification. * . + * + * @api */ void chThdSleep(systime_t time) { @@ -333,6 +351,8 @@ void chThdSleep(systime_t time) { * specified value. * * @param[in] time absolute system time + * + * @api */ void chThdSleepUntil(systime_t time) { @@ -346,6 +366,8 @@ void chThdSleepUntil(systime_t time) { * @brief Yields the time slot. * @details Yields the CPU control to the next thread in the ready list with * equal priority, if any. + * + * @api */ void chThdYield(void) { @@ -360,9 +382,13 @@ void chThdYield(void) { * specified exit status code, other threads can retrieve the * exit status code by invoking the function @p chThdWait(). * @post Eventual code after this function will never be executed, - * this function never returns. + * this function never returns. The compiler has no way to + * know this so do not assume that the compiler would remove + * the dead code. * * @param[in] msg thread exit code + * + * @api */ void chThdExit(msg_t msg) { Thread *tp = currp; @@ -391,6 +417,8 @@ void chThdExit(msg_t msg) { * @param[in] tp pointer to the thread * @return The same thread pointer passed as parameter * representing the new reference. + * + * @api */ Thread *chThdAddRef(Thread *tp) { @@ -411,6 +439,8 @@ Thread *chThdAddRef(Thread *tp) { * @note Static threads are not affected. * * @param[in] tp pointer to the thread + * + * @api */ void chThdRelease(Thread *tp) { trefs_t refs; @@ -469,6 +499,8 @@ void chThdRelease(Thread *tp) { * * @param[in] tp pointer to the thread * @return The exit code from the terminated thread. + * + * @api */ msg_t chThdWait(Thread *tp) { msg_t msg; diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c index 058433c09..070a9c620 100644 --- a/os/kernel/src/chvt.c +++ b/os/kernel/src/chvt.c @@ -36,6 +36,8 @@ VTList vtlist; /** * @brief Virtual Timers initialization. * @note Internal use only. + * + * @notapi */ void vt_init(void) { @@ -58,6 +60,8 @@ void vt_init(void) { * be disposed or reused. * @param[in] par a parameter that will be passed to the callback * function + * + * @iclass */ void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) { VirtualTimer *p; @@ -85,6 +89,8 @@ void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) { * @note The timer MUST be active when this function is invoked. * * @param[in] vtp the @p VirtualTimer structure pointer + * + * @iclass */ void chVTResetI(VirtualTimer *vtp) { @@ -110,6 +116,8 @@ void chVTResetI(VirtualTimer *vtp) { * @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_t chTimeIsWithin(systime_t start, systime_t end) { -- cgit v1.2.3 From 719e83e6e85e24242a95e9a4d48845fd5400dc5b Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 24 Sep 2010 17:31:31 +0000 Subject: Fixed bug 3074984, undone change to the virtual timers. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2186 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 9 ++++++--- os/kernel/src/chvt.c | 1 + 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index c7db9ad60..f12103324 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -143,9 +143,12 @@ static void wakeup(void *p) { dequeue(tp); } #endif - /* Done this way in order to allow a tail call.*/ - tp->p_u.rdymsg = RDY_TIMEOUT; - chSchReadyI(tp); + /* Handling the special case where the thread has been made ready by another + thread with higher priority.*/ + if (tp->p_state != THD_STATE_READY) { + tp->p_u.rdymsg = RDY_TIMEOUT; + chSchReadyI(tp); + } } /** diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c index 070a9c620..b622bb493 100644 --- a/os/kernel/src/chvt.c +++ b/os/kernel/src/chvt.c @@ -42,6 +42,7 @@ VTList vtlist; void vt_init(void) { vtlist.vt_next = vtlist.vt_prev = (void *)&vtlist; + vtlist.vt_time = (systime_t)-1; vtlist.vt_systime = 0; } -- cgit v1.2.3 From 5b3fec0235acc100600054917d9d393db189b5cb Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 24 Sep 2010 17:58:21 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2187 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index f12103324..ff10dbe2d 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -131,6 +131,10 @@ static void wakeup(void *p) { #if CH_USE_SEMAPHORES || (CH_USE_CONDVARS && CH_USE_CONDVARS_TIMEOUT) switch (tp->p_state) { + case THD_STATE_READY: + /* Handling the special case where the thread has been made ready by + another thread with higher priority.*/ + return; #if CH_USE_SEMAPHORES case THD_STATE_WTSEM: chSemFastSignalI((Semaphore *)tp->p_u.wtobjp); @@ -143,12 +147,8 @@ static void wakeup(void *p) { dequeue(tp); } #endif - /* Handling the special case where the thread has been made ready by another - thread with higher priority.*/ - if (tp->p_state != THD_STATE_READY) { - tp->p_u.rdymsg = RDY_TIMEOUT; - chSchReadyI(tp); - } + tp->p_u.rdymsg = RDY_TIMEOUT; + chSchReadyI(tp); } /** -- cgit v1.2.3 From 79b466c6f867a30e38ea2164a4f96b5ddba3d9e2 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 24 Sep 2010 18:05:46 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2188 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index ff10dbe2d..9adf656ff 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -129,12 +129,12 @@ void chSchGoSleepS(tstate_t newstate) { static void wakeup(void *p) { Thread *tp = (Thread *)p; -#if CH_USE_SEMAPHORES || (CH_USE_CONDVARS && CH_USE_CONDVARS_TIMEOUT) switch (tp->p_state) { case THD_STATE_READY: /* Handling the special case where the thread has been made ready by another thread with higher priority.*/ return; +#if CH_USE_SEMAPHORES || (CH_USE_CONDVARS && CH_USE_CONDVARS_TIMEOUT) #if CH_USE_SEMAPHORES case THD_STATE_WTSEM: chSemFastSignalI((Semaphore *)tp->p_u.wtobjp); @@ -145,8 +145,8 @@ static void wakeup(void *p) { #endif /* States requiring dequeuing.*/ dequeue(tp); - } #endif + } tp->p_u.rdymsg = RDY_TIMEOUT; chSchReadyI(tp); } -- cgit v1.2.3 From d97be800597f99b9a02c265a01c7902a07c45570 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 25 Sep 2010 15:46:22 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2199 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chthreads.c | 60 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 43 insertions(+), 17 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index c4aa7437c..237fd44fb 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -95,9 +95,7 @@ Thread *init_thread(Thread *tp, tprio_t prio) { queue_init(&tp->p_msgqueue); #endif #if CH_USE_REGISTRY - chSysLock(); REG_INSERT(tp); - chSysUnlock(); #endif #if defined(THREAD_EXT_EXIT_HOOK) THREAD_EXT_INIT_HOOK(tp); @@ -114,13 +112,16 @@ static void memfill(uint8_t *startp, uint8_t *endp, uint8_t v) { #endif /** - * @brief Initializes a new thread. + * @brief Creates a new thread into a static memory area. * @details The new thread is initialized but not inserted in the ready list, * the initial state is @p THD_STATE_SUSPENDED. * @post The initialized thread can be subsequently started by invoking * @p chThdResume(). * @note A thread can terminate by calling @p chThdExit() or by simply * returning from its main function. + * Threads created using this function do not obey to the + * @p CH_DBG_FILL_THREADS debug option because it would keep + * the kernel locked for too much time. * * @param[out] wsp pointer to a working area dedicated to the thread stack * @param[in] size size of the working area @@ -131,20 +132,16 @@ static void memfill(uint8_t *startp, uint8_t *endp, uint8_t v) { * @return The pointer to the @p Thread structure allocated for * the thread into the working space area. * - * @api + * @iclass */ -Thread *chThdInit(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) { +Thread *chThdCreateI(void *wsp, size_t size, + tprio_t prio, tfunc_t pf, void *arg) { /* Thread structure is layed out in the lower part of the thread workspace */ Thread *tp = wsp; chDbgCheck((wsp != NULL) && (size >= THD_WA_SIZE(0)) && (prio <= HIGHPRIO) && (pf != NULL), - "chThdInit"); -#if CH_DBG_FILL_THREADS - memfill((uint8_t *)wsp, (uint8_t *)wsp + sizeof(Thread), THREAD_FILL_VALUE); - memfill((uint8_t *)wsp + sizeof(Thread), - (uint8_t *)wsp + size, STACK_FILL_VALUE); -#endif + "chThdCreateI"); SETUP_CONTEXT(wsp, size, pf, arg); return init_thread(tp, prio); } @@ -167,8 +164,17 @@ Thread *chThdInit(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) { */ Thread *chThdCreateStatic(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) { - - return chThdResume(chThdInit(wsp, size, prio, pf, arg)); + Thread *tp; + +#if CH_DBG_FILL_THREADS + memfill((uint8_t *)wsp, (uint8_t *)wsp + sizeof(Thread), THREAD_FILL_VALUE); + memfill((uint8_t *)wsp + sizeof(Thread), + (uint8_t *)wsp + size, STACK_FILL_VALUE); +#endif + chSysLock(); + chSchWakeupS(tp = chThdCreateI(wsp, size, prio, pf, arg), RDY_OK); + chSysUnlock(); + return tp; } #if CH_USE_DYNAMIC && CH_USE_HEAP @@ -202,9 +208,19 @@ Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size, wsp = chHeapAlloc(heapp, size); if (wsp == NULL) return NULL; - tp = chThdInit(wsp, size, prio, pf, arg); + +#if CH_DBG_FILL_THREADS + memfill((uint8_t *)wsp, (uint8_t *)wsp + sizeof(Thread), THREAD_FILL_VALUE); + memfill((uint8_t *)wsp + sizeof(Thread), + (uint8_t *)wsp + size, STACK_FILL_VALUE); +#endif + + chSysLock(); + tp = chThdCreateI(wsp, size, prio, pf, arg); tp->p_flags = THD_MEM_MODE_HEAP; - return chThdResume(tp); + chSchWakeupS(tp, RDY_OK); + chSysUnlock(); + return tp; } #endif /* CH_USE_DYNAMIC && CH_USE_HEAP */ @@ -240,10 +256,20 @@ Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, wsp = chPoolAlloc(mp); if (wsp == NULL) return NULL; - tp = chThdInit(wsp, mp->mp_object_size, prio, pf, arg); + +#if CH_DBG_FILL_THREADS + memfill((uint8_t *)wsp, (uint8_t *)wsp + sizeof(Thread), THREAD_FILL_VALUE); + memfill((uint8_t *)wsp + sizeof(Thread), + (uint8_t *)wsp + size, STACK_FILL_VALUE); +#endif + + chSysLock(); + tp = chThdCreateI(wsp, mp->mp_object_size, prio, pf, arg); tp->p_flags = THD_MEM_MODE_MEMPOOL; tp->p_mpool = mp; - return chThdResume(tp); + chSchWakeupS(tp, RDY_OK); + chSysUnlock(); + return tp; } #endif /* CH_USE_DYNAMIC && CH_USE_MEMPOOLS */ -- cgit v1.2.3 From ad95e527ec5fe87a695555e9461e07881518e10c Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 25 Sep 2010 16:02:00 +0000 Subject: Fix to the fix... git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2201 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chthreads.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 237fd44fb..60d2397bd 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -260,7 +260,7 @@ Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, #if CH_DBG_FILL_THREADS memfill((uint8_t *)wsp, (uint8_t *)wsp + sizeof(Thread), THREAD_FILL_VALUE); memfill((uint8_t *)wsp + sizeof(Thread), - (uint8_t *)wsp + size, STACK_FILL_VALUE); + (uint8_t *)wsp + mp->mp_object_size, STACK_FILL_VALUE); #endif chSysLock(); -- cgit v1.2.3 From ae99c722b2306605d52583ff19ae4a3affe9b55e Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 26 Sep 2010 09:59:46 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2202 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chthreads.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 60d2397bd..8e7de6fab 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -119,7 +119,7 @@ static void memfill(uint8_t *startp, uint8_t *endp, uint8_t v) { * @p chThdResume(). * @note A thread can terminate by calling @p chThdExit() or by simply * returning from its main function. - * Threads created using this function do not obey to the + * @note Threads created using this function do not obey to the * @p CH_DBG_FILL_THREADS debug option because it would keep * the kernel locked for too much time. * -- cgit v1.2.3 From 012564866f8668143b4e35a5e50939af1c5374ae Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 26 Sep 2010 10:10:18 +0000 Subject: Documentation fixes to chThdCreateI(). git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2204 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chthreads.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 8e7de6fab..06451c18f 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -116,7 +116,8 @@ static void memfill(uint8_t *startp, uint8_t *endp, uint8_t v) { * @details The new thread is initialized but not inserted in the ready list, * the initial state is @p THD_STATE_SUSPENDED. * @post The initialized thread can be subsequently started by invoking - * @p chThdResume(). + * @p chThdResume(), @p chThdResumeI() or @p chSchWakeupS() + * depending on the execution context. * @note A thread can terminate by calling @p chThdExit() or by simply * returning from its main function. * @note Threads created using this function do not obey to the -- cgit v1.2.3 From 120a8fe256fbbbb915968f6c0f507abbf8a3c8ce Mon Sep 17 00:00:00 2001 From: liamstask Date: Mon, 27 Sep 2010 06:57:40 +0000 Subject: * copy/paste error on THREAD_EXT_INIT_HOOK git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2207 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chthreads.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 06451c18f..9d0bd84ae 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -97,7 +97,7 @@ Thread *init_thread(Thread *tp, tprio_t prio) { #if CH_USE_REGISTRY REG_INSERT(tp); #endif -#if defined(THREAD_EXT_EXIT_HOOK) +#if defined(THREAD_EXT_INIT_HOOK) THREAD_EXT_INIT_HOOK(tp); #endif return tp; -- cgit v1.2.3 From 44d5c906d5f9ca290be2d09a7fb6f2aa88b329c7 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 1 Oct 2010 06:59:37 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2215 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chthreads.c | 1 - 1 file changed, 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 9d0bd84ae..00f9704aa 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -514,7 +514,6 @@ void chThdRelease(Thread *tp) { * - If the thread was spawned by @p chThdCreateFromMemoryPool() * then the working area is returned to the owning memory pool. * . - * Please read the @ref article_lifecycle article for more details. * @pre The configuration option @p CH_USE_WAITEXIT must be enabled in * order to use this function. * @post Enabling @p chThdWait() requires 2-4 (depending on the -- cgit v1.2.3 From 009e8d28c38ef6b6797318aee29ca90910753988 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 11 Nov 2010 11:04:05 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2346 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chregistry.c | 2 +- os/kernel/src/chsem.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c index 95893de85..e95ad21a8 100644 --- a/os/kernel/src/chregistry.c +++ b/os/kernel/src/chregistry.c @@ -33,7 +33,7 @@ * - Next, returns the next, in creation order, active thread * in the system. * . - * The registry is meant to be mainly a debug feature, as example, + * The registry is meant to be mainly a debug feature, for example, * using the registry a debugger can enumerate the active threads * in any given moment or the shell can print the active threads * and their state.
diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index 58cd94808..3e1d2ce88 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -47,7 +47,7 @@ * . * Semaphores can be used as guards for mutual exclusion zones * (note that mutexes are recommended for this kind of use) but - * also have other uses, queues guards and counters as example.
+ * also have other uses, queues guards and counters for example.
* Semaphores usually use a FIFO queuing strategy but it is possible * to make them order threads by priority by enabling * @p CH_USE_SEMAPHORES_PRIORITY in @p chconf.h. -- cgit v1.2.3 From e889040710fe8e5ee4454b01803d0c8522f489f0 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 12 Nov 2010 18:47:41 +0000 Subject: Separated the dynamic threads code from the static threads code. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2349 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chdynamic.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++ os/kernel/src/chsys.c | 2 +- os/kernel/src/chthreads.c | 172 +++-------------------------------------- 3 files changed, 201 insertions(+), 163 deletions(-) create mode 100644 os/kernel/src/chdynamic.c (limited to 'os/kernel/src') diff --git a/os/kernel/src/chdynamic.c b/os/kernel/src/chdynamic.c new file mode 100644 index 000000000..fba8a0278 --- /dev/null +++ b/os/kernel/src/chdynamic.c @@ -0,0 +1,190 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT 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. + + ChibiOS/RT 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 chdynamic.c + * @brief Dynamic threads code. + * + * @addtogroup dynamic_threads + * @details Dynamic threads related APIs and services. + * @{ + */ + +#include "ch.h" + +#if CH_USE_DYNAMIC || defined(__DOXYGEN__) + +/** + * @brief Adds a reference to a thread object. + * @pre The configuration option @p CH_USE_DYNAMIC must be enabled in order + * to use this function. + * + * @param[in] tp pointer to the thread + * @return The same thread pointer passed as parameter + * representing the new reference. + * + * @api + */ +Thread *chThdAddRef(Thread *tp) { + + chSysLock(); + chDbgAssert(tp->p_refs < 255, "chThdAddRef(), #1", "too many references"); + tp->p_refs++; + chSysUnlock(); + return tp; +} + +/** + * @brief Releases a reference to a thread object. + * @details If the references counter reaches zero and the thread + * is in the @p THD_STATE_FINAL state then the thread's memory is + * returned to the proper allocator. + * @pre The configuration option @p CH_USE_DYNAMIC must be enabled in order + * to use this function. + * @note Static threads are not affected. + * + * @param[in] tp pointer to the thread + * + * @api + */ +void chThdRelease(Thread *tp) { + trefs_t refs; + + chSysLock(); + chDbgAssert(tp->p_refs > 0, "chThdRelease(), #1", "not referenced"); + refs = --tp->p_refs; + chSysUnlock(); + + /* If the references counter reaches zero then the memory can be returned + to the proper allocator. Of course static threads are not affected.*/ + if (refs == 0) { + switch (tp->p_flags & THD_MEM_MODE_MASK) { +#if CH_USE_HEAP + case THD_MEM_MODE_HEAP: + chHeapFree(tp); + break; +#endif +#if CH_USE_MEMPOOLS + case THD_MEM_MODE_MEMPOOL: + chPoolFree(tp->p_mpool, tp); + break; +#endif + } + } +} + +#if CH_USE_HEAP || defined(__DOXYGEN__) +/** + * @brief Creates a new thread allocating the memory from the heap. + * @pre The configuration options @p CH_USE_DYNAMIC and @p CH_USE_HEAP + * must be enabled in order to use this function. + * @note A thread can terminate by calling @p chThdExit() or by simply + * returning from its main function. + * @note The memory allocated for the thread is not released when the thread + * terminates but when a @p chThdWait() is performed. + * + * @param[in] heapp heap from which allocate the memory or @p NULL for the + * default heap + * @param[in] size size of the working area to be allocated + * @param[in] prio the priority level for the new thread + * @param[in] pf the thread function + * @param[in] arg an argument passed to the thread function. It can be + * @p NULL. + * @return The pointer to the @p Thread structure allocated for + * the thread into the working space area. + * @retval NULL if the memory cannot be allocated. + * + * @api + */ +Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size, + tprio_t prio, tfunc_t pf, void *arg) { + void *wsp; + Thread *tp; + + wsp = chHeapAlloc(heapp, size); + if (wsp == NULL) + return NULL; + +#if CH_DBG_FILL_THREADS + memfill((uint8_t *)wsp, (uint8_t *)wsp + sizeof(Thread), THREAD_FILL_VALUE); + memfill((uint8_t *)wsp + sizeof(Thread), + (uint8_t *)wsp + size, STACK_FILL_VALUE); +#endif + + chSysLock(); + tp = chThdCreateI(wsp, size, prio, pf, arg); + tp->p_flags = THD_MEM_MODE_HEAP; + chSchWakeupS(tp, RDY_OK); + chSysUnlock(); + return tp; +} +#endif /* CH_USE_HEAP */ + +#if CH_USE_MEMPOOLS || defined(__DOXYGEN__) +/** + * @brief Creates a new thread allocating the memory from the specified + * memory pool. + * @pre The configuration options @p CH_USE_DYNAMIC and @p CH_USE_MEMPOOLS + * must be enabled in order to use this function. + * @note A thread can terminate by calling @p chThdExit() or by simply + * returning from its main function. + * @note The memory allocated for the thread is not released when the thread + * terminates but when a @p chThdWait() is performed. + * + * @param[in] mp pointer to the memory pool object + * @param[in] prio the priority level for the new thread + * @param[in] pf the thread function + * @param[in] arg an argument passed to the thread function. It can be + * @p NULL. + * @return The pointer to the @p Thread structure allocated for + * the thread into the working space area. + * @retval NULL if the memory pool is empty. + * + * @api + */ +Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, + tfunc_t pf, void *arg) { + void *wsp; + Thread *tp; + + chDbgCheck(mp != NULL, "chThdCreateFromMemoryPool"); + + wsp = chPoolAlloc(mp); + if (wsp == NULL) + return NULL; + +#if CH_DBG_FILL_THREADS + memfill((uint8_t *)wsp, (uint8_t *)wsp + sizeof(Thread), THREAD_FILL_VALUE); + memfill((uint8_t *)wsp + sizeof(Thread), + (uint8_t *)wsp + mp->mp_object_size, STACK_FILL_VALUE); +#endif + + chSysLock(); + tp = chThdCreateI(wsp, mp->mp_object_size, prio, pf, arg); + tp->p_flags = THD_MEM_MODE_MEMPOOL; + tp->p_mpool = mp; + chSchWakeupS(tp, RDY_OK); + chSysUnlock(); + return tp; +} +#endif /* CH_USE_MEMPOOLS */ + +#endif /* CH_USE_DYNAMIC */ + +/** @} */ diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index a567b73da..9d3ec1929 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -88,7 +88,7 @@ void chSysInit(void) { #endif /* Now this instructions flow becomes the main thread.*/ - setcurrp(init_thread(&mainthread, NORMALPRIO)); + setcurrp(_thread_init(&mainthread, NORMALPRIO)); currp->p_state = THD_STATE_CURRENT; chSysEnable(); diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 00f9704aa..65468a3b2 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -67,7 +67,7 @@ * * @notapi */ -Thread *init_thread(Thread *tp, tprio_t prio) { +Thread *_thread_init(Thread *tp, tprio_t prio) { tp->p_prio = prio; tp->p_state = THD_STATE_SUSPENDED; @@ -103,13 +103,18 @@ Thread *init_thread(Thread *tp, tprio_t prio) { return tp; } -#if CH_DBG_FILL_THREADS -static void memfill(uint8_t *startp, uint8_t *endp, uint8_t v) { +#if CH_DBG_FILL_THREADS || defined(__DOXYGEN__) +/** + * @brief Memory fill utility. + * + * @notapi + */ +void _thread_memfill(uint8_t *startp, uint8_t *endp, uint8_t v) { while (startp < endp) *startp++ = v; } -#endif +#endif /* CH_DBG_FILL_THREADS */ /** * @brief Creates a new thread into a static memory area. @@ -144,7 +149,7 @@ Thread *chThdCreateI(void *wsp, size_t size, (prio <= HIGHPRIO) && (pf != NULL), "chThdCreateI"); SETUP_CONTEXT(wsp, size, pf, arg); - return init_thread(tp, prio); + return _thread_init(tp, prio); } /** @@ -178,102 +183,6 @@ Thread *chThdCreateStatic(void *wsp, size_t size, return tp; } -#if CH_USE_DYNAMIC && CH_USE_HEAP -/** - * @brief Creates a new thread allocating the memory from the heap. - * @pre The configuration options @p CH_USE_DYNAMIC and @p CH_USE_HEAP - * must be enabled in order to use this function. - * @note A thread can terminate by calling @p chThdExit() or by simply - * returning from its main function. - * @note The memory allocated for the thread is not released when the thread - * terminates but when a @p chThdWait() is performed. - * - * @param[in] heapp heap from which allocate the memory or @p NULL for the - * default heap - * @param[in] size size of the working area to be allocated - * @param[in] prio the priority level for the new thread - * @param[in] pf the thread function - * @param[in] arg an argument passed to the thread function. It can be - * @p NULL. - * @return The pointer to the @p Thread structure allocated for - * the thread into the working space area. - * @retval NULL if the memory cannot be allocated. - * - * @api - */ -Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size, - tprio_t prio, tfunc_t pf, void *arg) { - void *wsp; - Thread *tp; - - wsp = chHeapAlloc(heapp, size); - if (wsp == NULL) - return NULL; - -#if CH_DBG_FILL_THREADS - memfill((uint8_t *)wsp, (uint8_t *)wsp + sizeof(Thread), THREAD_FILL_VALUE); - memfill((uint8_t *)wsp + sizeof(Thread), - (uint8_t *)wsp + size, STACK_FILL_VALUE); -#endif - - chSysLock(); - tp = chThdCreateI(wsp, size, prio, pf, arg); - tp->p_flags = THD_MEM_MODE_HEAP; - chSchWakeupS(tp, RDY_OK); - chSysUnlock(); - return tp; -} -#endif /* CH_USE_DYNAMIC && CH_USE_HEAP */ - -#if CH_USE_DYNAMIC && CH_USE_MEMPOOLS -/** - * @brief Creates a new thread allocating the memory from the specified - * memory pool. - * @pre The configuration options @p CH_USE_DYNAMIC and @p CH_USE_MEMPOOLS - * must be enabled in order to use this function. - * @note A thread can terminate by calling @p chThdExit() or by simply - * returning from its main function. - * @note The memory allocated for the thread is not released when the thread - * terminates but when a @p chThdWait() is performed. - * - * @param[in] mp pointer to the memory pool object - * @param[in] prio the priority level for the new thread - * @param[in] pf the thread function - * @param[in] arg an argument passed to the thread function. It can be - * @p NULL. - * @return The pointer to the @p Thread structure allocated for - * the thread into the working space area. - * @retval NULL if the memory pool is empty. - * - * @api - */ -Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, - tfunc_t pf, void *arg) { - void *wsp; - Thread *tp; - - chDbgCheck(mp != NULL, "chThdCreateFromMemoryPool"); - - wsp = chPoolAlloc(mp); - if (wsp == NULL) - return NULL; - -#if CH_DBG_FILL_THREADS - memfill((uint8_t *)wsp, (uint8_t *)wsp + sizeof(Thread), THREAD_FILL_VALUE); - memfill((uint8_t *)wsp + sizeof(Thread), - (uint8_t *)wsp + mp->mp_object_size, STACK_FILL_VALUE); -#endif - - chSysLock(); - tp = chThdCreateI(wsp, mp->mp_object_size, prio, pf, arg); - tp->p_flags = THD_MEM_MODE_MEMPOOL; - tp->p_mpool = mp; - chSchWakeupS(tp, RDY_OK); - chSysUnlock(); - return tp; -} -#endif /* CH_USE_DYNAMIC && CH_USE_MEMPOOLS */ - /** * @brief Changes the running thread priority level then reschedules if * necessary. @@ -435,67 +344,6 @@ void chThdExit(msg_t msg) { chSchGoSleepS(THD_STATE_FINAL); } -#if CH_USE_DYNAMIC || defined(__DOXYGEN__) -/** - * @brief Adds a reference to a thread object. - * @pre The configuration option @p CH_USE_DYNAMIC must be enabled in order - * to use this function. - * - * @param[in] tp pointer to the thread - * @return The same thread pointer passed as parameter - * representing the new reference. - * - * @api - */ -Thread *chThdAddRef(Thread *tp) { - - chSysLock(); - chDbgAssert(tp->p_refs < 255, "chThdAddRef(), #1", "too many references"); - tp->p_refs++; - chSysUnlock(); - return tp; -} - -/** - * @brief Releases a reference to a thread object. - * @details If the references counter reaches zero and the thread - * is in the @p THD_STATE_FINAL state then the thread's memory is - * returned to the proper allocator. - * @pre The configuration option @p CH_USE_DYNAMIC must be enabled in order - * to use this function. - * @note Static threads are not affected. - * - * @param[in] tp pointer to the thread - * - * @api - */ -void chThdRelease(Thread *tp) { - trefs_t refs; - - chSysLock(); - chDbgAssert(tp->p_refs > 0, "chThdRelease(), #1", "not referenced"); - refs = --tp->p_refs; - chSysUnlock(); - - /* If the references counter reaches zero then the memory can be returned - to the proper allocator. Of course static threads are not affected.*/ - if (refs == 0) { - switch (tp->p_flags & THD_MEM_MODE_MASK) { -#if CH_USE_HEAP - case THD_MEM_MODE_HEAP: - chHeapFree(tp); - break; -#endif -#if CH_USE_MEMPOOLS - case THD_MEM_MODE_MEMPOOL: - chPoolFree(tp->p_mpool, tp); - break; -#endif - } - } -} -#endif /* CH_USE_DYNAMIC */ - #if CH_USE_WAITEXIT || defined(__DOXYGEN__) /** * @brief Blocks the execution of the invoking thread until the specified -- cgit v1.2.3 From 66c3169f4f74a769bd7f7cf8b8a5cdc0342bdc17 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 20 Nov 2010 08:43:30 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2390 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chdynamic.c | 18 ++++++++++++------ os/kernel/src/chthreads.c | 9 ++++++--- 2 files changed, 18 insertions(+), 9 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chdynamic.c b/os/kernel/src/chdynamic.c index fba8a0278..06e5bd00a 100644 --- a/os/kernel/src/chdynamic.c +++ b/os/kernel/src/chdynamic.c @@ -122,9 +122,12 @@ Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size, return NULL; #if CH_DBG_FILL_THREADS - memfill((uint8_t *)wsp, (uint8_t *)wsp + sizeof(Thread), THREAD_FILL_VALUE); - memfill((uint8_t *)wsp + sizeof(Thread), - (uint8_t *)wsp + size, STACK_FILL_VALUE); + _thread_memfill((uint8_t *)wsp, + (uint8_t *)wsp + sizeof(Thread), + THREAD_FILL_VALUE); + _thread_memfill((uint8_t *)wsp + sizeof(Thread), + (uint8_t *)wsp + size, + STACK_FILL_VALUE); #endif chSysLock(); @@ -170,9 +173,12 @@ Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, return NULL; #if CH_DBG_FILL_THREADS - memfill((uint8_t *)wsp, (uint8_t *)wsp + sizeof(Thread), THREAD_FILL_VALUE); - memfill((uint8_t *)wsp + sizeof(Thread), - (uint8_t *)wsp + mp->mp_object_size, STACK_FILL_VALUE); + _thread_memfill((uint8_t *)wsp, + (uint8_t *)wsp + sizeof(Thread), + THREAD_FILL_VALUE); + _thread_memfill((uint8_t *)wsp + sizeof(Thread), + (uint8_t *)wsp + mp->mp_object_size, + STACK_FILL_VALUE); #endif chSysLock(); diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 65468a3b2..4e8ae1c21 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -173,9 +173,12 @@ Thread *chThdCreateStatic(void *wsp, size_t size, Thread *tp; #if CH_DBG_FILL_THREADS - memfill((uint8_t *)wsp, (uint8_t *)wsp + sizeof(Thread), THREAD_FILL_VALUE); - memfill((uint8_t *)wsp + sizeof(Thread), - (uint8_t *)wsp + size, STACK_FILL_VALUE); + _thread_memfill((uint8_t *)wsp, + (uint8_t *)wsp + sizeof(Thread), + THREAD_FILL_VALUE); + _thread_memfill((uint8_t *)wsp + sizeof(Thread), + (uint8_t *)wsp + size, + STACK_FILL_VALUE); #endif chSysLock(); chSchWakeupS(tp = chThdCreateI(wsp, size, prio, pf, arg), RDY_OK); -- cgit v1.2.3 From b0bdd6eff685c2d678a052ebb1a0e9fa5512aaac Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 20 Nov 2010 10:46:51 +0000 Subject: Fixed bug 3113443. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2392 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chevents.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index a66a7fa28..a0ef2d1bb 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -382,11 +382,15 @@ eventmask_t chEvtWaitOneTimeout(eventmask_t mask, systime_t time) { chSysLock(); if ((m = (ctp->p_epending & mask)) == 0) { - if (TIME_IMMEDIATE == time) + if (TIME_IMMEDIATE == time) { + chSysUnlock(); return (eventmask_t)0; + } ctp->p_u.ewmask = mask; - if (chSchGoSleepTimeoutS(THD_STATE_WTOREVT, time) < RDY_OK) + if (chSchGoSleepTimeoutS(THD_STATE_WTOREVT, time) < RDY_OK) { + chSysUnlock(); return (eventmask_t)0; + } m = ctp->p_epending & mask; } m &= -m; @@ -421,11 +425,15 @@ eventmask_t chEvtWaitAnyTimeout(eventmask_t mask, systime_t time) { chSysLock(); if ((m = (ctp->p_epending & mask)) == 0) { - if (TIME_IMMEDIATE == time) + if (TIME_IMMEDIATE == time) { + chSysUnlock(); return (eventmask_t)0; + } ctp->p_u.ewmask = mask; - if (chSchGoSleepTimeoutS(THD_STATE_WTOREVT, time) < RDY_OK) + if (chSchGoSleepTimeoutS(THD_STATE_WTOREVT, time) < RDY_OK) { + chSysUnlock(); return (eventmask_t)0; + } m = ctp->p_epending & mask; } ctp->p_epending &= ~m; @@ -457,11 +465,15 @@ eventmask_t chEvtWaitAllTimeout(eventmask_t mask, systime_t time) { chSysLock(); if ((ctp->p_epending & mask) != mask) { - if (TIME_IMMEDIATE == time) + if (TIME_IMMEDIATE == time) { + chSysUnlock(); return (eventmask_t)0; + } ctp->p_u.ewmask = mask; - if (chSchGoSleepTimeoutS(THD_STATE_WTANDEVT, time) < RDY_OK) + if (chSchGoSleepTimeoutS(THD_STATE_WTANDEVT, time) < RDY_OK) { + chSysUnlock(); return (eventmask_t)0; + } } ctp->p_epending &= ~mask; -- cgit v1.2.3 From d973c3f25a6ab56e12b9f858b0692ec4297d84c9 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 23 Nov 2010 20:26:17 +0000 Subject: Fixed bug 3116888. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2425 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chdynamic.c | 13 ++++++++++--- os/kernel/src/chthreads.c | 5 ++++- 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chdynamic.c b/os/kernel/src/chdynamic.c index 06e5bd00a..5f1fc3401 100644 --- a/os/kernel/src/chdynamic.c +++ b/os/kernel/src/chdynamic.c @@ -71,17 +71,24 @@ void chThdRelease(Thread *tp) { refs = --tp->p_refs; chSysUnlock(); - /* If the references counter reaches zero then the memory can be returned - to the proper allocator. Of course static threads are not affected.*/ - if (refs == 0) { + /* If the references counter reaches zero and the thread is in its + terminated state then the memory can be returned to the proper + allocator. Of course static threads are not affected.*/ + if ((refs == 0) && (tp->p_state == THD_STATE_FINAL)) { switch (tp->p_flags & THD_MEM_MODE_MASK) { #if CH_USE_HEAP case THD_MEM_MODE_HEAP: +#if CH_USE_REGISTRY + REG_REMOVE(tp); +#endif chHeapFree(tp); break; #endif #if CH_USE_MEMPOOLS case THD_MEM_MODE_MEMPOOL: +#if CH_USE_REGISTRY + REG_REMOVE(tp); +#endif chPoolFree(tp->p_mpool, tp); break; #endif diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 4e8ae1c21..ced8a77e0 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -342,7 +342,10 @@ void chThdExit(msg_t msg) { chSchReadyI(list_remove(&tp->p_waiting)); #endif #if CH_USE_REGISTRY - REG_REMOVE(tp); + /* Static threads are immediately removed from the registry because + there is no memory to recover.*/ + if ((tp->p_flags & THD_MEM_MODE_MASK) == THD_MEM_MODE_STATIC) + REG_REMOVE(tp); #endif chSchGoSleepS(THD_STATE_FINAL); } -- cgit v1.2.3 From a21374eb7c0616fa2719be6052399b4571a901ab Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 27 Nov 2010 12:04:18 +0000 Subject: Missing doxygen tags. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2436 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chthreads.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index ced8a77e0..56cf087db 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -107,6 +107,10 @@ Thread *_thread_init(Thread *tp, tprio_t prio) { /** * @brief Memory fill utility. * + * @param[in] startp first address to fill + * @param[in] endp last address to fille +1 + * @param[in] v filler value + * * @notapi */ void _thread_memfill(uint8_t *startp, uint8_t *endp, uint8_t v) { -- cgit v1.2.3 From 5401b0fa1c1d6799b8fde25254860b04afc0faa3 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 27 Nov 2010 14:58:23 +0000 Subject: typo git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2438 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chthreads.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 56cf087db..51efc20d1 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -108,7 +108,7 @@ Thread *_thread_init(Thread *tp, tprio_t prio) { * @brief Memory fill utility. * * @param[in] startp first address to fill - * @param[in] endp last address to fille +1 + * @param[in] endp last address to fill +1 * @param[in] v filler value * * @notapi -- cgit v1.2.3 From 226ca59c9e7d36788f4c46993f5525de11204ada Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 12 Dec 2010 07:36:51 +0000 Subject: White space fixes. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2473 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 9d3ec1929..0051985ba 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -36,7 +36,7 @@ /** * @brief Idle thread working area. - * @see IDLE_THREAD_STACK_SIZE + * @see IDLE_THREAD_STACK_SIZE */ WORKING_AREA(_idle_thread_wa, IDLE_THREAD_STACK_SIZE); -- cgit v1.2.3 From f2386f6a22c55842203278c5b1f9691c5ac5f8fd Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 21 Dec 2010 10:30:39 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2515 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 5 ----- 1 file changed, 5 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 9adf656ff..5b04c1f3d 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -71,12 +71,7 @@ void scheduler_init(void) { * @iclass */ #if !defined(PORT_OPTIMIZED_READYI) || defined(__DOXYGEN__) -#if CH_OPTIMIZE_SPEED -/* NOTE: it is inlined in this module only.*/ -INLINE Thread *chSchReadyI(Thread *tp) { -#else Thread *chSchReadyI(Thread *tp) { -#endif Thread *cp; /* Integrity check.*/ -- cgit v1.2.3 From 930b0adb22b94625bbb01a5a987027b3b4162d34 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 31 Dec 2010 08:53:26 +0000 Subject: Fixed bug 3148525. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2555 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chqueues.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index b02fa6a64..d18d5d53a 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -196,8 +196,6 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, *bp++ = *iqp->q_rdptr++; if (iqp->q_rdptr >= iqp->q_top) iqp->q_rdptr = iqp->q_buffer; - if (nfy) - nfy(); chSysUnlock(); /* Gives a preemption chance in a controlled point.*/ r++; if (--n == 0) { -- cgit v1.2.3 From 90aa3805a2cbfb9e6d385d3051dd111be0a67569 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 1 Jan 2011 17:50:09 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2566 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chqueues.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index d18d5d53a..87a82acf2 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -134,7 +134,7 @@ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) { msg_t msg; chSysLock(); - + if (iqp->q_notify) iqp->q_notify(); -- cgit v1.2.3 From 89c12799e185423b6c571b78d5b44e11e67adf72 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 2 Jan 2011 10:13:43 +0000 Subject: Added new semaphore API chSemSetCounterI(). git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2569 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsem.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index 3e1d2ce88..18ea9e996 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -311,6 +311,38 @@ void chSemSignalI(Semaphore *sp) { } } +/** + * @brief Sets the semaphore counter to the specified value. + * @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 structure + * @param[in] n the new value of the semaphore counter. The value must + * be non-negative. + * + * @iclass + */ +void chSemSetCounterI(Semaphore *sp, cnt_t n) { + cnt_t cnt; + + chDbgCheck((sp != NULL) && (n >= 0), "chSemSetCounterI"); + + chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) || + ((sp->s_cnt < 0) && notempty(&sp->s_queue)), + "chSemSetCounterI(), #1", + "inconsistent semaphore"); + + cnt = sp->s_cnt; + sp->s_cnt = n; + while (++cnt <= 0) + chSchReadyI(lifo_remove(&sp->s_queue))->p_u.rdymsg = RDY_OK; +} + #if CH_USE_SEMSW /** * @brief Performs atomic signal and wait operations on two semaphores. -- cgit v1.2.3 From a1534ccb61d616ad15a69a668fe26466a87d76a9 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 2 Jan 2011 14:01:18 +0000 Subject: New queues APIs. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2571 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chqueues.c | 44 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index 87a82acf2..4a195fa9b 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -69,6 +69,22 @@ void chIQInit(InputQueue *iqp, uint8_t *bp, size_t size, qnotify_t infy) { chSemInit(&iqp->q_sem, 0); } +/** + * @brief Returns the filled space into an input queue. + * + * @param[in] iqp pointer to an @p InputQueue structure + * + * @iclass + */ +size_t chIQGetFullI(InputQueue *iqp) { + cnt_t cnt; + + cnt = chQSpaceI(iqp); + if (cnt < 0) + return 0; + return (size_t)cnt; +} + /** * @brief Resets an input queue. * @details All the data in the input queue is erased and lost, any waiting @@ -136,7 +152,7 @@ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) { chSysLock(); if (iqp->q_notify) - iqp->q_notify(); + iqp->q_notify(iqp); if ((msg = chSemWaitTimeoutS(&iqp->q_sem, time)) < RDY_OK) { chSysUnlock(); @@ -185,7 +201,7 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, while (TRUE) { if (chIQIsEmptyI(iqp)) { if (nfy) - nfy(); + nfy(iqp); if ((chSemWaitTimeoutS(&iqp->q_sem, time) != RDY_OK)) { chSysUnlock(); return r; @@ -201,7 +217,7 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, if (--n == 0) { chSysLock(); if (nfy) - nfy(); + nfy(iqp); chSysUnlock(); return r; } @@ -232,6 +248,22 @@ void chOQInit(OutputQueue *oqp, uint8_t *bp, size_t size, qnotify_t onfy) { chSemInit(&oqp->q_sem, (cnt_t)size); } +/** + * @brief Returns the filled space into an output queue. + * + * @param[in] oqp pointer to an @p OutputQueue structure + * + * @iclass + */ +size_t chOQGetFullI(OutputQueue *oqp) { + cnt_t cnt; + + cnt = chQSpaceI(oqp); + if (cnt < 0) + return chQSizeI(oqp); + return chQSizeI(oqp) - (size_t)cnt; +} + /** * @brief Resets an output queue. * @details All the data in the output queue is erased and lost, any waiting @@ -282,7 +314,7 @@ msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t time) { oqp->q_wrptr = oqp->q_buffer; if (oqp->q_notify) - oqp->q_notify(); + oqp->q_notify(oqp); chSysUnlock(); return Q_OK; @@ -346,7 +378,7 @@ size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp, while (TRUE) { if (chOQIsFullI(oqp)) { if (nfy) - nfy(); + nfy(oqp); if ((chSemWaitTimeoutS(&oqp->q_sem, time) != RDY_OK)) { chSysUnlock(); return w; @@ -362,7 +394,7 @@ size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp, if (--n == 0) { chSysLock(); if (nfy) - nfy(); + nfy(oqp); chSysUnlock(); return w; } -- cgit v1.2.3 From 7076a879620e2f372e133686c1c59623e379b10c Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 4 Jan 2011 20:55:32 +0000 Subject: Documentation related fixes. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2581 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chqueues.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index 4a195fa9b..8d459a7e8 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -73,6 +73,8 @@ void chIQInit(InputQueue *iqp, uint8_t *bp, size_t size, qnotify_t infy) { * @brief Returns the filled space into an input queue. * * @param[in] iqp pointer to an @p InputQueue structure + * @return The number of bytes in the queue. + * @retval 0 if the queue is empty. * * @iclass */ @@ -252,6 +254,8 @@ void chOQInit(OutputQueue *oqp, uint8_t *bp, size_t size, qnotify_t onfy) { * @brief Returns the filled space into an output queue. * * @param[in] oqp pointer to an @p OutputQueue structure + * @return The number of bytes in the queue. + * @retval 0 if the queue is empty. * * @iclass */ -- cgit v1.2.3 From 17f0815d52977bd1e3e9e662d2ffdccbaf77a6bd Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 21 Feb 2011 18:00:06 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2756 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chevents.c | 26 ++++++++++----- os/kernel/src/chmboxes.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+), 8 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index a0ef2d1bb..a64f59bdc 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -160,12 +160,12 @@ eventmask_t chEvtAddFlags(eventmask_t mask) { * * @api */ -void chEvtSignal(Thread *tp, eventmask_t mask) { +void chEvtSignalFlags(Thread *tp, eventmask_t mask) { chDbgCheck(tp != NULL, "chEvtSignal"); chSysLock(); - chEvtSignalI(tp, mask); + chEvtSignalFlagsI(tp, mask); chSchRescheduleS(); chSysUnlock(); } @@ -182,7 +182,7 @@ void chEvtSignal(Thread *tp, eventmask_t mask) { * * @iclass */ -void chEvtSignalI(Thread *tp, eventmask_t mask) { +void chEvtSignalFlagsI(Thread *tp, eventmask_t mask) { chDbgCheck(tp != NULL, "chEvtSignalI"); @@ -198,15 +198,20 @@ void chEvtSignalI(Thread *tp, eventmask_t mask) { /** * @brief Signals all the Event Listeners registered on the specified Event * Source. + * @details This function variants ORs the specified event flags to all the + * threads registered on the @p EventSource in addition to the event + * flags specified by the threads themselves in the + * @p EventListener objects. * * @param[in] esp pointer to the @p EventSource structure + * @param[in] mask the event flags set to be ORed * * @api */ -void chEvtBroadcast(EventSource *esp) { +void chEvtBroadcastFlags(EventSource *esp, eventmask_t mask) { chSysLock(); - chEvtBroadcastI(esp); + chEvtBroadcastFlagsI(esp, mask); chSchRescheduleS(); chSysUnlock(); } @@ -214,23 +219,28 @@ void chEvtBroadcast(EventSource *esp) { /** * @brief Signals all the Event Listeners registered on the specified Event * Source. + * @details This function variants ORs the specified event flags to all the + * threads registered on the @p EventSource in addition to the event + * flags specified by the threads themselves in the + * @p EventListener objects. * @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] esp pointer to the @p EventSource structure + * @param[in] mask the event flags set to be ORed * * @iclass */ -void chEvtBroadcastI(EventSource *esp) { +void chEvtBroadcastFlagsI(EventSource *esp, eventmask_t mask) { EventListener *elp; - chDbgCheck(esp != NULL, "chEvtBroadcastI"); + chDbgCheck(esp != NULL, "chEvtBroadcastMaskI"); elp = esp->es_next; while (elp != (EventListener *)esp) { - chEvtSignalI(elp->el_listener, elp->el_mask); + chEvtSignalFlagsI(elp->el_listener, elp->el_mask | mask); elp = elp->el_next; } } diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c index b2cef2470..e0b6ca014 100644 --- a/os/kernel/src/chmboxes.c +++ b/os/kernel/src/chmboxes.c @@ -155,6 +155,34 @@ msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) { return rdymsg; } +/** + * @brief Posts a message into a mailbox. + * @details This variant is non-blocking, the function returns a timeout + * condition if the queue is full. + * + * @param[in] mbp the pointer to an initialized Mailbox object + * @param[in] msg the message to be posted on the mailbox + * @return The operation status. + * @retval RDY_OK if a message has been correctly posted. + * @retval RDY_TIMEOUT if the mailbox is full and the message cannot be + * posted. + * + * @iclass + */ +msg_t chMBPostI(Mailbox *mbp, msg_t msg) { + + chDbgCheck(mbp != NULL, "chMBPostI"); + + if (chSemGetCounterI(&mbp->mb_emptysem) <= 0) + return RDY_TIMEOUT; + chSemFastWaitI(&mbp->mb_emptysem); + *mbp->mb_wrptr++ = msg; + if (mbp->mb_wrptr >= mbp->mb_top) + mbp->mb_wrptr = mbp->mb_buffer; + chSemSignalI(&mbp->mb_fullsem); + return RDY_OK; +} + /** * @brief Posts an high priority message into a mailbox. * @details The invoking thread waits until a empty slot in the mailbox becomes @@ -218,6 +246,34 @@ msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) { return rdymsg; } +/** + * @brief Posts an high priority message into a mailbox. + * @details This variant is non-blocking, the function returns a timeout + * condition if the queue is full. + * + * @param[in] mbp the pointer to an initialized Mailbox object + * @param[in] msg the message to be posted on the mailbox + * @return The operation status. + * @retval RDY_OK if a message has been correctly posted. + * @retval RDY_TIMEOUT if the mailbox is full and the message cannot be + * posted. + * + * @iclass + */ +msg_t chMBPostAheadI(Mailbox *mbp, msg_t msg) { + + chDbgCheck(mbp != NULL, "chMBPostAheadI"); + + if (chSemGetCounterI(&mbp->mb_emptysem) <= 0) + return RDY_TIMEOUT; + chSemFastWaitI(&mbp->mb_emptysem); + if (--mbp->mb_rdptr < mbp->mb_buffer) + mbp->mb_rdptr = mbp->mb_top - 1; + *mbp->mb_rdptr = msg; + chSemSignalI(&mbp->mb_fullsem); + return RDY_OK; +} + /** * @brief Retrieves a message from a mailbox. * @details The invoking thread waits until a message is posted in the mailbox @@ -280,6 +336,33 @@ msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t time) { } return rdymsg; } + +/** + * @brief Retrieves a message from a mailbox. + * @details This variant is non-blocking, the function returns a timeout + * condition if the queue is full. + * + * @param[in] mbp the pointer to an initialized Mailbox object + * @param[out] msgp pointer to a message variable for the received message + * @return The operation status. + * @retval RDY_OK if a message has been correctly fetched. + * @retval RDY_TIMEOUT if the mailbox is empty and a message cannot be + * fetched. + * + * @iclass + */ +msg_t chMBFetchI(Mailbox *mbp, msg_t *msgp) { + + chDbgCheck((mbp != NULL) && (msgp != NULL), "chMBFetchI"); + + if (chSemGetCounterI(&mbp->mb_fullsem) <= 0) + return RDY_TIMEOUT; + *msgp = *mbp->mb_rdptr++; + if (mbp->mb_rdptr >= mbp->mb_top) + mbp->mb_rdptr = mbp->mb_buffer; + chSemSignalI(&mbp->mb_emptysem); + return RDY_OK; +} #endif /* CH_USE_MAILBOXES */ /** @} */ -- cgit v1.2.3 From b3b1028036a2f18327fb97f2126192a2ace62bb2 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 21 Feb 2011 19:06:46 +0000 Subject: TIME_IMMEDIATE and TIME_INFINITE values swapped. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2757 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chcond.c | 22 +++++++++++----------- os/kernel/src/chschd.c | 4 +--- os/kernel/src/chthreads.c | 6 ++---- os/kernel/src/chvt.c | 12 +++++++----- 4 files changed, 21 insertions(+), 23 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c index 0ad9d459d..a6534eabc 100644 --- a/os/kernel/src/chcond.c +++ b/os/kernel/src/chcond.c @@ -203,11 +203,11 @@ msg_t chCondWaitS(CondVar *cp) { * mutex, the mutex ownership is lost. * * @param[in] cp pointer to the @p CondVar structure - * @param[in] time the number of ticks before the operation timeouts, - * the special value @p TIME_INFINITE is allowed. - * It is not possible to specify zero @p TIME_IMMEDIATE - * as timeout specification because it would make no sense - * in this function. + * @param[in] time the number of ticks before the operation timeouts, the + * special values are handled as follow: + * - @a TIME_INFINITE no timeout. + * - @a TIME_IMMEDIATE this value is not allowed. + * . * @return A message specifying how the invoking thread has been * released from the condition variable. * @retval RDY_OK if the condvar has been signaled using @@ -240,11 +240,11 @@ msg_t chCondWaitTimeout(CondVar *cp, systime_t time) { * mutex, the mutex ownership is lost. * * @param[in] cp pointer to the @p CondVar structure - * @param[in] time the number of ticks before the operation timeouts, - * the special value @p TIME_INFINITE is allowed. - * It is not possible to specify zero @p TIME_IMMEDIATE - * as timeout specification because it would make no sense - * in this function. + * @param[in] time the number of ticks before the operation timeouts, the + * special values are handled as follow: + * - @a TIME_INFINITE no timeout. + * - @a TIME_IMMEDIATE this value is not allowed. + * . * @return A message specifying how the invoking thread has been * released from the condition variable. * @retval RDY_OK if the condvar has been signaled using @@ -260,7 +260,7 @@ msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time) { Mutex *mp; msg_t msg; - chDbgCheck(cp != NULL, "chCondWaitTimeoutS"); + chDbgCheck((cp != NULL) && (time != TIME_IMMEDIATE), "chCondWaitTimeoutS"); chDbgAssert(currp->p_mtxlist != NULL, "chCondWaitTimeoutS(), #1", "not owning a mutex"); diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 5b04c1f3d..85e968904 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -160,9 +160,7 @@ static void wakeup(void *p) { * - @a TIME_INFINITE the thread enters an infinite sleep * state, this is equivalent to invoking * @p chSchGoSleepS() but, of course, less efficient. - * - @a TIME_IMMEDIATE this value is accepted but - * interpreted as a normal time specification not as an - * immediate timeout specification. + * - @a TIME_IMMEDIATE this value is not allowed. * . * @return The wakeup message. * @retval RDY_TIMEOUT if a timeout occurs. diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 51efc20d1..a00b5d3db 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -273,16 +273,14 @@ void chThdTerminate(Thread *tp) { * handled as follow: * - @a TIME_INFINITE the thread enters an infinite sleep * state. - * - @a TIME_IMMEDIATE this value is accepted but - * interpreted as a normal time specification not as an - * immediate timeout specification. + * - @a TIME_IMMEDIATE this value is not allowed. * . * * @api */ void chThdSleep(systime_t time) { - chDbgCheck(time != TIME_INFINITE, "chThdSleep"); + chDbgCheck(time != TIME_IMMEDIATE, "chThdSleep"); chSysLock(); chThdSleepS(time); diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c index b622bb493..016849186 100644 --- a/os/kernel/src/chvt.c +++ b/os/kernel/src/chvt.c @@ -52,10 +52,12 @@ void vt_init(void) { * the I-Locked state, see @ref system_states. * * @param[out] vtp the @p VirtualTimer structure pointer - * @param[in] time the number of time ticks, the value @p TIME_INFINITE - * is notallowed. The value @p TIME_IMMEDIATE is allowed - * but interpreted as a normal time specification not as - * an immediate timeout specification. + * @param[in] time the number of ticks before the operation timeouts, the + * special values are handled as follow: + * - @a TIME_INFINITE is allowed but interpreted as a + * normal time specification. + * - @a TIME_IMMEDIATE this value is not allowed. + * . * @param[in] vtfunc the timer callback function. After invoking the * callback the timer is disabled and the structure can * be disposed or reused. @@ -67,7 +69,7 @@ void vt_init(void) { void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) { VirtualTimer *p; - chDbgCheck((vtp != NULL) && (vtfunc != NULL) && (time != TIME_INFINITE), + chDbgCheck((vtp != NULL) && (vtfunc != NULL) && (time != TIME_IMMEDIATE), "chVTSetI"); vtp->vt_par = par; -- cgit v1.2.3 From 6f6e1a6401eda000dce198150937c7919b4c9855 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 23 Feb 2011 18:59:39 +0000 Subject: Improved messages subsystem. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2759 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmsg.c | 59 ++++++++++++++++----------------------------------- os/kernel/src/chmtx.c | 2 +- 2 files changed, 19 insertions(+), 42 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmsg.c b/os/kernel/src/chmsg.c index c3b4848b0..d4199bbb0 100644 --- a/os/kernel/src/chmsg.c +++ b/os/kernel/src/chmsg.c @@ -75,7 +75,7 @@ msg_t chMsgSend(Thread *tp, msg_t msg) { msg_insert(ctp, &tp->p_msgqueue); if (tp->p_state == THD_STATE_WTMSG) chSchReadyI(tp); - chSchGoSleepS(THD_STATE_SNDMSG); + chSchGoSleepS(THD_STATE_SNDMSGQ); msg = ctp->p_u.rdymsg; chSysUnlock(); return msg; @@ -83,69 +83,46 @@ msg_t chMsgSend(Thread *tp, msg_t msg) { /** * @brief Suspends the thread and waits for an incoming message. - * @post After receiving a message the function @p chMsgRelease() must be - * invoked in order to acknowledge the reception and send the answer. + * @post After receiving a message the function @p chMsgGet() must be + * called in order to retrieve the message and then @p chMsgRelease() + * must be invoked in order to acknowledge the reception and send + * the answer. * @note If the message is a pointer then you can assume that the data * pointed by the message is stable until you invoke @p chMsgRelease() * because the sending thread is suspended until then. * - * @return The message. + * @return A reference to the thread carrying the message. * * @api */ -msg_t chMsgWait(void) { - msg_t msg; +Thread *chMsgWait(void) { + Thread *tp; chSysLock(); if (!chMsgIsPendingI(currp)) chSchGoSleepS(THD_STATE_WTMSG); -#if defined(CH_ARCHITECTURE_STM8) - msg = chMsgGetI((volatile Thread *)currp); /* Temporary hack.*/ -#else - msg = chMsgGetI(currp); -#endif + tp = fifo_remove(&currp->p_msgqueue); + tp->p_state = THD_STATE_SNDMSG; chSysUnlock(); - return msg; -} - -/** - * @brief Returns the next message in the queue. - * @post After receiving a message the function @p chMsgRelease() must be - * invoked in order to acknowledge the reception and send the answer. - * @note If the message is a pointer then you can assume that the data - * pointed by the message is stable until you invoke @p chMsgRelease() - * because the sending thread is suspended until then. - * - * @return The message. - * @retval 0 if the queue is empty. - * - * @api - */ -msg_t chMsgGet(void) { - msg_t msg; - - chSysLock(); - msg = chMsgIsPendingI(currp) ? chMsgGetI(currp) : (msg_t)NULL; - chSysUnlock(); - return msg; + return tp; } /** * @brief Releases the thread waiting on top of the messages queue. * @pre Invoke this function only after a message has been received - * using @p chMsgWait() or @p chMsgGet(). + * using @p chMsgWait(). * - * @param[in] msg the message returned to the message sender + * @param[in] tp pointer to the thread + * @param[in] msg message to be returned to the sender * * @api */ -void chMsgRelease(msg_t msg) { +void chMsgRelease(Thread *tp, msg_t msg) { chSysLock(); - chDbgAssert(chMsgIsPendingI(currp), - "chMsgRelease(), #1", - "no message pending"); - chSchWakeupS(fifo_remove(&currp->p_msgqueue), msg); + chDbgAssert(tp->p_state == THD_STATE_SNDMSG, + "chMsgRelease(), #1", "invalid state"); + chMsgReleaseS(tp, msg); chSysUnlock(); } diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index b84c4d57e..826ef27fe 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -141,7 +141,7 @@ void chMtxLockS(Mutex *mp) { case THD_STATE_WTSEM: #endif #if CH_USE_MESSAGES_PRIORITY - case THD_STATE_SNDMSG: + case THD_STATE_SNDMSGQ: #endif /* Re-enqueues tp with its new priority on the queue.*/ prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); -- cgit v1.2.3 From a55d3c6e6b8d14d6310382f149593df231925c17 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 23 Feb 2011 20:24:05 +0000 Subject: Fixed bug 3190512. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2761 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmempools.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c index 092944b59..054823af0 100644 --- a/os/kernel/src/chmempools.c +++ b/os/kernel/src/chmempools.c @@ -75,10 +75,8 @@ void *chPoolAllocI(MemoryPool *mp) { if ((objp = mp->mp_next) != NULL) mp->mp_next = mp->mp_next->ph_next; -#if CH_USE_MEMCORE else if (mp->mp_provider != NULL) objp = mp->mp_provider(mp->mp_object_size); -#endif return objp; } -- cgit v1.2.3 From 24594525990ee1769ee933261b821211b4c299e8 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 24 Feb 2011 14:57:38 +0000 Subject: Fixed bugs 3191107 and 3191112. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2762 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chheap.c | 2 +- os/kernel/src/chmemcore.c | 38 +++++++++++++++++++------------------- os/kernel/src/chmempools.c | 2 +- 3 files changed, 21 insertions(+), 21 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c index 13db7cf6b..c655e3852 100644 --- a/os/kernel/src/chheap.c +++ b/os/kernel/src/chheap.c @@ -125,7 +125,7 @@ void *chHeapAlloc(MemoryHeap *heapp, size_t size) { if (heapp == NULL) heapp = &default_heap; - size = MEM_ALIGN_SIZE(size); + size = MEM_ALIGN_NEXT(size); qp = &heapp->h_free; H_LOCK(heapp); diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index 69d3014a5..1fed481c5 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -24,18 +24,20 @@ * @addtogroup memcore * @details Core Memory Manager related APIs and services. *

Operation mode

- * The core memory manager is a simplified allocator that only allows - * to allocate memory blocks without the possibility to free them.
- * This allocator is meant as a memory blocks provider for the other - * allocators such as: + * The core memory manager is a simplified allocator that only + * allows to allocate memory blocks without the possibility to + * free them.
+ * This allocator is meant as a memory blocks provider for the + * other allocators such as: * - C-Runtime allocator (through a compiler specific adapter module). * - Heap allocator (see @ref heaps). * - Memory pools allocator (see @ref pools). * . - * By having a centralized memory provider the various allocators can - * coexist and share the main memory.
- * This allocator, alone, is also useful for very simple applications - * that just require a simple way to get memory blocks. + * By having a centralized memory provider the various allocators + * can coexist and share the main memory.
+ * This allocator, alone, is also useful for very simple + * applications that just require a simple way to get memory + * blocks. * @pre In order to use the core memory manager APIs the @p CH_USE_MEMCORE * option must be enabled in @p chconf.h. * @{ @@ -57,22 +59,20 @@ void core_init(void) { #if CH_MEMCORE_SIZE == 0 extern uint8_t __heap_base__; extern uint8_t __heap_end__; - nextmem = &__heap_base__; - endmem = &__heap_end__; + nextmem = (uint8_t *)MEM_ALIGN_NEXT(&__heap_base__); + endmem = (uint8_t *)MEM_ALIGN_PREV(&__heap_end__); #else - static stkalign_t buffer[MEM_ALIGN_SIZE(CH_MEMCORE_SIZE) / - sizeof(stkalign_t)]; + static stkalign_t buffer[MEM_ALIGN_NEXT(CH_MEMCORE_SIZE)/MEM_ALIGN_SIZE]; nextmem = (uint8_t *)&buffer[0]; - endmem = (uint8_t *)&buffer[MEM_ALIGN_SIZE(CH_MEMCORE_SIZE) / - sizeof(stkalign_t)]; + endmem = (uint8_t *)&buffer[MEM_ALIGN_NEXT(CH_MEMCORE_SIZE)/MEM_ALIGN_SIZE]; #endif } /** * @brief Allocates a memory block. * @details The size of the returned block is aligned to the alignment - * type @p stkalign_t so it is not possible to allocate less - * than sizeof(stkalign_t). + * type so it is not possible to allocate less + * than MEM_ALIGN_SIZE. * * @param[in] size the size of the block to be allocated * @return A pointer to the allocated memory block. @@ -92,8 +92,8 @@ void *chCoreAlloc(size_t size) { /** * @brief Allocates a memory block. * @details The size of the returned block is aligned to the alignment - * type @p align_t so it is not possible to allocate less than - * sizeof(align_t). + * type so it is not possible to allocate less than + * MEM_ALIGN_SIZE. * * @param[in] size the size of the block to be allocated. * @return A pointer to the allocated memory block. @@ -104,7 +104,7 @@ void *chCoreAlloc(size_t size) { void *chCoreAllocI(size_t size) { void *p; - size = MEM_ALIGN_SIZE(size); + size = MEM_ALIGN_NEXT(size); if ((size_t)(endmem - nextmem) < size) return NULL; p = nextmem; diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c index 054823af0..83e6366f4 100644 --- a/os/kernel/src/chmempools.c +++ b/os/kernel/src/chmempools.c @@ -55,7 +55,7 @@ void chPoolInit(MemoryPool *mp, size_t size, memgetfunc_t provider) { chDbgCheck((mp != NULL) && (size >= sizeof(void *)), "chPoolInit"); mp->mp_next = NULL; - mp->mp_object_size = MEM_ALIGN_SIZE(size); + mp->mp_object_size = MEM_ALIGN_NEXT(size); mp->mp_provider = provider; } -- cgit v1.2.3 From 1d00697fe4f8bbe42e0c0d59f76879bd1e575883 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 26 Feb 2011 13:43:07 +0000 Subject: Fixed bug 3193062 (RVCT). git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2766 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmemcore.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index 1fed481c5..c28d150fa 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -57,10 +57,10 @@ static uint8_t *endmem; */ void core_init(void) { #if CH_MEMCORE_SIZE == 0 - extern uint8_t __heap_base__; - extern uint8_t __heap_end__; - nextmem = (uint8_t *)MEM_ALIGN_NEXT(&__heap_base__); - endmem = (uint8_t *)MEM_ALIGN_PREV(&__heap_end__); + extern uint8_t __heap_base__[]; + extern uint8_t __heap_end__[]; + nextmem = (uint8_t *)MEM_ALIGN_NEXT(__heap_base__); + endmem = (uint8_t *)MEM_ALIGN_PREV(__heap_end__); #else static stkalign_t buffer[MEM_ALIGN_NEXT(CH_MEMCORE_SIZE)/MEM_ALIGN_SIZE]; nextmem = (uint8_t *)&buffer[0]; -- cgit v1.2.3 From e7e79a6ccb4f3e320b2b8b7bad1b14d65218641d Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 18 Mar 2011 18:38:08 +0000 Subject: License updated. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2827 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chcond.c | 3 ++- os/kernel/src/chdebug.c | 3 ++- os/kernel/src/chdynamic.c | 3 ++- os/kernel/src/chevents.c | 3 ++- os/kernel/src/chheap.c | 3 ++- os/kernel/src/chlists.c | 3 ++- os/kernel/src/chmboxes.c | 3 ++- os/kernel/src/chmemcore.c | 3 ++- os/kernel/src/chmempools.c | 3 ++- os/kernel/src/chmsg.c | 3 ++- os/kernel/src/chmtx.c | 3 ++- os/kernel/src/chqueues.c | 3 ++- os/kernel/src/chregistry.c | 3 ++- os/kernel/src/chschd.c | 3 ++- os/kernel/src/chsem.c | 3 ++- os/kernel/src/chsys.c | 3 ++- os/kernel/src/chthreads.c | 3 ++- os/kernel/src/chvt.c | 3 ++- 18 files changed, 36 insertions(+), 18 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c index a6534eabc..456fc454f 100644 --- a/os/kernel/src/chcond.c +++ b/os/kernel/src/chcond.c @@ -1,5 +1,6 @@ /* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index 80323e183..be98cd40b 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -1,5 +1,6 @@ /* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chdynamic.c b/os/kernel/src/chdynamic.c index 5f1fc3401..acd23c244 100644 --- a/os/kernel/src/chdynamic.c +++ b/os/kernel/src/chdynamic.c @@ -1,5 +1,6 @@ /* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index a64f59bdc..d74ad2dc4 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -1,5 +1,6 @@ /* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c index c655e3852..a04646bcf 100644 --- a/os/kernel/src/chheap.c +++ b/os/kernel/src/chheap.c @@ -1,5 +1,6 @@ /* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chlists.c b/os/kernel/src/chlists.c index 878f1360c..c3168eafe 100644 --- a/os/kernel/src/chlists.c +++ b/os/kernel/src/chlists.c @@ -1,5 +1,6 @@ /* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c index e0b6ca014..af6ee5ea8 100644 --- a/os/kernel/src/chmboxes.c +++ b/os/kernel/src/chmboxes.c @@ -1,5 +1,6 @@ /* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index c28d150fa..d66ef5f1c 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -1,5 +1,6 @@ /* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c index 83e6366f4..38adc3d49 100644 --- a/os/kernel/src/chmempools.c +++ b/os/kernel/src/chmempools.c @@ -1,5 +1,6 @@ /* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chmsg.c b/os/kernel/src/chmsg.c index d4199bbb0..5002a892a 100644 --- a/os/kernel/src/chmsg.c +++ b/os/kernel/src/chmsg.c @@ -1,5 +1,6 @@ /* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 826ef27fe..af2b7f347 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -1,5 +1,6 @@ /* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index 8d459a7e8..05fbddfb9 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -1,5 +1,6 @@ /* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c index e95ad21a8..9eabe71c0 100644 --- a/os/kernel/src/chregistry.c +++ b/os/kernel/src/chregistry.c @@ -1,5 +1,6 @@ /* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 85e968904..210dbfdc1 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -1,5 +1,6 @@ /* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index 18ea9e996..3e0fcd0e8 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -1,5 +1,6 @@ /* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 0051985ba..db6521b87 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -1,5 +1,6 @@ /* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index a00b5d3db..234cd6ae1 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -1,5 +1,6 @@ /* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c index 016849186..b98396a3a 100644 --- a/os/kernel/src/chvt.c +++ b/os/kernel/src/chvt.c @@ -1,5 +1,6 @@ /* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. -- cgit v1.2.3 From f5ae2552307f20f3fa3d987591fa60576981ce3d Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 29 Mar 2011 14:51:08 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2850 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chdebug.c | 2 +- os/kernel/src/chheap.c | 2 +- os/kernel/src/chmemcore.c | 2 +- os/kernel/src/chschd.c | 2 +- os/kernel/src/chsys.c | 10 +++++----- os/kernel/src/chvt.c | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index be98cd40b..3c3c34c70 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -46,7 +46,7 @@ TraceBuffer trace_buffer; * @brief Trace circular buffer subsystem initialization. * @note Internal use only. */ -void trace_init(void) { +void _trace_init(void) { trace_buffer.tb_size = TRACE_BUFFER_SIZE; trace_buffer.tb_ptr = &trace_buffer.tb_buffer[0]; diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c index a04646bcf..bcfca9b77 100644 --- a/os/kernel/src/chheap.c +++ b/os/kernel/src/chheap.c @@ -65,7 +65,7 @@ static MemoryHeap default_heap; * * @notapi */ -void heap_init(void) { +void _heap_init(void) { default_heap.h_provider = chCoreAlloc; default_heap.h_free.h.u.next = (union heap_header *)NULL; default_heap.h_free.h.size = 0; diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index d66ef5f1c..311d170c5 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -56,7 +56,7 @@ static uint8_t *endmem; * * @notapi */ -void core_init(void) { +void _core_init(void) { #if CH_MEMCORE_SIZE == 0 extern uint8_t __heap_base__[]; extern uint8_t __heap_end__[]; diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 210dbfdc1..54e7918b1 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -45,7 +45,7 @@ ReadyList rlist; * * @notapi */ -void scheduler_init(void) { +void _scheduler_init(void) { queue_init(&rlist.r_queue); rlist.r_prio = NOPRIO; diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index db6521b87..29f4bdc7e 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -76,16 +76,16 @@ void chSysInit(void) { static Thread mainthread; port_init(); - scheduler_init(); - vt_init(); + _scheduler_init(); + _vt_init(); #if CH_USE_MEMCORE - core_init(); + _core_init(); #endif #if CH_USE_HEAP - heap_init(); + _heap_init(); #endif #if CH_DBG_ENABLE_TRACE - trace_init(); + _trace_init(); #endif /* Now this instructions flow becomes the main thread.*/ diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c index b98396a3a..4674c728e 100644 --- a/os/kernel/src/chvt.c +++ b/os/kernel/src/chvt.c @@ -40,7 +40,7 @@ VTList vtlist; * * @notapi */ -void vt_init(void) { +void _vt_init(void) { vtlist.vt_next = vtlist.vt_prev = (void *)&vtlist; vtlist.vt_time = (systime_t)-1; -- cgit v1.2.3 From de877486efb49378065f769ff423eef19ceb12e6 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 9 Apr 2011 15:10:15 +0000 Subject: Fixed bug 3276379. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2872 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsem.c | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index 3e0fcd0e8..c22a568ea 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -313,35 +313,32 @@ void chSemSignalI(Semaphore *sp) { } /** - * @brief Sets the semaphore counter to the specified value. - * @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. + * @brief Adds the specified value to the semaphore counter. * @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 structure - * @param[in] n the new value of the semaphore counter. The value must - * be non-negative. + * @param[in] n value to be added to the semaphore counter. The value + * must be positive. * * @iclass */ -void chSemSetCounterI(Semaphore *sp, cnt_t n) { - cnt_t cnt; +void chSemAddCounterI(Semaphore *sp, cnt_t n) { - chDbgCheck((sp != NULL) && (n >= 0), "chSemSetCounterI"); + chDbgCheck((sp != NULL) && (n > 0), "chSemAddCounterI"); chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) || ((sp->s_cnt < 0) && notempty(&sp->s_queue)), - "chSemSetCounterI(), #1", + "chSemAddCounterI(), #1", "inconsistent semaphore"); - cnt = sp->s_cnt; - sp->s_cnt = n; - while (++cnt <= 0) - chSchReadyI(lifo_remove(&sp->s_queue))->p_u.rdymsg = RDY_OK; + while (n > 0) { + if (++sp->s_cnt <= 0) + chSchReadyI(fifo_remove(&sp->s_queue))->p_u.rdymsg = RDY_OK; + n--; + } } #if CH_USE_SEMSW -- cgit v1.2.3 From 85f17ebe017f0ef2a42d96eb3525346db5b9c65e Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 13 May 2011 17:20:39 +0000 Subject: Customer CR. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2951 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsys.c | 4 ++++ os/kernel/src/chthreads.c | 3 +-- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 29f4bdc7e..5d3c0bcf4 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -35,6 +35,7 @@ #include "ch.h" +#if !CH_NO_IDLE_THREAD || defined(__DOXYGEN__) /** * @brief Idle thread working area. * @see IDLE_THREAD_STACK_SIZE @@ -59,6 +60,7 @@ void _idle_thread(void *p) { IDLE_LOOP_HOOK(); } } +#endif /* CH_NO_IDLE_THREAD */ /** * @brief ChibiOS/RT initialization. @@ -93,11 +95,13 @@ void chSysInit(void) { currp->p_state = THD_STATE_CURRENT; chSysEnable(); +#if !CH_NO_IDLE_THREAD /* This thread has the lowest priority in the system, its role is just to serve interrupts in its context while keeping the lowest energy saving mode compatible with the system status.*/ chThdCreateStatic(_idle_thread_wa, sizeof(_idle_thread_wa), IDLEPRIO, (tfunc_t)_idle_thread, NULL); +#endif } /** diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 234cd6ae1..7df276bea 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -206,8 +206,7 @@ Thread *chThdCreateStatic(void *wsp, size_t size, tprio_t chThdSetPriority(tprio_t newprio) { tprio_t oldprio; - chDbgCheck((newprio >= LOWPRIO) && (newprio <= HIGHPRIO), - "chThdSetPriority"); + chDbgCheck(newprio <= HIGHPRIO, "chThdSetPriority"); chSysLock(); #if CH_USE_MUTEXES -- cgit v1.2.3 From e0b53350156cef01da9b83e46127f7322e967909 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 17 May 2011 14:49:51 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2966 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 5d3c0bcf4..13a1a53fa 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -40,7 +40,7 @@ * @brief Idle thread working area. * @see IDLE_THREAD_STACK_SIZE */ -WORKING_AREA(_idle_thread_wa, IDLE_THREAD_STACK_SIZE); +WORKING_AREA(_idle_thread_wa, PORT_IDLE_THREAD_STACK_SIZE); /** * @brief This function implements the idle thread infinite loop. -- cgit v1.2.3 From b4aa14e88c9e28a16a5f9c0c220fac6cc36750ad Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 18 May 2011 09:03:50 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2971 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsys.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 13a1a53fa..6892ec73a 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -38,7 +38,7 @@ #if !CH_NO_IDLE_THREAD || defined(__DOXYGEN__) /** * @brief Idle thread working area. - * @see IDLE_THREAD_STACK_SIZE + * @see PORT_IDLE_THREAD_STACK_SIZE */ WORKING_AREA(_idle_thread_wa, PORT_IDLE_THREAD_STACK_SIZE); -- cgit v1.2.3 From 807c5f1882224c2afd471a44889b83c2adf80589 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 18 May 2011 17:54:55 +0000 Subject: Fixed bug 3303908. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2972 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 8 +-- os/kernel/src/chqueues.c | 124 +++++++++++++++++++++++++---------------------- os/kernel/src/chschd.c | 6 ++- 3 files changed, 75 insertions(+), 63 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index af2b7f347..df71d1cc6 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -134,14 +134,16 @@ void chMtxLockS(Mutex *mp) { prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); tp = ((Mutex *)tp->p_u.wtobjp)->m_owner; continue; -#if CH_USE_CONDVARS | CH_USE_SEMAPHORES_PRIORITY | CH_USE_MESSAGES_PRIORITY +#if CH_USE_CONDVARS | \ + (CH_USE_SEMAPHORES && CH_USE_SEMAPHORES_PRIORITY) | \ + (CH_USE_MESSAGES && CH_USE_MESSAGES_PRIORITY) #if CH_USE_CONDVARS case THD_STATE_WTCOND: #endif -#if CH_USE_SEMAPHORES_PRIORITY +#if CH_USE_SEMAPHORES && CH_USE_SEMAPHORES_PRIORITY case THD_STATE_WTSEM: #endif -#if CH_USE_MESSAGES_PRIORITY +#if CH_USE_MESSAGES && CH_USE_MESSAGES_PRIORITY case THD_STATE_SNDMSGQ: #endif /* Re-enqueues tp with its new priority on the queue.*/ diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index 05fbddfb9..f6ae10257 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -47,6 +47,30 @@ #if CH_USE_QUEUES || defined(__DOXYGEN__) +/** + * @brief Puts the invoking thread into the queue's threads queue. + * + * @param[out] qp pointer to an @p GenericQueue structure + * @param[in] time 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 threads queue. + * @retval RDY_OK is the normal exit, thread signaled. + * @retval RDY_RESET if the queue has been reset. + * @retval RDY_TIMEOUT if the queue operation timed out. + */ +static msg_t qwait(GenericQueue *qp, systime_t time) { + + if (TIME_IMMEDIATE == time) + return RDY_TIMEOUT; + currp->p_u.wtobjp = qp; + queue_insert(currp, &qp->q_waiting); + return chSchGoSleepTimeoutS(THD_STATE_WTQUEUE, time); +} + /** * @brief Initializes an input queue. * @details A Semaphore is internally initialized and works as a counter of @@ -64,28 +88,11 @@ */ void chIQInit(InputQueue *iqp, uint8_t *bp, size_t size, qnotify_t infy) { + queue_init(&iqp->q_waiting); + iqp->q_counter = 0; iqp->q_buffer = iqp->q_rdptr = iqp->q_wrptr = bp; iqp->q_top = bp + size; iqp->q_notify = infy; - chSemInit(&iqp->q_sem, 0); -} - -/** - * @brief Returns the filled space into an input queue. - * - * @param[in] iqp pointer to an @p InputQueue structure - * @return The number of bytes in the queue. - * @retval 0 if the queue is empty. - * - * @iclass - */ -size_t chIQGetFullI(InputQueue *iqp) { - cnt_t cnt; - - cnt = chQSpaceI(iqp); - if (cnt < 0) - return 0; - return (size_t)cnt; } /** @@ -102,7 +109,9 @@ size_t chIQGetFullI(InputQueue *iqp) { void chIQResetI(InputQueue *iqp) { iqp->q_rdptr = iqp->q_wrptr = iqp->q_buffer; - chSemResetI(&iqp->q_sem, 0); + iqp->q_counter = 0; + while (notempty(&iqp->q_waiting)) + chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = RDY_RESET; } /** @@ -123,10 +132,12 @@ msg_t chIQPutI(InputQueue *iqp, uint8_t b) { if (chIQIsFullI(iqp)) return Q_FULL; + iqp->q_counter++; *iqp->q_wrptr++ = b; if (iqp->q_wrptr >= iqp->q_top) iqp->q_wrptr = iqp->q_buffer; - chSemSignalI(&iqp->q_sem); + if (notempty(&iqp->q_waiting)) + chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = RDY_OK; return Q_OK; } @@ -150,17 +161,21 @@ msg_t chIQPutI(InputQueue *iqp, uint8_t b) { */ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) { uint8_t b; - msg_t msg; chSysLock(); - if (iqp->q_notify) iqp->q_notify(iqp); - if ((msg = chSemWaitTimeoutS(&iqp->q_sem, time)) < RDY_OK) { - chSysUnlock(); - return msg; + while (chIQIsEmptyI(iqp)) { + msg_t msg; + + if ((msg = qwait((GenericQueue *)iqp, time)) < RDY_OK) { + chSysUnlock(); + return msg; + } } + + iqp->q_counter--; b = *iqp->q_rdptr++; if (iqp->q_rdptr >= iqp->q_top) iqp->q_rdptr = iqp->q_buffer; @@ -202,16 +217,16 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, chSysLock(); while (TRUE) { - if (chIQIsEmptyI(iqp)) { + while (chIQIsEmptyI(iqp)) { if (nfy) nfy(iqp); - if ((chSemWaitTimeoutS(&iqp->q_sem, time) != RDY_OK)) { + if (qwait((GenericQueue *)iqp, time) != RDY_OK) { chSysUnlock(); return r; } } - else - chSemFastWaitI(&iqp->q_sem); + + iqp->q_counter--; *bp++ = *iqp->q_rdptr++; if (iqp->q_rdptr >= iqp->q_top) iqp->q_rdptr = iqp->q_buffer; @@ -245,28 +260,11 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, */ void chOQInit(OutputQueue *oqp, uint8_t *bp, size_t size, qnotify_t onfy) { + queue_init(&oqp->q_waiting); + oqp->q_counter = size; oqp->q_buffer = oqp->q_rdptr = oqp->q_wrptr = bp; oqp->q_top = bp + size; oqp->q_notify = onfy; - chSemInit(&oqp->q_sem, (cnt_t)size); -} - -/** - * @brief Returns the filled space into an output queue. - * - * @param[in] oqp pointer to an @p OutputQueue structure - * @return The number of bytes in the queue. - * @retval 0 if the queue is empty. - * - * @iclass - */ -size_t chOQGetFullI(OutputQueue *oqp) { - cnt_t cnt; - - cnt = chQSpaceI(oqp); - if (cnt < 0) - return chQSizeI(oqp); - return chQSizeI(oqp) - (size_t)cnt; } /** @@ -283,7 +281,9 @@ size_t chOQGetFullI(OutputQueue *oqp) { void chOQResetI(OutputQueue *oqp) { oqp->q_rdptr = oqp->q_wrptr = oqp->q_buffer; - chSemResetI(&oqp->q_sem, (cnt_t)(oqp->q_top - oqp->q_buffer)); + oqp->q_counter = chQSizeI(oqp); + while (notempty(&oqp->q_waiting)) + chSchReadyI(fifo_remove(&oqp->q_waiting))->p_u.rdymsg = RDY_RESET; } /** @@ -307,13 +307,18 @@ void chOQResetI(OutputQueue *oqp) { * @api */ msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t time) { - msg_t msg; chSysLock(); - if ((msg = chSemWaitTimeoutS(&oqp->q_sem, time)) < RDY_OK) { - chSysUnlock(); - return msg; + while (chOQIsFullI(oqp)) { + msg_t msg; + + if ((msg = qwait((GenericQueue *)oqp, time)) < RDY_OK) { + chSysUnlock(); + return msg; + } } + + oqp->q_counter--; *oqp->q_wrptr++ = b; if (oqp->q_wrptr >= oqp->q_top) oqp->q_wrptr = oqp->q_buffer; @@ -341,10 +346,12 @@ msg_t chOQGetI(OutputQueue *oqp) { if (chOQIsEmptyI(oqp)) return Q_EMPTY; + oqp->q_counter++; b = *oqp->q_rdptr++; if (oqp->q_rdptr >= oqp->q_top) oqp->q_rdptr = oqp->q_buffer; - chSemSignalI(&oqp->q_sem); + if (notempty(&oqp->q_waiting)) + chSchReadyI(fifo_remove(&oqp->q_waiting))->p_u.rdymsg = RDY_OK; return b; } @@ -381,16 +388,15 @@ size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp, chSysLock(); while (TRUE) { - if (chOQIsFullI(oqp)) { + while (chOQIsFullI(oqp)) { if (nfy) nfy(oqp); - if ((chSemWaitTimeoutS(&oqp->q_sem, time) != RDY_OK)) { + if (qwait((GenericQueue *)oqp, time) != RDY_OK) { chSysUnlock(); return w; } } - else - chSemFastWaitI(&oqp->q_sem); + oqp->q_counter--; *oqp->q_wrptr++ = *bp++; if (oqp->q_wrptr >= oqp->q_top) oqp->q_wrptr = oqp->q_buffer; diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 54e7918b1..d41649b4c 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -130,12 +130,16 @@ static void wakeup(void *p) { /* Handling the special case where the thread has been made ready by another thread with higher priority.*/ return; -#if CH_USE_SEMAPHORES || (CH_USE_CONDVARS && CH_USE_CONDVARS_TIMEOUT) +#if CH_USE_SEMAPHORES || CH_USE_QUEUES || \ + (CH_USE_CONDVARS && CH_USE_CONDVARS_TIMEOUT) #if CH_USE_SEMAPHORES case THD_STATE_WTSEM: chSemFastSignalI((Semaphore *)tp->p_u.wtobjp); /* Falls into, intentional. */ #endif +#if CH_USE_QUEUES + case THD_STATE_WTQUEUE: +#endif #if CH_USE_CONDVARS && CH_USE_CONDVARS_TIMEOUT case THD_STATE_WTCOND: #endif -- cgit v1.2.3 From 5e1249af266c9688ec575e5a2f14ecfe6084de49 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 19 May 2011 09:13:24 +0000 Subject: Fixed bug 3303841. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2973 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chheap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c index bcfca9b77..b90b21909 100644 --- a/os/kernel/src/chheap.c +++ b/os/kernel/src/chheap.c @@ -80,6 +80,8 @@ void _heap_init(void) { * @brief Initializes a memory heap from a static memory area. * @pre Both the heap buffer base and the heap size must be aligned to * the @p stkalign_t type size. + * @pre In order to use this function the option @p CH_USE_MALLOC_HEAP + * must be disabled. * * @param[out] heapp pointer to the memory heap descriptor to be initialized * @param[in] buf heap buffer base @@ -271,7 +273,7 @@ static Mutex hmtx; static Semaphore hsem; #endif -void heap_init(void) { +void _heap_init(void) { #if CH_USE_MUTEXES chMtxInit(&hmtx); -- cgit v1.2.3 From 3495905f51318549a2bd6764360a4812aac869fa Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 19 May 2011 17:46:52 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2974 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chqueues.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index f6ae10257..767a36e63 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -58,14 +58,14 @@ * . * @return A message specifying how the invoking thread has been * released from threads queue. - * @retval RDY_OK is the normal exit, thread signaled. - * @retval RDY_RESET if the queue has been reset. - * @retval RDY_TIMEOUT if the queue operation timed out. + * @retval Q_OK is the normal exit, thread signaled. + * @retval Q_RESET if the queue has been reset. + * @retval Q_TIMEOUT if the queue operation timed out. */ static msg_t qwait(GenericQueue *qp, systime_t time) { if (TIME_IMMEDIATE == time) - return RDY_TIMEOUT; + return Q_TIMEOUT; currp->p_u.wtobjp = qp; queue_insert(currp, &qp->q_waiting); return chSchGoSleepTimeoutS(THD_STATE_WTQUEUE, time); @@ -111,7 +111,7 @@ void chIQResetI(InputQueue *iqp) { iqp->q_rdptr = iqp->q_wrptr = iqp->q_buffer; iqp->q_counter = 0; while (notempty(&iqp->q_waiting)) - chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = RDY_RESET; + chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = Q_RESET; } /** @@ -137,7 +137,7 @@ msg_t chIQPutI(InputQueue *iqp, uint8_t b) { if (iqp->q_wrptr >= iqp->q_top) iqp->q_wrptr = iqp->q_buffer; if (notempty(&iqp->q_waiting)) - chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = RDY_OK; + chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = Q_OK; return Q_OK; } @@ -155,7 +155,7 @@ msg_t chIQPutI(InputQueue *iqp, uint8_t b) { * . * @return A byte value from the queue. * @retval Q_TIMEOUT if the specified time expired. - * @retval Q_RESET if the queue was reset. + * @retval Q_RESET if the queue has been reset. * * @api */ @@ -163,13 +163,13 @@ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) { uint8_t b; chSysLock(); - if (iqp->q_notify) - iqp->q_notify(iqp); - while (chIQIsEmptyI(iqp)) { msg_t msg; - if ((msg = qwait((GenericQueue *)iqp, time)) < RDY_OK) { + if (iqp->q_notify) + iqp->q_notify(iqp); + + if ((msg = qwait((GenericQueue *)iqp, time)) < Q_OK) { chSysUnlock(); return msg; } @@ -220,7 +220,7 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, while (chIQIsEmptyI(iqp)) { if (nfy) nfy(iqp); - if (qwait((GenericQueue *)iqp, time) != RDY_OK) { + if (qwait((GenericQueue *)iqp, time) != Q_OK) { chSysUnlock(); return r; } @@ -283,7 +283,7 @@ void chOQResetI(OutputQueue *oqp) { oqp->q_rdptr = oqp->q_wrptr = oqp->q_buffer; oqp->q_counter = chQSizeI(oqp); while (notempty(&oqp->q_waiting)) - chSchReadyI(fifo_remove(&oqp->q_waiting))->p_u.rdymsg = RDY_RESET; + chSchReadyI(fifo_remove(&oqp->q_waiting))->p_u.rdymsg = Q_RESET; } /** @@ -302,7 +302,7 @@ void chOQResetI(OutputQueue *oqp) { * @return The operation status. * @retval Q_OK if the operation succeeded. * @retval Q_TIMEOUT if the specified time expired. - * @retval Q_RESET if the queue was reset. + * @retval Q_RESET if the queue has been reset. * * @api */ @@ -312,7 +312,7 @@ msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t time) { while (chOQIsFullI(oqp)) { msg_t msg; - if ((msg = qwait((GenericQueue *)oqp, time)) < RDY_OK) { + if ((msg = qwait((GenericQueue *)oqp, time)) < Q_OK) { chSysUnlock(); return msg; } @@ -351,7 +351,7 @@ msg_t chOQGetI(OutputQueue *oqp) { if (oqp->q_rdptr >= oqp->q_top) oqp->q_rdptr = oqp->q_buffer; if (notempty(&oqp->q_waiting)) - chSchReadyI(fifo_remove(&oqp->q_waiting))->p_u.rdymsg = RDY_OK; + chSchReadyI(fifo_remove(&oqp->q_waiting))->p_u.rdymsg = Q_OK; return b; } @@ -391,7 +391,7 @@ size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp, while (chOQIsFullI(oqp)) { if (nfy) nfy(oqp); - if (qwait((GenericQueue *)oqp, time) != RDY_OK) { + if (qwait((GenericQueue *)oqp, time) != Q_OK) { chSysUnlock(); return w; } -- cgit v1.2.3 From f4ec81ae144ef2ae7ddd9a0e56082970420c0464 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 20 May 2011 12:46:24 +0000 Subject: USB CDC functionality restored, more improvements to the I/O queues. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2983 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chqueues.c | 41 +++++++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 18 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index 767a36e63..8532f8307 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -136,8 +136,10 @@ msg_t chIQPutI(InputQueue *iqp, uint8_t b) { *iqp->q_wrptr++ = b; if (iqp->q_wrptr >= iqp->q_top) iqp->q_wrptr = iqp->q_buffer; + if (notempty(&iqp->q_waiting)) chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = Q_OK; + return Q_OK; } @@ -146,6 +148,9 @@ msg_t chIQPutI(InputQueue *iqp, uint8_t b) { * @details This function reads a byte value from an input queue. If the queue * is empty then the calling thread is suspended until a byte arrives * in the queue or a timeout occurs. + * @note The callback is invoked if the queue is empty before entering the + * @p THD_STATE_WTQUEUE state in order to solicit the low level to + * start queue filling. * * @param[in] iqp pointer to an @p InputQueue structure * @param[in] time the number of ticks before the operation timeouts, @@ -192,8 +197,9 @@ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) { * been reset. * @note The function is not atomic, if you need atomicity it is suggested * to use a semaphore or a mutex for mutual exclusion. - * @note The queue callback is invoked before entering a sleep state and at - * the end of the transfer. + * @note The callback is invoked if the queue is empty before entering the + * @p THD_STATE_WTQUEUE state in order to solicit the low level to + * start queue filling. * * @param[in] iqp pointer to an @p InputQueue structure * @param[out] bp pointer to the data buffer @@ -220,6 +226,7 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, while (chIQIsEmptyI(iqp)) { if (nfy) nfy(iqp); + if (qwait((GenericQueue *)iqp, time) != Q_OK) { chSysUnlock(); return r; @@ -230,15 +237,12 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, *bp++ = *iqp->q_rdptr++; if (iqp->q_rdptr >= iqp->q_top) iqp->q_rdptr = iqp->q_buffer; + chSysUnlock(); /* Gives a preemption chance in a controlled point.*/ r++; - if (--n == 0) { - chSysLock(); - if (nfy) - nfy(iqp); - chSysUnlock(); + if (--n == 0) return r; - } + chSysLock(); } } @@ -291,6 +295,8 @@ void chOQResetI(OutputQueue *oqp) { * @details This function writes a byte value to an output queue. If the queue * is full then the calling thread is suspended until there is space * in the queue or a timeout occurs. + * @note The callback is invoked after writing the character into the + * buffer. * * @param[in] oqp pointer to an @p OutputQueue structure * @param[in] b the byte value to be written in the queue @@ -350,8 +356,10 @@ msg_t chOQGetI(OutputQueue *oqp) { b = *oqp->q_rdptr++; if (oqp->q_rdptr >= oqp->q_top) oqp->q_rdptr = oqp->q_buffer; + if (notempty(&oqp->q_waiting)) chSchReadyI(fifo_remove(&oqp->q_waiting))->p_u.rdymsg = Q_OK; + return b; } @@ -363,8 +371,8 @@ msg_t chOQGetI(OutputQueue *oqp) { * been reset. * @note The function is not atomic, if you need atomicity it is suggested * to use a semaphore or a mutex for mutual exclusion. - * @note The queue callback is invoked before entering a sleep state and at - * the end of the transfer. + * @note The callback is invoked after writing each character into the + * buffer. * * @param[in] oqp pointer to an @p OutputQueue structure * @param[out] bp pointer to the data buffer @@ -389,8 +397,6 @@ size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp, chSysLock(); while (TRUE) { while (chOQIsFullI(oqp)) { - if (nfy) - nfy(oqp); if (qwait((GenericQueue *)oqp, time) != Q_OK) { chSysUnlock(); return w; @@ -400,15 +406,14 @@ size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp, *oqp->q_wrptr++ = *bp++; if (oqp->q_wrptr >= oqp->q_top) oqp->q_wrptr = oqp->q_buffer; + + if (nfy) + nfy(oqp); + chSysUnlock(); /* Gives a preemption chance in a controlled point.*/ w++; - if (--n == 0) { - chSysLock(); - if (nfy) - nfy(oqp); - chSysUnlock(); + if (--n == 0) return w; - } chSysLock(); } } -- cgit v1.2.3 From d79eea31a268ce14b60b30d929b2d2c905048d98 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 8 Jul 2011 19:29:00 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3135 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsys.c | 3 +++ os/kernel/src/chthreads.c | 7 ++++--- 2 files changed, 7 insertions(+), 3 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 6892ec73a..8d9ce4905 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -55,6 +55,7 @@ WORKING_AREA(_idle_thread_wa, PORT_IDLE_THREAD_STACK_SIZE); void _idle_thread(void *p) { (void)p; + chRegSetThreadName("idle"); while (TRUE) { port_wait_for_interrupt(); IDLE_LOOP_HOOK(); @@ -95,6 +96,8 @@ void chSysInit(void) { currp->p_state = THD_STATE_CURRENT; chSysEnable(); + chRegSetThreadName("main"); + #if !CH_NO_IDLE_THREAD /* This thread has the lowest priority in the system, its role is just to serve interrupts in its context while keeping the lowest energy saving diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 7df276bea..3d64eb993 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -89,15 +89,16 @@ Thread *_thread_init(Thread *tp, tprio_t prio) { #if CH_USE_DYNAMIC tp->p_refs = 1; #endif +#if CH_USE_REGISTRY + tp->p_name = NULL; + REG_INSERT(tp); +#endif #if CH_USE_WAITEXIT list_init(&tp->p_waiting); #endif #if CH_USE_MESSAGES queue_init(&tp->p_msgqueue); #endif -#if CH_USE_REGISTRY - REG_INSERT(tp); -#endif #if defined(THREAD_EXT_INIT_HOOK) THREAD_EXT_INIT_HOOK(tp); #endif -- cgit v1.2.3 From b38e1f2c96ca1940f210be9ec2de6eeb076f1a10 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 9 Jul 2011 09:15:49 +0000 Subject: Improvements to the trace buffer and other debug features. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3139 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chdebug.c | 23 ++++++++++++----------- os/kernel/src/chthreads.c | 4 ++-- 2 files changed, 14 insertions(+), 13 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index 3c3c34c70..208ac2a69 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -40,7 +40,7 @@ /** * @brief Public trace buffer. */ -TraceBuffer trace_buffer; +ch_trace_buffer_t ch_dbg_trace_buffer; /** * @brief Trace circular buffer subsystem initialization. @@ -48,8 +48,8 @@ TraceBuffer trace_buffer; */ void _trace_init(void) { - trace_buffer.tb_size = TRACE_BUFFER_SIZE; - trace_buffer.tb_ptr = &trace_buffer.tb_buffer[0]; + ch_dbg_trace_buffer.tb_size = CH_TRACE_BUFFER_SIZE; + ch_dbg_trace_buffer.tb_ptr = &ch_dbg_trace_buffer.tb_buffer[0]; } /** @@ -61,12 +61,13 @@ void _trace_init(void) { */ void chDbgTrace(Thread *otp) { - trace_buffer.tb_ptr->cse_wtobjp = otp->p_u.wtobjp; - trace_buffer.tb_ptr->cse_time = chTimeNow(); - trace_buffer.tb_ptr->cse_state = otp->p_state; - trace_buffer.tb_ptr->cse_tid = (unsigned)currp >> 6; - if (++trace_buffer.tb_ptr >= &trace_buffer.tb_buffer[TRACE_BUFFER_SIZE]) - trace_buffer.tb_ptr = &trace_buffer.tb_buffer[0]; + ch_dbg_trace_buffer.tb_ptr->se_time = chTimeNow(); + ch_dbg_trace_buffer.tb_ptr->se_tp = currp; + ch_dbg_trace_buffer.tb_ptr->se_wtobjp = otp->p_u.wtobjp; + ch_dbg_trace_buffer.tb_ptr->se_state = (uint8_t)otp->p_state; + if (++ch_dbg_trace_buffer.tb_ptr >= + &ch_dbg_trace_buffer.tb_buffer[CH_TRACE_BUFFER_SIZE]) + ch_dbg_trace_buffer.tb_ptr = &ch_dbg_trace_buffer.tb_buffer[0]; } #endif /* CH_DBG_ENABLE_TRACE */ @@ -78,7 +79,7 @@ void chDbgTrace(Thread *otp) { * written once and then the system is halted. This variable can be * set to @p NULL if the halt is caused by a stack overflow. */ -char *panic_msg; +char *ch_dbg_panic_msg; /** * @brief Prints a panic message on the console and then halts the system. @@ -87,7 +88,7 @@ char *panic_msg; */ void chDbgPanic(char *msg) { - panic_msg = msg; + ch_dbg_panic_msg = msg; chSysHalt(); } #endif /* CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK */ diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 3d64eb993..b68263a7b 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -181,10 +181,10 @@ Thread *chThdCreateStatic(void *wsp, size_t size, #if CH_DBG_FILL_THREADS _thread_memfill((uint8_t *)wsp, (uint8_t *)wsp + sizeof(Thread), - THREAD_FILL_VALUE); + CH_THREAD_FILL_VALUE); _thread_memfill((uint8_t *)wsp + sizeof(Thread), (uint8_t *)wsp + size, - STACK_FILL_VALUE); + CH_STACK_FILL_VALUE); #endif chSysLock(); chSchWakeupS(tp = chThdCreateI(wsp, size, prio, pf, arg), RDY_OK); -- cgit v1.2.3 From fbdd64538eb54452fd320e20eaba2fb094874a3e Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 10 Jul 2011 08:45:36 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3144 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chdebug.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index 208ac2a69..0e378cc6d 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -40,7 +40,7 @@ /** * @brief Public trace buffer. */ -ch_trace_buffer_t ch_dbg_trace_buffer; +ch_trace_buffer_t dbg_trace_buffer; /** * @brief Trace circular buffer subsystem initialization. @@ -48,8 +48,8 @@ ch_trace_buffer_t ch_dbg_trace_buffer; */ void _trace_init(void) { - ch_dbg_trace_buffer.tb_size = CH_TRACE_BUFFER_SIZE; - ch_dbg_trace_buffer.tb_ptr = &ch_dbg_trace_buffer.tb_buffer[0]; + dbg_trace_buffer.tb_size = CH_TRACE_BUFFER_SIZE; + dbg_trace_buffer.tb_ptr = &dbg_trace_buffer.tb_buffer[0]; } /** @@ -61,13 +61,13 @@ void _trace_init(void) { */ void chDbgTrace(Thread *otp) { - ch_dbg_trace_buffer.tb_ptr->se_time = chTimeNow(); - ch_dbg_trace_buffer.tb_ptr->se_tp = currp; - ch_dbg_trace_buffer.tb_ptr->se_wtobjp = otp->p_u.wtobjp; - ch_dbg_trace_buffer.tb_ptr->se_state = (uint8_t)otp->p_state; - if (++ch_dbg_trace_buffer.tb_ptr >= - &ch_dbg_trace_buffer.tb_buffer[CH_TRACE_BUFFER_SIZE]) - ch_dbg_trace_buffer.tb_ptr = &ch_dbg_trace_buffer.tb_buffer[0]; + dbg_trace_buffer.tb_ptr->se_time = chTimeNow(); + dbg_trace_buffer.tb_ptr->se_tp = currp; + dbg_trace_buffer.tb_ptr->se_wtobjp = otp->p_u.wtobjp; + dbg_trace_buffer.tb_ptr->se_state = (uint8_t)otp->p_state; + if (++dbg_trace_buffer.tb_ptr >= + &dbg_trace_buffer.tb_buffer[CH_TRACE_BUFFER_SIZE]) + dbg_trace_buffer.tb_ptr = &dbg_trace_buffer.tb_buffer[0]; } #endif /* CH_DBG_ENABLE_TRACE */ @@ -79,7 +79,7 @@ void chDbgTrace(Thread *otp) { * written once and then the system is halted. This variable can be * set to @p NULL if the halt is caused by a stack overflow. */ -char *ch_dbg_panic_msg; +char *dbg_panic_msg; /** * @brief Prints a panic message on the console and then halts the system. @@ -88,7 +88,7 @@ char *ch_dbg_panic_msg; */ void chDbgPanic(char *msg) { - ch_dbg_panic_msg = msg; + dbg_panic_msg = msg; chSysHalt(); } #endif /* CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK */ -- cgit v1.2.3 From 075ff711f1c9cf031fa4708c6b704f120d9a509d Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 7 Aug 2011 09:00:12 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3192 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsys.c | 6 ++++++ os/kernel/src/chthreads.c | 3 +++ 2 files changed, 9 insertions(+) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 8d9ce4905..4c8cd708d 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -77,6 +77,9 @@ void _idle_thread(void *p) { */ void chSysInit(void) { static Thread mainthread; +#if CH_DBG_ENABLE_STACK_CHECK + extern stkalign_t __main_thread_stack_base__; +#endif port_init(); _scheduler_init(); @@ -94,6 +97,9 @@ void chSysInit(void) { /* Now this instructions flow becomes the main thread.*/ setcurrp(_thread_init(&mainthread, NORMALPRIO)); currp->p_state = THD_STATE_CURRENT; +#if CH_DBG_ENABLE_STACK_CHECK + currp->p_stklimit = &__main_thread_stack_base__; +#endif chSysEnable(); chRegSetThreadName("main"); diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index b68263a7b..182de7673 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -99,6 +99,9 @@ Thread *_thread_init(Thread *tp, tprio_t prio) { #if CH_USE_MESSAGES queue_init(&tp->p_msgqueue); #endif +#if CH_DBG_ENABLE_STACK_CHECK + tp->p_stklimit = (stkalign_t *)(tp + 1); +#endif #if defined(THREAD_EXT_INIT_HOOK) THREAD_EXT_INIT_HOOK(tp); #endif -- cgit v1.2.3 From 68ae8aa1bca89d841dc539562dd53cd546fe2649 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 9 Aug 2011 10:09:05 +0000 Subject: Fixed missing CH_ prefix in filler constants. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3215 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chdynamic.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chdynamic.c b/os/kernel/src/chdynamic.c index acd23c244..fd60071e8 100644 --- a/os/kernel/src/chdynamic.c +++ b/os/kernel/src/chdynamic.c @@ -132,10 +132,10 @@ Thread *chThdCreateFromHeap(MemoryHeap *heapp, size_t size, #if CH_DBG_FILL_THREADS _thread_memfill((uint8_t *)wsp, (uint8_t *)wsp + sizeof(Thread), - THREAD_FILL_VALUE); + CH_THREAD_FILL_VALUE); _thread_memfill((uint8_t *)wsp + sizeof(Thread), (uint8_t *)wsp + size, - STACK_FILL_VALUE); + CH_STACK_FILL_VALUE); #endif chSysLock(); @@ -183,10 +183,10 @@ Thread *chThdCreateFromMemoryPool(MemoryPool *mp, tprio_t prio, #if CH_DBG_FILL_THREADS _thread_memfill((uint8_t *)wsp, (uint8_t *)wsp + sizeof(Thread), - THREAD_FILL_VALUE); + CH_THREAD_FILL_VALUE); _thread_memfill((uint8_t *)wsp + sizeof(Thread), (uint8_t *)wsp + mp->mp_object_size, - STACK_FILL_VALUE); + CH_STACK_FILL_VALUE); #endif chSysLock(); -- cgit v1.2.3 From b9933c2089f5f0cd93738ae9081c45fcf3df54b7 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 11 Aug 2011 17:51:37 +0000 Subject: Implemented system state checker debug option, remove the option CH_USE_NESTED_LOCKS. Documentation improvements and fixes. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3221 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chdebug.c | 163 +++++++++++++++++++++++++++++++++++++++++++++--- os/kernel/src/chmtx.c | 1 + os/kernel/src/chschd.c | 3 - os/kernel/src/chsys.c | 22 +------ 4 files changed, 157 insertions(+), 32 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index 0e378cc6d..28d4f7520 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -24,18 +24,161 @@ * * @addtogroup debug * @details Debug APIs and services: + * - Runtime system state and call protocol check. The following + * panic messages can be generated: + * - SV#1, misplaced @p chSysDisable(). + * - SV#2, misplaced @p chSysSuspend() + * - SV#3, misplaced @p chSysEnable(). + * - SV#4, misplaced @p chSysLock(). + * - SV#5, misplaced @p chSysUnlock(). + * - SV#6, misplaced @p chSysLockFromIsr(). + * - SV#7, misplaced @p chSysUnlockFromIsr(). + * - SV#8, misplaced @p CH_IRQ_PROLOGUE(). + * - SV#9, misplaced @p CH_IRQ_EPILOGUE(). + * . * - Trace buffer. * - Parameters check. * - Kernel assertions. + * - Kernel panics. * . - * @pre In order to use the debug APIs the @p CH_DBG_ENABLE_TRACE, - * @p CH_DBG_ENABLE_ASSERTS, @p CH_DBG_ENABLE_CHECKS options must - * be enabled in @p chconf.h. + * @note Stack checks are not implemented in this module but in the port + * layer in an architecture-dependent way. * @{ */ #include "ch.h" +/*===========================================================================*/ +/* System state checker related code and variables. */ +/*===========================================================================*/ + +#if CH_DBG_SYSTEM_STATE_CHECK || defined(__DOXYGEN__) + +/** + * @brief ISR nesting level. + */ +cnt_t dbg_isr_cnt; + +/** + * @brief Lock nesting level. + */ +cnt_t dbg_lock_cnt; + +/** + * @brief Guard code for @p chSysDisable(). + * + * @notapi + */ +void dbg_check_disable(void) { + + if ((dbg_isr_cnt != 0) || (dbg_lock_cnt != 0)) + chDbgPanic("SV#1"); +} + +/** + * @brief Guard code for @p chSysSuspend(). + * + * @notapi + */ +void dbg_check_suspend(void) { + + if ((dbg_isr_cnt != 0) || (dbg_lock_cnt != 0)) + chDbgPanic("SV#2"); +} + +/** + * @brief Guard code for @p chSysEnable(). + * + * @notapi + */ +void dbg_check_enable(void) { + + if ((dbg_isr_cnt != 0) || (dbg_lock_cnt != 0)) + chDbgPanic("SV#3"); +} + +/** + * @brief Guard code for @p chSysLock(). + * + * @notapi + */ +void dbg_check_lock(void) { + + if ((dbg_isr_cnt != 0) || (dbg_lock_cnt != 0)) + chDbgPanic("SV#4"); + dbg_lock_cnt = 1; +} + +/** + * @brief Guard code for @p chSysUnlock(). + * + * @notapi + */ +void dbg_check_unlock(void) { + + if ((dbg_isr_cnt != 0) || (dbg_lock_cnt <= 0)) + chDbgPanic("SV#5"); + dbg_lock_cnt = 0; +} + +/** + * @brief Guard code for @p chSysLockFromIsr(). + * + * @notapi + */ +void dbg_check_lock_from_isr(void) { + + if ((dbg_isr_cnt <= 0) || (dbg_lock_cnt != 0)) + chDbgPanic("SV#6"); + dbg_lock_cnt = 1; +} + +/** + * @brief Guard code for @p chSysUnlockFromIsr(). + * + * @notapi + */ +void dbg_check_unlock_from_isr(void) { + + if ((dbg_isr_cnt <= 0) || (dbg_lock_cnt <= 0)) + chDbgPanic("SV#7"); + dbg_lock_cnt = 0; +} + +/** + * @brief Guard code for @p CH_IRQ_PROLOGUE(). + * + * @notapi + */ +void dbg_check_enter_isr(void) { + + port_lock_from_isr(); + if (dbg_isr_cnt < 0) + chDbgPanic("SV#8"); + dbg_isr_cnt++; + port_unlock_from_isr(); +} + +/** + * @brief Guard code for @p CH_IRQ_EPILOGUE(). + * + * @notapi + */ +void dbg_check_leave_isr(void) { + + port_lock_from_isr(); + if (dbg_isr_cnt <= 0) + chDbgPanic("SV#9"); + dbg_isr_cnt--; + port_unlock_from_isr(); +} + +#endif /* CH_DBG_SYSTEM_STATE_CHECK */ + +/*===========================================================================*/ +/* Trace related code and variables. */ +/*===========================================================================*/ + #if CH_DBG_ENABLE_TRACE || defined(__DOXYGEN__) /** * @brief Public trace buffer. @@ -59,7 +202,7 @@ void _trace_init(void) { * * @notapi */ -void chDbgTrace(Thread *otp) { +void dbg_trace(Thread *otp) { dbg_trace_buffer.tb_ptr->se_time = chTimeNow(); dbg_trace_buffer.tb_ptr->se_tp = currp; @@ -71,13 +214,15 @@ void chDbgTrace(Thread *otp) { } #endif /* CH_DBG_ENABLE_TRACE */ -#if CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || \ - CH_DBG_ENABLE_STACK_CHECK || defined(__DOXYGEN__) +/*===========================================================================*/ +/* Panic related code and variables. */ +/*===========================================================================*/ + +#if CH_DBG_ENABLED || defined(__DOXYGEN__) /** * @brief Pointer to the panic message. * @details This pointer is meant to be accessed through the debugger, it is - * written once and then the system is halted. This variable can be - * set to @p NULL if the halt is caused by a stack overflow. + * written once and then the system is halted. */ char *dbg_panic_msg; @@ -91,6 +236,6 @@ void chDbgPanic(char *msg) { dbg_panic_msg = msg; chSysHalt(); } -#endif /* CH_DBG_ENABLE_ASSERTS || CH_DBG_ENABLE_CHECKS || CH_DBG_ENABLE_STACK_CHECK */ +#endif /* CH_DBG_ENABLED */ /** @} */ diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index df71d1cc6..21b92e388 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -157,6 +157,7 @@ void chMtxLockS(Mutex *mp) { #endif /* Re-enqueues tp with its new priority on the ready list.*/ chSchReadyI(dequeue(tp)); + break; } break; } diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index d41649b4c..e989f4039 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -113,7 +113,6 @@ void chSchGoSleepS(tstate_t newstate) { #endif setcurrp(fifo_remove(&rlist.r_queue)); currp->p_state = THD_STATE_CURRENT; - chDbgTrace(otp); chSysSwitchI(currp, otp); } #endif /* !defined(PORT_OPTIMIZED_GOSLEEPS) */ @@ -222,7 +221,6 @@ void chSchWakeupS(Thread *ntp, msg_t msg) { #endif setcurrp(ntp); ntp->p_state = THD_STATE_CURRENT; - chDbgTrace(otp); chSysSwitchI(ntp, otp); } } @@ -247,7 +245,6 @@ void chSchDoRescheduleI(void) { setcurrp(fifo_remove(&rlist.r_queue)); currp->p_state = THD_STATE_CURRENT; chSchReadyI(otp); - chDbgTrace(otp); chSysSwitchI(currp, otp); } #endif /* !defined(PORT_OPTIMIZED_DORESCHEDULEI) */ diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 4c8cd708d..6c63e113f 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -98,6 +98,8 @@ void chSysInit(void) { setcurrp(_thread_init(&mainthread, NORMALPRIO)); currp->p_state = THD_STATE_CURRENT; #if CH_DBG_ENABLE_STACK_CHECK + /* This is a special case because the main thread Thread structure is not + adjacent to its stack area.*/ currp->p_stklimit = &__main_thread_stack_base__; #endif chSysEnable(); @@ -141,24 +143,4 @@ void chSysTimerHandlerI(void) { #endif } -#if CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED -void chSysLock(void) { - - chDbgAssert(currp->p_locks >= 0, - "chSysLock(), #1", - "negative nesting counter"); - if (currp->p_locks++ == 0) - port_lock(); -} - -void chSysUnlock(void) { - - chDbgAssert(currp->p_locks > 0, - "chSysUnlock(), #1", - "non-positive nesting counter"); - if (--currp->p_locks == 0) - port_unlock(); -} -#endif /* CH_USE_NESTED_LOCKS && !CH_OPTIMIZE_SPEED */ - /** @} */ -- cgit v1.2.3 From 43752ee8d132fc57028a9ff15156c5bfcd81c013 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 12 Aug 2011 11:10:19 +0000 Subject: Extended state check to all kernel I-class and s-class APIs, corrected some test cases where call protocol rules were not strictly observerd. No the whole test suite pass with the state checker enabled. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3223 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chcond.c | 4 ++++ os/kernel/src/chdebug.c | 34 ++++++++++++++++++++++++++++++++-- os/kernel/src/chevents.c | 2 ++ os/kernel/src/chmboxes.c | 6 ++++++ os/kernel/src/chmemcore.c | 2 ++ os/kernel/src/chmempools.c | 2 ++ os/kernel/src/chmtx.c | 3 +++ os/kernel/src/chqueues.c | 8 ++++++++ os/kernel/src/chschd.c | 13 ++++++++++++- os/kernel/src/chsem.c | 13 +++++-------- os/kernel/src/chsys.c | 2 ++ os/kernel/src/chthreads.c | 2 ++ os/kernel/src/chvt.c | 2 ++ 13 files changed, 82 insertions(+), 11 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c index 456fc454f..d1aeb75af 100644 --- a/os/kernel/src/chcond.c +++ b/os/kernel/src/chcond.c @@ -86,6 +86,7 @@ void chCondSignal(CondVar *cp) { */ void chCondSignalI(CondVar *cp) { + chDbgCheckClassI(); chDbgCheck(cp != NULL, "chCondSignalI"); if (notempty(&cp->c_queue)) @@ -120,6 +121,7 @@ void chCondBroadcast(CondVar *cp) { */ void chCondBroadcastI(CondVar *cp) { + chDbgCheckClassI(); chDbgCheck(cp != NULL, "chCondBroadcastI"); /* Empties the condition variable queue and inserts all the Threads into the @@ -177,6 +179,7 @@ msg_t chCondWaitS(CondVar *cp) { Mutex *mp; msg_t msg; + chDbgCheckClassS(); chDbgCheck(cp != NULL, "chCondWaitS"); chDbgAssert(ctp->p_mtxlist != NULL, "chCondWaitS(), #1", @@ -261,6 +264,7 @@ msg_t chCondWaitTimeoutS(CondVar *cp, systime_t time) { Mutex *mp; msg_t msg; + chDbgCheckClassS(); chDbgCheck((cp != NULL) && (time != TIME_IMMEDIATE), "chCondWaitTimeoutS"); chDbgAssert(currp->p_mtxlist != NULL, "chCondWaitTimeoutS(), #1", diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index 28d4f7520..8fd081c05 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -35,6 +35,8 @@ * - SV#7, misplaced @p chSysUnlockFromIsr(). * - SV#8, misplaced @p CH_IRQ_PROLOGUE(). * - SV#9, misplaced @p CH_IRQ_EPILOGUE(). + * - SV#10, misplaced I-class function. + * - SV#11, misplaced S-class function. * . * - Trace buffer. * - Parameters check. @@ -153,7 +155,7 @@ void dbg_check_unlock_from_isr(void) { void dbg_check_enter_isr(void) { port_lock_from_isr(); - if (dbg_isr_cnt < 0) + if ((dbg_isr_cnt < 0) || (dbg_lock_cnt != 0)) chDbgPanic("SV#8"); dbg_isr_cnt++; port_unlock_from_isr(); @@ -167,12 +169,40 @@ void dbg_check_enter_isr(void) { void dbg_check_leave_isr(void) { port_lock_from_isr(); - if (dbg_isr_cnt <= 0) + if ((dbg_isr_cnt <= 0) || (dbg_lock_cnt != 0)) chDbgPanic("SV#9"); dbg_isr_cnt--; port_unlock_from_isr(); } +/** + * @brief I-class functions context check. + * @details Verifies that the system is in an appropriate state for invoking + * an I-class API function. A panic is generated if the state is + * not compatible. + * + * @api + */ +void chDbgCheckClassI(void) { + + if ((dbg_isr_cnt < 0) || (dbg_lock_cnt <= 0)) + chDbgPanic("SV#10"); +} + +/** + * @brief S-class functions context check. + * @details Verifies that the system is in an appropriate state for invoking + * an S-class API function. A panic is generated if the state is + * not compatible. + * + * @api + */ +void chDbgCheckClassS(void) { + + if ((dbg_isr_cnt != 0) || (dbg_lock_cnt <= 0)) + chDbgPanic("SV#11"); +} + #endif /* CH_DBG_SYSTEM_STATE_CHECK */ /*===========================================================================*/ diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index d74ad2dc4..7193e3a12 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -185,6 +185,7 @@ void chEvtSignalFlags(Thread *tp, eventmask_t mask) { */ void chEvtSignalFlagsI(Thread *tp, eventmask_t mask) { + chDbgCheckClassI(); chDbgCheck(tp != NULL, "chEvtSignalI"); tp->p_epending |= mask; @@ -237,6 +238,7 @@ void chEvtBroadcastFlags(EventSource *esp, eventmask_t mask) { void chEvtBroadcastFlagsI(EventSource *esp, eventmask_t mask) { EventListener *elp; + chDbgCheckClassI(); chDbgCheck(esp != NULL, "chEvtBroadcastMaskI"); elp = esp->es_next; diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c index af6ee5ea8..bf5fdfe29 100644 --- a/os/kernel/src/chmboxes.c +++ b/os/kernel/src/chmboxes.c @@ -143,6 +143,7 @@ msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t time) { msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) { msg_t rdymsg; + chDbgCheckClassS(); chDbgCheck(mbp != NULL, "chMBPostS"); rdymsg = chSemWaitTimeoutS(&mbp->mb_emptysem, time); @@ -172,6 +173,7 @@ msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) { */ msg_t chMBPostI(Mailbox *mbp, msg_t msg) { + chDbgCheckClassI(); chDbgCheck(mbp != NULL, "chMBPostI"); if (chSemGetCounterI(&mbp->mb_emptysem) <= 0) @@ -234,6 +236,7 @@ msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t time) { msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) { msg_t rdymsg; + chDbgCheckClassS(); chDbgCheck(mbp != NULL, "chMBPostAheadS"); rdymsg = chSemWaitTimeoutS(&mbp->mb_emptysem, time); @@ -263,6 +266,7 @@ msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) { */ msg_t chMBPostAheadI(Mailbox *mbp, msg_t msg) { + chDbgCheckClassI(); chDbgCheck(mbp != NULL, "chMBPostAheadI"); if (chSemGetCounterI(&mbp->mb_emptysem) <= 0) @@ -325,6 +329,7 @@ msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t time) { msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t time) { msg_t rdymsg; + chDbgCheckClassS(); chDbgCheck((mbp != NULL) && (msgp != NULL), "chMBFetchS"); rdymsg = chSemWaitTimeoutS(&mbp->mb_fullsem, time); @@ -354,6 +359,7 @@ msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t time) { */ msg_t chMBFetchI(Mailbox *mbp, msg_t *msgp) { + chDbgCheckClassI(); chDbgCheck((mbp != NULL) && (msgp != NULL), "chMBFetchI"); if (chSemGetCounterI(&mbp->mb_fullsem) <= 0) diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index 311d170c5..0eac9a429 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -105,6 +105,8 @@ void *chCoreAlloc(size_t size) { void *chCoreAllocI(size_t size) { void *p; + chDbgCheckClassI(); + size = MEM_ALIGN_NEXT(size); if ((size_t)(endmem - nextmem) < size) return NULL; diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c index 38adc3d49..767bfda09 100644 --- a/os/kernel/src/chmempools.c +++ b/os/kernel/src/chmempools.c @@ -72,6 +72,7 @@ void chPoolInit(MemoryPool *mp, size_t size, memgetfunc_t provider) { void *chPoolAllocI(MemoryPool *mp) { void *objp; + chDbgCheckClassI(); chDbgCheck(mp != NULL, "chPoolAllocI"); if ((objp = mp->mp_next) != NULL) @@ -114,6 +115,7 @@ void *chPoolAlloc(MemoryPool *mp) { void chPoolFreeI(MemoryPool *mp, void *objp) { struct pool_header *php = objp; + chDbgCheckClassI(); chDbgCheck((mp != NULL) && (objp != NULL) && MEM_IS_ALIGNED(objp), "chPoolFreeI"); diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 21b92e388..7d5bbe15e 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -114,6 +114,7 @@ void chMtxLock(Mutex *mp) { void chMtxLockS(Mutex *mp) { Thread *ctp = currp; + chDbgCheckClassS(); chDbgCheck(mp != NULL, "chMtxLockS"); /* Ia the mutex already locked? */ @@ -225,6 +226,7 @@ bool_t chMtxTryLock(Mutex *mp) { */ bool_t chMtxTryLockS(Mutex *mp) { + chDbgCheckClassS(); chDbgCheck(mp != NULL, "chMtxTryLockS"); if (mp->m_owner != NULL) @@ -309,6 +311,7 @@ Mutex *chMtxUnlockS(void) { Thread *ctp = currp; Mutex *ump, *mp; + chDbgCheckClassS(); chDbgAssert(ctp->p_mtxlist != NULL, "chMtxUnlockS(), #1", "owned mutexes list empty"); diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index 8532f8307..cf3d21732 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -108,6 +108,8 @@ void chIQInit(InputQueue *iqp, uint8_t *bp, size_t size, qnotify_t infy) { */ void chIQResetI(InputQueue *iqp) { + chDbgCheckClassI(); + iqp->q_rdptr = iqp->q_wrptr = iqp->q_buffer; iqp->q_counter = 0; while (notempty(&iqp->q_waiting)) @@ -129,6 +131,8 @@ void chIQResetI(InputQueue *iqp) { */ msg_t chIQPutI(InputQueue *iqp, uint8_t b) { + chDbgCheckClassI(); + if (chIQIsFullI(iqp)) return Q_FULL; @@ -284,6 +288,8 @@ void chOQInit(OutputQueue *oqp, uint8_t *bp, size_t size, qnotify_t onfy) { */ void chOQResetI(OutputQueue *oqp) { + chDbgCheckClassI(); + oqp->q_rdptr = oqp->q_wrptr = oqp->q_buffer; oqp->q_counter = chQSizeI(oqp); while (notempty(&oqp->q_waiting)) @@ -349,6 +355,8 @@ msg_t chOQPutTimeout(OutputQueue *oqp, uint8_t b, systime_t time) { msg_t chOQGetI(OutputQueue *oqp) { uint8_t b; + chDbgCheckClassI(); + if (chOQIsEmptyI(oqp)) return Q_EMPTY; diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index e989f4039..b481a0b6a 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -75,7 +75,8 @@ void _scheduler_init(void) { Thread *chSchReadyI(Thread *tp) { Thread *cp; - /* Integrity check.*/ + /* Integrity checks.*/ + chDbgCheckClassI(); chDbgAssert((tp->p_state != THD_STATE_READY) && (tp->p_state != THD_STATE_FINAL), "chSchReadyI(), #1", @@ -107,6 +108,8 @@ Thread *chSchReadyI(Thread *tp) { void chSchGoSleepS(tstate_t newstate) { Thread *otp; + chDbgCheckClassS(); + (otp = currp)->p_state = newstate; #if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; @@ -173,6 +176,8 @@ static void wakeup(void *p) { */ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { + chDbgCheckClassS(); + if (TIME_INFINITE != time) { VirtualTimer vt; @@ -207,6 +212,8 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { #if !defined(PORT_OPTIMIZED_WAKEUPS) || defined(__DOXYGEN__) void chSchWakeupS(Thread *ntp, msg_t msg) { + chDbgCheckClassS(); + ntp->p_u.rdymsg = msg; /* If the waken thread has a not-greater priority than the current one then it is just inserted in the ready list else it made @@ -237,6 +244,8 @@ void chSchWakeupS(Thread *ntp, msg_t msg) { void chSchDoRescheduleI(void) { Thread *otp; + chDbgCheckClassI(); + #if CH_TIME_QUANTUM > 0 rlist.r_preempt = CH_TIME_QUANTUM; #endif @@ -259,6 +268,8 @@ void chSchDoRescheduleI(void) { #if !defined(PORT_OPTIMIZED_RESCHEDULES) || defined(__DOXYGEN__) void chSchRescheduleS(void) { + chDbgCheckClassS(); + if (chSchIsRescRequiredI()) chSchDoRescheduleI(); } diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index c22a568ea..bf985bead 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -129,8 +129,8 @@ void chSemReset(Semaphore *sp, cnt_t n) { void chSemResetI(Semaphore *sp, cnt_t n) { cnt_t cnt; + chDbgCheckClassI(); chDbgCheck((sp != NULL) && (n >= 0), "chSemResetI"); - chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) || ((sp->s_cnt < 0) && notempty(&sp->s_queue)), "chSemResetI(), #1", @@ -177,8 +177,8 @@ msg_t chSemWait(Semaphore *sp) { */ msg_t chSemWaitS(Semaphore *sp) { + chDbgCheckClassS(); chDbgCheck(sp != NULL, "chSemWaitS"); - chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) || ((sp->s_cnt < 0) && notempty(&sp->s_queue)), "chSemWaitS(), #1", @@ -242,8 +242,8 @@ msg_t chSemWaitTimeout(Semaphore *sp, systime_t time) { */ msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) { + chDbgCheckClassS(); chDbgCheck(sp != NULL, "chSemWaitTimeoutS"); - chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) || ((sp->s_cnt < 0) && notempty(&sp->s_queue)), "chSemWaitTimeoutS(), #1", @@ -271,7 +271,6 @@ msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) { void chSemSignal(Semaphore *sp) { chDbgCheck(sp != NULL, "chSemSignal"); - chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) || ((sp->s_cnt < 0) && notempty(&sp->s_queue)), "chSemSignal(), #1", @@ -296,8 +295,8 @@ void chSemSignal(Semaphore *sp) { */ void chSemSignalI(Semaphore *sp) { + chDbgCheckClassI(); chDbgCheck(sp != NULL, "chSemSignalI"); - chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) || ((sp->s_cnt < 0) && notempty(&sp->s_queue)), "chSemSignalI(), #1", @@ -327,8 +326,8 @@ void chSemSignalI(Semaphore *sp) { */ void chSemAddCounterI(Semaphore *sp, cnt_t n) { + chDbgCheckClassI(); chDbgCheck((sp != NULL) && (n > 0), "chSemAddCounterI"); - chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) || ((sp->s_cnt < 0) && notempty(&sp->s_queue)), "chSemAddCounterI(), #1", @@ -361,12 +360,10 @@ msg_t chSemSignalWait(Semaphore *sps, Semaphore *spw) { msg_t msg; chDbgCheck((sps != NULL) && (spw != NULL), "chSemSignalWait"); - chDbgAssert(((sps->s_cnt >= 0) && isempty(&sps->s_queue)) || ((sps->s_cnt < 0) && notempty(&sps->s_queue)), "chSemSignalWait(), #1", "inconsistent semaphore"); - chDbgAssert(((spw->s_cnt >= 0) && isempty(&spw->s_queue)) || ((spw->s_cnt < 0) && notempty(&spw->s_queue)), "chSemSignalWait(), #2", diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 6c63e113f..866ee81a8 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -128,6 +128,8 @@ void chSysInit(void) { */ void chSysTimerHandlerI(void) { + chDbgCheckClassI(); + #if CH_TIME_QUANTUM > 0 /* Running thread has not used up quantum yet? */ if (rlist.r_preempt > 0) diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 182de7673..19accdb55 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -154,6 +154,8 @@ Thread *chThdCreateI(void *wsp, size_t size, /* Thread structure is layed out in the lower part of the thread workspace */ Thread *tp = wsp; + chDbgCheckClassI(); + chDbgCheck((wsp != NULL) && (size >= THD_WA_SIZE(0)) && (prio <= HIGHPRIO) && (pf != NULL), "chThdCreateI"); diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c index 4674c728e..fb8e0b0c1 100644 --- a/os/kernel/src/chvt.c +++ b/os/kernel/src/chvt.c @@ -70,6 +70,7 @@ void _vt_init(void) { void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) { VirtualTimer *p; + chDbgCheckClassI(); chDbgCheck((vtp != NULL) && (vtfunc != NULL) && (time != TIME_IMMEDIATE), "chVTSetI"); @@ -98,6 +99,7 @@ void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) { */ void chVTResetI(VirtualTimer *vtp) { + chDbgCheckClassI(); chDbgCheck(vtp != NULL, "chVTResetI"); chDbgAssert(vtp->vt_func != NULL, "chVTResetI(), #1", -- cgit v1.2.3 From aaad958769e757093a258cfdd5c75f515534fd7a Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 13 Aug 2011 07:06:02 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3224 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 74 ++++++++++++++++++++++++-------------------------- 1 file changed, 36 insertions(+), 38 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index b481a0b6a..f2014b8c7 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -76,7 +76,6 @@ Thread *chSchReadyI(Thread *tp) { Thread *cp; /* Integrity checks.*/ - chDbgCheckClassI(); chDbgAssert((tp->p_state != THD_STATE_READY) && (tp->p_state != THD_STATE_FINAL), "chSchReadyI(), #1", @@ -116,7 +115,7 @@ void chSchGoSleepS(tstate_t newstate) { #endif setcurrp(fifo_remove(&rlist.r_queue)); currp->p_state = THD_STATE_CURRENT; - chSysSwitchI(currp, otp); + chSysSwitch(currp, otp); } #endif /* !defined(PORT_OPTIMIZED_GOSLEEPS) */ @@ -228,36 +227,11 @@ void chSchWakeupS(Thread *ntp, msg_t msg) { #endif setcurrp(ntp); ntp->p_state = THD_STATE_CURRENT; - chSysSwitchI(ntp, otp); + chSysSwitch(ntp, otp); } } #endif /* !defined(PORT_OPTIMIZED_WAKEUPS) */ -/** - * @brief Switches to the first thread on the runnable queue. - * @note It is intended to be called if @p chSchRescRequiredI() evaluates - * to @p TRUE. - * - * @iclass - */ -#if !defined(PORT_OPTIMIZED_DORESCHEDULEI) || defined(__DOXYGEN__) -void chSchDoRescheduleI(void) { - Thread *otp; - - chDbgCheckClassI(); - -#if CH_TIME_QUANTUM > 0 - rlist.r_preempt = CH_TIME_QUANTUM; -#endif - otp = currp; - /* Picks the first thread from the ready queue and makes it current.*/ - setcurrp(fifo_remove(&rlist.r_queue)); - currp->p_state = THD_STATE_CURRENT; - chSchReadyI(otp); - chSysSwitchI(currp, otp); -} -#endif /* !defined(PORT_OPTIMIZED_DORESCHEDULEI) */ - /** * @brief Performs a reschedule if a higher priority thread is runnable. * @details If a thread with a higher priority than the current thread is in @@ -271,24 +245,25 @@ void chSchRescheduleS(void) { chDbgCheckClassS(); if (chSchIsRescRequiredI()) - chSchDoRescheduleI(); + chSchDoReschedule(); } #endif /* !defined(PORT_OPTIMIZED_RESCHEDULES) */ /** - * @brief Evaluates if a reschedule is required. + * @brief Evaluates if preemption is required. * @details The decision is taken by comparing the relative priorities and * depending on the state of the round robin timeout counter. - * @note This function is meant to be used in the timer interrupt handler - * where @p chVTDoTickI() is invoked. + * @note Not a user function, it is meant to be invoked by the scheduler + * itself or from within the port layer. * - * @retval TRUE if there is a thread that should go in running state. - * @retval FALSE if a reschedule is not required. + * @retval TRUE if there is a thread that must go in running state + * immediately. + * @retval FALSE if preemption is not required. * - * @iclass + * @special */ -#if !defined(PORT_OPTIMIZED_ISRESCHREQUIREDEXI) || defined(__DOXYGEN__) -bool_t chSchIsRescRequiredExI(void) { +#if !defined(PORT_OPTIMIZED_ISPREEMPTIONREQUIRED) || defined(__DOXYGEN__) +bool_t chSchIsPreemptionRequired(void) { tprio_t p1 = firstprio(&rlist.r_queue); tprio_t p2 = currp->p_prio; #if CH_TIME_QUANTUM > 0 @@ -303,6 +278,29 @@ bool_t chSchIsRescRequiredExI(void) { return p1 > p2; #endif } -#endif /* !defined(PORT_OPTIMIZED_ISRESCHREQUIREDEXI) */ +#endif /* !defined(PORT_OPTIMIZED_ISPREEMPTIONREQUIRED) */ + +/** + * @brief Switches to the first thread on the runnable queue. + * @note Not a user function, it is meant to be invoked by the scheduler + * itself or from within the port layer. + * + * @special + */ +#if !defined(PORT_OPTIMIZED_DORESCHEDULE) || defined(__DOXYGEN__) +void chSchDoReschedule(void) { + Thread *otp; + +#if CH_TIME_QUANTUM > 0 + rlist.r_preempt = CH_TIME_QUANTUM; +#endif + otp = currp; + /* Picks the first thread from the ready queue and makes it current.*/ + setcurrp(fifo_remove(&rlist.r_queue)); + currp->p_state = THD_STATE_CURRENT; + chSchReadyI(otp); + chSysSwitch(currp, otp); +} +#endif /* !defined(PORT_OPTIMIZED_DORESCHEDULE) */ /** @} */ -- cgit v1.2.3 From 4e35a12a2a84afa813bf619df3bbb8146b98a973 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 20 Aug 2011 14:25:49 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3243 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chthreads.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 19accdb55..46039561b 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -80,9 +80,6 @@ Thread *_thread_init(Thread *tp, tprio_t prio) { #if CH_USE_EVENTS tp->p_epending = 0; #endif -#if CH_USE_NESTED_LOCKS - tp->p_locks = 0; -#endif #if CH_DBG_THREADS_PROFILING tp->p_time = 0; #endif -- cgit v1.2.3 From c9be79def630f153b0b2d28e905939c15743f989 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 23 Aug 2011 10:09:08 +0000 Subject: Kernel documentation fixes and improvements. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3251 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmsg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmsg.c b/os/kernel/src/chmsg.c index 5002a892a..403df1580 100644 --- a/os/kernel/src/chmsg.c +++ b/os/kernel/src/chmsg.c @@ -109,7 +109,7 @@ Thread *chMsgWait(void) { } /** - * @brief Releases the thread waiting on top of the messages queue. + * @brief Releases a sender thread specifying a response message. * @pre Invoke this function only after a message has been received * using @p chMsgWait(). * -- cgit v1.2.3 From 5a3a608ad919591b88af842b0ce15f4e22790710 Mon Sep 17 00:00:00 2001 From: barthess Date: Tue, 20 Sep 2011 16:00:30 +0000 Subject: Fixed bug 3411207 git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3360 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chthreads.c | 1 + 1 file changed, 1 insertion(+) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 46039561b..73236c850 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -353,6 +353,7 @@ void chThdExit(msg_t msg) { REG_REMOVE(tp); #endif chSchGoSleepS(THD_STATE_FINAL); + chSysUnlock(); } #if CH_USE_WAITEXIT || defined(__DOXYGEN__) -- cgit v1.2.3 From 5463b41d3a7a81da20c88631535c088decd61999 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 20 Sep 2011 17:08:22 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3362 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chthreads.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 73236c850..b2231ef17 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -335,6 +335,27 @@ void chThdYield(void) { * @api */ void chThdExit(msg_t msg) { + + chSysLock(); + chThdExitS(msg); + /* The thread never returns here.*/ +} + +/** + * @brief Terminates the current thread. + * @details The thread goes in the @p THD_STATE_FINAL state holding the + * specified exit status code, other threads can retrieve the + * exit status code by invoking the function @p chThdWait(). + * @post Eventual code after this function will never be executed, + * this function never returns. The compiler has no way to + * know this so do not assume that the compiler would remove + * the dead code. + * + * @param[in] msg thread exit code + * + * @sclass + */ +void chThdExitS(msg_t msg) { Thread *tp = currp; chSysLock(); @@ -353,7 +374,8 @@ void chThdExit(msg_t msg) { REG_REMOVE(tp); #endif chSchGoSleepS(THD_STATE_FINAL); - chSysUnlock(); + /* The thread never returns here.*/ + chDbgAssert(FALSE, "chThdExitS(), #1", "zombies apocalypse"); } #if CH_USE_WAITEXIT || defined(__DOXYGEN__) -- cgit v1.2.3 From c69417e365e3f495588ad7b88e9ee8fc16b3fcdb Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 20 Sep 2011 17:10:56 +0000 Subject: Fixed bug 3411207. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3363 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chthreads.c | 1 - 1 file changed, 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index b2231ef17..bf43c6c43 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -358,7 +358,6 @@ void chThdExit(msg_t msg) { void chThdExitS(msg_t msg) { Thread *tp = currp; - chSysLock(); tp->p_u.exitcode = msg; #if defined(THREAD_EXT_EXIT_HOOK) THREAD_EXT_EXIT_HOOK(tp); -- cgit v1.2.3 From c39d08fc2ae9c43f73114e24292520306bddde19 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 23 Sep 2011 15:48:55 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3384 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsys.c | 5 +---- os/kernel/src/chthreads.c | 2 -- 2 files changed, 1 insertion(+), 6 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 866ee81a8..78caa88f6 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -36,10 +36,7 @@ #include "ch.h" #if !CH_NO_IDLE_THREAD || defined(__DOXYGEN__) -/** - * @brief Idle thread working area. - * @see PORT_IDLE_THREAD_STACK_SIZE - */ +/* Idle thread working area.*/ WORKING_AREA(_idle_thread_wa, PORT_IDLE_THREAD_STACK_SIZE); /** diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index bf43c6c43..7b48f2b00 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -32,8 +32,6 @@ * area. In this scenario static variables are shared among all * threads while automatic variables are local to the thread.
* Operations defined for threads: - * - Init, a thread is prepared and put in the suspended - * state. * - Create, a thread is started on the specified thread * function. This operation is available in multiple variants, * both static and dynamic. -- cgit v1.2.3 From 309b1e411426e8d36d9a552ef2870da3db912a80 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 23 Oct 2011 11:39:45 +0000 Subject: Improvements to the USB driver, first phase. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3449 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chqueues.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index cf3d21732..b32ccf803 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -152,9 +152,8 @@ msg_t chIQPutI(InputQueue *iqp, uint8_t b) { * @details This function reads a byte value from an input queue. If the queue * is empty then the calling thread is suspended until a byte arrives * in the queue or a timeout occurs. - * @note The callback is invoked if the queue is empty before entering the - * @p THD_STATE_WTQUEUE state in order to solicit the low level to - * start queue filling. + * @note The callback is invoked before reading the character from the + * buffer or before entering the state @p THD_STATE_WTQUEUE. * * @param[in] iqp pointer to an @p InputQueue structure * @param[in] time the number of ticks before the operation timeouts, @@ -172,12 +171,11 @@ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) { uint8_t b; chSysLock(); + if (iqp->q_notify) + iqp->q_notify(iqp); + while (chIQIsEmptyI(iqp)) { msg_t msg; - - if (iqp->q_notify) - iqp->q_notify(iqp); - if ((msg = qwait((GenericQueue *)iqp, time)) < Q_OK) { chSysUnlock(); return msg; @@ -201,9 +199,8 @@ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) { * been reset. * @note The function is not atomic, if you need atomicity it is suggested * to use a semaphore or a mutex for mutual exclusion. - * @note The callback is invoked if the queue is empty before entering the - * @p THD_STATE_WTQUEUE state in order to solicit the low level to - * start queue filling. + * @note The callback is invoked before reading each character from the + * buffer or before entering the state @p THD_STATE_WTQUEUE. * * @param[in] iqp pointer to an @p InputQueue structure * @param[out] bp pointer to the data buffer @@ -227,10 +224,10 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, chSysLock(); while (TRUE) { - while (chIQIsEmptyI(iqp)) { - if (nfy) - nfy(iqp); + if (nfy) + nfy(iqp); + while (chIQIsEmptyI(iqp)) { if (qwait((GenericQueue *)iqp, time) != Q_OK) { chSysUnlock(); return r; -- cgit v1.2.3 From de5dcbba856524599a8f06d3a9bdbf1b01db44c2 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 21 Jan 2012 14:29:42 +0000 Subject: License text updated with new year. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3846 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chcond.c | 2 +- os/kernel/src/chdebug.c | 2 +- os/kernel/src/chdynamic.c | 2 +- os/kernel/src/chevents.c | 2 +- os/kernel/src/chheap.c | 2 +- os/kernel/src/chlists.c | 2 +- os/kernel/src/chmboxes.c | 2 +- os/kernel/src/chmemcore.c | 2 +- os/kernel/src/chmempools.c | 2 +- os/kernel/src/chmsg.c | 2 +- os/kernel/src/chmtx.c | 2 +- os/kernel/src/chqueues.c | 2 +- os/kernel/src/chregistry.c | 2 +- os/kernel/src/chschd.c | 2 +- os/kernel/src/chsem.c | 2 +- os/kernel/src/chsys.c | 2 +- os/kernel/src/chthreads.c | 2 +- os/kernel/src/chvt.c | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c index d1aeb75af..ae62f1a31 100644 --- a/os/kernel/src/chcond.c +++ b/os/kernel/src/chcond.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. + 2011,2012 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index 8fd081c05..8d38dcd6e 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. + 2011,2012 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chdynamic.c b/os/kernel/src/chdynamic.c index fd60071e8..9ef62d487 100644 --- a/os/kernel/src/chdynamic.c +++ b/os/kernel/src/chdynamic.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. + 2011,2012 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index 7193e3a12..6749255e8 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. + 2011,2012 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c index b90b21909..f84276779 100644 --- a/os/kernel/src/chheap.c +++ b/os/kernel/src/chheap.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. + 2011,2012 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chlists.c b/os/kernel/src/chlists.c index c3168eafe..b7821493e 100644 --- a/os/kernel/src/chlists.c +++ b/os/kernel/src/chlists.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. + 2011,2012 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c index bf5fdfe29..86f88dce7 100644 --- a/os/kernel/src/chmboxes.c +++ b/os/kernel/src/chmboxes.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. + 2011,2012 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index 0eac9a429..a13a85873 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. + 2011,2012 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c index 767bfda09..6d1f7e866 100644 --- a/os/kernel/src/chmempools.c +++ b/os/kernel/src/chmempools.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. + 2011,2012 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chmsg.c b/os/kernel/src/chmsg.c index 403df1580..50814ef9c 100644 --- a/os/kernel/src/chmsg.c +++ b/os/kernel/src/chmsg.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. + 2011,2012 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 7d5bbe15e..975a63094 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. + 2011,2012 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index b32ccf803..3e9ea24f9 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. + 2011,2012 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c index 9eabe71c0..52c180a3a 100644 --- a/os/kernel/src/chregistry.c +++ b/os/kernel/src/chregistry.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. + 2011,2012 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index f2014b8c7..4acc500af 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. + 2011,2012 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index bf985bead..be1d363a5 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. + 2011,2012 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 78caa88f6..41946cdaf 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. + 2011,2012 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 7b48f2b00..a73697eb4 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. + 2011,2012 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c index fb8e0b0c1..4869cebef 100644 --- a/os/kernel/src/chvt.c +++ b/os/kernel/src/chvt.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. + 2011,2012 Giovanni Di Sirio. This file is part of ChibiOS/RT. -- cgit v1.2.3 From 4401d0e7b2874074e37c90e0178667a854d0da1f Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 6 Feb 2012 19:45:47 +0000 Subject: Round robin scheduling improvements. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3930 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 95 +++++++++++++++++++++++++++++++++++++++-------- os/kernel/src/chsys.c | 4 +- os/kernel/src/chthreads.c | 3 ++ 3 files changed, 85 insertions(+), 17 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 4acc500af..3dd226b1b 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -49,9 +49,6 @@ void _scheduler_init(void) { queue_init(&rlist.r_queue); rlist.r_prio = NOPRIO; -#if CH_TIME_QUANTUM > 0 - rlist.r_preempt = CH_TIME_QUANTUM; -#endif #if CH_USE_REGISTRY rlist.r_newer = rlist.r_older = (Thread *)&rlist; #endif @@ -59,6 +56,8 @@ void _scheduler_init(void) { /** * @brief Inserts a thread in the Ready List. + * @details The thread is positioned behind all threads with higher or equal + * priority. * @pre The thread must not be already inserted in any list through its * @p p_next and @p p_prev or list corruption would occur. * @post This function does not reschedule so a call to a rescheduling @@ -111,7 +110,9 @@ void chSchGoSleepS(tstate_t newstate) { (otp = currp)->p_state = newstate; #if CH_TIME_QUANTUM > 0 - rlist.r_preempt = CH_TIME_QUANTUM; + /* The thread is renouncing its remaining time slices so it will have a new + time quantum when it will wakeup.*/ + otp->p_preempt = CH_TIME_QUANTUM; #endif setcurrp(fifo_remove(&rlist.r_queue)); currp->p_state = THD_STATE_CURRENT; @@ -222,9 +223,6 @@ void chSchWakeupS(Thread *ntp, msg_t msg) { chSchReadyI(ntp); else { Thread *otp = chSchReadyI(currp); -#if CH_TIME_QUANTUM > 0 - rlist.r_preempt = CH_TIME_QUANTUM; -#endif setcurrp(ntp); ntp->p_state = THD_STATE_CURRENT; chSysSwitch(ntp, otp); @@ -237,7 +235,7 @@ void chSchWakeupS(Thread *ntp, msg_t msg) { * @details If a thread with a higher priority than the current thread is in * the ready list then make the higher priority thread running. * - * @iclass + * @sclass */ #if !defined(PORT_OPTIMIZED_RESCHEDULES) || defined(__DOXYGEN__) void chSchRescheduleS(void) { @@ -245,7 +243,7 @@ void chSchRescheduleS(void) { chDbgCheckClassS(); if (chSchIsRescRequiredI()) - chSchDoReschedule(); + chSchDoRescheduleAhead(); } #endif /* !defined(PORT_OPTIMIZED_RESCHEDULES) */ @@ -271,7 +269,7 @@ bool_t chSchIsPreemptionRequired(void) { if the first thread on the ready queue has a higher priority. Otherwise, if the running thread has used up its time quantum, reschedule if the first thread on the ready queue has equal or higher priority.*/ - return rlist.r_preempt ? p1 > p2 : p1 >= p2; + return currp->r_preempt ? p1 > p2 : p1 >= p2; #else /* If the round robin preemption feature is not enabled then performs a simpler comparison.*/ @@ -282,25 +280,92 @@ bool_t chSchIsPreemptionRequired(void) { /** * @brief Switches to the first thread on the runnable queue. + * @details The current thread is positioned in the ready list behind all + * threads having the same priority. The thread regains its time + * quantum. * @note Not a user function, it is meant to be invoked by the scheduler * itself or from within the port layer. * * @special */ -#if !defined(PORT_OPTIMIZED_DORESCHEDULE) || defined(__DOXYGEN__) -void chSchDoReschedule(void) { +#if !defined(PORT_OPTIMIZED_DORESCHEDULEBEHIND) || defined(__DOXYGEN__) +void chSchDoRescheduleBehind(void) { Thread *otp; -#if CH_TIME_QUANTUM > 0 - rlist.r_preempt = CH_TIME_QUANTUM; -#endif otp = currp; /* Picks the first thread from the ready queue and makes it current.*/ setcurrp(fifo_remove(&rlist.r_queue)); currp->p_state = THD_STATE_CURRENT; + otp->p_preempt = CH_TIME_QUANTUM; chSchReadyI(otp); chSysSwitch(currp, otp); } +#endif /* !defined(PORT_OPTIMIZED_DORESCHEDULEBEHIND) */ + +/** + * @brief Switches to the first thread on the runnable queue. + * @details The current thread is positioned in the ready list ahead of all + * threads having the same priority. + * @note Not a user function, it is meant to be invoked by the scheduler + * itself or from within the port layer. + * + * @special + */ +#if !defined(PORT_OPTIMIZED_DORESCHEDULEAHEAD) || defined(__DOXYGEN__) +void chSchDoRescheduleAhead(void) { + Thread *otp, *cp; + + otp = currp; + /* Picks the first thread from the ready queue and makes it current.*/ + setcurrp(fifo_remove(&rlist.r_queue)); + currp->p_state = THD_STATE_CURRENT; + + otp->p_state = THD_STATE_READY; + cp = (Thread *)&rlist.r_queue; + do { + cp = cp->p_next; + } while (cp->p_prio > otp->p_prio); + /* Insertion on p_prev.*/ + otp->p_next = cp; + otp->p_prev = cp->p_prev; + otp->p_prev->p_next = cp->p_prev = otp; + + chSysSwitch(currp, otp); +} +#endif /* !defined(PORT_OPTIMIZED_DORESCHEDULEAHEAD) */ + +/** + * @brief Switches to the first thread on the runnable queue. + * @details The current thread is positioned in the ready list behind or + * ahead of all threads having the same priority depending on + * if it used its whole time slice. + * @note Not a user function, it is meant to be invoked by the scheduler + * itself or from within the port layer. + * + * @special + */ +#if !defined(PORT_OPTIMIZED_DORESCHEDULE) || defined(__DOXYGEN__) +void chSchDoReschedule(void) { + +#if CH_TIME_QUANTUM > 0 + /* If CH_TIME_QUANTUM is enabled then there are two different scenarios to + handle on preemption: time quantum elapsed or not.*/ + if (currp->p_preempt == 0) { + /* The thread consumed its time quantum so it is enqueued behind threads + with same priority level, however, it acquires a new time quantum.*/ + chSchDoRescheduleBehind(); + } + else { + /* The thread didn't consume all its time quantum so it is put ahead of + threads with equal priority and does not acquire a new time quantum.*/ + chSchDoRescheduleAhead(); + } +#else /* !(CH_TIME_QUANTUM > 0) */ + /* If the round-robin mechanism is disabled then the thread goes always + ahead of its peers.*/ + chSchDoRescheduleAhead(); +#endif /* !(CH_TIME_QUANTUM > 0) */ +} #endif /* !defined(PORT_OPTIMIZED_DORESCHEDULE) */ /** @} */ diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 41946cdaf..e433a8e42 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -129,9 +129,9 @@ void chSysTimerHandlerI(void) { #if CH_TIME_QUANTUM > 0 /* Running thread has not used up quantum yet? */ - if (rlist.r_preempt > 0) + if (currp->p_preempt > 0) /* Decrement remaining quantum.*/ - rlist.r_preempt--; + currp->p_preempt--; #endif #if CH_DBG_THREADS_PROFILING currp->p_time++; diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index a73697eb4..eccf466d0 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -71,6 +71,9 @@ Thread *_thread_init(Thread *tp, tprio_t prio) { tp->p_prio = prio; tp->p_state = THD_STATE_SUSPENDED; tp->p_flags = THD_MEM_MODE_STATIC; +#if CH_TIME_QUANTUM > 0 + tp->p_preempt = CH_TIME_QUANTUM; +#endif #if CH_USE_MUTEXES tp->p_realprio = prio; tp->p_mtxlist = NULL; -- cgit v1.2.3 From d32014ff1ead0fd53a405aaf82869dbe442c7c16 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 8 Feb 2012 08:51:26 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3943 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 3dd226b1b..808e06300 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -269,7 +269,7 @@ bool_t chSchIsPreemptionRequired(void) { if the first thread on the ready queue has a higher priority. Otherwise, if the running thread has used up its time quantum, reschedule if the first thread on the ready queue has equal or higher priority.*/ - return currp->r_preempt ? p1 > p2 : p1 >= p2; + return currp->p_preempt ? p1 > p2 : p1 >= p2; #else /* If the round robin preemption feature is not enabled then performs a simpler comparison.*/ -- cgit v1.2.3 From 18b8b495244411bb33254ea0d8b868259077be7d Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 8 Feb 2012 17:53:52 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3946 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 3 +++ os/kernel/src/chvt.c | 3 +-- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 808e06300..9739a595b 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -127,10 +127,12 @@ void chSchGoSleepS(tstate_t newstate) { static void wakeup(void *p) { Thread *tp = (Thread *)p; + chSysLockFromIsr(); switch (tp->p_state) { case THD_STATE_READY: /* Handling the special case where the thread has been made ready by another thread with higher priority.*/ + chSysUnlockFromIsr(); return; #if CH_USE_SEMAPHORES || CH_USE_QUEUES || \ (CH_USE_CONDVARS && CH_USE_CONDVARS_TIMEOUT) @@ -151,6 +153,7 @@ static void wakeup(void *p) { } tp->p_u.rdymsg = RDY_TIMEOUT; chSchReadyI(tp); + chSysUnlockFromIsr(); } /** diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c index 4869cebef..6389aaf6d 100644 --- a/os/kernel/src/chvt.c +++ b/os/kernel/src/chvt.c @@ -49,8 +49,7 @@ void _vt_init(void) { /** * @brief Enables a virtual timer. - * @note The associated function is invoked by an interrupt handler within - * the I-Locked state, see @ref system_states. + * @note The associated function is invoked from interrupt context. * * @param[out] vtp the @p VirtualTimer structure pointer * @param[in] time the number of ticks before the operation timeouts, the -- cgit v1.2.3 From cb5fb91d7174222a07842a2d795f28bcda2ef704 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 12 Feb 2012 09:01:03 +0000 Subject: Fixed bug 3486874. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3951 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 9739a595b..6f28d04bb 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -299,7 +299,9 @@ void chSchDoRescheduleBehind(void) { /* Picks the first thread from the ready queue and makes it current.*/ setcurrp(fifo_remove(&rlist.r_queue)); currp->p_state = THD_STATE_CURRENT; +#if CH_TIME_QUANTUM > 0 otp->p_preempt = CH_TIME_QUANTUM; +#endif chSchReadyI(otp); chSysSwitch(currp, otp); } -- cgit v1.2.3 From 52e98077ee867e31189c43ad592cf97f386cac93 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 15 Mar 2012 19:54:36 +0000 Subject: Fixed bug 3504450. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4039 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmboxes.c | 1 + 1 file changed, 1 insertion(+) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c index 86f88dce7..163f93f20 100644 --- a/os/kernel/src/chmboxes.c +++ b/os/kernel/src/chmboxes.c @@ -364,6 +364,7 @@ msg_t chMBFetchI(Mailbox *mbp, msg_t *msgp) { if (chSemGetCounterI(&mbp->mb_fullsem) <= 0) return RDY_TIMEOUT; + chSemFastWaitI(&mbp->mb_fullsem); *msgp = *mbp->mb_rdptr++; if (mbp->mb_rdptr >= mbp->mb_top) mbp->mb_rdptr = mbp->mb_buffer; -- cgit v1.2.3 From f5a3976c393fffdc95627f27d4c49136fa9ec8ca Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 26 Mar 2012 09:13:37 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4055 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chevents.c | 2 +- os/kernel/src/chheap.c | 2 +- os/kernel/src/chmtx.c | 6 +++--- os/kernel/src/chthreads.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index 6749255e8..2b3247543 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -376,7 +376,7 @@ eventmask_t chEvtWaitAll(eventmask_t mask) { * This means that Event Listeners with a lower event identifier have * an higher priority. * - * @param[in] mask mask of the event flagss that the function should wait + * @param[in] mask mask of the event flags that the function should wait * for, @p ALL_EVENTS enables all the events * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c index f84276779..1e7f99dce 100644 --- a/os/kernel/src/chheap.c +++ b/os/kernel/src/chheap.c @@ -31,7 +31,7 @@ * are guaranteed to be thread safe.
* By enabling the @p CH_USE_MALLOC_HEAP option the heap manager * will use the runtime-provided @p malloc() and @p free() as - * backend for the heap APIs instead of the system provided + * back end for the heap APIs instead of the system provided * allocator. * @pre In order to use the heap APIs the @p CH_USE_HEAP option must * be enabled in @p chconf.h. diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 975a63094..20a4700fe 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -117,14 +117,14 @@ void chMtxLockS(Mutex *mp) { chDbgCheckClassS(); chDbgCheck(mp != NULL, "chMtxLockS"); - /* Ia the mutex already locked? */ + /* Is the mutex already locked? */ if (mp->m_owner != NULL) { /* Priority inheritance protocol; explores the thread-mutex dependencies boosting the priority of all the affected threads to equal the priority of the running thread requesting the mutex.*/ Thread *tp = mp->m_owner; /* Does the running thread have higher priority than the mutex - ownning thread? */ + owning thread? */ while (tp->p_prio < ctp->p_prio) { /* Make priority of thread tp match the running thread's priority.*/ tp->p_prio = ctp->p_prio; @@ -258,7 +258,7 @@ Mutex *chMtxUnlock(void) { chDbgAssert(ctp->p_mtxlist->m_owner == ctp, "chMtxUnlock(), #2", "ownership failure"); - /* Removes the top Mutex from the Threads's owned mutexes list and matk it + /* Removes the top Mutex from the Thread's owned mutexes list and matk it as not owned.*/ ump = ctp->p_mtxlist; ctp->p_mtxlist = ump->m_next; diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index eccf466d0..0be671c16 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -149,7 +149,7 @@ void _thread_memfill(uint8_t *startp, uint8_t *endp, uint8_t v) { */ Thread *chThdCreateI(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) { - /* Thread structure is layed out in the lower part of the thread workspace */ + /* Thread structure is layed out in the lower part of the thread workspace.*/ Thread *tp = wsp; chDbgCheckClassI(); -- cgit v1.2.3 From 7abee7168a90b07f3746779e338b4523d48724b0 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 9 Apr 2012 13:13:25 +0000 Subject: Added new function chPoolLoadArray(). git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4088 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmempools.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c index 6d1f7e866..8ef5cc403 100644 --- a/os/kernel/src/chmempools.c +++ b/os/kernel/src/chmempools.c @@ -60,8 +60,34 @@ void chPoolInit(MemoryPool *mp, size_t size, memgetfunc_t provider) { mp->mp_provider = provider; } +/** + * @brief Loads a memory pool with an array of static objects. + * @pre The memory pool must be already been initialized. + * @pre The array elements must be of the right size for the specified + * memory pool. + * @post The memory pool contains the elements of the input array. + * + * @param[in] mp pointer to a @p MemoryPool structure + * @param[in] p pointer to the array first element + * @param[in] n number of elements in the array + * + * @api + */ +void chPoolLoadArray(MemoryPool *mp, void *p, size_t n) { + + chDbgCheck((mp != NULL) && MEM_IS_ALIGNED(p) && (n != 0), + "chPoolLoadArray"); + + while (n) { + chPoolAdd(mp, p); + p = (void *)(((uint8_t *)p) + mp->mp_object_size); + n--; + } +} + /** * @brief Allocates an object from a memory pool. + * @pre The memory pool must be already been initialized. * * @param[in] mp pointer to a @p MemoryPool structure * @return The pointer to the allocated object. @@ -84,6 +110,7 @@ void *chPoolAllocI(MemoryPool *mp) { /** * @brief Allocates an object from a memory pool. + * @pre The memory pool must be already been initialized. * * @param[in] mp pointer to a @p MemoryPool structure * @return The pointer to the allocated object. @@ -101,14 +128,15 @@ void *chPoolAlloc(MemoryPool *mp) { } /** - * @brief Releases (or adds) an object into (to) a memory pool. + * @brief Releases an object into a memory pool. + * @pre The memory pool must be already been initialized. * @pre The freed object must be of the right size for the specified * memory pool. * @pre The freed object must be memory aligned to the size of * @p stkalign_t type. * * @param[in] mp pointer to a @p MemoryPool structure - * @param[in] objp the pointer to the object to be released or added + * @param[in] objp the pointer to the object to be released * * @iclass */ @@ -124,14 +152,15 @@ void chPoolFreeI(MemoryPool *mp, void *objp) { } /** - * @brief Releases (or adds) an object into (to) a memory pool. + * @brief Releases an object into a memory pool. + * @pre The memory pool must be already been initialized. * @pre The freed object must be of the right size for the specified * memory pool. * @pre The freed object must be memory aligned to the size of * @p stkalign_t type. * * @param[in] mp pointer to a @p MemoryPool structure - * @param[in] objp the pointer to the object to be released or added + * @param[in] objp the pointer to the object to be released * * @api */ @@ -141,6 +170,7 @@ void chPoolFree(MemoryPool *mp, void *objp) { chPoolFreeI(mp, objp); chSysUnlock(); } + #endif /* CH_USE_MEMPOOLS */ /** @} */ -- cgit v1.2.3 From 814b642a0ced73a71ceb3b548c2c570e8631dd58 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 18 Apr 2012 16:40:15 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4112 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 20a4700fe..6e32ca439 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -258,7 +258,7 @@ Mutex *chMtxUnlock(void) { chDbgAssert(ctp->p_mtxlist->m_owner == ctp, "chMtxUnlock(), #2", "ownership failure"); - /* Removes the top Mutex from the Thread's owned mutexes list and matk it + /* Removes the top Mutex from the Thread's owned mutexes list and marks it as not owned.*/ ump = ctp->p_mtxlist; ctp->p_mtxlist = ump->m_next; -- cgit v1.2.3 From a4283e0d49d6a527d84fb5be020f75cecfda4edc Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 29 Apr 2012 12:39:44 +0000 Subject: Memory Pools improvement. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4146 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmempools.c | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c index 8ef5cc403..21d205fc8 100644 --- a/os/kernel/src/chmempools.c +++ b/os/kernel/src/chmempools.c @@ -27,7 +27,10 @@ *

Operation mode

* The Memory Pools APIs allow to allocate/free fixed size objects in * constant time and reliably without memory fragmentation - * problems. + * problems.
+ * Memory Pools do not enforce any alignment constraint on the + * contained object however the objects must be properly aligned + * to contain a pointer to void. * @pre In order to use the memory pools APIs the @p CH_USE_MEMPOOLS option * must be enabled in @p chconf.h. * @{ @@ -56,7 +59,7 @@ void chPoolInit(MemoryPool *mp, size_t size, memgetfunc_t provider) { chDbgCheck((mp != NULL) && (size >= sizeof(void *)), "chPoolInit"); mp->mp_next = NULL; - mp->mp_object_size = MEM_ALIGN_NEXT(size); + mp->mp_object_size = size; mp->mp_provider = provider; } @@ -75,8 +78,7 @@ void chPoolInit(MemoryPool *mp, size_t size, memgetfunc_t provider) { */ void chPoolLoadArray(MemoryPool *mp, void *p, size_t n) { - chDbgCheck((mp != NULL) && MEM_IS_ALIGNED(p) && (n != 0), - "chPoolLoadArray"); + chDbgCheck((mp != NULL) && (n != 0), "chPoolLoadArray"); while (n) { chPoolAdd(mp, p); @@ -132,8 +134,7 @@ void *chPoolAlloc(MemoryPool *mp) { * @pre The memory pool must be already been initialized. * @pre The freed object must be of the right size for the specified * memory pool. - * @pre The freed object must be memory aligned to the size of - * @p stkalign_t type. + * @pre The object must be properly aligned to contain a pointer to void. * * @param[in] mp pointer to a @p MemoryPool structure * @param[in] objp the pointer to the object to be released @@ -144,8 +145,7 @@ void chPoolFreeI(MemoryPool *mp, void *objp) { struct pool_header *php = objp; chDbgCheckClassI(); - chDbgCheck((mp != NULL) && (objp != NULL) && MEM_IS_ALIGNED(objp), - "chPoolFreeI"); + chDbgCheck((mp != NULL) && (objp != NULL), "chPoolFreeI"); php->ph_next = mp->mp_next; mp->mp_next = php; @@ -156,8 +156,7 @@ void chPoolFreeI(MemoryPool *mp, void *objp) { * @pre The memory pool must be already been initialized. * @pre The freed object must be of the right size for the specified * memory pool. - * @pre The freed object must be memory aligned to the size of - * @p stkalign_t type. + * @pre The object must be properly aligned to contain a pointer to void. * * @param[in] mp pointer to a @p MemoryPool structure * @param[in] objp the pointer to the object to be released -- cgit v1.2.3 From 8f8b7f2c69575736da9004c8dc45c770b0f08c48 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 8 May 2012 19:02:16 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4177 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chqueues.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index 3e9ea24f9..adb5dd807 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -37,7 +37,7 @@ * together. * . * I/O queues are usually used as an implementation layer for the I/O - * channels interface, also see @ref io_channels. + * channels interface, also see @ref IO_CHANNEL. * @pre In order to use the I/O queues the @p CH_USE_QUEUES option must * be enabled in @p chconf.h. * @{ -- cgit v1.2.3 From d094e348c5d1a3785289c69c5185bbaca1257de8 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 11 Jun 2012 16:54:35 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4266 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chqueues.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index adb5dd807..79bf409cb 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -83,16 +83,19 @@ static msg_t qwait(GenericQueue *qp, systime_t time) { * @param[in] size size of the queue buffer * @param[in] infy pointer to a callback function that is invoked when * data is read from the queue. The value can be @p NULL. + * @param[in] link application defined pointer * * @init */ -void chIQInit(InputQueue *iqp, uint8_t *bp, size_t size, qnotify_t infy) { +void chIQInit(InputQueue *iqp, uint8_t *bp, size_t size, qnotify_t infy, + void *link) { queue_init(&iqp->q_waiting); iqp->q_counter = 0; iqp->q_buffer = iqp->q_rdptr = iqp->q_wrptr = bp; iqp->q_top = bp + size; iqp->q_notify = infy; + iqp->q_link = link; } /** @@ -260,16 +263,19 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, * @param[in] size size of the queue buffer * @param[in] onfy pointer to a callback function that is invoked when * data is written to the queue. The value can be @p NULL. + * @param[in] link application defined pointer * * @init */ -void chOQInit(OutputQueue *oqp, uint8_t *bp, size_t size, qnotify_t onfy) { +void chOQInit(OutputQueue *oqp, uint8_t *bp, size_t size, qnotify_t onfy, + void *link) { queue_init(&oqp->q_waiting); oqp->q_counter = size; oqp->q_buffer = oqp->q_rdptr = oqp->q_wrptr = bp; oqp->q_top = bp + size; oqp->q_notify = onfy; + oqp->q_link = link; } /** -- cgit v1.2.3 From 456a8cbd82f200dda163e7997d60fe4a92c5841e Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 16 Jun 2012 15:07:15 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4280 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chschd.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index 6f28d04bb..a7864bc71 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -74,6 +74,8 @@ void _scheduler_init(void) { Thread *chSchReadyI(Thread *tp) { Thread *cp; + chDbgCheckClassI(); + /* Integrity checks.*/ chDbgAssert((tp->p_state != THD_STATE_READY) && (tp->p_state != THD_STATE_FINAL), -- cgit v1.2.3 From c6914081835f10258d873af8526ae405ffe5b25c Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 17 Jun 2012 06:53:49 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4283 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chdebug.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index 8d38dcd6e..0bee1b4ea 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -108,7 +108,7 @@ void dbg_check_lock(void) { if ((dbg_isr_cnt != 0) || (dbg_lock_cnt != 0)) chDbgPanic("SV#4"); - dbg_lock_cnt = 1; + dbg_enter_lock(); } /** @@ -120,7 +120,7 @@ void dbg_check_unlock(void) { if ((dbg_isr_cnt != 0) || (dbg_lock_cnt <= 0)) chDbgPanic("SV#5"); - dbg_lock_cnt = 0; + dbg_leave_lock(); } /** @@ -132,7 +132,7 @@ void dbg_check_lock_from_isr(void) { if ((dbg_isr_cnt <= 0) || (dbg_lock_cnt != 0)) chDbgPanic("SV#6"); - dbg_lock_cnt = 1; + dbg_enter_lock(); } /** @@ -144,7 +144,7 @@ void dbg_check_unlock_from_isr(void) { if ((dbg_isr_cnt <= 0) || (dbg_lock_cnt <= 0)) chDbgPanic("SV#7"); - dbg_lock_cnt = 0; + dbg_leave_lock(); } /** -- cgit v1.2.3 From 2abe2c479f15f9b4c66af007461c1ab2e2626ee0 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 23 Jun 2012 12:03:00 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4328 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chdebug.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index 0bee1b4ea..55631481f 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -254,14 +254,14 @@ void dbg_trace(Thread *otp) { * @details This pointer is meant to be accessed through the debugger, it is * written once and then the system is halted. */ -char *dbg_panic_msg; +const char *dbg_panic_msg; /** * @brief Prints a panic message on the console and then halts the system. * * @param[in] msg the pointer to the panic message string */ -void chDbgPanic(char *msg) { +void chDbgPanic(const char *msg) { dbg_panic_msg = msg; chSysHalt(); -- cgit v1.2.3 From f197ecf1cd2483c16d4b6da0f623227d06f242ea Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 30 Jun 2012 08:56:02 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4362 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index be1d363a5..10aee42d3 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -303,7 +303,7 @@ void chSemSignalI(Semaphore *sp) { "inconsistent semaphore"); if (++sp->s_cnt <= 0) { - /* note, it is done this way in order to allow a tail call on + /* Note, it is done this way in order to allow a tail call on chSchReadyI().*/ Thread *tp = fifo_remove(&sp->s_queue); tp->p_u.rdymsg = RDY_OK; -- cgit v1.2.3 From 7d892ef699164466cd328bc59a6e7effd8109a85 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 29 Jul 2012 07:28:09 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4486 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmboxes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c index 163f93f20..a9eddb2e9 100644 --- a/os/kernel/src/chmboxes.c +++ b/os/kernel/src/chmboxes.c @@ -41,7 +41,7 @@ * If larger messages need to be exchanged then a pointer to a * structure can be posted in the mailbox but the posting side has * no predefined way to know when the message has been processed. A - * possible approach is to allocate memory (from a memory pool as + * possible approach is to allocate memory (from a memory pool for * example) from the posting side and free it on the fetching side. * Another approach is to set a "done" flag into the structure pointed * by the message. @@ -346,7 +346,7 @@ msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t time) { /** * @brief Retrieves a message from a mailbox. * @details This variant is non-blocking, the function returns a timeout - * condition if the queue is full. + * condition if the queue is empty. * * @param[in] mbp the pointer to an initialized Mailbox object * @param[out] msgp pointer to a message variable for the received message -- cgit v1.2.3 From 48e503d8d46b13a185503cb20b4396e5728417ed Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 29 Jul 2012 07:29:54 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4487 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmboxes.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c index a9eddb2e9..50ce22b7f 100644 --- a/os/kernel/src/chmboxes.c +++ b/os/kernel/src/chmboxes.c @@ -57,8 +57,8 @@ * @brief Initializes a Mailbox object. * * @param[out] mbp the pointer to the Mailbox structure to be initialized - * @param[in] buf the circular messages buffer - * @param[in] n the buffer size as number of @p msg_t + * @param[in] buf pointer to the messages buffer as an array of @p msg_t + * @param[in] n size of the buffer as number of @p msg_t * * @init */ -- cgit v1.2.3 From 3d94ca6c47fd6ebbea0f23a86af0b273aa59a8e1 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 29 Jul 2012 07:43:15 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4488 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmboxes.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c index 50ce22b7f..860e92db9 100644 --- a/os/kernel/src/chmboxes.c +++ b/os/kernel/src/chmboxes.c @@ -58,7 +58,7 @@ * * @param[out] mbp the pointer to the Mailbox structure to be initialized * @param[in] buf pointer to the messages buffer as an array of @p msg_t - * @param[in] n size of the buffer as number of @p msg_t + * @param[in] n number of elements in the buffer array * * @init */ -- cgit v1.2.3 From 4bdf358424068f452a4d5a450e6001a03ca4f819 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 22 Aug 2012 14:23:02 +0000 Subject: Added mem git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4613 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chregistry.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c index 52c180a3a..5036a52bc 100644 --- a/os/kernel/src/chregistry.c +++ b/os/kernel/src/chregistry.c @@ -50,6 +50,51 @@ #if CH_USE_REGISTRY || defined(__DOXYGEN__) +/* Converting configuration options in bit masks in order to be encoded in + the global variable ch_root.*/ +#if CH_DBG_ENABLE_STACK_CHECK +#define MSK_DBG_ENABLE_STACK_CHECK 1 +#else +#define MSK_DBG_ENABLE_STACK_CHECK 0 +#endif + +#if CH_USE_DYNAMIC +#define MSK_USE_DYNAMIC 2 +#else +#define MSK_USE_DYNAMIC 0 +#endif + +#if CH_TIME_QUANTUM > 0 +#define MSK_TIME_QUANTUM 4 +#else +#define MSK_TIME_QUANTUM 0 +#endif + +#if CH_DBG_THREADS_PROFILING +#define MSK_DBG_THREADS_PROFILING 8 +#else +#define MSK_DBG_THREADS_PROFILING 0 +#endif + +/** + * @brief OS signature in ROM plus debug-related information. + */ +ROMCONST chroot_t ch_root = { + "CHRT", + (uint8_t)sizeof (chroot_t), + (uint8_t)0, + (uint16_t)((CH_KERNEL_MAJOR << 11) | + (CH_KERNEL_MINOR << 6) | + (CH_KERNEL_PATCH) << 0), + (uint8_t)sizeof (void *), + (uint8_t)(MSK_DBG_THREADS_PROFILING | MSK_TIME_QUANTUM | + MSK_USE_DYNAMIC | MSK_DBG_ENABLE_STACK_CHECK), + (uint8_t)0, + (uint8_t)0, + &rlist, + &vtlist +}; + /** * @brief Returns the first thread in the system. * @details Returns the most ancient thread in the system, usually this is -- cgit v1.2.3 From d51331c78ad8c4c5ad4769d6271cb0e06c11beb1 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 22 Aug 2012 15:11:04 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4614 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chregistry.c | 57 +++++++++++++++++++++------------------------- os/kernel/src/chsys.c | 12 +++++++--- 2 files changed, 35 insertions(+), 34 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c index 5036a52bc..4a383a379 100644 --- a/os/kernel/src/chregistry.c +++ b/os/kernel/src/chregistry.c @@ -50,34 +50,11 @@ #if CH_USE_REGISTRY || defined(__DOXYGEN__) -/* Converting configuration options in bit masks in order to be encoded in - the global variable ch_root.*/ -#if CH_DBG_ENABLE_STACK_CHECK -#define MSK_DBG_ENABLE_STACK_CHECK 1 -#else -#define MSK_DBG_ENABLE_STACK_CHECK 0 -#endif - -#if CH_USE_DYNAMIC -#define MSK_USE_DYNAMIC 2 -#else -#define MSK_USE_DYNAMIC 0 -#endif - -#if CH_TIME_QUANTUM > 0 -#define MSK_TIME_QUANTUM 4 -#else -#define MSK_TIME_QUANTUM 0 -#endif - -#if CH_DBG_THREADS_PROFILING -#define MSK_DBG_THREADS_PROFILING 8 -#else -#define MSK_DBG_THREADS_PROFILING 0 -#endif +#define THD_OFFSET(field) (uint8_t)((size_t)&_mainthread.field - \ + (size_t)&_mainthread) -/** - * @brief OS signature in ROM plus debug-related information. +/* + * OS signature in ROM plus debug-related information. */ ROMCONST chroot_t ch_root = { "CHRT", @@ -87,12 +64,30 @@ ROMCONST chroot_t ch_root = { (CH_KERNEL_MINOR << 6) | (CH_KERNEL_PATCH) << 0), (uint8_t)sizeof (void *), - (uint8_t)(MSK_DBG_THREADS_PROFILING | MSK_TIME_QUANTUM | - MSK_USE_DYNAMIC | MSK_DBG_ENABLE_STACK_CHECK), + (uint8_t)sizeof (systime_t), + THD_OFFSET(p_prio), + THD_OFFSET(p_ctx), + THD_OFFSET(p_newer), + THD_OFFSET(p_older), + THD_OFFSET(p_name), +#if CH_DBG_ENABLE_STACK_CHECK + THD_OFFSET(p_stklimit), +#else (uint8_t)0, +#endif + THD_OFFSET(p_state), + THD_OFFSET(p_flags), +#if CH_USE_DYNAMIC + THD_OFFSET(p_refs), +#else + (uint8_t)0, +#endif +#if CH_TIME_QUANTUM > 0 + THD_OFFSET(p_preempt), +#else (uint8_t)0, - &rlist, - &vtlist +#endif + THD_OFFSET(p_time) }; /** diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index e433a8e42..5bc86807b 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -36,9 +36,16 @@ #include "ch.h" #if !CH_NO_IDLE_THREAD || defined(__DOXYGEN__) -/* Idle thread working area.*/ +/** + * @brief Idle thread working area. + */ WORKING_AREA(_idle_thread_wa, PORT_IDLE_THREAD_STACK_SIZE); +/** + * @brief Main thread structure. + */ +Thread _mainthread; + /** * @brief This function implements the idle thread infinite loop. * @details The function puts the processor in the lowest power mode capable @@ -73,7 +80,6 @@ void _idle_thread(void *p) { * @special */ void chSysInit(void) { - static Thread mainthread; #if CH_DBG_ENABLE_STACK_CHECK extern stkalign_t __main_thread_stack_base__; #endif @@ -92,7 +98,7 @@ void chSysInit(void) { #endif /* Now this instructions flow becomes the main thread.*/ - setcurrp(_thread_init(&mainthread, NORMALPRIO)); + setcurrp(_thread_init(&_mainthread, NORMALPRIO)); currp->p_state = THD_STATE_CURRENT; #if CH_DBG_ENABLE_STACK_CHECK /* This is a special case because the main thread Thread structure is not -- cgit v1.2.3 From 03cba7d3085ad61c55902c790099c691938eee55 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 22 Aug 2012 16:33:49 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4615 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chregistry.c | 27 ++++++++++++++------------- os/kernel/src/chsys.c | 8 ++------ 2 files changed, 16 insertions(+), 19 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c index 4a383a379..2e63a13f6 100644 --- a/os/kernel/src/chregistry.c +++ b/os/kernel/src/chregistry.c @@ -50,8 +50,8 @@ #if CH_USE_REGISTRY || defined(__DOXYGEN__) -#define THD_OFFSET(field) (uint8_t)((size_t)&_mainthread.field - \ - (size_t)&_mainthread) +#define offsetof(st, m) \ + ((size_t)((char *)&((st *)0)->m - (char *)0)) /* * OS signature in ROM plus debug-related information. @@ -65,29 +65,30 @@ ROMCONST chroot_t ch_root = { (CH_KERNEL_PATCH) << 0), (uint8_t)sizeof (void *), (uint8_t)sizeof (systime_t), - THD_OFFSET(p_prio), - THD_OFFSET(p_ctx), - THD_OFFSET(p_newer), - THD_OFFSET(p_older), - THD_OFFSET(p_name), + (uint8_t)sizeof (Thread), + (uint8_t)offsetof(Thread, p_prio), + (uint8_t)offsetof(Thread, p_ctx), + (uint8_t)offsetof(Thread, p_newer), + (uint8_t)offsetof(Thread, p_older), + (uint8_t)offsetof(Thread, p_name), #if CH_DBG_ENABLE_STACK_CHECK - THD_OFFSET(p_stklimit), + (uint8_t)offsetof(Thread, p_stklimit), #else (uint8_t)0, #endif - THD_OFFSET(p_state), - THD_OFFSET(p_flags), + (uint8_t)offsetof(Thread, p_state), + (uint8_t)offsetof(Thread, p_flags), #if CH_USE_DYNAMIC - THD_OFFSET(p_refs), + (uint8_t)offsetof(Thread, p_refs), #else (uint8_t)0, #endif #if CH_TIME_QUANTUM > 0 - THD_OFFSET(p_preempt), + (uint8_t)offsetof(Thread, p_preempt), #else (uint8_t)0, #endif - THD_OFFSET(p_time) + (uint8_t)offsetof(Thread, p_time) }; /** diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 5bc86807b..9a7be60ee 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -41,11 +41,6 @@ */ WORKING_AREA(_idle_thread_wa, PORT_IDLE_THREAD_STACK_SIZE); -/** - * @brief Main thread structure. - */ -Thread _mainthread; - /** * @brief This function implements the idle thread infinite loop. * @details The function puts the processor in the lowest power mode capable @@ -80,6 +75,7 @@ void _idle_thread(void *p) { * @special */ void chSysInit(void) { + static Thread mainthread; #if CH_DBG_ENABLE_STACK_CHECK extern stkalign_t __main_thread_stack_base__; #endif @@ -98,7 +94,7 @@ void chSysInit(void) { #endif /* Now this instructions flow becomes the main thread.*/ - setcurrp(_thread_init(&_mainthread, NORMALPRIO)); + setcurrp(_thread_init(&mainthread, NORMALPRIO)); currp->p_state = THD_STATE_CURRENT; #if CH_DBG_ENABLE_STACK_CHECK /* This is a special case because the main thread Thread structure is not -- cgit v1.2.3 From f200dd71c5c0909a1b0a89e55082b4b9935a06d6 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 22 Aug 2012 16:36:18 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4616 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chregistry.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c index 2e63a13f6..971133457 100644 --- a/os/kernel/src/chregistry.c +++ b/os/kernel/src/chregistry.c @@ -50,7 +50,7 @@ #if CH_USE_REGISTRY || defined(__DOXYGEN__) -#define offsetof(st, m) \ +#define _offsetof(st, m) \ ((size_t)((char *)&((st *)0)->m - (char *)0)) /* @@ -66,29 +66,29 @@ ROMCONST chroot_t ch_root = { (uint8_t)sizeof (void *), (uint8_t)sizeof (systime_t), (uint8_t)sizeof (Thread), - (uint8_t)offsetof(Thread, p_prio), - (uint8_t)offsetof(Thread, p_ctx), - (uint8_t)offsetof(Thread, p_newer), - (uint8_t)offsetof(Thread, p_older), - (uint8_t)offsetof(Thread, p_name), + (uint8_t)_offsetof(Thread, p_prio), + (uint8_t)_offsetof(Thread, p_ctx), + (uint8_t)_offsetof(Thread, p_newer), + (uint8_t)_offsetof(Thread, p_older), + (uint8_t)_offsetof(Thread, p_name), #if CH_DBG_ENABLE_STACK_CHECK - (uint8_t)offsetof(Thread, p_stklimit), + (uint8_t)_offsetof(Thread, p_stklimit), #else (uint8_t)0, #endif - (uint8_t)offsetof(Thread, p_state), - (uint8_t)offsetof(Thread, p_flags), + (uint8_t)_offsetof(Thread, p_state), + (uint8_t)_offsetof(Thread, p_flags), #if CH_USE_DYNAMIC - (uint8_t)offsetof(Thread, p_refs), + (uint8_t)_offsetof(Thread, p_refs), #else (uint8_t)0, #endif #if CH_TIME_QUANTUM > 0 - (uint8_t)offsetof(Thread, p_preempt), + (uint8_t)_offsetof(Thread, p_preempt), #else (uint8_t)0, #endif - (uint8_t)offsetof(Thread, p_time) + (uint8_t)_offsetof(Thread, p_time) }; /** -- cgit v1.2.3 From dfe62fbbe0e3503e929469747b8021689c723b3a Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 9 Sep 2012 07:48:44 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4644 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chqueues.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index 79bf409cb..ec8fec2b3 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -36,8 +36,6 @@ * are implemented by pairing an input queue and an output queue * together. * . - * I/O queues are usually used as an implementation layer for the I/O - * channels interface, also see @ref IO_CHANNEL. * @pre In order to use the I/O queues the @p CH_USE_QUEUES option must * be enabled in @p chconf.h. * @{ -- cgit v1.2.3 From 5b39691e9eaa4f03b14794b824487f324aea7ca2 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 16 Sep 2012 08:31:38 +0000 Subject: Kernel events improvements. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4667 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chevents.c | 75 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 61 insertions(+), 14 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index 2b3247543..3518b6975 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -17,6 +17,9 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ +/* + Concepts and parts of this file have been contributed by Scott (skute). + */ /** * @file chevents.c @@ -77,10 +80,11 @@ void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t mask) { chDbgCheck((esp != NULL) && (elp != NULL), "chEvtRegisterMask"); chSysLock(); - elp->el_next = esp->es_next; - esp->es_next = elp; + elp->el_next = esp->es_next; + esp->es_next = elp; elp->el_listener = currp; - elp->el_mask = mask; + elp->el_mask = mask; + elp->el_flags = 0; chSysUnlock(); } @@ -154,25 +158,25 @@ eventmask_t chEvtAddFlags(eventmask_t mask) { } /** - * @brief Adds (OR) a set of event flags on the specified @p Thread. + * @brief Adds a set of event flags directly to specified @p Thread. * * @param[in] tp the thread to be signaled * @param[in] mask the event flags set to be ORed * * @api */ -void chEvtSignalFlags(Thread *tp, eventmask_t mask) { +void chEvtSignal(Thread *tp, eventmask_t mask) { chDbgCheck(tp != NULL, "chEvtSignal"); chSysLock(); - chEvtSignalFlagsI(tp, mask); + chEvtSignalI(tp, mask); chSchRescheduleS(); chSysUnlock(); } /** - * @brief Adds (OR) a set of event flags on the specified @p Thread. + * @brief Adds a set of event flags directly to specified @p Thread. * @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 @@ -183,7 +187,7 @@ void chEvtSignalFlags(Thread *tp, eventmask_t mask) { * * @iclass */ -void chEvtSignalFlagsI(Thread *tp, eventmask_t mask) { +void chEvtSignalI(Thread *tp, eventmask_t mask) { chDbgCheckClassI(); chDbgCheck(tp != NULL, "chEvtSignalI"); @@ -206,14 +210,14 @@ void chEvtSignalFlagsI(Thread *tp, eventmask_t mask) { * @p EventListener objects. * * @param[in] esp pointer to the @p EventSource structure - * @param[in] mask the event flags set to be ORed + * @param[in] flags the flags set to be added to the listener flags mask * * @api */ -void chEvtBroadcastFlags(EventSource *esp, eventmask_t mask) { +void chEvtBroadcastFlags(EventSource *esp, flagsmask_t flags) { chSysLock(); - chEvtBroadcastFlagsI(esp, mask); + chEvtBroadcastFlagsI(esp, flags); chSchRescheduleS(); chSysUnlock(); } @@ -231,11 +235,11 @@ void chEvtBroadcastFlags(EventSource *esp, eventmask_t mask) { * reschedule must not be performed in ISRs. * * @param[in] esp pointer to the @p EventSource structure - * @param[in] mask the event flags set to be ORed + * @param[in] flags the flags set to be added to the listener flags mask * * @iclass */ -void chEvtBroadcastFlagsI(EventSource *esp, eventmask_t mask) { +void chEvtBroadcastFlagsI(EventSource *esp, flagsmask_t flags) { EventListener *elp; chDbgCheckClassI(); @@ -243,11 +247,54 @@ void chEvtBroadcastFlagsI(EventSource *esp, eventmask_t mask) { elp = esp->es_next; while (elp != (EventListener *)esp) { - chEvtSignalFlagsI(elp->el_listener, elp->el_mask | mask); + elp->el_flags |= flags; + chEvtSignalI(elp->el_listener, elp->el_mask); elp = elp->el_next; } } +/** + * @brief Returns the flags associated to an @p EventListener. + * @details The flags are returned and the @p EventListener flags mask is + * cleared. + * + * @param[in] elp pointer to the @p EventListener structure + * @return The flags added to the listener by the associated + * event source. + * + * @iclass + */ +flagsmask_t chEvtGetAndClearFlagsI(EventListener *elp) { + flagsmask_t flags; + + flags = elp->el_flags; + elp->el_flags = 0; + + return flags; +} + +/** + * @brief Returns the flags associated to an @p EventListener. + * @details The flags are returned and the @p EventListener flags mask is + * cleared. + * + * @param[in] elp pointer to the @p EventListener structure + * @return The flags added to the listener by the associated + * event source. + * + * @iclass + */ +flagsmask_t chEvtGetAndClearFlags(EventListener *elp) { + flagsmask_t flags; + + chSysLock(); + flags = elp->el_flags; + elp->el_flags = 0; + chSysUnlock(); + + return flags; +} + /** * @brief Invokes the event handlers associated to an event flags mask. * -- cgit v1.2.3 From 1824750b9fcc929d4e0cc133f9e2b08ac541db53 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 16 Sep 2012 08:34:56 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4668 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chevents.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index 3518b6975..bb948ab52 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -264,11 +264,13 @@ void chEvtBroadcastFlagsI(EventSource *esp, flagsmask_t flags) { * * @iclass */ -flagsmask_t chEvtGetAndClearFlagsI(EventListener *elp) { +flagsmask_t chEvtGetAndClearFlags(EventListener *elp) { flagsmask_t flags; + chSysLock(); flags = elp->el_flags; elp->el_flags = 0; + chSysUnlock(); return flags; } @@ -284,13 +286,11 @@ flagsmask_t chEvtGetAndClearFlagsI(EventListener *elp) { * * @iclass */ -flagsmask_t chEvtGetAndClearFlags(EventListener *elp) { +flagsmask_t chEvtGetAndClearFlagsI(EventListener *elp) { flagsmask_t flags; - chSysLock(); flags = elp->el_flags; elp->el_flags = 0; - chSysUnlock(); return flags; } -- cgit v1.2.3 From 6d730a713cac352e97f868ac08b05169cffb2a82 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 16 Sep 2012 08:39:30 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4669 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chevents.c | 111 ++++++++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 55 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index bb948ab52..2d0e1ab93 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -126,7 +126,7 @@ void chEvtUnregister(EventSource *esp, EventListener *elp) { * * @api */ -eventmask_t chEvtClearFlags(eventmask_t mask) { +eventmask_t chEvtGetAndClearEvents(eventmask_t mask) { eventmask_t m; chSysLock(); @@ -147,7 +147,7 @@ eventmask_t chEvtClearFlags(eventmask_t mask) { * * @api */ -eventmask_t chEvtAddFlags(eventmask_t mask) { +eventmask_t chEvtAddEvents(eventmask_t mask) { chSysLock(); @@ -157,6 +157,60 @@ eventmask_t chEvtAddFlags(eventmask_t mask) { return mask; } +/** + * @brief Signals all the Event Listeners registered on the specified Event + * Source. + * @details This function variants ORs the specified event flags to all the + * threads registered on the @p EventSource in addition to the event + * flags specified by the threads themselves in the + * @p EventListener objects. + * @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] esp pointer to the @p EventSource structure + * @param[in] flags the flags set to be added to the listener flags mask + * + * @iclass + */ +void chEvtBroadcastFlagsI(EventSource *esp, flagsmask_t flags) { + EventListener *elp; + + chDbgCheckClassI(); + chDbgCheck(esp != NULL, "chEvtBroadcastMaskI"); + + elp = esp->es_next; + while (elp != (EventListener *)esp) { + elp->el_flags |= flags; + chEvtSignalI(elp->el_listener, elp->el_mask); + elp = elp->el_next; + } +} + +/** + * @brief Returns the flags associated to an @p EventListener. + * @details The flags are returned and the @p EventListener flags mask is + * cleared. + * + * @param[in] elp pointer to the @p EventListener structure + * @return The flags added to the listener by the associated + * event source. + * + * @iclass + */ +flagsmask_t chEvtGetAndClearFlags(EventListener *elp) { + flagsmask_t flags; + + chSysLock(); + + flags = elp->el_flags; + elp->el_flags = 0; + + chSysUnlock(); + return flags; +} + /** * @brief Adds a set of event flags directly to specified @p Thread. * @@ -222,59 +276,6 @@ void chEvtBroadcastFlags(EventSource *esp, flagsmask_t flags) { chSysUnlock(); } -/** - * @brief Signals all the Event Listeners registered on the specified Event - * Source. - * @details This function variants ORs the specified event flags to all the - * threads registered on the @p EventSource in addition to the event - * flags specified by the threads themselves in the - * @p EventListener objects. - * @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] esp pointer to the @p EventSource structure - * @param[in] flags the flags set to be added to the listener flags mask - * - * @iclass - */ -void chEvtBroadcastFlagsI(EventSource *esp, flagsmask_t flags) { - EventListener *elp; - - chDbgCheckClassI(); - chDbgCheck(esp != NULL, "chEvtBroadcastMaskI"); - - elp = esp->es_next; - while (elp != (EventListener *)esp) { - elp->el_flags |= flags; - chEvtSignalI(elp->el_listener, elp->el_mask); - elp = elp->el_next; - } -} - -/** - * @brief Returns the flags associated to an @p EventListener. - * @details The flags are returned and the @p EventListener flags mask is - * cleared. - * - * @param[in] elp pointer to the @p EventListener structure - * @return The flags added to the listener by the associated - * event source. - * - * @iclass - */ -flagsmask_t chEvtGetAndClearFlags(EventListener *elp) { - flagsmask_t flags; - - chSysLock(); - flags = elp->el_flags; - elp->el_flags = 0; - chSysUnlock(); - - return flags; -} - /** * @brief Returns the flags associated to an @p EventListener. * @details The flags are returned and the @p EventListener flags mask is -- cgit v1.2.3 From c17f03701a8d102888ce06752c3b53fc9bd2ddac Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 3 Oct 2012 13:52:13 +0000 Subject: Added GC persistence to the ch_debug object (ex ch_root). git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4732 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chregistry.c | 4 ++-- os/kernel/src/chsys.c | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c index 971133457..976e3a51a 100644 --- a/os/kernel/src/chregistry.c +++ b/os/kernel/src/chregistry.c @@ -56,9 +56,9 @@ /* * OS signature in ROM plus debug-related information. */ -ROMCONST chroot_t ch_root = { +volatile ROMCONST chdebug_t ch_debug = { "CHRT", - (uint8_t)sizeof (chroot_t), + (uint8_t)sizeof (chdebug_t), (uint8_t)0, (uint16_t)((CH_KERNEL_MAJOR << 11) | (CH_KERNEL_MINOR << 6) | diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 9a7be60ee..10987f56d 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -83,6 +83,9 @@ void chSysInit(void) { port_init(); _scheduler_init(); _vt_init(); +#if CH_USE_REGISTRY + (void)&ch_debug; +#endif #if CH_USE_MEMCORE _core_init(); #endif -- cgit v1.2.3 From 6d1ecacaf4a001fea2af72ec3682ace59f45adb8 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 3 Oct 2012 19:35:13 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4733 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chregistry.c | 6 +++--- os/kernel/src/chsys.c | 7 ++++--- 2 files changed, 7 insertions(+), 6 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c index 976e3a51a..8b9f40f85 100644 --- a/os/kernel/src/chregistry.c +++ b/os/kernel/src/chregistry.c @@ -56,10 +56,10 @@ /* * OS signature in ROM plus debug-related information. */ -volatile ROMCONST chdebug_t ch_debug = { - "CHRT", - (uint8_t)sizeof (chdebug_t), +ROMCONST chdebug_t ch_debug = { + "main", (uint8_t)0, + (uint8_t)sizeof (chdebug_t), (uint16_t)((CH_KERNEL_MAJOR << 11) | (CH_KERNEL_MINOR << 6) | (CH_KERNEL_PATCH) << 0), diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 10987f56d..1946a8263 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -83,9 +83,6 @@ void chSysInit(void) { port_init(); _scheduler_init(); _vt_init(); -#if CH_USE_REGISTRY - (void)&ch_debug; -#endif #if CH_USE_MEMCORE _core_init(); #endif @@ -106,7 +103,11 @@ void chSysInit(void) { #endif chSysEnable(); +#if CH_USE_REGISTRY + chRegSetThreadName((const char *)&ch_debug); +#else chRegSetThreadName("main"); +#endif #if !CH_NO_IDLE_THREAD /* This thread has the lowest priority in the system, its role is just to -- cgit v1.2.3 From 4542e4c7506b80777d940c63f68889821b50abb8 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 3 Oct 2012 19:49:01 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4734 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsys.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index 1946a8263..cad546277 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -103,11 +103,9 @@ void chSysInit(void) { #endif chSysEnable(); -#if CH_USE_REGISTRY + /* Note, &ch_debug points to the string "main" if the registry is + active, else the parameter is ignored.*/ chRegSetThreadName((const char *)&ch_debug); -#else - chRegSetThreadName("main"); -#endif #if !CH_NO_IDLE_THREAD /* This thread has the lowest priority in the system, its role is just to -- cgit v1.2.3 From 9e120509c1647811681472008ed7668ef17283ce Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 13 Oct 2012 11:05:55 +0000 Subject: Fixed bug 3576776. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4759 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chregistry.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c index 8b9f40f85..5a28ac2fb 100644 --- a/os/kernel/src/chregistry.c +++ b/os/kernel/src/chregistry.c @@ -88,7 +88,11 @@ ROMCONST chdebug_t ch_debug = { #else (uint8_t)0, #endif +#if CH_DBG_THREADS_PROFILING (uint8_t)_offsetof(Thread, p_time) +#else + (uint8_t)0 +#endif }; /** -- cgit v1.2.3 From 64e7fd5a530201190720c8b25535998c9ebf8e84 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 2 Jan 2013 10:11:02 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@5012 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chevents.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index 2d0e1ab93..c2822f8e9 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -142,7 +142,7 @@ eventmask_t chEvtGetAndClearEvents(eventmask_t mask) { * @brief Adds (OR) a set of event flags on the current thread, this is * @b much faster than using @p chEvtBroadcast() or @p chEvtSignal(). * - * @param[in] mask the event flags to be ORed + * @param[in] mask the event flags to be added * @return The current pending events mask. * * @api -- cgit v1.2.3 From 04db761f7e787b9f920aa2c264b6133d1b1815ff Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 2 Jan 2013 14:01:11 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@5017 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chsem.c | 2 +- os/kernel/src/chthreads.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index 10aee42d3..0ec331b41 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -347,7 +347,7 @@ void chSemAddCounterI(Semaphore *sp, cnt_t n) { * to use this function. * * @param[in] sps pointer to a @p Semaphore structure to be signaled - * @param[in] spw pointer to a @p Semaphore structure to be wait on + * @param[in] spw pointer to a @p Semaphore structure to wait on * @return A message specifying how the invoking thread has been * released from the semaphore. * @retval RDY_OK if the thread has not stopped on the semaphore or the diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 0be671c16..0df804df7 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -233,7 +233,7 @@ tprio_t chThdSetPriority(tprio_t newprio) { * in the @p THD_STATE_SUSPENDED state. * @post The specified thread is immediately started or put in the ready * list depending on the relative priority levels. - * @note Use this function to start threads created with @p chThdInit(). + * @note Use this function to start threads created with @p chThdCreateI(). * * @param[in] tp pointer to the thread * @return The pointer to the thread. @@ -388,9 +388,9 @@ void chThdExitS(msg_t msg) { * The memory used by the exited thread is handled in different ways * depending on the API that spawned the thread: * - If the thread was spawned by @p chThdCreateStatic() or by - * @p chThdInit() then nothing happens and the thread working area - * is not released or modified in any way. This is the default, - * totally static, behavior. + * @p chThdCreateI() then nothing happens and the thread working + * area is not released or modified in any way. This is the + * default, totally static, behavior. * - If the thread was spawned by @p chThdCreateFromHeap() then * the working area is returned to the system heap. * - If the thread was spawned by @p chThdCreateFromMemoryPool() -- cgit v1.2.3 From 739e24c329dc3ca72349dec8f4ce16b69abd62e9 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 6 Jan 2013 09:10:58 +0000 Subject: Merged another patch to the C++ wrapper. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@5036 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmempools.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c index 21d205fc8..dc0b3ab85 100644 --- a/os/kernel/src/chmempools.c +++ b/os/kernel/src/chmempools.c @@ -41,8 +41,6 @@ #if CH_USE_MEMPOOLS || defined(__DOXYGEN__) /** * @brief Initializes an empty memory pool. - * @note The size is internally aligned to be a multiple of the - * @p stkalign_t type size. * * @param[out] mp pointer to a @p MemoryPool structure * @param[in] size the size of the objects contained in this memory pool, -- cgit v1.2.3 From 184a71345c6a36a9a8664eda8fbcc3ea728267a8 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 2 Feb 2013 10:58:09 +0000 Subject: Updated license years. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@5102 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chcond.c | 2 +- os/kernel/src/chdebug.c | 2 +- os/kernel/src/chdynamic.c | 2 +- os/kernel/src/chevents.c | 2 +- os/kernel/src/chheap.c | 2 +- os/kernel/src/chlists.c | 2 +- os/kernel/src/chmboxes.c | 2 +- os/kernel/src/chmemcore.c | 2 +- os/kernel/src/chmempools.c | 2 +- os/kernel/src/chmsg.c | 2 +- os/kernel/src/chmtx.c | 2 +- os/kernel/src/chqueues.c | 2 +- os/kernel/src/chregistry.c | 2 +- os/kernel/src/chschd.c | 2 +- os/kernel/src/chsem.c | 2 +- os/kernel/src/chsys.c | 2 +- os/kernel/src/chthreads.c | 2 +- os/kernel/src/chvt.c | 2 +- 18 files changed, 18 insertions(+), 18 deletions(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c index ae62f1a31..c217bf6fd 100644 --- a/os/kernel/src/chcond.c +++ b/os/kernel/src/chcond.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011,2012,2013 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chdebug.c b/os/kernel/src/chdebug.c index 55631481f..c69ce8f3f 100644 --- a/os/kernel/src/chdebug.c +++ b/os/kernel/src/chdebug.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011,2012,2013 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chdynamic.c b/os/kernel/src/chdynamic.c index 9ef62d487..632367ca1 100644 --- a/os/kernel/src/chdynamic.c +++ b/os/kernel/src/chdynamic.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011,2012,2013 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chevents.c b/os/kernel/src/chevents.c index c2822f8e9..1a2285779 100644 --- a/os/kernel/src/chevents.c +++ b/os/kernel/src/chevents.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011,2012,2013 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chheap.c b/os/kernel/src/chheap.c index 1e7f99dce..23bcff6b4 100644 --- a/os/kernel/src/chheap.c +++ b/os/kernel/src/chheap.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011,2012,2013 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chlists.c b/os/kernel/src/chlists.c index b7821493e..8ee309200 100644 --- a/os/kernel/src/chlists.c +++ b/os/kernel/src/chlists.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011,2012,2013 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chmboxes.c b/os/kernel/src/chmboxes.c index 860e92db9..6f09a8d26 100644 --- a/os/kernel/src/chmboxes.c +++ b/os/kernel/src/chmboxes.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011,2012,2013 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chmemcore.c b/os/kernel/src/chmemcore.c index a13a85873..0ff26bc76 100644 --- a/os/kernel/src/chmemcore.c +++ b/os/kernel/src/chmemcore.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011,2012,2013 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chmempools.c b/os/kernel/src/chmempools.c index dc0b3ab85..44faa057a 100644 --- a/os/kernel/src/chmempools.c +++ b/os/kernel/src/chmempools.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011,2012,2013 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chmsg.c b/os/kernel/src/chmsg.c index 50814ef9c..ad97da79c 100644 --- a/os/kernel/src/chmsg.c +++ b/os/kernel/src/chmsg.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011,2012,2013 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 6e32ca439..84d7e53a6 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011,2012,2013 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index ec8fec2b3..871e499a0 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011,2012,2013 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chregistry.c b/os/kernel/src/chregistry.c index 5a28ac2fb..645172833 100644 --- a/os/kernel/src/chregistry.c +++ b/os/kernel/src/chregistry.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011,2012,2013 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chschd.c b/os/kernel/src/chschd.c index a7864bc71..1106cf03f 100644 --- a/os/kernel/src/chschd.c +++ b/os/kernel/src/chschd.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011,2012,2013 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index 0ec331b41..2dc7ee354 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011,2012,2013 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chsys.c b/os/kernel/src/chsys.c index cad546277..a6f1d15ba 100644 --- a/os/kernel/src/chsys.c +++ b/os/kernel/src/chsys.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011,2012,2013 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 0df804df7..8a9fe11b6 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011,2012,2013 Giovanni Di Sirio. This file is part of ChibiOS/RT. diff --git a/os/kernel/src/chvt.c b/os/kernel/src/chvt.c index 6389aaf6d..a8e3ce499 100644 --- a/os/kernel/src/chvt.c +++ b/os/kernel/src/chvt.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011,2012,2013 Giovanni Di Sirio. This file is part of ChibiOS/RT. -- cgit v1.2.3 From c4a01fccefa5105067b4f8c05709c4ccf4734310 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 26 Apr 2013 12:42:56 +0000 Subject: Fixed bug #404. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@5629 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chthreads.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src') diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 8a9fe11b6..9f6973c90 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -149,7 +149,7 @@ void _thread_memfill(uint8_t *startp, uint8_t *endp, uint8_t v) { */ Thread *chThdCreateI(void *wsp, size_t size, tprio_t prio, tfunc_t pf, void *arg) { - /* Thread structure is layed out in the lower part of the thread workspace.*/ + /* Thread structure is laid out in the lower part of the thread workspace.*/ Thread *tp = wsp; chDbgCheckClassI(); -- cgit v1.2.3