task_manage.c

説明を見る。
00001 /*
00002  *  TOPPERS/ASP Kernel
00003  *      Toyohashi Open Platform for Embedded Real-Time Systems/
00004  *      Advanced Standard Profile Kernel
00005  * 
00006  *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
00007  *                              Toyohashi Univ. of Technology, JAPAN
00008  *  Copyright (C) 2005-2008 by Embedded and Real-Time Systems Laboratory
00009  *              Graduate School of Information Science, Nagoya Univ., JAPAN
00010  * 
00011  *  上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
00012  *  ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
00013  *  変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
00014  *  (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
00015  *      権表示,この利用条件および下記の無保証規定が,そのままの形でソー
00016  *      スコード中に含まれていること.
00017  *  (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
00018  *      用できる形で再配布する場合には,再配布に伴うドキュメント(利用
00019  *      者マニュアルなど)に,上記の著作権表示,この利用条件および下記
00020  *      の無保証規定を掲載すること.
00021  *  (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
00022  *      用できない形で再配布する場合には,次のいずれかの条件を満たすこ
00023  *      と.
00024  *    (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
00025  *        作権表示,この利用条件および下記の無保証規定を掲載すること.
00026  *    (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
00027  *        報告すること.
00028  *  (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
00029  *      害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
00030  *      また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
00031  *      由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
00032  *      免責すること.
00033  * 
00034  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
00035  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
00036  *  に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
00037  *  アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
00038  *  の責任を負わない.
00039  * 
00040  *  @(#) $Id: task_manage.c 748 2008-03-07 17:18:06Z hiro $
00041  */
00042 
00043 /*
00044  *      タスク管理機能
00045  */
00046 
00047 #include "kernel_impl.h"
00048 #include "check.h"
00049 #include "task.h"
00050 #include "wait.h"
00051 
00052 /*
00053  *  トレースログマクロのデフォルト定義
00054  */
00055 #ifndef LOG_ACT_TSK_ENTER
00056 #define LOG_ACT_TSK_ENTER(tskid)
00057 #endif /* LOG_ACT_TSK_ENTER */
00058 
00059 #ifndef LOG_ACT_TSK_LEAVE
00060 #define LOG_ACT_TSK_LEAVE(ercd)
00061 #endif /* LOG_ACT_TSK_LEAVE */
00062 
00063 #ifndef LOG_IACT_TSK_ENTER
00064 #define LOG_IACT_TSK_ENTER(tskid)
00065 #endif /* LOG_IACT_TSK_ENTER */
00066 
00067 #ifndef LOG_IACT_TSK_LEAVE
00068 #define LOG_IACT_TSK_LEAVE(ercd)
00069 #endif /* LOG_IACT_TSK_LEAVE */
00070 
00071 #ifndef LOG_CAN_ACT_ENTER
00072 #define LOG_CAN_ACT_ENTER(tskid)
00073 #endif /* LOG_CAN_ACT_ENTER */
00074 
00075 #ifndef LOG_CAN_ACT_LEAVE
00076 #define LOG_CAN_ACT_LEAVE(ercd)
00077 #endif /* LOG_CAN_ACT_LEAVE */
00078 
00079 #ifndef LOG_EXT_TSK_ENTER
00080 #define LOG_EXT_TSK_ENTER()
00081 #endif /* LOG_EXT_TSK_ENTER */
00082 
00083 #ifndef LOG_EXT_TSK_LEAVE
00084 #define LOG_EXT_TSK_LEAVE(ercd)
00085 #endif /* LOG_EXT_TSK_LEAVE */
00086 
00087 #ifndef LOG_TER_TSK_ENTER
00088 #define LOG_TER_TSK_ENTER(tskid)
00089 #endif /* LOG_TER_TSK_ENTER */
00090 
00091 #ifndef LOG_TER_TSK_LEAVE
00092 #define LOG_TER_TSK_LEAVE(ercd)
00093 #endif /* LOG_TER_TSK_LEAVE */
00094 
00095 #ifndef LOG_CHG_PRI_ENTER
00096 #define LOG_CHG_PRI_ENTER(tskid, tskpri)
00097 #endif /* LOG_CHG_PRI_ENTER */
00098 
00099 #ifndef LOG_CHG_PRI_LEAVE
00100 #define LOG_CHG_PRI_LEAVE(ercd)
00101 #endif /* LOG_CHG_PRI_LEAVE */
00102 
00103 #ifndef LOG_GET_PRI_ENTER
00104 #define LOG_GET_PRI_ENTER(tskid, p_tskpri)
00105 #endif /* LOG_GET_PRI_ENTER */
00106 
00107 #ifndef LOG_GET_PRI_LEAVE
00108 #define LOG_GET_PRI_LEAVE(ercd, tskpri)
00109 #endif /* LOG_GET_PRI_LEAVE */
00110 
00111 #ifndef LOG_GET_INF_ENTER
00112 #define LOG_GET_INF_ENTER(p_exinf)
00113 #endif /* LOG_GET_INF_ENTER */
00114 
00115 #ifndef LOG_GET_INF_LEAVE
00116 #define LOG_GET_INF_LEAVE(ercd, exinf)
00117 #endif /* LOG_GET_INF_LEAVE */
00118 
00119 /*
00120  *  タスクの起動
00121  */
00122 #ifdef TOPPERS_act_tsk
00123 
00124 ER
00125 act_tsk(ID tskid)
00126 {
00127     TCB     *p_tcb;
00128     ER      ercd;
00129 
00130     LOG_ACT_TSK_ENTER(tskid);
00131     CHECK_TSKCTX_UNL();
00132     CHECK_TSKID_SELF(tskid);
00133     p_tcb = get_tcb_self(tskid);
00134 
00135     t_lock_cpu();
00136     if (TSTAT_DORMANT(p_tcb->tstat)) {
00137         if (make_active(p_tcb)) {
00138             dispatch();
00139         }
00140         ercd = E_OK;
00141     }
00142     else if (!(p_tcb->actque)) {
00143         p_tcb->actque = true;
00144         ercd = E_OK;
00145     }
00146     else {
00147         ercd = E_QOVR;
00148     }
00149     t_unlock_cpu();
00150 
00151   error_exit:
00152     LOG_ACT_TSK_LEAVE(ercd);
00153     return(ercd);
00154 }
00155 
00156 #endif /* TOPPERS_act_tsk */
00157 
00158 /*
00159  *  タスクの起動(非タスクコンテキスト用)
00160  */
00161 #ifdef TOPPERS_iact_tsk
00162 
00163 ER
00164 iact_tsk(ID tskid)
00165 {
00166     TCB     *p_tcb;
00167     ER      ercd;
00168 
00169     LOG_IACT_TSK_ENTER(tskid);
00170     CHECK_INTCTX_UNL();
00171     CHECK_TSKID(tskid);
00172     p_tcb = get_tcb(tskid);
00173 
00174     i_lock_cpu();
00175     if (TSTAT_DORMANT(p_tcb->tstat)) {
00176         if (make_active(p_tcb)) {
00177             reqflg = true;
00178         }
00179         ercd = E_OK;
00180     }
00181     else if (!(p_tcb->actque)) {
00182         p_tcb->actque = true;
00183         ercd = E_OK;
00184     }
00185     else {
00186         ercd = E_QOVR;
00187     }
00188     i_unlock_cpu();
00189 
00190   error_exit:
00191     LOG_IACT_TSK_LEAVE(ercd);
00192     return(ercd);
00193 }
00194 
00195 #endif /* TOPPERS_iact_tsk */
00196 
00197 /*
00198  *  タスク起動要求のキャンセル
00199  */
00200 #ifdef TOPPERS_can_act
00201 
00202 ER_UINT
00203 can_act(ID tskid)
00204 {
00205     TCB     *p_tcb;
00206     ER_UINT ercd;
00207 
00208     LOG_CAN_ACT_ENTER(tskid);
00209     CHECK_TSKCTX_UNL();
00210     CHECK_TSKID_SELF(tskid);
00211     p_tcb = get_tcb_self(tskid);
00212 
00213     t_lock_cpu();
00214     ercd = p_tcb->actque ? 1 : 0;
00215     p_tcb->actque = false;
00216     t_unlock_cpu();
00217 
00218   error_exit:
00219     LOG_CAN_ACT_LEAVE(ercd);
00220     return(ercd);
00221 }
00222 
00223 #endif /* TOPPERS_can_act */
00224 
00225 /*
00226  *  自タスクの終了
00227  */
00228 #ifdef TOPPERS_ext_tsk
00229 
00230 ER
00231 ext_tsk(void)
00232 {
00233     ER      ercd;
00234 
00235     LOG_EXT_TSK_ENTER();
00236     CHECK_TSKCTX();
00237 
00238     if (t_sense_lock()) {
00239         /*
00240          *  CPUロック状態でext_tskが呼ばれた場合は,CPUロックを解除し
00241          *  てからタスクを終了する.実装上は,サービスコール内でのCPU
00242          *  ロックを省略すればよいだけ.
00243          */
00244     }
00245     else {
00246         t_lock_cpu();
00247     }
00248     if (disdsp) {
00249         /*
00250          *  ディスパッチ禁止状態でext_tskが呼ばれた場合は,ディスパッ
00251          *  チ許可状態にしてからタスクを終了する.
00252          */
00253         disdsp = false;
00254     }
00255     if (t_get_ipm() != TIPM_ENAALL) {
00256         /*
00257          *  割込み優先度マスク(IPM)がTIPM_ENAALL以外の状態でext_tsk
00258          *  が呼ばれた場合は,IPMをTIPM_ENAALLにしてからタスクを終了す
00259          *  る.
00260          */
00261         t_set_ipm(TIPM_ENAALL);
00262     }
00263     dspflg = true;
00264 
00265     (void) make_non_runnable(p_runtsk);
00266     make_dormant(p_runtsk);
00267     if (p_runtsk->actque) {
00268         p_runtsk->actque = false;
00269         (void) make_active(p_runtsk);
00270     }
00271     exit_and_dispatch();
00272     assert(0);
00273 
00274   error_exit:
00275     LOG_EXT_TSK_LEAVE(ercd);
00276     return(ercd);
00277 }
00278 
00279 #endif /* TOPPERS_ext_tsk */
00280 
00281 /*
00282  *  タスクの強制終了
00283  */
00284 #ifdef TOPPERS_ter_tsk
00285 
00286 ER
00287 ter_tsk(ID tskid)
00288 {
00289     TCB     *p_tcb;
00290     ER      ercd;
00291 
00292     LOG_TER_TSK_ENTER(tskid);
00293     CHECK_TSKCTX_UNL();
00294     CHECK_TSKID(tskid);
00295     p_tcb = get_tcb(tskid);
00296     CHECK_NONSELF(p_tcb);
00297 
00298     t_lock_cpu();
00299     if (TSTAT_DORMANT(p_tcb->tstat)) {
00300         ercd = E_OBJ;
00301     }
00302     else {
00303         if (TSTAT_RUNNABLE(p_tcb->tstat)) {
00304             /*
00305              *  p_tcbは自タスクでないため,(シングルプロセッサでは)実
00306              *  行状態でなく,make_non_runnable(p_tcb)でタスクディスパッ
00307              *  チが必要になることはない.
00308              */
00309             (void) make_non_runnable(p_tcb);
00310         }
00311         else if (TSTAT_WAITING(p_tcb->tstat)) {
00312             wait_dequeue_wobj(p_tcb);
00313             wait_dequeue_tmevtb(p_tcb);
00314         }
00315         make_dormant(p_tcb);
00316         if (p_tcb->actque) {
00317             p_tcb->actque = false;
00318             if (make_active(p_tcb)) {
00319                 dispatch();
00320             }
00321         }
00322         ercd = E_OK;
00323     }
00324     t_unlock_cpu();
00325 
00326   error_exit:
00327     LOG_TER_TSK_LEAVE(ercd);
00328     return(ercd);
00329 }
00330 
00331 #endif /* TOPPERS_ter_tsk */
00332 
00333 /*
00334  *  タスク優先度の変更
00335  */
00336 #ifdef TOPPERS_chg_pri
00337 
00338 ER
00339 chg_pri(ID tskid, PRI tskpri)
00340 {
00341     TCB     *p_tcb;
00342     uint_t  newpri;
00343     ER      ercd;
00344 
00345     LOG_CHG_PRI_ENTER(tskid, tskpri);
00346     CHECK_TSKCTX_UNL();
00347     CHECK_TSKID_SELF(tskid);
00348     CHECK_TPRI_INI(tskpri);
00349     p_tcb = get_tcb_self(tskid);
00350     newpri = (tskpri == TPRI_INI) ? p_tcb->p_tinib->ipriority
00351                                         : INT_PRIORITY(tskpri);
00352 
00353     t_lock_cpu();
00354     if (TSTAT_DORMANT(p_tcb->tstat)) {
00355         ercd = E_OBJ;
00356     }
00357     else {
00358         if (change_priority(p_tcb, newpri)) {
00359             dispatch();
00360         }
00361         ercd = E_OK;
00362     }
00363     t_unlock_cpu();
00364 
00365   error_exit:
00366     LOG_CHG_PRI_LEAVE(ercd);
00367     return(ercd);
00368 }
00369 
00370 #endif /* TOPPERS_chg_pri */
00371 
00372 /*
00373  *  タスク優先度の参照
00374  */
00375 #ifdef TOPPERS_get_pri
00376 
00377 ER
00378 get_pri(ID tskid, PRI *p_tskpri)
00379 {
00380     TCB     *p_tcb;
00381     ER      ercd;
00382 
00383     LOG_GET_PRI_ENTER(tskid, p_tskpri);
00384     CHECK_TSKCTX_UNL();
00385     CHECK_TSKID_SELF(tskid);
00386     p_tcb = get_tcb_self(tskid);
00387 
00388     t_lock_cpu();
00389     if (TSTAT_DORMANT(p_tcb->tstat)) {
00390         ercd = E_OBJ;
00391     }
00392     else {
00393         *p_tskpri = EXT_TSKPRI(p_tcb->priority);
00394         ercd = E_OK;
00395     }
00396     t_unlock_cpu();
00397 
00398   error_exit:
00399     LOG_GET_PRI_LEAVE(ercd, *p_tskpri);
00400     return(ercd);
00401 }
00402 
00403 #endif /* TOPPERS_get_pri */
00404 
00405 /*
00406  *  自タスクの拡張情報の参照
00407  */
00408 #ifdef TOPPERS_get_inf
00409 
00410 ER
00411 get_inf(intptr_t *p_exinf)
00412 {
00413     ER      ercd;
00414 
00415     LOG_GET_INF_ENTER(p_exinf);
00416     CHECK_TSKCTX_UNL();
00417 
00418     t_lock_cpu();
00419     *p_exinf = p_runtsk->p_tinib->exinf;
00420     ercd = E_OK;
00421     t_unlock_cpu();
00422 
00423   error_exit:
00424     LOG_GET_INF_LEAVE(ercd, *p_exinf);
00425     return(ercd);
00426 }
00427 
00428 #endif /* TOPPERS_get_inf */

Copyright © 2008 by Kijineko Inc.

ホームページ制作