task_sync.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_sync.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_SLP_TSK_ENTER
00056 #define LOG_SLP_TSK_ENTER()
00057 #endif /* LOG_SLP_TSK_ENTER */
00058 
00059 #ifndef LOG_SLP_TSK_LEAVE
00060 #define LOG_SLP_TSK_LEAVE(ercd)
00061 #endif /* LOG_SLP_TSK_LEAVE */
00062 
00063 #ifndef LOG_TSLP_TSK_ENTER
00064 #define LOG_TSLP_TSK_ENTER(tmout)
00065 #endif /* LOG_TSLP_TSK_ENTER */
00066 
00067 #ifndef LOG_TSLP_TSK_LEAVE
00068 #define LOG_TSLP_TSK_LEAVE(ercd)
00069 #endif /* LOG_TSLP_TSK_LEAVE */
00070 
00071 #ifndef LOG_WUP_TSK_ENTER
00072 #define LOG_WUP_TSK_ENTER(tskid)
00073 #endif /* LOG_WUP_TSK_ENTER */
00074 
00075 #ifndef LOG_WUP_TSK_LEAVE
00076 #define LOG_WUP_TSK_LEAVE(ercd)
00077 #endif /* LOG_WUP_TSK_LEAVE */
00078 
00079 #ifndef LOG_IWUP_TSK_ENTER
00080 #define LOG_IWUP_TSK_ENTER(tskid)
00081 #endif /* LOG_IWUP_TSK_ENTER */
00082 
00083 #ifndef LOG_IWUP_TSK_LEAVE
00084 #define LOG_IWUP_TSK_LEAVE(ercd)
00085 #endif /* LOG_IWUP_TSK_LEAVE */
00086 
00087 #ifndef LOG_CAN_WUP_ENTER
00088 #define LOG_CAN_WUP_ENTER(tskid)
00089 #endif /* LOG_CAN_WUP_ENTER */
00090 
00091 #ifndef LOG_CAN_WUP_LEAVE
00092 #define LOG_CAN_WUP_LEAVE(ercd)
00093 #endif /* LOG_CAN_WUP_LEAVE */
00094 
00095 #ifndef LOG_REL_WAI_ENTER
00096 #define LOG_REL_WAI_ENTER(tskid)
00097 #endif /* LOG_REL_WAI_ENTER */
00098 
00099 #ifndef LOG_REL_WAI_LEAVE
00100 #define LOG_REL_WAI_LEAVE(ercd)
00101 #endif /* LOG_REL_WAI_LEAVE */
00102 
00103 #ifndef LOG_IREL_WAI_ENTER
00104 #define LOG_IREL_WAI_ENTER(tskid)
00105 #endif /* LOG_IREL_WAI_ENTER */
00106 
00107 #ifndef LOG_IREL_WAI_LEAVE
00108 #define LOG_IREL_WAI_LEAVE(ercd)
00109 #endif /* LOG_IREL_WAI_LEAVE */
00110 
00111 #ifndef LOG_SUS_TSK_ENTER
00112 #define LOG_SUS_TSK_ENTER(tskid)
00113 #endif /* LOG_SUS_TSK_ENTER */
00114 
00115 #ifndef LOG_SUS_TSK_LEAVE
00116 #define LOG_SUS_TSK_LEAVE(ercd)
00117 #endif /* LOG_SUS_TSK_LEAVE */
00118 
00119 #ifndef LOG_RSM_TSK_ENTER
00120 #define LOG_RSM_TSK_ENTER(tskid)
00121 #endif /* LOG_RSM_TSK_ENTER */
00122 
00123 #ifndef LOG_RSM_TSK_LEAVE
00124 #define LOG_RSM_TSK_LEAVE(ercd)
00125 #endif /* LOG_RSM_TSK_LEAVE */
00126 
00127 #ifndef LOG_DLY_TSK_ENTER
00128 #define LOG_DLY_TSK_ENTER(dlytim)
00129 #endif /* LOG_DLY_TSK_ENTER */
00130 
00131 #ifndef LOG_DLY_TSK_LEAVE
00132 #define LOG_DLY_TSK_LEAVE(ercd)
00133 #endif /* LOG_DLY_TSK_LEAVE */
00134 
00135 /*
00136  *  起床待ち
00137  */
00138 #ifdef TOPPERS_slp_tsk
00139 
00140 ER
00141 slp_tsk(void)
00142 {
00143     WINFO   winfo;
00144     ER      ercd;
00145 
00146     LOG_SLP_TSK_ENTER();
00147     CHECK_DISPATCH();
00148 
00149     t_lock_cpu();
00150     if (p_runtsk->wupque) {
00151         p_runtsk->wupque = false;
00152         ercd = E_OK;
00153     }
00154     else {
00155         p_runtsk->tstat = (TS_WAITING | TS_WAIT_SLP);
00156         make_wait(&winfo);
00157         LOG_TSKSTAT(p_runtsk);
00158         dispatch();
00159         ercd = winfo.wercd;
00160     }
00161     t_unlock_cpu();
00162 
00163   error_exit:
00164     LOG_SLP_TSK_LEAVE(ercd);
00165     return(ercd);
00166 }
00167 
00168 #endif /* TOPPERS_slp_tsk */
00169 
00170 /*
00171  *  起床待ち(タイムアウトあり)
00172  */
00173 #ifdef TOPPERS_tslp_tsk
00174 
00175 ER
00176 tslp_tsk(TMO tmout)
00177 {
00178     WINFO   winfo;
00179     TMEVTB  tmevtb;
00180     ER      ercd;
00181 
00182     LOG_TSLP_TSK_ENTER(tmout);
00183     CHECK_DISPATCH();
00184     CHECK_TMOUT(tmout);
00185 
00186     t_lock_cpu();
00187     if (p_runtsk->wupque) {
00188         p_runtsk->wupque = false;
00189         ercd = E_OK;
00190     }
00191     else if (tmout == TMO_POL) {
00192         ercd = E_TMOUT;
00193     }
00194     else {
00195         p_runtsk->tstat = (TS_WAITING | TS_WAIT_SLP);
00196         make_wait_tmout(&winfo, &tmevtb, tmout);
00197         LOG_TSKSTAT(p_runtsk);
00198         dispatch();
00199         ercd = winfo.wercd;
00200     }
00201     t_unlock_cpu();
00202 
00203   error_exit:
00204     LOG_TSLP_TSK_LEAVE(ercd);
00205     return(ercd);
00206 }
00207 
00208 #endif /* TOPPERS_tslp_tsk */
00209 
00210 /*
00211  *  タスクの起床
00212  */
00213 #ifdef TOPPERS_wup_tsk
00214 
00215 ER
00216 wup_tsk(ID tskid)
00217 {
00218     TCB     *p_tcb;
00219     ER      ercd;
00220 
00221     LOG_WUP_TSK_ENTER(tskid);
00222     CHECK_TSKCTX_UNL();
00223     CHECK_TSKID_SELF(tskid);
00224     p_tcb = get_tcb_self(tskid);
00225 
00226     t_lock_cpu();
00227     if (TSTAT_DORMANT(p_tcb->tstat)) {
00228         ercd = E_OBJ;
00229     }
00230     else if (TSTAT_WAIT_SLP(p_tcb->tstat)) {
00231         if (wait_complete(p_tcb)) {
00232             dispatch();
00233         }
00234         ercd = E_OK;
00235     }
00236     else if (!(p_tcb->wupque)) {
00237         p_tcb->wupque = true;
00238         ercd = E_OK;
00239     }
00240     else {
00241         ercd = E_QOVR;
00242     }
00243     t_unlock_cpu();
00244 
00245   error_exit:
00246     LOG_WUP_TSK_LEAVE(ercd);
00247     return(ercd);
00248 }
00249 
00250 #endif /* TOPPERS_wup_tsk */
00251 
00252 /*
00253  *  タスクの起床(非タスクコンテキスト用)
00254  */
00255 #ifdef TOPPERS_iwup_tsk
00256 
00257 ER
00258 iwup_tsk(ID tskid)
00259 {
00260     TCB     *p_tcb;
00261     ER      ercd;
00262 
00263     LOG_IWUP_TSK_ENTER(tskid);
00264     CHECK_INTCTX_UNL();
00265     CHECK_TSKID(tskid);
00266     p_tcb = get_tcb(tskid);
00267 
00268     i_lock_cpu();
00269     if (TSTAT_DORMANT(p_tcb->tstat)) {
00270         ercd = E_OBJ;
00271     }
00272     else if (TSTAT_WAIT_SLP(p_tcb->tstat)) {
00273         if (wait_complete(p_tcb)) {
00274             reqflg = true;
00275         }
00276         ercd = E_OK;
00277     }
00278     else if (!(p_tcb->wupque)) {
00279         p_tcb->wupque = true;
00280         ercd = E_OK;
00281     }
00282     else {
00283         ercd = E_QOVR;
00284     }
00285     i_unlock_cpu();
00286 
00287   error_exit:
00288     LOG_IWUP_TSK_LEAVE(ercd);
00289     return(ercd);
00290 }
00291 
00292 #endif /* TOPPERS_iwup_tsk */
00293 
00294 /*
00295  *  タスク起床要求のキャンセル
00296  */
00297 #ifdef TOPPERS_can_wup
00298 
00299 ER_UINT
00300 can_wup(ID tskid)
00301 {
00302     TCB     *p_tcb;
00303     ER_UINT ercd;
00304 
00305     LOG_CAN_WUP_ENTER(tskid);
00306     CHECK_TSKCTX_UNL();
00307     CHECK_TSKID_SELF(tskid);
00308     p_tcb = get_tcb_self(tskid);
00309 
00310     t_lock_cpu();
00311     if (TSTAT_DORMANT(p_tcb->tstat)) {
00312         ercd = E_OBJ;
00313     }
00314     else {
00315         ercd = p_tcb->wupque ? 1 : 0;
00316         p_tcb->wupque = false;
00317     }
00318     t_unlock_cpu();
00319 
00320   error_exit:
00321     LOG_CAN_WUP_LEAVE(ercd);
00322     return(ercd);
00323 }
00324 
00325 #endif /* TOPPERS_can_wup */
00326 
00327 /*
00328  *  待ち状態の強制解除
00329  */
00330 #ifdef TOPPERS_rel_wai
00331 
00332 ER
00333 rel_wai(ID tskid)
00334 {
00335     TCB     *p_tcb;
00336     ER      ercd;
00337 
00338     LOG_REL_WAI_ENTER(tskid);
00339     CHECK_TSKCTX_UNL();
00340     CHECK_TSKID(tskid);
00341     p_tcb = get_tcb(tskid);
00342 
00343     t_lock_cpu();
00344     if (!TSTAT_WAITING(p_tcb->tstat)) {
00345         ercd = E_OBJ;
00346     }
00347     else {
00348         if (wait_release(p_tcb)) {
00349             dispatch();
00350         }
00351         ercd = E_OK;
00352     }
00353     t_unlock_cpu();
00354 
00355   error_exit:
00356     LOG_REL_WAI_LEAVE(ercd);
00357     return(ercd);
00358 }
00359 
00360 #endif /* TOPPERS_rel_wai */
00361 
00362 /*
00363  *  待ち状態の強制解除(非タスクコンテキスト用)
00364  */
00365 #ifdef TOPPERS_irel_wai
00366 
00367 ER
00368 irel_wai(ID tskid)
00369 {
00370     TCB     *p_tcb;
00371     ER      ercd;
00372 
00373     LOG_IREL_WAI_ENTER(tskid);
00374     CHECK_INTCTX_UNL();
00375     CHECK_TSKID(tskid);
00376     p_tcb = get_tcb(tskid);
00377 
00378     i_lock_cpu();
00379     if (!TSTAT_WAITING(p_tcb->tstat)) {
00380         ercd = E_OBJ;
00381     }
00382     else {
00383         if (wait_release(p_tcb)) {
00384             reqflg = true;
00385         }
00386         ercd = E_OK;
00387     }
00388     i_unlock_cpu();
00389 
00390   error_exit:
00391     LOG_IREL_WAI_LEAVE(ercd);
00392     return(ercd);
00393 }
00394 
00395 #endif /* TOPPERS_irel_wai */
00396 
00397 /*
00398  *  強制待ち状態への移行
00399  */
00400 #ifdef TOPPERS_sus_tsk
00401 
00402 ER
00403 sus_tsk(ID tskid)
00404 {
00405     TCB     *p_tcb;
00406     ER      ercd;
00407 
00408     LOG_SUS_TSK_ENTER(tskid);
00409     CHECK_TSKCTX_UNL();
00410     CHECK_TSKID_SELF(tskid);
00411     p_tcb = get_tcb_self(tskid);
00412 
00413     t_lock_cpu();
00414     if (p_tcb == p_runtsk && !dspflg) {
00415         ercd = E_CTX;
00416     }
00417     else if (TSTAT_DORMANT(p_tcb->tstat)) {
00418         ercd = E_OBJ;
00419     }
00420     else if (TSTAT_RUNNABLE(p_tcb->tstat)) {
00421         /*
00422          *  実行できる状態から強制待ち状態への遷移
00423          */
00424         p_tcb->tstat = TS_SUSPENDED;
00425         LOG_TSKSTAT(p_tcb);
00426         if (make_non_runnable(p_tcb)) {
00427             dispatch();
00428         }
00429         ercd = E_OK;
00430     }
00431     else if (TSTAT_SUSPENDED(p_tcb->tstat)) {
00432         ercd = E_QOVR;
00433     }
00434     else {
00435         /*
00436          *  待ち状態から二重待ち状態への遷移
00437          */
00438         p_tcb->tstat |= TS_SUSPENDED;
00439         LOG_TSKSTAT(p_tcb);
00440         ercd = E_OK;
00441     }
00442     t_unlock_cpu();
00443 
00444   error_exit:
00445     LOG_SUS_TSK_LEAVE(ercd);
00446     return(ercd);
00447 }
00448 
00449 #endif /* TOPPERS_sus_tsk */
00450 
00451 /*
00452  *  強制待ち状態からの再開
00453  */
00454 #ifdef TOPPERS_rsm_tsk
00455 
00456 ER
00457 rsm_tsk(ID tskid)
00458 {
00459     TCB     *p_tcb;
00460     ER      ercd;
00461 
00462     LOG_RSM_TSK_ENTER(tskid);
00463     CHECK_TSKCTX_UNL();
00464     CHECK_TSKID(tskid);
00465     p_tcb = get_tcb(tskid);
00466 
00467     t_lock_cpu();
00468     if (!TSTAT_SUSPENDED(p_tcb->tstat)) {
00469         ercd = E_OBJ;
00470     }
00471     else if (!TSTAT_WAITING(p_tcb->tstat)) {
00472         /*
00473          *  強制待ち状態から実行できる状態への遷移
00474          */
00475         if (make_runnable(p_tcb)) {
00476             dispatch();
00477         }
00478         ercd = E_OK;
00479     }
00480     else {
00481         /*
00482          *  二重待ち状態から待ち状態への遷移
00483          */
00484         p_tcb->tstat &= ~TS_SUSPENDED;
00485         LOG_TSKSTAT(p_tcb);
00486         ercd = E_OK;
00487     }
00488     t_unlock_cpu();
00489 
00490   error_exit:
00491     LOG_RSM_TSK_LEAVE(ercd);
00492     return(ercd);
00493 }
00494 
00495 #endif /* TOPPERS_rsm_tsk */
00496 
00497 /*
00498  *  自タスクの遅延
00499  */
00500 #ifdef TOPPERS_dly_tsk
00501 
00502 ER
00503 dly_tsk(RELTIM dlytim)
00504 {
00505     WINFO   winfo;
00506     TMEVTB  tmevtb;
00507     ER      ercd;
00508 
00509     LOG_DLY_TSK_ENTER(dlytim);
00510     CHECK_DISPATCH();
00511     CHECK_PAR(dlytim <= TMAX_RELTIM);
00512 
00513     t_lock_cpu();
00514     p_runtsk->tstat = (TS_WAITING | TS_WAIT_DLY);
00515     (void) make_non_runnable(p_runtsk);
00516     p_runtsk->p_winfo = &winfo;
00517     winfo.p_tmevtb = &tmevtb;
00518     tmevtb_enqueue(&tmevtb, dlytim, (CBACK) wait_tmout_ok, (void *) p_runtsk);
00519     LOG_TSKSTAT(p_runtsk);
00520     dispatch();
00521     ercd = winfo.wercd;
00522     t_unlock_cpu();
00523 
00524   error_exit:
00525     LOG_DLY_TSK_LEAVE(ercd);
00526     return(ercd);
00527 }
00528 
00529 #endif /* TOPPERS_dly_tsk */

Copyright © 2008 by Kijineko Inc.

ホームページ制作