task_sync.c

説明を見る。
00001 /*
00002  *  TOPPERS/JSP Kernel
00003  *      Toyohashi Open Platform for Embedded Real-Time Systems/
00004  *      Just Standard Profile Kernel
00005  * 
00006  *  Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
00007  *                              Toyohashi Univ. of Technology, JAPAN
00008  * 
00009  *  上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation 
00010  *  によって公表されている GNU General Public License の Version 2 に記
00011  *  述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
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  *  本ソフトウェアは,無保証で提供されているものである.上記著作権者お
00032  *  よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
00033  *  含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
00034  *  接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
00035  * 
00036  *  @(#) $Id: task_sync.c,v 1.7 2003/12/20 08:12:24 hiro Exp $
00037  */
00038 
00039 /*
00040  *      タスク付属同期機能
00041  */
00042 
00043 #include "jsp_kernel.h"
00044 #include "check.h"
00045 #include "task.h"
00046 #include "wait.h"
00047 
00048 /*
00049  *  起床待ち
00050  */
00051 #ifdef __slp_tsk
00052 
00053 SYSCALL ER
00054 slp_tsk()
00055 {
00056         WINFO   winfo;
00057         ER      ercd;
00058 
00059         LOG_SLP_TSK_ENTER();
00060         CHECK_DISPATCH();
00061 
00062         t_lock_cpu();
00063         if (runtsk->wupcnt) {
00064                 runtsk->wupcnt = FALSE;
00065                 ercd = E_OK;
00066         }
00067         else {
00068                 runtsk->tstat = (TS_WAITING | TS_WAIT_SLEEP);
00069                 make_wait(&winfo);
00070                 LOG_TSKSTAT(runtsk);
00071                 dispatch();
00072                 ercd = winfo.wercd;
00073         }
00074         t_unlock_cpu();
00075 
00076     exit:
00077         LOG_SLP_TSK_LEAVE(ercd);
00078         return(ercd);
00079 }
00080 
00081 #endif /* __slp_tsk */
00082 
00083 /*
00084  *  起床待ち(タイムアウトあり)
00085  */
00086 #ifdef __tslp_tsk
00087 
00088 SYSCALL ER
00089 tslp_tsk(TMO tmout)
00090 {
00091         WINFO   winfo;
00092         TMEVTB  tmevtb;
00093         ER      ercd;
00094 
00095         LOG_TSLP_TSK_ENTER(tmout);
00096         CHECK_DISPATCH();
00097         CHECK_TMOUT(tmout);
00098 
00099         t_lock_cpu();
00100         if (runtsk->wupcnt) {
00101                 runtsk->wupcnt = FALSE;
00102                 ercd = E_OK;
00103         }
00104         else if (tmout == TMO_POL) {
00105                 ercd = E_TMOUT;
00106         }
00107         else {
00108                 runtsk->tstat = (TS_WAITING | TS_WAIT_SLEEP);
00109                 make_wait_tmout(&winfo, &tmevtb, tmout);
00110                 LOG_TSKSTAT(runtsk);
00111                 dispatch();
00112                 ercd = winfo.wercd;
00113         }
00114         t_unlock_cpu();
00115 
00116     exit:
00117         LOG_TSLP_TSK_LEAVE(ercd);
00118         return(ercd);
00119 }
00120 
00121 #endif /* __tslp_tsk */
00122 
00123 /*
00124  *  タスクの起床
00125  */
00126 #ifdef __wup_tsk
00127 
00128 SYSCALL ER
00129 wup_tsk(ID tskid)
00130 {
00131         TCB     *tcb;
00132         UINT    tstat;
00133         ER      ercd;
00134 
00135         LOG_WUP_TSK_ENTER(tskid);
00136         CHECK_TSKCTX_UNL();
00137         CHECK_TSKID_SELF(tskid);
00138         tcb = get_tcb_self(tskid);
00139 
00140         t_lock_cpu();
00141         if (TSTAT_DORMANT(tstat = tcb->tstat)) {
00142                 ercd = E_OBJ;
00143         }
00144         else if ((tstat & TS_WAIT_SLEEP) != 0) {
00145                 if (wait_complete(tcb)) {
00146                         dispatch();
00147                 }
00148                 ercd = E_OK;
00149         }
00150         else if (!(tcb->wupcnt)) {
00151                 tcb->wupcnt = TRUE;
00152                 ercd = E_OK;
00153         }
00154         else {
00155                 ercd = E_QOVR;
00156         }
00157         t_unlock_cpu();
00158 
00159     exit:
00160         LOG_WUP_TSK_LEAVE(ercd);
00161         return(ercd);
00162 }
00163 
00164 #endif /* __wup_tsk */
00165 
00166 /*
00167  *  タスクの起床(非タスクコンテキスト用)
00168  */
00169 #ifdef __iwup_tsk
00170 
00171 SYSCALL ER
00172 iwup_tsk(ID tskid)
00173 {
00174         TCB     *tcb;
00175         UINT    tstat;
00176         ER      ercd;
00177 
00178         LOG_IWUP_TSK_ENTER(tskid);
00179         CHECK_INTCTX_UNL();
00180         CHECK_TSKID(tskid);
00181         tcb = get_tcb(tskid);
00182 
00183         i_lock_cpu();
00184         if (TSTAT_DORMANT(tstat = tcb->tstat)) {
00185                 ercd = E_OBJ;
00186         }
00187         else if ((tstat & TS_WAIT_SLEEP) != 0) {
00188                 if (wait_complete(tcb)) {
00189                         reqflg = TRUE;
00190                 }
00191                 ercd = E_OK;
00192         }
00193         else if (!(tcb->wupcnt)) {
00194                 tcb->wupcnt = TRUE;
00195                 ercd = E_OK;
00196         }
00197         else {
00198                 ercd = E_QOVR;
00199         }
00200         i_unlock_cpu();
00201 
00202     exit:
00203         LOG_IWUP_TSK_LEAVE(ercd);
00204         return(ercd);
00205 }
00206 
00207 #endif /* __iwup_tsk */
00208 
00209 /*
00210  *  タスク起床要求のキャンセル
00211  */
00212 #ifdef __can_wup
00213 
00214 SYSCALL ER_UINT
00215 can_wup(ID tskid)
00216 {
00217         TCB     *tcb;
00218         ER_UINT ercd;
00219 
00220         LOG_CAN_WUP_ENTER(tskid);
00221         CHECK_TSKCTX_UNL();
00222         CHECK_TSKID_SELF(tskid);
00223         tcb = get_tcb_self(tskid);
00224 
00225         t_lock_cpu();
00226         if (TSTAT_DORMANT(tcb->tstat)) {
00227                 ercd = E_OBJ;
00228         }
00229         else {
00230                 ercd = tcb->wupcnt ? 1 : 0;
00231                 tcb->wupcnt = FALSE;
00232         }
00233         t_unlock_cpu();
00234 
00235     exit:
00236         LOG_CAN_WUP_LEAVE(ercd);
00237         return(ercd);
00238 }
00239 
00240 #endif /* __can_wup */
00241 
00242 /*
00243  *  待ち状態の強制解除
00244  */
00245 #ifdef __rel_wai
00246 
00247 SYSCALL ER
00248 rel_wai(ID tskid)
00249 {
00250         TCB     *tcb;
00251         ER      ercd;
00252 
00253         LOG_REL_WAI_ENTER(tskid);
00254         CHECK_TSKCTX_UNL();
00255         CHECK_TSKID(tskid);
00256         tcb = get_tcb(tskid);
00257 
00258         t_lock_cpu();
00259         if (!(TSTAT_WAITING(tcb->tstat))) {
00260                 ercd = E_OBJ;
00261         }
00262         else {
00263                 if (wait_release(tcb)) {
00264                         dispatch();
00265                 }
00266                 ercd = E_OK;
00267         }
00268         t_unlock_cpu();
00269 
00270     exit:
00271         LOG_REL_WAI_LEAVE(ercd);
00272         return(ercd);
00273 }
00274 
00275 #endif /* __rel_wai */
00276 
00277 /*
00278  *  待ち状態の強制解除(非タスクコンテキスト用)
00279  */
00280 #ifdef __irel_wai
00281 
00282 SYSCALL ER
00283 irel_wai(ID tskid)
00284 {
00285         TCB     *tcb;
00286         ER      ercd;
00287 
00288         LOG_IREL_WAI_ENTER(tskid);
00289         CHECK_INTCTX_UNL();
00290         CHECK_TSKID(tskid);
00291         tcb = get_tcb(tskid);
00292 
00293         i_lock_cpu();
00294         if (!(TSTAT_WAITING(tcb->tstat))) {
00295                 ercd = E_OBJ;
00296         }
00297         else {
00298                 if (wait_release(tcb)) {
00299                         reqflg = TRUE;
00300                 }
00301                 ercd = E_OK;
00302         }
00303         i_unlock_cpu();
00304 
00305     exit:
00306         LOG_IREL_WAI_LEAVE(ercd);
00307         return(ercd);
00308 }
00309 
00310 #endif /* __irel_wai */
00311 
00312 /*
00313  *  強制待ち状態への移行
00314  */
00315 #ifdef __sus_tsk
00316 
00317 SYSCALL ER
00318 sus_tsk(ID tskid)
00319 {
00320         TCB     *tcb;
00321         UINT    tstat;
00322         ER      ercd;
00323 
00324         LOG_SUS_TSK_ENTER(tskid);
00325         CHECK_TSKCTX_UNL();
00326         CHECK_TSKID_SELF(tskid);
00327         tcb = get_tcb_self(tskid);
00328 
00329         t_lock_cpu();
00330         if (tcb == runtsk && !(enadsp)) {
00331                 ercd = E_CTX;
00332         }
00333         else if (TSTAT_DORMANT(tstat = tcb->tstat)) {
00334                 ercd = E_OBJ;
00335         }
00336         else if (TSTAT_RUNNABLE(tstat)) {
00337                 /*
00338                  *  実行できる状態から強制待ち状態への遷移
00339                  */
00340                 tcb->tstat = TS_SUSPENDED;
00341                 LOG_TSKSTAT(tcb);
00342                 if (make_non_runnable(tcb)) {
00343                         dispatch();
00344                 }
00345                 ercd = E_OK;
00346         }
00347         else if (TSTAT_SUSPENDED(tstat)) {
00348                 ercd = E_QOVR;
00349         }
00350         else {
00351                 /*
00352                  *  待ち状態から二重待ち状態への遷移
00353                  */
00354                 tcb->tstat |= TS_SUSPENDED;
00355                 LOG_TSKSTAT(tcb);
00356                 ercd = E_OK;
00357         }
00358         t_unlock_cpu();
00359 
00360     exit:
00361         LOG_SUS_TSK_LEAVE(ercd);
00362         return(ercd);
00363 }
00364 
00365 #endif /* __sus_tsk */
00366 
00367 /*
00368  *  強制待ち状態からの再開
00369  */
00370 #ifdef __rsm_tsk
00371 
00372 SYSCALL ER
00373 rsm_tsk(ID tskid)
00374 {
00375         TCB     *tcb;
00376         UINT    tstat;
00377         ER      ercd;
00378 
00379         LOG_RSM_TSK_ENTER(tskid);
00380         CHECK_TSKCTX_UNL();
00381         CHECK_TSKID(tskid);
00382         tcb = get_tcb(tskid);
00383 
00384         t_lock_cpu();
00385         if (!(TSTAT_SUSPENDED(tstat = tcb->tstat))) {
00386                 ercd = E_OBJ;
00387         }
00388         else if (!(TSTAT_WAITING(tstat))) {
00389                 /*
00390                  *  強制待ち状態から実行できる状態への遷移
00391                  */
00392                 if (make_runnable(tcb)) {
00393                         dispatch();
00394                 }
00395                 ercd = E_OK;
00396         }
00397         else {
00398                 /*
00399                  *  二重待ち状態から待ち状態への遷移
00400                  */
00401                 tcb->tstat &= ~TS_SUSPENDED;
00402                 LOG_TSKSTAT(tcb);
00403                 ercd = E_OK;
00404         }
00405         t_unlock_cpu();
00406 
00407     exit:
00408         LOG_RSM_TSK_LEAVE(ercd);
00409         return(ercd);
00410 }
00411 
00412 #endif /* __rsm_tsk */
00413 
00414 /*
00415  *  強制待ち状態からの強制再開
00416  *
00417  *  JSPカーネルでは,frsm_tsk と rsm_tsk は同一の処理となる.frsm_tsk 
00418  *  が呼ばれると,frsm_tsk と rsm_tsk の両方のサービスコールのトレース
00419  *  ログが出力される.ログ取得後に rsm_tsk のトレースログを削除するこ
00420  *  とが必要である.rsm_tsk のトレースログを正しく削除するためには,タ
00421  *  スクディスパッチのログと,タスク例外処理のログも取得することが必要
00422  *  となるので,注意が必要である.
00423  */
00424 #ifdef __frsm_tsk
00425 
00426 SYSCALL ER
00427 frsm_tsk(ID tskid)
00428 {
00429         ER      ercd;
00430 
00431         LOG_FRSM_TSK_ENTER(tskid);
00432         ercd = rsm_tsk(tskid);
00433         LOG_FRSM_TSK_LEAVE(ercd);
00434         return(ercd);
00435 }
00436 
00437 #endif /* __frsm_tsk */
00438 
00439 /*
00440  *  自タスクの遅延
00441  */
00442 #ifdef __dly_tsk
00443 
00444 SYSCALL ER
00445 dly_tsk(RELTIM dlytim)
00446 {
00447         WINFO   winfo;
00448         TMEVTB  tmevtb;
00449         ER      ercd;
00450 
00451         LOG_DLY_TSK_ENTER(dlytim);
00452         CHECK_DISPATCH();
00453         CHECK_PAR(dlytim <= TMAX_RELTIM);
00454 
00455         t_lock_cpu();
00456         runtsk->tstat = TS_WAITING;
00457         make_non_runnable(runtsk);
00458         runtsk->winfo = &winfo;
00459         winfo.tmevtb = &tmevtb;
00460         tmevtb_enqueue(&tmevtb, dlytim, (CBACK) wait_tmout_ok, (VP) runtsk);
00461         LOG_TSKSTAT(runtsk);
00462         dispatch();
00463         ercd = winfo.wercd;
00464         t_unlock_cpu();
00465 
00466     exit:
00467         LOG_DLY_TSK_LEAVE(ercd);
00468         return(ercd);
00469 }
00470 
00471 #endif /* __dly_tsk */
00472 

Copyright © 2006 by TAKAGI Nobuhisa.
Copyright © 2006 by Kijineko Inc..
このページは Mon Dec 18 17:18:41 2006 に Doxygen によって生成されました。
データ入力からプログラム開発まで!様々なスキルを持ったメンバーが登録しています【@SOHO】