diff --git a/os/hal/platforms/STM32/OTGv1/usb_lld.c b/os/hal/platforms/STM32/OTGv1/usb_lld.c index f6287a49c..0aa9adf24 100644 --- a/os/hal/platforms/STM32/OTGv1/usb_lld.c +++ b/os/hal/platforms/STM32/OTGv1/usb_lld.c @@ -317,7 +317,7 @@ static void otg_fifo_write_from_queue(volatile uint32_t *fifop, /* Updating queue.*/ chSysLock(); oqp->q_counter += n; - while (notempty(&oqp->q_waiting)) + while (queue_notempty(&oqp->q_waiting)) chSchReadyI(fifo_remove(&oqp->q_waiting))->p_u.rdymsg = Q_OK; chSchRescheduleS(); chSysUnlock(); @@ -429,7 +429,7 @@ static void otg_fifo_read_to_queue(volatile uint32_t *fifop, /* Updating queue.*/ chSysLock(); iqp->q_counter += n; - while (notempty(&iqp->q_waiting)) + while (queue_notempty(&iqp->q_waiting)) chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = Q_OK; chSchRescheduleS(); chSysUnlock(); diff --git a/os/kernel/include/ch.h b/os/kernel/include/ch.h index 677aa58b7..026b14267 100644 --- a/os/kernel/include/ch.h +++ b/os/kernel/include/ch.h @@ -100,11 +100,14 @@ #endif /** @} */ +typedef struct Thread Thread; + #include "chconf.h" #include "chtypes.h" #include "chdebug.h" -#include "chlists.h" #include "chcore.h" +#include "chthreads.h" +//#include "chlists.h" #include "chsys.h" #include "chvt.h" #include "chschd.h" @@ -118,7 +121,6 @@ #include "chmemcore.h" #include "chheap.h" #include "chmempools.h" -#include "chthreads.h" #include "chdynamic.h" #include "chregistry.h" #include "chinline.h" diff --git a/os/kernel/include/chlists.h b/os/kernel/include/chlists.h deleted file mode 100644 index caf2560b4..000000000 --- a/os/kernel/include/chlists.h +++ /dev/null @@ -1,127 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012,2013 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.h - * @brief Thread queues/lists macros and structures. - * @note All the macros present in this module, while public, are not - * an OS API and should not be directly used in the user applications - * code. - * - * @addtogroup internals - * @{ - */ - -#ifndef _CHLISTS_H_ -#define _CHLISTS_H_ - -typedef struct Thread Thread; - -/** - * @brief Threads queue initialization. - * - * @notapi - */ -#define queue_init(tqp) ((tqp)->p_next = (tqp)->p_prev = (Thread *)(tqp)); - -/** - * @brief Threads list initialization. - * - * @notapi - */ -#define list_init(tlp) ((tlp)->p_next = (Thread *)(tlp)) - -/** - * @brief Evaluates to @p TRUE if the specified threads queue or list is - * empty. - * - * @notapi - */ -#define isempty(p) ((p)->p_next == (Thread *)(p)) - -/** - * @brief Evaluates to @p TRUE if the specified threads queue or list is - * not empty. - * - * @notapi - */ -#define notempty(p) ((p)->p_next != (Thread *)(p)) - -/** - * @brief Data part of a static threads queue initializer. - * @details This macro should be used when statically initializing a threads - * queue that is part of a bigger structure. - * - * @param[in] name the name of the threads queue variable - */ -#define _THREADSQUEUE_DATA(name) {(Thread *)&name, (Thread *)&name} - -/** - * @brief Static threads queue initializer. - * @details Statically initialized threads queues require no explicit - * initialization using @p queue_init(). - * - * @param[in] name the name of the threads queue variable - */ -#define THREADSQUEUE_DECL(name) ThreadsQueue name = _THREADSQUEUE_DATA(name) - -/** - * @extends ThreadsList - * - * @brief Generic threads bidirectional linked list header and element. - */ -typedef struct { - Thread *p_next; /**< First @p Thread in the queue, or - @p ThreadQueue when empty. */ - Thread *p_prev; /**< Last @p Thread in the queue, or - @p ThreadQueue when empty. */ -} ThreadsQueue; - -/** - * @brief Generic threads single link list, it works like a stack. - */ -typedef struct { - - Thread *p_next; /**< Last pushed @p Thread on the stack - list, or pointer to itself if - empty. */ -} ThreadsList; - -#if !CH_OPTIMIZE_SPEED - -#ifdef __cplusplus -extern "C" { -#endif - void prio_insert(Thread *tp, ThreadsQueue *tqp); - void queue_insert(Thread *tp, ThreadsQueue *tqp); - Thread *fifo_remove(ThreadsQueue *tqp); - Thread *lifo_remove(ThreadsQueue *tqp); - Thread *dequeue(Thread *tp); - void list_insert(Thread *tp, ThreadsList *tlp); - Thread *list_remove(ThreadsList *tlp); -#ifdef __cplusplus -} -#endif - -#endif /* !CH_OPTIMIZE_SPEED */ - -#endif /* _CHLISTS_H_ */ - -/** @} */ diff --git a/os/kernel/include/chmtx.h b/os/kernel/include/chmtx.h index 124127a88..00ebb2a23 100644 --- a/os/kernel/include/chmtx.h +++ b/os/kernel/include/chmtx.h @@ -86,7 +86,7 @@ extern "C" { * * @sclass */ -#define chMtxQueueNotEmptyS(mp) notempty(&(mp)->m_queue) +#define chMtxQueueNotEmptyS(mp) queue_notempty(&(mp)->m_queue) /** @} */ #endif /* CH_USE_MUTEXES */ diff --git a/os/kernel/include/chthreads.h b/os/kernel/include/chthreads.h index 77f72caca..1341cb1ea 100644 --- a/os/kernel/include/chthreads.h +++ b/os/kernel/include/chthreads.h @@ -20,7 +20,7 @@ /** * @file chthreads.h - * @brief Threads macros and structures. + * @brief Threads module macros and structures. * * @addtogroup threads * @{ @@ -29,6 +29,10 @@ #ifndef _CHTHREADS_H_ #define _CHTHREADS_H_ +/*===========================================================================*/ +/* Module constants. */ +/*===========================================================================*/ + /** * @name Thread states * @{ @@ -76,6 +80,42 @@ #define THD_TERMINATE 4 /**< @brief Termination requested flag. */ /** @} */ +/*===========================================================================*/ +/* Module pre-compile time settings. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Derived constants and error checks. */ +/*===========================================================================*/ + +/*===========================================================================*/ +/* Module data structures and types. */ +/*===========================================================================*/ + +/* Forward declaration required by the mutexes stack structure present + in every thread.*/ +#if CH_USE_MUTEXES +typedef struct Mutex Mutex; +#endif + +/** + * @brief Generic threads single link list, it works like a stack. + */ +typedef struct { + + Thread *p_next; /**< @brief Next in the list/queue. */ +} ThreadsList; + +/** + * @extends ThreadsList + * + * @brief Generic threads bidirectional linked list header and element. + */ +typedef struct { + Thread *p_next; /**< @brief Next in the list/queue. */ + Thread *p_prev; /**< @brief Previous in the queue. */ +} ThreadsQueue; + /** * @extends ThreadsQueue * @@ -221,6 +261,32 @@ struct Thread { */ typedef msg_t (*tfunc_t)(void *); +/*===========================================================================*/ +/* Module macros. */ +/*===========================================================================*/ + +/** + * @brief Data part of a static threads queue initializer. + * @details This macro should be used when statically initializing a threads + * queue that is part of a bigger structure. + * + * @param[in] name the name of the threads queue variable + */ +#define _THREADSQUEUE_DATA(name) {(Thread *)&name, (Thread *)&name} + +/** + * @brief Static threads queue initializer. + * @details Statically initialized threads queues require no explicit + * initialization using @p queue_init(). + * + * @param[in] name the name of the threads queue variable + */ +#define THREADSQUEUE_DECL(name) ThreadsQueue name = _THREADSQUEUE_DATA(name) + +/*===========================================================================*/ +/* External declarations. */ +/*===========================================================================*/ + /** * @name Macro Functions * @{ @@ -253,14 +319,6 @@ typedef msg_t (*tfunc_t)(void *); */ #define chThdGetTicks(tp) ((tp)->p_time) -/** - * @brief Returns the pointer to the @p Thread local storage area, if any. - * @note Can be invoked in any context. - * - * @special - */ -#define chThdLS() (void *)(currp + 1) - /** * @brief Verifies if the specified thread is in the @p THD_STATE_FINAL state. * @note Can be invoked in any context. @@ -375,6 +433,70 @@ extern "C" { } #endif +/*===========================================================================*/ +/* Module inline functions. */ +/*===========================================================================*/ + +/** + * @brief Threads list initialization. + * + * @notapi + */ +static inline void list_init(ThreadsList *tlp) { + + tlp->p_next = (Thread *)tlp; +} + +/** + * @brief Evaluates to @p TRUE if the specified threads list is empty. + * + * @notapi + */ +static inline bool_t list_isempty(ThreadsList *tlp) { + + return (bool_t)(tlp->p_next == (Thread *)tlp); +} + +/** + * @brief Evaluates to @p TRUE if the specified threads list is not empty. + * + * @notapi + */ +static inline bool_t list_notempty(ThreadsList *tlp) { + + return (bool_t)(tlp->p_next != (Thread *)tlp); +} + +/** + * @brief Threads queue initialization. + * + * @notapi + */ +static inline void queue_init(ThreadsQueue *tqp) { + + tqp->p_next = tqp->p_prev = (Thread *)tqp; +} + +/** + * @brief Evaluates to @p TRUE if the specified threads queue is empty. + * + * @notapi + */ +static inline bool_t queue_isempty(ThreadsQueue *tqp) { + + return (bool_t)(tqp->p_next == (Thread *)tqp); +} + +/** + * @brief Evaluates to @p TRUE if the specified threads queue is not empty. + * + * @notapi + */ +static inline bool_t queue_notempty(ThreadsQueue *tqp) { + + return (bool_t)(tqp->p_next != (Thread *)tqp); +} + #endif /* _CHTHREADS_H_ */ /** @} */ diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c index c217bf6fd..0e404808f 100644 --- a/os/kernel/src/chcond.c +++ b/os/kernel/src/chcond.c @@ -68,7 +68,7 @@ void chCondSignal(CondVar *cp) { chDbgCheck(cp != NULL, "chCondSignal"); chSysLock(); - if (notempty(&cp->c_queue)) + if (queue_notempty(&cp->c_queue)) chSchWakeupS(fifo_remove(&cp->c_queue), RDY_OK); chSysUnlock(); } @@ -89,7 +89,7 @@ void chCondSignalI(CondVar *cp) { chDbgCheckClassI(); chDbgCheck(cp != NULL, "chCondSignalI"); - if (notempty(&cp->c_queue)) + if (queue_notempty(&cp->c_queue)) chSchReadyI(fifo_remove(&cp->c_queue))->p_u.rdymsg = RDY_OK; } diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index 871e499a0..fa2bd527b 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -113,7 +113,7 @@ void chIQResetI(InputQueue *iqp) { iqp->q_rdptr = iqp->q_wrptr = iqp->q_buffer; iqp->q_counter = 0; - while (notempty(&iqp->q_waiting)) + while (queue_notempty(&iqp->q_waiting)) chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = Q_RESET; } @@ -142,7 +142,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)) + if (queue_notempty(&iqp->q_waiting)) chSchReadyI(fifo_remove(&iqp->q_waiting))->p_u.rdymsg = Q_OK; return Q_OK; @@ -293,7 +293,7 @@ void chOQResetI(OutputQueue *oqp) { oqp->q_rdptr = oqp->q_wrptr = oqp->q_buffer; oqp->q_counter = chQSizeI(oqp); - while (notempty(&oqp->q_waiting)) + while (queue_notempty(&oqp->q_waiting)) chSchReadyI(fifo_remove(&oqp->q_waiting))->p_u.rdymsg = Q_RESET; } @@ -366,7 +366,7 @@ msg_t chOQGetI(OutputQueue *oqp) { if (oqp->q_rdptr >= oqp->q_top) oqp->q_rdptr = oqp->q_buffer; - if (notempty(&oqp->q_waiting)) + if (queue_notempty(&oqp->q_waiting)) chSchReadyI(fifo_remove(&oqp->q_waiting))->p_u.rdymsg = Q_OK; return b; diff --git a/os/kernel/src/chsem.c b/os/kernel/src/chsem.c index 2dc7ee354..7ea365291 100644 --- a/os/kernel/src/chsem.c +++ b/os/kernel/src/chsem.c @@ -131,8 +131,8 @@ void chSemResetI(Semaphore *sp, cnt_t n) { chDbgCheckClassI(); chDbgCheck((sp != NULL) && (n >= 0), "chSemResetI"); - chDbgAssert(((sp->s_cnt >= 0) && isempty(&sp->s_queue)) || - ((sp->s_cnt < 0) && notempty(&sp->s_queue)), + chDbgAssert(((sp->s_cnt >= 0) && queue_isempty(&sp->s_queue)) || + ((sp->s_cnt < 0) && queue_notempty(&sp->s_queue)), "chSemResetI(), #1", "inconsistent semaphore"); @@ -179,8 +179,8 @@ 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)), + chDbgAssert(((sp->s_cnt >= 0) && queue_isempty(&sp->s_queue)) || + ((sp->s_cnt < 0) && queue_notempty(&sp->s_queue)), "chSemWaitS(), #1", "inconsistent semaphore"); @@ -244,8 +244,8 @@ 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)), + chDbgAssert(((sp->s_cnt >= 0) && queue_isempty(&sp->s_queue)) || + ((sp->s_cnt < 0) && queue_notempty(&sp->s_queue)), "chSemWaitTimeoutS(), #1", "inconsistent semaphore"); @@ -271,8 +271,8 @@ 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)), + chDbgAssert(((sp->s_cnt >= 0) && queue_isempty(&sp->s_queue)) || + ((sp->s_cnt < 0) && queue_notempty(&sp->s_queue)), "chSemSignal(), #1", "inconsistent semaphore"); @@ -297,8 +297,8 @@ 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)), + chDbgAssert(((sp->s_cnt >= 0) && queue_isempty(&sp->s_queue)) || + ((sp->s_cnt < 0) && queue_notempty(&sp->s_queue)), "chSemSignalI(), #1", "inconsistent semaphore"); @@ -328,8 +328,8 @@ 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)), + chDbgAssert(((sp->s_cnt >= 0) && queue_isempty(&sp->s_queue)) || + ((sp->s_cnt < 0) && queue_notempty(&sp->s_queue)), "chSemAddCounterI(), #1", "inconsistent semaphore"); @@ -360,12 +360,12 @@ 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)), + chDbgAssert(((sps->s_cnt >= 0) && queue_isempty(&sps->s_queue)) || + ((sps->s_cnt < 0) && queue_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)), + chDbgAssert(((spw->s_cnt >= 0) && queue_isempty(&spw->s_queue)) || + ((spw->s_cnt < 0) && queue_notempty(&spw->s_queue)), "chSemSignalWait(), #2", "inconsistent semaphore"); diff --git a/os/kernel/src/chthreads.c b/os/kernel/src/chthreads.c index 7652cbfb1..37d25eb7b 100644 --- a/os/kernel/src/chthreads.c +++ b/os/kernel/src/chthreads.c @@ -364,7 +364,7 @@ void chThdExitS(msg_t msg) { THREAD_EXT_EXIT_HOOK(tp); #endif #if CH_USE_WAITEXIT - while (notempty(&tp->p_waiting)) + while (list_notempty(&tp->p_waiting)) chSchReadyI(list_remove(&tp->p_waiting)); #endif #if CH_USE_REGISTRY diff --git a/test/testmtx.c b/test/testmtx.c index f83a9744a..52b5cebd4 100644 --- a/test/testmtx.c +++ b/test/testmtx.c @@ -446,13 +446,13 @@ static void mtx5_execute(void) { chMtxUnlockS(); chSysUnlock(); - test_assert(3, isempty(&m1.m_queue), "queue not empty"); + test_assert(3, queue_isempty(&m1.m_queue), "queue not empty"); test_assert(4, m1.m_owner == NULL, "still owned"); test_assert(5, chThdGetPriority() == prio, "wrong priority level"); chMtxLock(&m1); chMtxUnlockAll(); - test_assert(6, isempty(&m1.m_queue), "queue not empty"); + test_assert(6, queue_isempty(&m1.m_queue), "queue not empty"); test_assert(7, m1.m_owner == NULL, "still owned"); } diff --git a/test/testsem.c b/test/testsem.c index 20774b618..3de2e68fb 100644 --- a/test/testsem.c +++ b/test/testsem.c @@ -151,7 +151,7 @@ static void sem2_execute(void) { */ msg = chSemWaitTimeout(&sem1, TIME_IMMEDIATE); test_assert(1, msg == RDY_TIMEOUT, "wrong wake-up message"); - test_assert(2, isempty(&sem1.s_queue), "queue not empty"); + test_assert(2, queue_isempty(&sem1.s_queue), "queue not empty"); test_assert(3, sem1.s_cnt == 0, "counter not zero"); /* @@ -162,7 +162,7 @@ static void sem2_execute(void) { msg = chSemWaitTimeout(&sem1, MS2ST(500)); test_wait_threads(); test_assert(4, msg == RDY_OK, "wrong wake-up message"); - test_assert(5, isempty(&sem1.s_queue), "queue not empty"); + test_assert(5, queue_isempty(&sem1.s_queue), "queue not empty"); test_assert(6, sem1.s_cnt == 0, "counter not zero"); /* @@ -174,7 +174,7 @@ static void sem2_execute(void) { test_emit_token('A' + i); msg = chSemWaitTimeout(&sem1, MS2ST(500)); test_assert(7, msg == RDY_TIMEOUT, "wrong wake-up message"); - test_assert(8, isempty(&sem1.s_queue), "queue not empty"); + test_assert(8, queue_isempty(&sem1.s_queue), "queue not empty"); test_assert(9, sem1.s_cnt == 0, "counter not zero"); } test_assert_sequence(10, "ABCDE"); @@ -218,11 +218,11 @@ static void sem3_execute(void) { threads[0] = chThdCreateStatic(wa[0], WA_SIZE, chThdGetPriority()+1, thread3, 0); chSemSignalWait(&sem1, &sem1); - test_assert(1, isempty(&sem1.s_queue), "queue not empty"); + test_assert(1, queue_isempty(&sem1.s_queue), "queue not empty"); test_assert(2, sem1.s_cnt == 0, "counter not zero"); chSemSignalWait(&sem1, &sem1); - test_assert(3, isempty(&sem1.s_queue), "queue not empty"); + test_assert(3, queue_isempty(&sem1.s_queue), "queue not empty"); test_assert(4, sem1.s_cnt == 0, "counter not zero"); }