|
|
eventflag.c説明を見る。00001 /* 00002 * TOPPERS/FDMP Kernel 00003 * Toyohashi Open Platform for Embedded Real-Time Systems/ 00004 * Function Distributed Multiprocessor Kernel 00005 * 00006 * Copyright (C) 2000-2004 by Embedded and Real-Time Systems Laboratory 00007 * Toyohashi Univ. of Technology, JAPAN 00008 * Copyright (C) 2005-2006 by Embedded and Real-Time Systems Laboratory 00009 * Graduate School of Information Science, Nagoya Univ., JAPAN 00010 * 00011 * 上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation 00012 * によって公表されている GNU General Public License の Version 2 に記 00013 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア 00014 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下, 00015 * 利用と呼ぶ)することを無償で許諾する. 00016 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作 00017 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー 00018 * スコード中に含まれていること. 00019 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使 00020 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用 00021 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記 00022 * の無保証規定を掲載すること. 00023 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使 00024 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ 00025 * と. 00026 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著 00027 * 作権表示,この利用条件および下記の無保証規定を掲載すること. 00028 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに 00029 * 報告すること. 00030 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損 00031 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること. 00032 * 00033 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お 00034 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も 00035 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直 00036 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない. 00037 * 00038 * @(#) $Id: eventflag.c,v 1.3 2006/03/14 04:37:54 honda Exp $ 00039 */ 00040 00046 #include "fdmp_kernel.h" 00047 #include "check.h" 00048 #include "task.h" 00049 #include "wait.h" 00050 #include "eventflag.h" 00051 00055 extern const ID tmax_flgid; 00056 00060 extern const FLGINIB flginib_table[]; 00061 00065 extern FLGCB flgcb_table[]; 00066 00070 #define TNUM_FLG ((UINT)(tmax_flgid - TMIN_ID + 1)) 00071 00072 /* 00073 * イベントフラグIDからイベントフラグ管理ブロックを取り出すためのマクロ 00074 */ 00075 #define INDEX_FLG(flgid) ((UINT)((flgid) - TMIN_ID)) 00076 #define get_flgcb(ccb, flgid) (&(((FLGCB *)(ccb->flg.cb_table))[INDEX_FLG(flgid)])) 00077 00084 typedef struct eventflag_waiting_information { 00085 WINFO winfo; /* 標準の待ち情報ブロック */ 00086 WOBJCB *wobjcb; /* 待ちオブジェクトの管理ブロック */ 00087 CCB *ccb; /* オブジェクトが所属するCCB */ 00088 FLGPTN waiptn; /* 待ちパターン */ 00089 MODE wfmode; /* 待ちモード */ 00090 FLGPTN flgptn; /* 待ち解除時のパターン */ 00091 } WINFO_FLG; 00092 00096 #ifdef __flgini 00097 00098 void 00099 eventflag_initialize(void) 00100 { 00101 UINT i; 00102 FLGCB *flgcb; 00103 00104 for (flgcb = flgcb_table, i = 0; i < TNUM_FLG; flgcb++, i++) { 00105 queue_initialize(&(flgcb->wait_queue)); 00106 flgcb->flginib = &(flginib_table[i]); 00107 flgcb->flgptn = flgcb->flginib->iflgptn; 00108 } 00109 00110 my_local_exccb->flg.cb_table = &flgcb_table[0]; 00111 my_local_exccb->flg.max_id = tmax_flgid; 00112 } 00113 00114 #endif /* __flgini */ 00115 00119 #ifdef __flgcnd 00120 00121 BOOL 00122 eventflag_cond(FLGCB *flgcb, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn) 00123 { 00124 if ((wfmode & TWF_ORW) != 0 ? (flgcb->flgptn & waiptn) != 0 00125 : (flgcb->flgptn & waiptn) == waiptn) { 00126 *p_flgptn = flgcb->flgptn; 00127 if ((flgcb->flginib->flgatr & TA_CLR) != 0) { 00128 flgcb->flgptn = 0; 00129 } 00130 return(TRUE); 00131 } 00132 return(FALSE); 00133 } 00134 00135 #endif /* __flgcnd */ 00136 00140 #ifdef __set_flg 00141 00142 SYSCALL ER 00143 set_flg(ID flgid, FLGPTN setptn) 00144 { 00145 FLGCB *flgcb; 00146 TCB *tcb; 00147 WINFO_FLG *winfo; 00148 ER ercd; 00149 CCB *ccb, *tccb; 00150 BOOL dspreq = FALSE; 00151 00152 LOG_SET_FLG_ENTER(flgid, setptn); 00153 CHECK_TSKCTX_UNL(); 00154 ccb = T_CHECK_CLSID_CCB(flgid); 00155 flgid = remove_clsid(flgid); 00156 CHECK_FLGID(ccb, flgid); 00157 flgcb = get_flgcb(ccb, flgid); 00158 00159 retry: 00160 T_ACQUIRE_LOCK(ccb->obj_lock); 00161 if (!(queue_empty(&(flgcb->wait_queue)))) { 00162 tcb = (TCB *)(flgcb->wait_queue.next); 00163 tccb = get_ccb(tcb->clsid); 00164 winfo = (WINFO_FLG *)(tcb->winfo); 00165 /* 00166 * eventflag_cond() がTRUEの場合のみロックを取得すればよいが, 00167 * eventflag_cond() が破壊的コードであるため(flgcb->flgptn = 0) 00168 * 実行前にロックを取得する. 00169 */ 00170 T_ACQUIRE_NESTED_LOCK(tccb->tsk_lock, ccb->obj_lock); 00171 flgcb->flgptn |= setptn; 00172 if (eventflag_cond(flgcb, winfo->waiptn, 00173 winfo->wfmode, &(winfo->flgptn))) { 00174 queue_delete(&(tcb->task_queue)); 00175 if (wait_complete(tccb, tcb)) { 00176 dspreq = dispatch_request(tccb->prcid); 00177 } 00178 00179 } 00180 T_RELEASE_NESTED_LOCK(tccb->tsk_lock, ccb->obj_lock); 00181 } 00182 else { 00183 flgcb->flgptn |= setptn; 00184 } 00185 T_RELEASE_LOCK_AND_DISPATCH(ccb->obj_lock, dspreq); 00186 ercd = E_OK; 00187 00188 exit: 00189 LOG_SET_FLG_LEAVE(ercd); 00190 return(ercd); 00191 } 00192 00193 #endif /* __set_flg */ 00194 00198 #ifdef __iset_flg 00199 00200 SYSCALL ER 00201 iset_flg(ID flgid, FLGPTN setptn) 00202 { 00203 FLGCB *flgcb; 00204 TCB *tcb; 00205 WINFO_FLG *winfo; 00206 ER ercd; 00207 CCB *ccb, *tccb; 00208 00209 LOG_ISET_FLG_ENTER(flgid, setptn); 00210 CHECK_INTCTX_UNL(); 00211 ccb = I_CHECK_CLSID_CCB(flgid); 00212 flgid = remove_clsid(flgid); 00213 CHECK_FLGID(ccb, flgid); 00214 flgcb = get_flgcb(ccb, flgid); 00215 00216 retry: 00217 I_ACQUIRE_LOCK(ccb->obj_lock); 00218 if (!(queue_empty(&(flgcb->wait_queue)))) { 00219 tcb = (TCB *)(flgcb->wait_queue.next); 00220 tccb = get_ccb(tcb->clsid); 00221 winfo = (WINFO_FLG *)(tcb->winfo); 00222 /* 00223 * eventflag_cond() がTRUEの場合のみロックを取得すればよいが, 00224 * eventflag_cond() が破壊的コードであるため(flgcb->flgptn = 0) 00225 * 実行前にロックを取得する. 00226 */ 00227 I_ACQUIRE_NESTED_LOCK(tccb->tsk_lock, ccb->obj_lock); 00228 flgcb->flgptn |= setptn; 00229 if (eventflag_cond(flgcb, winfo->waiptn, 00230 winfo->wfmode, &(winfo->flgptn))) { 00231 queue_delete(&(tcb->task_queue)); 00232 if (wait_complete(ccb, tcb)) { 00233 if (dispatch_request(tccb->prcid)) { 00234 reqflg = TRUE; 00235 } 00236 } 00237 } 00238 I_RELEASE_NESTED_LOCK(tccb->tsk_lock, ccb->obj_lock); 00239 } 00240 else { 00241 flgcb->flgptn |= setptn; 00242 } 00243 I_RELEASE_LOCK(ccb->obj_lock); 00244 ercd = E_OK; 00245 00246 exit: 00247 LOG_ISET_FLG_LEAVE(ercd); 00248 return(ercd); 00249 } 00250 00251 #endif /* __iset_flg */ 00252 00256 #ifdef __clr_flg 00257 00258 SYSCALL ER 00259 clr_flg(ID flgid, FLGPTN clrptn) 00260 { 00261 FLGCB *flgcb; 00262 ER ercd; 00263 CCB *ccb; 00264 00265 LOG_CLR_FLG_ENTER(flgid, clrptn); 00266 CHECK_TSKCTX_UNL(); 00267 ccb = T_CHECK_CLSID_CCB(flgid); 00268 flgid = remove_clsid(flgid); 00269 CHECK_FLGID(ccb, flgid); 00270 flgcb = get_flgcb(ccb, flgid); 00271 00272 retry: 00273 T_ACQUIRE_LOCK(ccb->obj_lock); 00274 flgcb->flgptn &= clrptn; 00275 T_RELEASE_LOCK(ccb->obj_lock); 00276 ercd = E_OK; 00277 00278 exit: 00279 LOG_CLR_FLG_LEAVE(ercd); 00280 return(ercd); 00281 } 00282 00283 #endif /* __clr_flg */ 00284 00288 #ifdef __wai_flg 00289 00290 SYSCALL ER 00291 wai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn) 00292 { 00293 FLGCB *flgcb; 00294 WINFO_FLG winfo; 00295 ER ercd; 00296 CCB *ccb; 00297 00298 LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn); 00299 CHECK_DISPATCH(); 00300 ccb = T_CHECK_CLSID_CCB(flgid); 00301 flgid = remove_clsid(flgid); 00302 CHECK_FLGID(ccb, flgid); 00303 CHECK_PAR(waiptn != 0); 00304 CHECK_PAR((wfmode & ~TWF_ORW) == 0); 00305 flgcb = get_flgcb(ccb, flgid); 00306 00307 retry: 00308 T_ACQUIRE_LOCK(ccb->obj_lock); 00309 if (!(queue_empty(&(flgcb->wait_queue)))) { 00310 RELEASE_LOCK(ccb->obj_lock); 00311 ercd = E_ILUSE; 00312 } 00313 else if (eventflag_cond(flgcb, waiptn, wfmode, p_flgptn)) { 00314 RELEASE_LOCK(ccb->obj_lock); 00315 ercd = E_OK; 00316 } 00317 else { 00318 winfo.waiptn = waiptn; 00319 winfo.wfmode = wfmode; 00320 T_ACQUIRE_NESTED_LOCK_AND_CHECK_RUNNABLE(ccb->obj_lock); 00321 wobj_make_wait(ccb, (WOBJCB *) flgcb, (WINFO_WOBJ *) &winfo); 00322 T_RELEASE_NESTED_LOCK(runccb->tsk_lock, ccb->obj_lock); 00323 RELEASE_LOCK(ccb->obj_lock); 00324 dispatch(); 00325 ercd = winfo.winfo.wercd; 00326 if (ercd == E_OK) { 00327 *p_flgptn = winfo.flgptn; 00328 } 00329 } 00330 t_unlock_cpu(); 00331 00332 exit: 00333 LOG_WAI_FLG_LEAVE(ercd, *p_flgptn); 00334 return(ercd); 00335 } 00336 00337 #endif /* __wai_flg */ 00338 00342 #ifdef __pol_flg 00343 00344 SYSCALL ER 00345 pol_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn) 00346 { 00347 FLGCB *flgcb; 00348 ER ercd; 00349 CCB *ccb; 00350 00351 LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn); 00352 CHECK_TSKCTX_UNL(); 00353 ccb = T_CHECK_CLSID_CCB(flgid); 00354 flgid = remove_clsid(flgid); 00355 CHECK_FLGID(ccb, flgid); 00356 CHECK_PAR(waiptn != 0); 00357 CHECK_PAR((wfmode & ~TWF_ORW) == 0); 00358 flgcb = get_flgcb(ccb, flgid); 00359 00360 retry: 00361 T_ACQUIRE_LOCK(ccb->obj_lock); 00362 if (!(queue_empty(&(flgcb->wait_queue)))) { 00363 ercd = E_ILUSE; 00364 } 00365 else if (eventflag_cond(flgcb, waiptn, wfmode, p_flgptn)) { 00366 ercd = E_OK; 00367 } 00368 else { 00369 ercd = E_TMOUT; 00370 } 00371 T_RELEASE_LOCK(ccb->obj_lock); 00372 00373 exit: 00374 LOG_POL_FLG_LEAVE(ercd, *p_flgptn); 00375 return(ercd); 00376 } 00377 00378 #endif /* __pol_flg */ 00379 00383 #ifdef __twai_flg 00384 00385 SYSCALL ER 00386 twai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn, TMO tmout) 00387 { 00388 FLGCB *flgcb; 00389 WINFO_FLG winfo; 00390 TMEVTB tmevtb; 00391 ER ercd = E_OK; 00392 CCB *ccb; 00393 00394 LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout); 00395 CHECK_DISPATCH(); 00396 ccb = T_CHECK_CLSID_CCB(flgid); 00397 flgid = remove_clsid(flgid); 00398 CHECK_FLGID(ccb, flgid); 00399 CHECK_PAR(waiptn != 0); 00400 CHECK_PAR((wfmode & ~TWF_ORW) == 0); 00401 CHECK_TMOUT(tmout); 00402 flgcb = get_flgcb(ccb, flgid); 00403 00404 retry: 00405 T_ACQUIRE_LOCK(ccb->obj_lock); 00406 if (!(queue_empty(&(flgcb->wait_queue)))) { 00407 RELEASE_LOCK(ccb->obj_lock); 00408 ercd = E_ILUSE; 00409 } 00410 else if (eventflag_cond(flgcb, waiptn, wfmode, p_flgptn)) { 00411 RELEASE_LOCK(ccb->obj_lock); 00412 ercd = E_OK; 00413 } 00414 else if (tmout == TMO_POL) { 00415 RELEASE_LOCK(ccb->obj_lock); 00416 ercd = E_TMOUT; 00417 } 00418 else { 00419 winfo.waiptn = waiptn; 00420 winfo.wfmode = wfmode; 00421 T_ACQUIRE_NESTED_LOCK_AND_CHECK_RUNNABLE(ccb->obj_lock); 00422 wobj_make_wait_tmout(ccb, (WOBJCB *) flgcb, (WINFO_WOBJ *) &winfo, 00423 &tmevtb, tmout); 00424 T_RELEASE_NESTED_LOCK(runccb->tsk_lock, ccb->obj_lock); 00425 RELEASE_LOCK(ccb->obj_lock); 00426 dispatch(); 00427 ercd = winfo.winfo.wercd; 00428 if (ercd == E_OK) { 00429 *p_flgptn = winfo.flgptn; 00430 } 00431 } 00432 t_unlock_cpu(); 00433 00434 exit: 00435 LOG_TWAI_FLG_LEAVE(ercd, *p_flgptn); 00436 return(ercd); 00437 } 00438 00439 #endif /* __twai_flg */ Copyright © 2006 by TAKAGI Nobuhisa. このページは Mon Apr 3 23:49:12 2006 に Doxygen によって生成されました。 |