Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of mbed-rtos by
rt_List.c
00001 /*---------------------------------------------------------------------------- 00002 * RL-ARM - RTX 00003 *---------------------------------------------------------------------------- 00004 * Name: RT_LIST.C 00005 * Purpose: Functions for the management of different lists 00006 * Rev.: V4.60 00007 *---------------------------------------------------------------------------- 00008 * 00009 * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH 00010 * All rights reserved. 00011 * Redistribution and use in source and binary forms, with or without 00012 * modification, are permitted provided that the following conditions are met: 00013 * - Redistributions of source code must retain the above copyright 00014 * notice, this list of conditions and the following disclaimer. 00015 * - Redistributions in binary form must reproduce the above copyright 00016 * notice, this list of conditions and the following disclaimer in the 00017 * documentation and/or other materials provided with the distribution. 00018 * - Neither the name of ARM nor the names of its contributors may be used 00019 * to endorse or promote products derived from this software without 00020 * specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00023 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00024 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 00025 * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE 00026 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 00027 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 00028 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00029 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 00030 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 00031 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00032 * POSSIBILITY OF SUCH DAMAGE. 00033 *---------------------------------------------------------------------------*/ 00034 00035 #include "rt_TypeDef.h" 00036 #include "RTX_Conf.h" 00037 #include "rt_System.h" 00038 #include "rt_List.h" 00039 #include "rt_Task.h" 00040 #include "rt_Time.h" 00041 #include "rt_HAL_CM.h" 00042 00043 /*---------------------------------------------------------------------------- 00044 * Global Variables 00045 *---------------------------------------------------------------------------*/ 00046 00047 /* List head of chained ready tasks */ 00048 struct OS_XCB os_rdy; 00049 /* List head of chained delay tasks */ 00050 struct OS_XCB os_dly; 00051 00052 00053 /*---------------------------------------------------------------------------- 00054 * Functions 00055 *---------------------------------------------------------------------------*/ 00056 00057 00058 /*--------------------------- rt_put_prio -----------------------------------*/ 00059 00060 void rt_put_prio (P_XCB p_CB, P_TCB p_task) { 00061 /* Put task identified with "p_task" into list ordered by priority. */ 00062 /* "p_CB" points to head of list; list has always an element at end with */ 00063 /* a priority less than "p_task->prio". */ 00064 P_TCB p_CB2; 00065 U32 prio; 00066 BOOL sem_mbx = __FALSE; 00067 00068 if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) { 00069 sem_mbx = __TRUE; 00070 } 00071 prio = p_task->prio; 00072 p_CB2 = p_CB->p_lnk; 00073 /* Search for an entry in the list */ 00074 while (p_CB2 != NULL && prio <= p_CB2->prio) { 00075 p_CB = (P_XCB)p_CB2; 00076 p_CB2 = p_CB2->p_lnk; 00077 } 00078 /* Entry found, insert the task into the list */ 00079 p_task->p_lnk = p_CB2; 00080 p_CB->p_lnk = p_task; 00081 if (sem_mbx) { 00082 if (p_CB2 != NULL) { 00083 p_CB2->p_rlnk = p_task; 00084 } 00085 p_task->p_rlnk = (P_TCB)p_CB; 00086 } 00087 else { 00088 p_task->p_rlnk = NULL; 00089 } 00090 } 00091 00092 00093 /*--------------------------- rt_get_first ----------------------------------*/ 00094 00095 P_TCB rt_get_first (P_XCB p_CB) { 00096 /* Get task at head of list: it is the task with highest priority. */ 00097 /* "p_CB" points to head of list. */ 00098 P_TCB p_first; 00099 00100 p_first = p_CB->p_lnk; 00101 p_CB->p_lnk = p_first->p_lnk; 00102 if (p_CB->cb_type == SCB || p_CB->cb_type == MCB || p_CB->cb_type == MUCB) { 00103 if (p_first->p_lnk != NULL) { 00104 p_first->p_lnk->p_rlnk = (P_TCB)p_CB; 00105 p_first->p_lnk = NULL; 00106 } 00107 p_first->p_rlnk = NULL; 00108 } 00109 else { 00110 p_first->p_lnk = NULL; 00111 } 00112 return (p_first); 00113 } 00114 00115 00116 /*--------------------------- rt_put_rdy_first ------------------------------*/ 00117 00118 void rt_put_rdy_first (P_TCB p_task) { 00119 /* Put task identified with "p_task" at the head of the ready list. The */ 00120 /* task must have at least a priority equal to highest priority in list. */ 00121 p_task->p_lnk = os_rdy.p_lnk; 00122 p_task->p_rlnk = NULL; 00123 os_rdy.p_lnk = p_task; 00124 } 00125 00126 00127 /*--------------------------- rt_get_same_rdy_prio --------------------------*/ 00128 00129 P_TCB rt_get_same_rdy_prio (void) { 00130 /* Remove a task of same priority from ready list if any exists. Other- */ 00131 /* wise return NULL. */ 00132 P_TCB p_first; 00133 00134 p_first = os_rdy.p_lnk; 00135 if (p_first->prio == os_tsk.run->prio) { 00136 os_rdy.p_lnk = os_rdy.p_lnk->p_lnk; 00137 return (p_first); 00138 } 00139 return (NULL); 00140 } 00141 00142 00143 /*--------------------------- rt_resort_prio --------------------------------*/ 00144 00145 void rt_resort_prio (P_TCB p_task) { 00146 /* Re-sort ordered lists after the priority of 'p_task' has changed. */ 00147 P_TCB p_CB; 00148 00149 if (p_task->p_rlnk == NULL) { 00150 if (p_task->state == READY) { 00151 /* Task is chained into READY list. */ 00152 p_CB = (P_TCB)&os_rdy; 00153 goto res; 00154 } 00155 } 00156 else { 00157 p_CB = p_task->p_rlnk; 00158 while (p_CB->cb_type == TCB) { 00159 /* Find a header of this task chain list. */ 00160 p_CB = p_CB->p_rlnk; 00161 } 00162 res:rt_rmv_list (p_task); 00163 rt_put_prio ((P_XCB)p_CB, p_task); 00164 } 00165 } 00166 00167 00168 /*--------------------------- rt_put_dly ------------------------------------*/ 00169 00170 void rt_put_dly (P_TCB p_task, U16 delay) { 00171 /* Put a task identified with "p_task" into chained delay wait list using */ 00172 /* a delay value of "delay". */ 00173 P_TCB p; 00174 U32 delta,idelay = delay; 00175 00176 p = (P_TCB)&os_dly; 00177 if (p->p_dlnk == NULL) { 00178 /* Delay list empty */ 00179 delta = 0; 00180 goto last; 00181 } 00182 delta = os_dly.delta_time; 00183 while (delta < idelay) { 00184 if (p->p_dlnk == NULL) { 00185 /* End of list found */ 00186 last: p_task->p_dlnk = NULL; 00187 p->p_dlnk = p_task; 00188 p_task->p_blnk = p; 00189 p->delta_time = (U16)(idelay - delta); 00190 p_task->delta_time = 0; 00191 return; 00192 } 00193 p = p->p_dlnk; 00194 delta += p->delta_time; 00195 } 00196 /* Right place found */ 00197 p_task->p_dlnk = p->p_dlnk; 00198 p->p_dlnk = p_task; 00199 p_task->p_blnk = p; 00200 if (p_task->p_dlnk != NULL) { 00201 p_task->p_dlnk->p_blnk = p_task; 00202 } 00203 p_task->delta_time = (U16)(delta - idelay); 00204 p->delta_time -= p_task->delta_time; 00205 } 00206 00207 00208 /*--------------------------- rt_dec_dly ------------------------------------*/ 00209 00210 void rt_dec_dly (void) { 00211 /* Decrement delta time of list head: remove tasks having a value of zero.*/ 00212 P_TCB p_rdy; 00213 00214 if (os_dly.p_dlnk == NULL) { 00215 return; 00216 } 00217 os_dly.delta_time--; 00218 while ((os_dly.delta_time == 0) && (os_dly.p_dlnk != NULL)) { 00219 p_rdy = os_dly.p_dlnk; 00220 if (p_rdy->p_rlnk != NULL) { 00221 /* Task is really enqueued, remove task from semaphore/mailbox */ 00222 /* timeout waiting list. */ 00223 p_rdy->p_rlnk->p_lnk = p_rdy->p_lnk; 00224 if (p_rdy->p_lnk != NULL) { 00225 p_rdy->p_lnk->p_rlnk = p_rdy->p_rlnk; 00226 p_rdy->p_lnk = NULL; 00227 } 00228 p_rdy->p_rlnk = NULL; 00229 } 00230 rt_put_prio (&os_rdy, p_rdy); 00231 os_dly.delta_time = p_rdy->delta_time; 00232 if (p_rdy->state == WAIT_ITV) { 00233 /* Calculate the next time for interval wait. */ 00234 p_rdy->delta_time = p_rdy->interval_time + (U16)os_time; 00235 } 00236 p_rdy->state = READY; 00237 os_dly.p_dlnk = p_rdy->p_dlnk; 00238 if (p_rdy->p_dlnk != NULL) { 00239 p_rdy->p_dlnk->p_blnk = (P_TCB)&os_dly; 00240 p_rdy->p_dlnk = NULL; 00241 } 00242 p_rdy->p_blnk = NULL; 00243 } 00244 } 00245 00246 00247 /*--------------------------- rt_rmv_list -----------------------------------*/ 00248 00249 void rt_rmv_list (P_TCB p_task) { 00250 /* Remove task identified with "p_task" from ready, semaphore or mailbox */ 00251 /* waiting list if enqueued. */ 00252 P_TCB p_b; 00253 00254 if (p_task->p_rlnk != NULL) { 00255 /* A task is enqueued in semaphore / mailbox waiting list. */ 00256 p_task->p_rlnk->p_lnk = p_task->p_lnk; 00257 if (p_task->p_lnk != NULL) { 00258 p_task->p_lnk->p_rlnk = p_task->p_rlnk; 00259 } 00260 return; 00261 } 00262 00263 p_b = (P_TCB)&os_rdy; 00264 while (p_b != NULL) { 00265 /* Search the ready list for task "p_task" */ 00266 if (p_b->p_lnk == p_task) { 00267 p_b->p_lnk = p_task->p_lnk; 00268 return; 00269 } 00270 p_b = p_b->p_lnk; 00271 } 00272 } 00273 00274 00275 /*--------------------------- rt_rmv_dly ------------------------------------*/ 00276 00277 void rt_rmv_dly (P_TCB p_task) { 00278 /* Remove task identified with "p_task" from delay list if enqueued. */ 00279 P_TCB p_b; 00280 00281 p_b = p_task->p_blnk; 00282 if (p_b != NULL) { 00283 /* Task is really enqueued */ 00284 p_b->p_dlnk = p_task->p_dlnk; 00285 if (p_task->p_dlnk != NULL) { 00286 /* 'p_task' is in the middle of list */ 00287 p_b->delta_time += p_task->delta_time; 00288 p_task->p_dlnk->p_blnk = p_b; 00289 p_task->p_dlnk = NULL; 00290 } 00291 else { 00292 /* 'p_task' is at the end of list */ 00293 p_b->delta_time = 0; 00294 } 00295 p_task->p_blnk = NULL; 00296 } 00297 } 00298 00299 00300 /*--------------------------- rt_psq_enq ------------------------------------*/ 00301 00302 void rt_psq_enq (OS_ID entry, U32 arg) { 00303 /* Insert post service request "entry" into ps-queue. */ 00304 U32 idx; 00305 00306 idx = rt_inc_qi (os_psq->size, &os_psq->count, &os_psq->first); 00307 if (idx < os_psq->size) { 00308 os_psq->q[idx].id = entry; 00309 os_psq->q[idx].arg = arg; 00310 } 00311 else { 00312 os_error (OS_ERR_FIFO_OVF); 00313 } 00314 } 00315 00316 00317 /*---------------------------------------------------------------------------- 00318 * end of file 00319 *---------------------------------------------------------------------------*/ 00320
Generated on Wed Jul 13 2022 18:32:39 by
