|
|
mailbox.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: mailbox.c,v 1.3 2006/03/14 04:37:54 honda Exp $ 00039 */ 00040 00045 #include "fdmp_kernel.h" 00046 #include "check.h" 00047 #include "task.h" 00048 #include "wait.h" 00049 #include "mailbox.h" 00050 00054 extern const ID tmax_mbxid; 00055 00059 extern const MBXINIB mbxinib_table[]; 00060 00064 extern MBXCB mbxcb_table[]; 00065 00069 #define TNUM_MBX ((UINT)(tmax_mbxid - TMIN_ID + 1)) 00070 00074 #define INDEX_MBX(mbxid) ((UINT)((mbxid) - TMIN_ID)) 00075 #define get_mbxcb(ccb, mbxid) (&(((MBXCB *)(ccb->mbx.cb_table))[INDEX_MBX(mbxid)])) 00076 00080 typedef struct mailbox_waiting_information { 00081 WINFO winfo; /* 標準の待ち情報ブロック */ 00082 WOBJCB *wobjcb; /* 待ちオブジェクトの管理ブロック */ 00083 CCB *ccb; /* オブジェクトが所属するクラスID */ 00084 T_MSG *pk_msg; /* 受信したメッセージ */ 00085 } WINFO_MBX; 00086 00090 #ifdef __mbxini 00091 00092 void 00093 mailbox_initialize() 00094 { 00095 UINT i; 00096 MBXCB *mbxcb; 00097 00098 for (mbxcb = mbxcb_table, i = 0; i < TNUM_MBX; mbxcb++, i++) { 00099 queue_initialize(&(mbxcb->wait_queue)); 00100 mbxcb->mbxinib = &(mbxinib_table[i]); 00101 mbxcb->head = NULL; 00102 } 00103 00104 my_local_exccb->mbx.cb_table = &mbxcb_table[0]; 00105 my_local_exccb->mbx.max_id = tmax_mbxid; 00106 } 00107 00108 #endif /* __mbxini */ 00109 00113 #define MSGPRI(pk_msg) (((T_MSG_PRI *) pk_msg)->msgpri) 00114 00118 Inline void 00119 enqueue_msg_pri(T_MSG **p_prevmsg_next, T_MSG *pk_msg) 00120 { 00121 T_MSG *pk_nextmsg; 00122 00123 while ((pk_nextmsg = *p_prevmsg_next) != NULL) { 00124 if (MSGPRI(pk_nextmsg) > MSGPRI(pk_msg)) { 00125 break; 00126 } 00127 p_prevmsg_next = &(pk_nextmsg->next); 00128 } 00129 pk_msg->next = pk_nextmsg; 00130 *p_prevmsg_next = pk_msg; 00131 } 00132 00133 00137 #ifdef __snd_mbx 00138 00139 SYSCALL ER 00140 snd_mbx(ID mbxid, T_MSG *pk_msg) 00141 { 00142 MBXCB *mbxcb; 00143 TCB *tcb; 00144 ER ercd; 00145 CCB *ccb, *tccb; 00146 BOOL dspreq = FALSE; 00147 00148 LOG_SND_MBX_ENTER(mbxid, pk_msg); 00149 CHECK_TSKCTX_UNL(); 00150 ccb = T_CHECK_CLSID_CCB(mbxid); 00151 mbxid = remove_clsid(mbxid); 00152 CHECK_MBXID(ccb, mbxid); 00153 mbxcb = get_mbxcb(ccb, mbxid); 00154 CHECK_PAR((mbxcb->mbxinib->mbxatr & TA_MPRI) == 0 00155 || (TMIN_MPRI <= MSGPRI(pk_msg) 00156 && MSGPRI(pk_msg) <= mbxcb->mbxinib->maxmpri)); 00157 00158 retry: 00159 T_ACQUIRE_LOCK(ccb->obj_lock); 00160 if (!(queue_empty(&(mbxcb->wait_queue)))) { 00161 tcb = (TCB *) (mbxcb->wait_queue.next); 00162 tccb = get_ccb(tcb->clsid); 00163 ((WINFO_MBX *)(tcb->winfo))->pk_msg = pk_msg; 00164 /* 00165 * T_ACQUIRE_NESTED_LOCK()は,T_ACQUIRE_LOCK()との間をリトライで 00166 * 繰り返し実行するため,この間非破壊コードでなければならない. 00167 */ 00168 T_ACQUIRE_NESTED_LOCK(tccb->tsk_lock, ccb->obj_lock); 00169 /* 待ちキューから削除する */ 00170 queue_delete_next(&(mbxcb->wait_queue)); 00171 if (wait_complete(tccb, tcb)) { 00172 dspreq = dispatch_request(tccb->prcid); 00173 } 00174 T_RELEASE_NESTED_LOCK(tccb->tsk_lock, ccb->obj_lock); 00175 ercd = E_OK; 00176 } 00177 else if ((mbxcb->mbxinib->mbxatr & TA_MPRI) != 0) { 00178 enqueue_msg_pri(&(mbxcb->head), pk_msg); 00179 ercd = E_OK; 00180 } 00181 else { 00182 pk_msg->next = NULL; 00183 if (mbxcb->head != NULL) { 00184 mbxcb->last->next = pk_msg; 00185 } 00186 else { 00187 mbxcb->head = pk_msg; 00188 } 00189 mbxcb->last = pk_msg; 00190 ercd = E_OK; 00191 } 00192 T_RELEASE_LOCK_AND_DISPATCH(ccb->obj_lock, dspreq); 00193 00194 exit: 00195 LOG_SND_MBX_LEAVE(ercd); 00196 return(ercd); 00197 } 00198 00199 #endif /* __snd_mbx */ 00200 00204 #ifdef __rcv_mbx 00205 00206 SYSCALL ER 00207 rcv_mbx(ID mbxid, T_MSG **ppk_msg) 00208 { 00209 MBXCB *mbxcb; 00210 WINFO_MBX winfo; 00211 ER ercd; 00212 CCB *ccb; 00213 00214 LOG_RCV_MBX_ENTER(mbxid, ppk_msg); 00215 CHECK_DISPATCH(); 00216 ccb = T_CHECK_CLSID_CCB(mbxid); 00217 mbxid = remove_clsid(mbxid); 00218 CHECK_MBXID(ccb, mbxid); 00219 mbxcb = get_mbxcb(ccb, mbxid); 00220 00221 retry: 00222 T_ACQUIRE_LOCK(ccb->obj_lock); 00223 if (mbxcb->head != NULL) { 00224 *ppk_msg = mbxcb->head; 00225 mbxcb->head = (*ppk_msg)->next; 00226 RELEASE_LOCK(ccb->obj_lock); 00227 ercd = E_OK; 00228 } 00229 else { 00230 T_ACQUIRE_NESTED_LOCK_AND_CHECK_RUNNABLE(ccb->obj_lock); 00231 wobj_make_wait(ccb, (WOBJCB *) mbxcb, (WINFO_WOBJ *) &winfo); 00232 T_RELEASE_NESTED_LOCK(runccb->tsk_lock, ccb->obj_lock); 00233 RELEASE_LOCK(ccb->obj_lock); 00234 dispatch(); 00235 ercd = winfo.winfo.wercd; 00236 if (ercd == E_OK) { 00237 *ppk_msg = winfo.pk_msg; 00238 } 00239 } 00240 t_unlock_cpu(); 00241 00242 exit: 00243 LOG_RCV_MBX_LEAVE(ercd, *ppk_msg); 00244 return(ercd); 00245 } 00246 00247 #endif /* __rcv_mbx */ 00248 00252 #ifdef __prcv_mbx 00253 00254 SYSCALL ER 00255 prcv_mbx(ID mbxid, T_MSG **ppk_msg) 00256 { 00257 MBXCB *mbxcb; 00258 ER ercd; 00259 CCB *ccb; 00260 00261 LOG_PRCV_MBX_ENTER(mbxid, ppk_msg); 00262 CHECK_TSKCTX_UNL(); 00263 ccb = T_CHECK_CLSID_CCB(mbxid); 00264 mbxid = remove_clsid(mbxid); 00265 CHECK_MBXID(ccb, mbxid); 00266 mbxcb = get_mbxcb(ccb, mbxid); 00267 00268 retry: 00269 T_ACQUIRE_LOCK(ccb->obj_lock); 00270 if (mbxcb->head != NULL) { 00271 *ppk_msg = mbxcb->head; 00272 mbxcb->head = (*ppk_msg)->next; 00273 ercd = E_OK; 00274 } 00275 else { 00276 ercd = E_TMOUT; 00277 } 00278 T_RELEASE_LOCK(ccb->obj_lock); 00279 00280 exit: 00281 LOG_PRCV_MBX_LEAVE(ercd, *ppk_msg); 00282 return(ercd); 00283 } 00284 00285 #endif /* __prcv_mbx */ 00286 00290 #ifdef __trcv_mbx 00291 00292 SYSCALL ER 00293 trcv_mbx(ID mbxid, T_MSG **ppk_msg, TMO tmout) 00294 { 00295 MBXCB *mbxcb; 00296 WINFO_MBX winfo; 00297 TMEVTB tmevtb; 00298 ER ercd; 00299 CCB *ccb; 00300 00301 LOG_TRCV_MBX_ENTER(mbxid, ppk_msg, tmout); 00302 CHECK_DISPATCH(); 00303 ccb = T_CHECK_CLSID_CCB(mbxid); 00304 mbxid = remove_clsid(mbxid); 00305 CHECK_MBXID(ccb, mbxid); 00306 CHECK_TMOUT(tmout); 00307 mbxcb = get_mbxcb(ccb, mbxid); 00308 00309 retry: 00310 T_ACQUIRE_LOCK(ccb->obj_lock); 00311 if (mbxcb->head != NULL) { 00312 *ppk_msg = mbxcb->head; 00313 mbxcb->head = (*ppk_msg)->next; 00314 RELEASE_LOCK(ccb->obj_lock); 00315 ercd = E_OK; 00316 } 00317 else if (tmout == TMO_POL) { 00318 RELEASE_LOCK(ccb->obj_lock); 00319 ercd = E_TMOUT; 00320 } 00321 else { 00322 T_ACQUIRE_NESTED_LOCK_AND_CHECK_RUNNABLE(ccb->obj_lock); 00323 wobj_make_wait_tmout(ccb, (WOBJCB *) mbxcb, (WINFO_WOBJ *) &winfo, 00324 &tmevtb, tmout); 00325 T_RELEASE_NESTED_LOCK(runccb->tsk_lock, ccb->obj_lock); 00326 RELEASE_LOCK(ccb->obj_lock); 00327 dispatch(); 00328 ercd = winfo.winfo.wercd; 00329 if (ercd == E_OK) { 00330 *ppk_msg = winfo.pk_msg; 00331 } 00332 } 00333 t_unlock_cpu(); 00334 00335 exit: 00336 LOG_TRCV_MBX_LEAVE(ercd, *ppk_msg); 00337 return(ercd); 00338 } 00339 00340 #endif /* __trcv_mbx */ Copyright © 2006 by TAKAGI Nobuhisa. このページは Mon Apr 3 23:49:12 2006 に Doxygen によって生成されました。 |