]>
git.gir.st - tmk_keyboard.git/blob - tmk_core/tool/mbed/mbed-sdk/libraries/rtos/rtx/TARGET_CORTEX_A/rt_List.c
1 /*----------------------------------------------------------------------------
3 *----------------------------------------------------------------------------
5 * Purpose: Functions for the management of different lists
7 *----------------------------------------------------------------------------
9 * Copyright (c) 1999-2009 KEIL, 2009-2012 ARM Germany GmbH
10 * All rights reserved.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions are met:
13 * - Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * - Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * - Neither the name of ARM nor the names of its contributors may be used
19 * to endorse or promote products derived from this software without
20 * specific prior written permission.
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
23 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDERS AND CONTRIBUTORS BE
26 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 * POSSIBILITY OF SUCH DAMAGE.
33 *---------------------------------------------------------------------------*/
35 #include "rt_TypeDef.h"
36 #include "RTX_Config.h"
37 #include "rt_System.h"
42 #include "rt_HAL_CA.h"
44 #include "rt_HAL_CM.h"
47 /*----------------------------------------------------------------------------
49 *---------------------------------------------------------------------------*/
51 /* List head of chained ready tasks */
53 /* List head of chained delay tasks */
57 /*----------------------------------------------------------------------------
59 *---------------------------------------------------------------------------*/
62 /*--------------------------- rt_put_prio -----------------------------------*/
64 void rt_put_prio (P_XCB p_CB
, P_TCB p_task
) {
65 /* Put task identified with "p_task" into list ordered by priority. */
66 /* "p_CB" points to head of list; list has always an element at end with */
67 /* a priority less than "p_task->prio". */
70 BOOL sem_mbx
= __FALSE
;
72 if (p_CB
->cb_type
== SCB
|| p_CB
->cb_type
== MCB
|| p_CB
->cb_type
== MUCB
) {
77 /* Search for an entry in the list */
78 while (p_CB2
!= NULL
&& prio
<= p_CB2
->prio
) {
82 /* Entry found, insert the task into the list */
83 p_task
->p_lnk
= p_CB2
;
87 p_CB2
->p_rlnk
= p_task
;
89 p_task
->p_rlnk
= (P_TCB
)p_CB
;
92 p_task
->p_rlnk
= NULL
;
97 /*--------------------------- rt_get_first ----------------------------------*/
99 P_TCB
rt_get_first (P_XCB p_CB
) {
100 /* Get task at head of list: it is the task with highest priority. */
101 /* "p_CB" points to head of list. */
104 p_first
= p_CB
->p_lnk
;
105 p_CB
->p_lnk
= p_first
->p_lnk
;
106 if (p_CB
->cb_type
== SCB
|| p_CB
->cb_type
== MCB
|| p_CB
->cb_type
== MUCB
) {
107 if (p_first
->p_lnk
!= NULL
) {
108 p_first
->p_lnk
->p_rlnk
= (P_TCB
)p_CB
;
109 p_first
->p_lnk
= NULL
;
111 p_first
->p_rlnk
= NULL
;
114 p_first
->p_lnk
= NULL
;
120 /*--------------------------- rt_put_rdy_first ------------------------------*/
122 void rt_put_rdy_first (P_TCB p_task
) {
123 /* Put task identified with "p_task" at the head of the ready list. The */
124 /* task must have at least a priority equal to highest priority in list. */
125 p_task
->p_lnk
= os_rdy
.p_lnk
;
126 p_task
->p_rlnk
= NULL
;
127 os_rdy
.p_lnk
= p_task
;
131 /*--------------------------- rt_get_same_rdy_prio --------------------------*/
133 P_TCB
rt_get_same_rdy_prio (void) {
134 /* Remove a task of same priority from ready list if any exists. Other- */
135 /* wise return NULL. */
138 p_first
= os_rdy
.p_lnk
;
139 if (p_first
->prio
== os_tsk
.run
->prio
) {
140 os_rdy
.p_lnk
= os_rdy
.p_lnk
->p_lnk
;
147 /*--------------------------- rt_resort_prio --------------------------------*/
149 void rt_resort_prio (P_TCB p_task
) {
150 /* Re-sort ordered lists after the priority of 'p_task' has changed. */
153 if (p_task
->p_rlnk
== NULL
) {
154 if (p_task
->state
== READY
) {
155 /* Task is chained into READY list. */
156 p_CB
= (P_TCB
)&os_rdy
;
161 p_CB
= p_task
->p_rlnk
;
162 while (p_CB
->cb_type
== TCB
) {
163 /* Find a header of this task chain list. */
166 res
:rt_rmv_list (p_task
);
167 rt_put_prio ((P_XCB
)p_CB
, p_task
);
172 /*--------------------------- rt_put_dly ------------------------------------*/
174 void rt_put_dly (P_TCB p_task
, U16 delay
) {
175 /* Put a task identified with "p_task" into chained delay wait list using */
176 /* a delay value of "delay". */
178 U32 delta
,idelay
= delay
;
181 if (p
->p_dlnk
== NULL
) {
182 /* Delay list empty */
186 delta
= os_dly
.delta_time
;
187 while (delta
< idelay
) {
188 if (p
->p_dlnk
== NULL
) {
189 /* End of list found */
190 last
: p_task
->p_dlnk
= NULL
;
193 p
->delta_time
= (U16
)(idelay
- delta
);
194 p_task
->delta_time
= 0;
198 delta
+= p
->delta_time
;
200 /* Right place found */
201 p_task
->p_dlnk
= p
->p_dlnk
;
204 if (p_task
->p_dlnk
!= NULL
) {
205 p_task
->p_dlnk
->p_blnk
= p_task
;
207 p_task
->delta_time
= (U16
)(delta
- idelay
);
208 p
->delta_time
-= p_task
->delta_time
;
212 /*--------------------------- rt_dec_dly ------------------------------------*/
214 void rt_dec_dly (void) {
215 /* Decrement delta time of list head: remove tasks having a value of zero.*/
218 if (os_dly
.p_dlnk
== NULL
) {
222 while ((os_dly
.delta_time
== 0) && (os_dly
.p_dlnk
!= NULL
)) {
223 p_rdy
= os_dly
.p_dlnk
;
224 if (p_rdy
->p_rlnk
!= NULL
) {
225 /* Task is really enqueued, remove task from semaphore/mailbox */
226 /* timeout waiting list. */
227 p_rdy
->p_rlnk
->p_lnk
= p_rdy
->p_lnk
;
228 if (p_rdy
->p_lnk
!= NULL
) {
229 p_rdy
->p_lnk
->p_rlnk
= p_rdy
->p_rlnk
;
232 p_rdy
->p_rlnk
= NULL
;
234 rt_put_prio (&os_rdy
, p_rdy
);
235 os_dly
.delta_time
= p_rdy
->delta_time
;
236 if (p_rdy
->state
== WAIT_ITV
) {
237 /* Calculate the next time for interval wait. */
238 p_rdy
->delta_time
= p_rdy
->interval_time
+ (U16
)os_time
;
240 p_rdy
->state
= READY
;
241 os_dly
.p_dlnk
= p_rdy
->p_dlnk
;
242 if (p_rdy
->p_dlnk
!= NULL
) {
243 p_rdy
->p_dlnk
->p_blnk
= (P_TCB
)&os_dly
;
244 p_rdy
->p_dlnk
= NULL
;
246 p_rdy
->p_blnk
= NULL
;
251 /*--------------------------- rt_rmv_list -----------------------------------*/
253 void rt_rmv_list (P_TCB p_task
) {
254 /* Remove task identified with "p_task" from ready, semaphore or mailbox */
255 /* waiting list if enqueued. */
258 if (p_task
->p_rlnk
!= NULL
) {
259 /* A task is enqueued in semaphore / mailbox waiting list. */
260 p_task
->p_rlnk
->p_lnk
= p_task
->p_lnk
;
261 if (p_task
->p_lnk
!= NULL
) {
262 p_task
->p_lnk
->p_rlnk
= p_task
->p_rlnk
;
267 p_b
= (P_TCB
)&os_rdy
;
268 while (p_b
!= NULL
) {
269 /* Search the ready list for task "p_task" */
270 if (p_b
->p_lnk
== p_task
) {
271 p_b
->p_lnk
= p_task
->p_lnk
;
279 /*--------------------------- rt_rmv_dly ------------------------------------*/
281 void rt_rmv_dly (P_TCB p_task
) {
282 /* Remove task identified with "p_task" from delay list if enqueued. */
285 p_b
= p_task
->p_blnk
;
287 /* Task is really enqueued */
288 p_b
->p_dlnk
= p_task
->p_dlnk
;
289 if (p_task
->p_dlnk
!= NULL
) {
290 /* 'p_task' is in the middle of list */
291 p_b
->delta_time
+= p_task
->delta_time
;
292 p_task
->p_dlnk
->p_blnk
= p_b
;
293 p_task
->p_dlnk
= NULL
;
296 /* 'p_task' is at the end of list */
299 p_task
->p_blnk
= NULL
;
304 /*--------------------------- rt_psq_enq ------------------------------------*/
306 void rt_psq_enq (OS_ID entry
, U32 arg
) {
307 /* Insert post service request "entry" into ps-queue. */
310 idx
= rt_inc_qi (os_psq
->size
, &os_psq
->count
, &os_psq
->first
);
311 if (idx
< os_psq
->size
) {
312 os_psq
->q
[idx
].id
= entry
;
313 os_psq
->q
[idx
].arg
= arg
;
316 os_error (OS_ERR_FIFO_OVF
);
321 /*----------------------------------------------------------------------------
323 *---------------------------------------------------------------------------*/