eventflag.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: eventflag.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 #include "eventflag.h"
00052 
00053 /*
00054  *  トレースログマクロのデフォルト定義
00055  */
00056 #ifndef LOG_SET_FLG_ENTER
00057 #define LOG_SET_FLG_ENTER(flgid, setptn)
00058 #endif /* LOG_SET_FLG_ENTER */
00059 
00060 #ifndef LOG_SET_FLG_LEAVE
00061 #define LOG_SET_FLG_LEAVE(ercd)
00062 #endif /* LOG_SET_FLG_LEAVE */
00063 
00064 #ifndef LOG_ISET_FLG_ENTER
00065 #define LOG_ISET_FLG_ENTER(flgid, setptn)
00066 #endif /* LOG_ISET_FLG_ENTER */
00067 
00068 #ifndef LOG_ISET_FLG_LEAVE
00069 #define LOG_ISET_FLG_LEAVE(ercd)
00070 #endif /* LOG_ISET_FLG_LEAVE */
00071 
00072 #ifndef LOG_CLR_FLG_ENTER
00073 #define LOG_CLR_FLG_ENTER(flgid, clrptn)
00074 #endif /* LOG_CLR_FLG_ENTER */
00075 
00076 #ifndef LOG_CLR_FLG_LEAVE
00077 #define LOG_CLR_FLG_LEAVE(ercd)
00078 #endif /* LOG_CLR_FLG_LEAVE */
00079 
00080 #ifndef LOG_WAI_FLG_ENTER
00081 #define LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn)
00082 #endif /* LOG_WAI_FLG_ENTER */
00083 
00084 #ifndef LOG_WAI_FLG_LEAVE
00085 #define LOG_WAI_FLG_LEAVE(ercd, flgptn)
00086 #endif /* LOG_WAI_FLG_LEAVE */
00087 
00088 #ifndef LOG_POL_FLG_ENTER
00089 #define LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn)
00090 #endif /* LOG_POL_FLG_ENTER */
00091 
00092 #ifndef LOG_POL_FLG_LEAVE
00093 #define LOG_POL_FLG_LEAVE(ercd, flgptn)
00094 #endif /* LOG_POL_FLG_LEAVE */
00095 
00096 #ifndef LOG_TWAI_FLG_ENTER
00097 #define LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout)
00098 #endif /* LOG_TWAI_FLG_ENTER */
00099 
00100 #ifndef LOG_TWAI_FLG_LEAVE
00101 #define LOG_TWAI_FLG_LEAVE(ercd, flgptn)
00102 #endif /* LOG_TWAI_FLG_LEAVE */
00103 
00104 #ifndef LOG_INI_FLG_ENTER
00105 #define LOG_INI_FLG_ENTER(flgid)
00106 #endif /* LOG_INI_FLG_ENTER */
00107 
00108 #ifndef LOG_INI_FLG_LEAVE
00109 #define LOG_INI_FLG_LEAVE(ercd)
00110 #endif /* LOG_INI_FLG_LEAVE */
00111 
00112 #ifndef LOG_REF_FLG_ENTER
00113 #define LOG_REF_FLG_ENTER(flgid, pk_rflg)
00114 #endif /* LOG_REF_FLG_ENTER */
00115 
00116 #ifndef LOG_REF_FLG_LEAVE
00117 #define LOG_REF_FLG_LEAVE(ercd, pk_rflg)
00118 #endif /* LOG_REF_FLG_LEAVE */
00119 
00120 /*
00121  *  イベントフラグの数
00122  */
00123 #define tnum_flg    ((uint_t)(tmax_flgid - TMIN_FLGID + 1))
00124 
00125 /*
00126  *  イベントフラグIDからイベントフラグ管理ブロックを取り出すためのマクロ
00127  */
00128 #define INDEX_FLG(flgid)    ((uint_t)((flgid) - TMIN_FLGID))
00129 #define get_flgcb(flgid)    (&(flgcb_table[INDEX_FLG(flgid)]))
00130 
00131 /*
00132  *  イベントフラグ機能の初期化
00133  */
00134 #ifdef TOPPERS_flgini
00135 
00136 void
00137 initialize_eventflag(void)
00138 {
00139     uint_t  i;
00140     FLGCB   *p_flgcb;
00141 
00142     for (p_flgcb = flgcb_table, i = 0; i < tnum_flg; p_flgcb++, i++) {
00143         queue_initialize(&(p_flgcb->wait_queue));
00144         p_flgcb->p_flginib = &(flginib_table[i]);
00145         p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
00146     }
00147 }
00148 
00149 #endif /* TOPPERS_flgini */
00150 
00151 /*
00152  *  イベントフラグ待ち解除条件のチェック
00153  */
00154 #ifdef TOPPERS_flgcnd
00155 
00156 bool_t
00157 check_flg_cond(FLGCB *p_flgcb, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
00158 {
00159     if ((wfmode & TWF_ORW) != 0U ? (p_flgcb->flgptn & waiptn) != 0U
00160                                     : (p_flgcb->flgptn & waiptn) == waiptn) {
00161         *p_flgptn = p_flgcb->flgptn;
00162         if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
00163             p_flgcb->flgptn = 0U;
00164         }
00165         return(true);
00166     }
00167     return(false);
00168 }
00169 
00170 #endif /* TOPPERS_flgcnd */
00171 
00172 /*
00173  *  イベントフラグのセット
00174  */
00175 #ifdef TOPPERS_set_flg
00176 
00177 ER
00178 set_flg(ID flgid, FLGPTN setptn)
00179 {
00180     FLGCB   *p_flgcb;
00181     QUEUE   *p_queue;
00182     TCB     *p_tcb;
00183     WINFO_FLG *p_winfo_flg;
00184     bool_t  dspreq = false;
00185     ER      ercd;
00186 
00187     LOG_SET_FLG_ENTER(flgid, setptn);
00188     CHECK_TSKCTX_UNL();
00189     CHECK_FLGID(flgid);
00190     p_flgcb = get_flgcb(flgid);
00191 
00192     t_lock_cpu();
00193     p_flgcb->flgptn |= setptn;
00194     p_queue = p_flgcb->wait_queue.p_next;
00195     while (p_queue != &(p_flgcb->wait_queue)) {
00196         p_tcb = (TCB *) p_queue;
00197         p_queue = p_queue->p_next;
00198         p_winfo_flg = (WINFO_FLG *)(p_tcb->p_winfo);
00199         if (check_flg_cond(p_flgcb, p_winfo_flg->waiptn,
00200                             p_winfo_flg->wfmode, &(p_winfo_flg->flgptn))) {
00201             queue_delete(&(p_tcb->task_queue));
00202             if (wait_complete(p_tcb)) {
00203                 dspreq = true;
00204             }
00205             if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
00206                 break;
00207             }
00208         }
00209     }
00210     if (dspreq) {
00211         dispatch();
00212     }
00213     ercd = E_OK;
00214     t_unlock_cpu();
00215 
00216   error_exit:
00217     LOG_SET_FLG_LEAVE(ercd);
00218     return(ercd);
00219 }
00220 
00221 #endif /* TOPPERS_set_flg */
00222 
00223 /*
00224  *  イベントフラグのセット(非タスクコンテキスト用)
00225  */
00226 #ifdef TOPPERS_iset_flg
00227 
00228 ER
00229 iset_flg(ID flgid, FLGPTN setptn)
00230 {
00231     FLGCB   *p_flgcb;
00232     QUEUE   *p_queue;
00233     TCB     *p_tcb;
00234     WINFO_FLG *p_winfo_flg;
00235     ER      ercd;
00236 
00237     LOG_ISET_FLG_ENTER(flgid, setptn);
00238     CHECK_INTCTX_UNL();
00239     CHECK_FLGID(flgid);
00240     p_flgcb = get_flgcb(flgid);
00241 
00242     i_lock_cpu();
00243     p_flgcb->flgptn |= setptn;
00244     p_queue = p_flgcb->wait_queue.p_next;
00245     while (p_queue != &(p_flgcb->wait_queue)) {
00246         p_tcb = (TCB *) p_queue;
00247         p_queue = p_queue->p_next;
00248         p_winfo_flg = (WINFO_FLG *)(p_tcb->p_winfo);
00249         if (check_flg_cond(p_flgcb, p_winfo_flg->waiptn,
00250                             p_winfo_flg->wfmode, &(p_winfo_flg->flgptn))) {
00251             queue_delete(&(p_tcb->task_queue));
00252             if (wait_complete(p_tcb)) {
00253                 reqflg = true;
00254             }
00255             if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
00256                 break;
00257             }
00258         }
00259     }
00260     ercd = E_OK;
00261     i_unlock_cpu();
00262 
00263   error_exit:
00264     LOG_ISET_FLG_LEAVE(ercd);
00265     return(ercd);
00266 }
00267 
00268 #endif /* TOPPERS_iset_flg */
00269 
00270 /*
00271  *  イベントフラグのクリア
00272  */
00273 #ifdef TOPPERS_clr_flg
00274 
00275 ER
00276 clr_flg(ID flgid, FLGPTN clrptn)
00277 {
00278     FLGCB   *p_flgcb;
00279     ER      ercd;
00280 
00281     LOG_CLR_FLG_ENTER(flgid, clrptn);
00282     CHECK_TSKCTX_UNL();
00283     CHECK_FLGID(flgid);
00284     p_flgcb = get_flgcb(flgid);
00285 
00286     t_lock_cpu();
00287     p_flgcb->flgptn &= clrptn; 
00288     ercd = E_OK;
00289     t_unlock_cpu();
00290 
00291   error_exit:
00292     LOG_CLR_FLG_LEAVE(ercd);
00293     return(ercd);
00294 }
00295 
00296 #endif /* TOPPERS_clr_flg */
00297 
00298 /*
00299  *  イベントフラグ待ち
00300  */
00301 #ifdef TOPPERS_wai_flg
00302 
00303 ER
00304 wai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
00305 {
00306     FLGCB   *p_flgcb;
00307     WINFO_FLG winfo_flg;
00308     ER      ercd;
00309 
00310     LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
00311     CHECK_DISPATCH();
00312     CHECK_FLGID(flgid);
00313     CHECK_PAR(waiptn != 0U);
00314     CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
00315     p_flgcb = get_flgcb(flgid);
00316 
00317     t_lock_cpu();
00318     if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
00319                     && !queue_empty(&(p_flgcb->wait_queue))) {
00320         ercd = E_ILUSE;
00321     }
00322     else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
00323         ercd = E_OK;
00324     }
00325     else {
00326         winfo_flg.waiptn = waiptn;
00327         winfo_flg.wfmode = wfmode;
00328         p_runtsk->tstat = (TS_WAITING | TS_WAIT_FLG);
00329         wobj_make_wait((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg);
00330         dispatch();
00331         ercd = winfo_flg.winfo.wercd;
00332         if (ercd == E_OK) {
00333             *p_flgptn = winfo_flg.flgptn;
00334         }
00335     }
00336     t_unlock_cpu();
00337 
00338   error_exit:
00339     LOG_WAI_FLG_LEAVE(ercd, *p_flgptn);
00340     return(ercd);
00341 }
00342 
00343 #endif /* TOPPERS_wai_flg */
00344 
00345 /*
00346  *  イベントフラグ待ち(ポーリング)
00347  */
00348 #ifdef TOPPERS_pol_flg
00349 
00350 ER
00351 pol_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
00352 {
00353     FLGCB   *p_flgcb;
00354     ER      ercd;
00355 
00356     LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
00357     CHECK_TSKCTX_UNL();
00358     CHECK_FLGID(flgid);
00359     CHECK_PAR(waiptn != 0U);
00360     CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
00361     p_flgcb = get_flgcb(flgid);
00362 
00363     t_lock_cpu();
00364     if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
00365                     && !queue_empty(&(p_flgcb->wait_queue))) {
00366         ercd = E_ILUSE;
00367     }
00368     else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
00369         ercd = E_OK;
00370     }
00371     else {
00372         ercd = E_TMOUT;
00373     }
00374     t_unlock_cpu();
00375 
00376   error_exit:
00377     LOG_POL_FLG_LEAVE(ercd, *p_flgptn);
00378     return(ercd);
00379 }
00380 
00381 #endif /* TOPPERS_pol_flg */
00382 
00383 /*
00384  *  イベントフラグ待ち(タイムアウトあり)
00385  */
00386 #ifdef TOPPERS_twai_flg
00387 
00388 ER
00389 twai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn, TMO tmout)
00390 {
00391     FLGCB   *p_flgcb;
00392     WINFO_FLG winfo_flg;
00393     TMEVTB  tmevtb;
00394     ER      ercd;
00395 
00396     LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout);
00397     CHECK_DISPATCH();
00398     CHECK_FLGID(flgid);
00399     CHECK_PAR(waiptn != 0U);
00400     CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
00401     CHECK_TMOUT(tmout);
00402     p_flgcb = get_flgcb(flgid);
00403 
00404     t_lock_cpu();
00405     if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
00406                     && !queue_empty(&(p_flgcb->wait_queue))) {
00407         ercd = E_ILUSE;
00408     }
00409     else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
00410         ercd = E_OK;
00411     }
00412     else if (tmout == TMO_POL) {
00413         ercd = E_TMOUT;
00414     }
00415     else {
00416         winfo_flg.waiptn = waiptn;
00417         winfo_flg.wfmode = wfmode;
00418         p_runtsk->tstat = (TS_WAITING | TS_WAIT_FLG);
00419         wobj_make_wait_tmout((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg,
00420                                                         &tmevtb, tmout);
00421         dispatch();
00422         ercd = winfo_flg.winfo.wercd;
00423         if (ercd == E_OK) {
00424             *p_flgptn = winfo_flg.flgptn;
00425         }
00426     }
00427     t_unlock_cpu();
00428 
00429   error_exit:
00430     LOG_TWAI_FLG_LEAVE(ercd, *p_flgptn);
00431     return(ercd);
00432 }
00433 
00434 #endif /* TOPPERS_twai_flg */
00435 
00436 /*
00437  *  イベントフラグの再初期化
00438  */
00439 #ifdef TOPPERS_ini_flg
00440 
00441 ER
00442 ini_flg(ID flgid)
00443 {
00444     FLGCB   *p_flgcb;
00445     bool_t  dspreq;
00446     ER      ercd;
00447     
00448     LOG_INI_FLG_ENTER(flgid);
00449     CHECK_TSKCTX_UNL();
00450     CHECK_FLGID(flgid);
00451     p_flgcb = get_flgcb(flgid);
00452 
00453     t_lock_cpu();
00454     dspreq = init_wait_queue(&(p_flgcb->wait_queue));
00455     p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
00456     if (dspreq) {
00457         dispatch();
00458     }
00459     ercd = E_OK;
00460     t_unlock_cpu();
00461 
00462   error_exit:
00463     LOG_INI_FLG_LEAVE(ercd);
00464     return(ercd);
00465 }
00466 
00467 #endif /* TOPPERS_ini_flg */
00468 
00469 /*
00470  *  イベントフラグの状態参照
00471  */
00472 #ifdef TOPPERS_ref_flg
00473 
00474 ER
00475 ref_flg(ID flgid, T_RFLG *pk_rflg)
00476 {
00477     FLGCB   *p_flgcb;
00478     ER      ercd;
00479     
00480     LOG_REF_FLG_ENTER(flgid, pk_rflg);
00481     CHECK_TSKCTX_UNL();
00482     CHECK_FLGID(flgid);
00483     p_flgcb = get_flgcb(flgid);
00484 
00485     t_lock_cpu();
00486     pk_rflg->wtskid = wait_tskid(&(p_flgcb->wait_queue));
00487     pk_rflg->flgptn = p_flgcb->flgptn;
00488     ercd = E_OK;
00489     t_unlock_cpu();
00490 
00491   error_exit:
00492     LOG_REF_FLG_LEAVE(ercd, pk_rflg);
00493     return(ercd);
00494 }
00495 
00496 #endif /* TOPPERS_ref_flg */

Copyright © 2008 by Kijineko Inc.

ホームページ制作