3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
11 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
12 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
13 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
14 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
24 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
26 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
28 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
30 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
31 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
34 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
35 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
36 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
37 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
40 * @(#) $Id: task_manage.c 2018 2010-12-31 13:43:05Z ertl-hiro $
47 #include "kernel_impl.h"
55 #ifndef LOG_ACRE_TSK_ENTER
56 #define LOG_ACRE_TSK_ENTER(pk_ctsk)
57 #endif /* LOG_ACRE_TSK_ENTER */
59 #ifndef LOG_ACRE_TSK_LEAVE
60 #define LOG_ACRE_TSK_LEAVE(ercd)
61 #endif /* LOG_ACRE_TSK_LEAVE */
63 #ifndef LOG_DEL_TSK_ENTER
64 #define LOG_DEL_TSK_ENTER(tskid)
65 #endif /* LOG_DEL_TSK_ENTER */
67 #ifndef LOG_DEL_TSK_LEAVE
68 #define LOG_DEL_TSK_LEAVE(ercd)
69 #endif /* LOG_DEL_TSK_LEAVE */
71 #ifndef LOG_ACT_TSK_ENTER
72 #define LOG_ACT_TSK_ENTER(tskid)
73 #endif /* LOG_ACT_TSK_ENTER */
75 #ifndef LOG_ACT_TSK_LEAVE
76 #define LOG_ACT_TSK_LEAVE(ercd)
77 #endif /* LOG_ACT_TSK_LEAVE */
79 #ifndef LOG_IACT_TSK_ENTER
80 #define LOG_IACT_TSK_ENTER(tskid)
81 #endif /* LOG_IACT_TSK_ENTER */
83 #ifndef LOG_IACT_TSK_LEAVE
84 #define LOG_IACT_TSK_LEAVE(ercd)
85 #endif /* LOG_IACT_TSK_LEAVE */
87 #ifndef LOG_CAN_ACT_ENTER
88 #define LOG_CAN_ACT_ENTER(tskid)
89 #endif /* LOG_CAN_ACT_ENTER */
91 #ifndef LOG_CAN_ACT_LEAVE
92 #define LOG_CAN_ACT_LEAVE(ercd)
93 #endif /* LOG_CAN_ACT_LEAVE */
95 #ifndef LOG_EXT_TSK_ENTER
96 #define LOG_EXT_TSK_ENTER()
97 #endif /* LOG_EXT_TSK_ENTER */
99 #ifndef LOG_EXT_TSK_LEAVE
100 #define LOG_EXT_TSK_LEAVE(ercd)
101 #endif /* LOG_EXT_TSK_LEAVE */
103 #ifndef LOG_TER_TSK_ENTER
104 #define LOG_TER_TSK_ENTER(tskid)
105 #endif /* LOG_TER_TSK_ENTER */
107 #ifndef LOG_TER_TSK_LEAVE
108 #define LOG_TER_TSK_LEAVE(ercd)
109 #endif /* LOG_TER_TSK_LEAVE */
111 #ifndef LOG_CHG_PRI_ENTER
112 #define LOG_CHG_PRI_ENTER(tskid, tskpri)
113 #endif /* LOG_CHG_PRI_ENTER */
115 #ifndef LOG_CHG_PRI_LEAVE
116 #define LOG_CHG_PRI_LEAVE(ercd)
117 #endif /* LOG_CHG_PRI_LEAVE */
119 #ifndef LOG_GET_PRI_ENTER
120 #define LOG_GET_PRI_ENTER(tskid, p_tskpri)
121 #endif /* LOG_GET_PRI_ENTER */
123 #ifndef LOG_GET_PRI_LEAVE
124 #define LOG_GET_PRI_LEAVE(ercd, tskpri)
125 #endif /* LOG_GET_PRI_LEAVE */
127 #ifndef LOG_GET_INF_ENTER
128 #define LOG_GET_INF_ENTER(p_exinf)
129 #endif /* LOG_GET_INF_ENTER */
131 #ifndef LOG_GET_INF_LEAVE
132 #define LOG_GET_INF_LEAVE(ercd, exinf)
133 #endif /* LOG_GET_INF_LEAVE */
138 #ifdef TOPPERS_acre_tsk
141 acre_tsk(const T_CTSK *pk_ctsk)
149 LOG_ACRE_TSK_ENTER(pk_ctsk);
151 CHECK_RSATR(pk_ctsk->tskatr, TA_ACT|TARGET_TSKATR);
152 CHECK_ALIGN_FUNC(pk_ctsk->task);
153 CHECK_NONNULL_FUNC(pk_ctsk->task);
154 CHECK_TPRI(pk_ctsk->itskpri);
155 CHECK_STKSZ_MIN(pk_ctsk->stksz);
156 CHECK_ALIGN_STKSZ(pk_ctsk->stksz);
157 CHECK_ALIGN_STACK(pk_ctsk->stk);
158 tskatr = pk_ctsk->tskatr;
162 if (queue_empty(&free_tcb)) {
167 stk = kernel_malloc(pk_ctsk->stksz);
168 tskatr |= TA_MEMALLOC;
174 p_tcb = ((TCB *) queue_delete_next(&free_tcb));
175 p_tinib = (TINIB *)(p_tcb->p_tinib);
176 p_tinib->tskatr = tskatr;
177 p_tinib->exinf = pk_ctsk->exinf;
178 p_tinib->task = pk_ctsk->task;
179 p_tinib->ipriority = INT_PRIORITY(pk_ctsk->itskpri);
180 #ifdef USE_TSKINICTXB
181 init_tskinictxb(&(p_tinib->tskinictxb), stk, pk_ctsk);
182 #else /* USE_TSKINICTXB */
183 p_tinib->stksz = pk_ctsk->stksz;
185 #endif /* USE_TSKINICTXB */
186 p_tinib->texatr = TA_NULL;
187 p_tinib->texrtn = NULL;
189 p_tcb->actque = false;
191 if ((p_tcb->p_tinib->tskatr & TA_ACT) != 0U) {
200 LOG_ACRE_TSK_LEAVE(ercd);
204 #endif /* TOPPERS_acre_tsk */
209 #ifdef TOPPERS_del_tsk
218 LOG_DEL_TSK_ENTER(tskid);
221 p_tcb = get_tcb(tskid);
224 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
227 else if (TSKID(p_tcb) > tmax_stskid && TSTAT_DORMANT(p_tcb->tstat)) {
228 p_tinib = (TINIB *)(p_tcb->p_tinib);
229 #ifdef USE_TSKINICTXB
230 term_tskinictxb(&(p_tinib->tskinictxb));
231 #else /* USE_TSKINICTXB */
232 if ((p_tinib->tskatr & TA_MEMALLOC) != 0U) {
233 kernel_free(p_tinib->stk);
235 #endif /* USE_TSKINICTXB */
236 p_tinib->tskatr = TA_NOEXS;
237 queue_insert_prev(&free_tcb, &(p_tcb->task_queue));
246 LOG_DEL_TSK_LEAVE(ercd);
250 #endif /* TOPPERS_del_tsk */
255 #ifdef TOPPERS_act_tsk
263 LOG_ACT_TSK_ENTER(tskid);
265 CHECK_TSKID_SELF(tskid);
266 p_tcb = get_tcb_self(tskid);
269 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
272 else if (TSTAT_DORMANT(p_tcb->tstat)) {
273 if (make_active(p_tcb)) {
278 else if (!(p_tcb->actque)) {
279 p_tcb->actque = true;
288 LOG_ACT_TSK_LEAVE(ercd);
292 #endif /* TOPPERS_act_tsk */
295 * タスクの起動(非タスクコンテキスト用)
297 #ifdef TOPPERS_iact_tsk
305 LOG_IACT_TSK_ENTER(tskid);
308 p_tcb = get_tcb(tskid);
311 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
314 else if (TSTAT_DORMANT(p_tcb->tstat)) {
315 if (make_active(p_tcb)) {
320 else if (!(p_tcb->actque)) {
321 p_tcb->actque = true;
330 LOG_IACT_TSK_LEAVE(ercd);
334 #endif /* TOPPERS_iact_tsk */
339 #ifdef TOPPERS_can_act
347 LOG_CAN_ACT_ENTER(tskid);
349 CHECK_TSKID_SELF(tskid);
350 p_tcb = get_tcb_self(tskid);
353 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
357 ercd = p_tcb->actque ? 1 : 0;
359 p_tcb->actque = false;
363 LOG_CAN_ACT_LEAVE(ercd);
367 #endif /* TOPPERS_can_act */
372 #ifdef TOPPERS_ext_tsk
382 if (t_sense_lock()) {
384 * CPUロック状態でext_tskが呼ばれた場合は,CPUロックを解除し
385 * てからタスクを終了する.実装上は,サービスコール内でのCPU
394 * ディスパッチ禁止状態でext_tskが呼ばれた場合は,ディスパッ
395 * チ許可状態にしてからタスクを終了する.
401 * 割込み優先度マスク(IPM)がTIPM_ENAALL以外の状態でext_tsk
402 * が呼ばれた場合は,IPMをTIPM_ENAALLにしてからタスクを終了す
405 t_set_ipm(TIPM_ENAALL);
410 (void) make_non_runnable(p_runtsk);
411 make_dormant(p_runtsk);
412 if (p_runtsk->actque) {
413 p_runtsk->actque = false;
414 (void) make_active(p_runtsk);
420 LOG_EXT_TSK_LEAVE(ercd);
424 #endif /* TOPPERS_ext_tsk */
429 #ifdef TOPPERS_ter_tsk
437 LOG_TER_TSK_ENTER(tskid);
440 p_tcb = get_tcb(tskid);
441 CHECK_NONSELF(p_tcb);
444 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
447 else if (TSTAT_DORMANT(p_tcb->tstat)) {
451 if (TSTAT_RUNNABLE(p_tcb->tstat)) {
453 * p_tcbは自タスクでないため,(シングルプロセッサでは)実
454 * 行状態でなく,make_non_runnable(p_tcb)でタスクディスパッ
457 (void) make_non_runnable(p_tcb);
459 else if (TSTAT_WAITING(p_tcb->tstat)) {
460 wait_dequeue_wobj(p_tcb);
461 wait_dequeue_tmevtb(p_tcb);
465 p_tcb->actque = false;
466 if (make_active(p_tcb)) {
475 LOG_TER_TSK_LEAVE(ercd);
479 #endif /* TOPPERS_ter_tsk */
484 #ifdef TOPPERS_chg_pri
487 chg_pri(ID tskid, PRI tskpri)
493 LOG_CHG_PRI_ENTER(tskid, tskpri);
495 CHECK_TSKID_SELF(tskid);
496 CHECK_TPRI_INI(tskpri);
497 p_tcb = get_tcb_self(tskid);
498 newpri = (tskpri == TPRI_INI) ? p_tcb->p_tinib->ipriority
499 : INT_PRIORITY(tskpri);
502 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
505 else if (TSTAT_DORMANT(p_tcb->tstat)) {
509 if (change_priority(p_tcb, newpri)) {
517 LOG_CHG_PRI_LEAVE(ercd);
521 #endif /* TOPPERS_chg_pri */
526 #ifdef TOPPERS_get_pri
529 get_pri(ID tskid, PRI *p_tskpri)
534 LOG_GET_PRI_ENTER(tskid, p_tskpri);
536 CHECK_TSKID_SELF(tskid);
537 p_tcb = get_tcb_self(tskid);
540 if (p_tcb->p_tinib->tskatr == TA_NOEXS) {
543 else if (TSTAT_DORMANT(p_tcb->tstat)) {
547 *p_tskpri = EXT_TSKPRI(p_tcb->priority);
553 LOG_GET_PRI_LEAVE(ercd, *p_tskpri);
557 #endif /* TOPPERS_get_pri */
562 #ifdef TOPPERS_get_inf
565 get_inf(intptr_t *p_exinf)
569 LOG_GET_INF_ENTER(p_exinf);
573 *p_exinf = p_runtsk->p_tinib->exinf;
578 LOG_GET_INF_LEAVE(ercd, *p_exinf);
582 #endif /* TOPPERS_get_inf */