ChibiOS/RT
2.5.1
chlists.c
Go to the documentation of this file.
00001 /*
00002     ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
00003                  2011,2012 Giovanni Di Sirio.
00004 
00005     This file is part of ChibiOS/RT.
00006 
00007     ChibiOS/RT is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 3 of the License, or
00010     (at your option) any later version.
00011 
00012     ChibiOS/RT is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 */
00020 
00021 /**
00022  * @file    chlists.c
00023  * @brief   Thread queues/lists code.
00024  *
00025  * @addtogroup internals
00026  * @details All the functions present in this module, while public, are not
00027  *          OS APIs and should not be directly used in the user applications
00028  *          code.
00029  * @{
00030  */
00031 #include "ch.h"
00032 
00033 #if !CH_OPTIMIZE_SPEED || defined(__DOXYGEN__)
00034 /**
00035  * @brief   Inserts a thread into a priority ordered queue.
00036  * @note    The insertion is done by scanning the list from the highest
00037  *          priority toward the lowest.
00038  *
00039  * @param[in] tp        the pointer to the thread to be inserted in the list
00040  * @param[in] tqp       the pointer to the threads list header
00041  *
00042  * @notapi
00043  */
00044 void prio_insert(Thread *tp, ThreadsQueue *tqp) {
00045 
00046   /* cp iterates over the queue.*/
00047   Thread *cp = (Thread *)tqp;
00048   do {
00049     /* Iterate to next thread in queue.*/
00050     cp = cp->p_next;
00051     /* Not end of queue? and cp has equal or higher priority than tp?.*/
00052   } while ((cp != (Thread *)tqp) && (cp->p_prio >= tp->p_prio));
00053   /* Insertion on p_prev.*/
00054   tp->p_next = cp;
00055   tp->p_prev = cp->p_prev;
00056   tp->p_prev->p_next = cp->p_prev = tp;
00057 }
00058 
00059 /**
00060  * @brief   Inserts a Thread into a queue.
00061  *
00062  * @param[in] tp        the pointer to the thread to be inserted in the list
00063  * @param[in] tqp       the pointer to the threads list header
00064  *
00065  * @notapi
00066  */
00067 void queue_insert(Thread *tp, ThreadsQueue *tqp) {
00068 
00069   tp->p_next = (Thread *)tqp;
00070   tp->p_prev = tqp->p_prev;
00071   tp->p_prev->p_next = tqp->p_prev = tp;
00072 }
00073 
00074 /**
00075  * @brief   Removes the first-out Thread from a queue and returns it.
00076  * @note    If the queue is priority ordered then this function returns the
00077  *          thread with the highest priority.
00078  *
00079  * @param[in] tqp       the pointer to the threads list header
00080  * @return              The removed thread pointer.
00081  *
00082  * @notapi
00083  */
00084 Thread *fifo_remove(ThreadsQueue *tqp) {
00085   Thread *tp = tqp->p_next;
00086 
00087   (tqp->p_next = tp->p_next)->p_prev = (Thread *)tqp;
00088   return tp;
00089 }
00090 
00091 /**
00092  * @brief   Removes the last-out Thread from a queue and returns it.
00093  * @note    If the queue is priority ordered then this function returns the
00094  *          thread with the lowest priority.
00095  *
00096  * @param[in] tqp   the pointer to the threads list header
00097  * @return          The removed thread pointer.
00098  *
00099  * @notapi
00100  */
00101 Thread *lifo_remove(ThreadsQueue *tqp) {
00102   Thread *tp = tqp->p_prev;
00103 
00104   (tqp->p_prev = tp->p_prev)->p_next = (Thread *)tqp;
00105   return tp;
00106 }
00107 
00108 /**
00109  * @brief   Removes a Thread from a queue and returns it.
00110  * @details The thread is removed from the queue regardless of its relative
00111  *          position and regardless the used insertion method.
00112  *
00113  * @param[in] tp        the pointer to the thread to be removed from the queue
00114  * @return              The removed thread pointer.
00115  *
00116  * @notapi
00117  */
00118 Thread *dequeue(Thread *tp) {
00119 
00120   tp->p_prev->p_next = tp->p_next;
00121   tp->p_next->p_prev = tp->p_prev;
00122   return tp;
00123 }
00124 
00125 /**
00126  * @brief   Pushes a Thread on top of a stack list.
00127  *
00128  * @param[in] tp    the pointer to the thread to be inserted in the list
00129  * @param[in] tlp   the pointer to the threads list header
00130  *
00131  * @notapi
00132  */
00133 void list_insert(Thread *tp, ThreadsList *tlp) {
00134 
00135   tp->p_next = tlp->p_next;
00136   tlp->p_next = tp;
00137 }
00138 
00139 /**
00140  * @brief   Pops a Thread from the top of a stack list and returns it.
00141  * @pre     The list must be non-empty before calling this function.
00142  *
00143  * @param[in] tlp       the pointer to the threads list header
00144  * @return              The removed thread pointer.
00145  *
00146  * @notapi
00147  */
00148 Thread *list_remove(ThreadsList *tlp) {
00149 
00150   Thread *tp = tlp->p_next;
00151   tlp->p_next = tp->p_next;
00152   return tp;
00153 }
00154 #endif /* CH_OPTIMIZE_SPEED */
00155 
00156 /** @} */