|
|
dataqueue.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: dataqueue.c,v 1.9 2003/06/04 01:46:16 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 #include "dataqueue.h" 00048 00049 /* 00050 * データキューIDの最大値(kernel_cfg.c) 00051 */ 00052 extern const ID tmax_dtqid; 00053 00054 /* 00055 * データキュー初期化ブロックのエリア(kernel_cfg.c) 00056 */ 00057 extern const DTQINIB dtqinib_table[]; 00058 00059 /* 00060 * データキューの数 00061 */ 00062 #define TNUM_DTQ ((UINT)(tmax_dtqid - TMIN_DTQID + 1)) 00063 00064 /* 00065 * データキュー管理ブロックのエリア(kernel_cfg.c) 00066 */ 00067 extern DTQCB dtqcb_table[]; 00068 00069 /* 00070 * データキューIDからデータキュー管理ブロックを取り出すためのマクロ 00071 */ 00072 #define INDEX_DTQ(dtqid) ((UINT)((dtqid) - TMIN_DTQID)) 00073 #define get_dtqcb(dtqid) (&(dtqcb_table[INDEX_DTQ(dtqid)])) 00074 00075 /* 00076 * データキュー待ち情報ブロックの定義 00077 * 00078 * データキューへの送信待ちとデータキューからの受信待ちで,同じ待ち情 00079 * 報ブロックを使う. 00080 */ 00081 typedef struct dataqueue_waiting_information { 00082 WINFO winfo; /* 標準の待ち情報ブロック */ 00083 WOBJCB *wobjcb; /* 待ちオブジェクトの管理ブロック */ 00084 VP_INT data; /* 送受信データ */ 00085 } WINFO_DTQ; 00086 00087 /* 00088 * データキュー機能の初期化 00089 */ 00090 #ifdef __dtqini 00091 00092 void 00093 dataqueue_initialize(void) 00094 { 00095 UINT i; 00096 DTQCB *dtqcb; 00097 00098 for (dtqcb = dtqcb_table, i = 0; i < TNUM_DTQ; dtqcb++, i++) { 00099 queue_initialize(&(dtqcb->swait_queue)); 00100 dtqcb->dtqinib = &(dtqinib_table[i]); 00101 queue_initialize(&(dtqcb->rwait_queue)); 00102 dtqcb->count = 0; 00103 dtqcb->head = 0; 00104 dtqcb->tail = 0; 00105 } 00106 } 00107 00108 #endif /* __dtqini */ 00109 00110 /* 00111 * データキュー領域にデータを格納 00112 */ 00113 #ifdef __dtqenq 00114 00115 BOOL 00116 enqueue_data(DTQCB *dtqcb, VP_INT data) 00117 { 00118 if (dtqcb->count < dtqcb->dtqinib->dtqcnt) { 00119 *((VP_INT *)(dtqcb->dtqinib->dtq) + dtqcb->tail) = data; 00120 dtqcb->count++; 00121 dtqcb->tail++; 00122 if (dtqcb->tail >= dtqcb->dtqinib->dtqcnt) { 00123 dtqcb->tail = 0; 00124 } 00125 return(TRUE); 00126 } 00127 return(FALSE); 00128 } 00129 00130 #endif /* __dtqenq */ 00131 00132 /* 00133 * データキュー領域にデータを強制格納 00134 */ 00135 #ifdef __dtqfenq 00136 00137 void 00138 force_enqueue_data(DTQCB *dtqcb, VP_INT data) 00139 { 00140 *((VP_INT *)(dtqcb->dtqinib->dtq) + dtqcb->tail) = data; 00141 dtqcb->tail++; 00142 if (dtqcb->tail >= dtqcb->dtqinib->dtqcnt) { 00143 dtqcb->tail = 0; 00144 } 00145 if (dtqcb->count < dtqcb->dtqinib->dtqcnt) { 00146 dtqcb->count++; 00147 } 00148 else { 00149 dtqcb->head = dtqcb->tail; 00150 } 00151 } 00152 00153 #endif /* __dtqfenq */ 00154 00155 /* 00156 * データキュー領域からデータを取出し 00157 */ 00158 #ifdef __dtqdeq 00159 00160 BOOL 00161 dequeue_data(DTQCB *dtqcb, VP_INT *p_data) 00162 { 00163 if (dtqcb->count > 0) { 00164 *p_data = *((VP_INT *)(dtqcb->dtqinib->dtq) + dtqcb->head); 00165 dtqcb->count--; 00166 dtqcb->head++; 00167 if (dtqcb->head >= dtqcb->dtqinib->dtqcnt) { 00168 dtqcb->head = 0; 00169 } 00170 return(TRUE); 00171 } 00172 return(FALSE); 00173 } 00174 00175 #endif /* __dtqdeq */ 00176 00177 /* 00178 * 受信待ちキューの先頭タスクへのデータ送信 00179 */ 00180 #ifdef __dtqsnd 00181 00182 TCB * 00183 send_data_rwait(DTQCB *dtqcb, VP_INT data) 00184 { 00185 TCB *tcb; 00186 00187 if (!(queue_empty(&(dtqcb->rwait_queue)))) { 00188 tcb = (TCB *) queue_delete_next(&(dtqcb->rwait_queue)); 00189 ((WINFO_DTQ *)(tcb->winfo))->data = data; 00190 return(tcb); 00191 } 00192 return(NULL); 00193 } 00194 00195 #endif /* __dtqsnd */ 00196 00197 /* 00198 * 送信待ちキューの先頭タスクからのデータ受信 00199 */ 00200 #ifdef __dtqrcv 00201 00202 TCB * 00203 receive_data_swait(DTQCB *dtqcb, VP_INT *p_data) 00204 { 00205 TCB *tcb; 00206 00207 if (!(queue_empty(&(dtqcb->swait_queue)))) { 00208 tcb = (TCB *) queue_delete_next(&(dtqcb->swait_queue)); 00209 *p_data = ((WINFO_DTQ *)(tcb->winfo))->data; 00210 return(tcb); 00211 } 00212 return(NULL); 00213 } 00214 00215 #endif /* __dtqrcv */ 00216 00217 /* 00218 * データキューへの送信 00219 */ 00220 #ifdef __snd_dtq 00221 00222 SYSCALL ER 00223 snd_dtq(ID dtqid, VP_INT data) 00224 { 00225 DTQCB *dtqcb; 00226 WINFO_DTQ winfo; 00227 TCB *tcb; 00228 ER ercd; 00229 00230 LOG_SND_DTQ_ENTER(dtqid, data); 00231 CHECK_DISPATCH(); 00232 CHECK_DTQID(dtqid); 00233 dtqcb = get_dtqcb(dtqid); 00234 00235 t_lock_cpu(); 00236 if ((tcb = send_data_rwait(dtqcb, data)) != NULL) { 00237 if (wait_complete(tcb)) { 00238 dispatch(); 00239 } 00240 ercd = E_OK; 00241 } 00242 else if (enqueue_data(dtqcb, data)) { 00243 ercd = E_OK; 00244 } 00245 else { 00246 winfo.data = data; 00247 wobj_make_wait((WOBJCB *) dtqcb, (WINFO_WOBJ *) &winfo); 00248 dispatch(); 00249 ercd = winfo.winfo.wercd; 00250 } 00251 t_unlock_cpu(); 00252 00253 exit: 00254 LOG_SND_DTQ_LEAVE(ercd); 00255 return(ercd); 00256 } 00257 00258 #endif /* __snd_dtq */ 00259 00260 /* 00261 * データキューへの送信(ポーリング) 00262 */ 00263 #ifdef __psnd_dtq 00264 00265 SYSCALL ER 00266 psnd_dtq(ID dtqid, VP_INT data) 00267 { 00268 DTQCB *dtqcb; 00269 TCB *tcb; 00270 ER ercd; 00271 00272 LOG_PSND_DTQ_ENTER(dtqid, data); 00273 CHECK_TSKCTX_UNL(); 00274 CHECK_DTQID(dtqid); 00275 dtqcb = get_dtqcb(dtqid); 00276 00277 t_lock_cpu(); 00278 if ((tcb = send_data_rwait(dtqcb, data)) != NULL) { 00279 if (wait_complete(tcb)) { 00280 dispatch(); 00281 } 00282 ercd = E_OK; 00283 } 00284 else if (enqueue_data(dtqcb, data)) { 00285 ercd = E_OK; 00286 } 00287 else { 00288 ercd = E_TMOUT; 00289 } 00290 t_unlock_cpu(); 00291 00292 exit: 00293 LOG_PSND_DTQ_LEAVE(ercd); 00294 return(ercd); 00295 } 00296 00297 #endif /* __psnd_dtq */ 00298 00299 /* 00300 * データキューへの送信(ポーリング,非タスクコンテキスト用) 00301 */ 00302 #ifdef __ipsnd_dtq 00303 00304 SYSCALL ER 00305 ipsnd_dtq(ID dtqid, VP_INT data) 00306 { 00307 DTQCB *dtqcb; 00308 TCB *tcb; 00309 ER ercd; 00310 00311 LOG_IPSND_DTQ_ENTER(dtqid, data); 00312 CHECK_INTCTX_UNL(); 00313 CHECK_DTQID(dtqid); 00314 dtqcb = get_dtqcb(dtqid); 00315 00316 i_lock_cpu(); 00317 if ((tcb = send_data_rwait(dtqcb, data)) != NULL) { 00318 if (wait_complete(tcb)) { 00319 reqflg = TRUE; 00320 } 00321 ercd = E_OK; 00322 } 00323 else if (enqueue_data(dtqcb, data)) { 00324 ercd = E_OK; 00325 } 00326 else { 00327 ercd = E_TMOUT; 00328 } 00329 i_unlock_cpu(); 00330 00331 exit: 00332 LOG_IPSND_DTQ_LEAVE(ercd); 00333 return(ercd); 00334 } 00335 00336 #endif /* __ipsnd_dtq */ 00337 00338 /* 00339 * データキューへの送信(タイムアウトあり) 00340 */ 00341 #ifdef __tsnd_dtq 00342 00343 SYSCALL ER 00344 tsnd_dtq(ID dtqid, VP_INT data, TMO tmout) 00345 { 00346 DTQCB *dtqcb; 00347 WINFO_DTQ winfo; 00348 TMEVTB tmevtb; 00349 TCB *tcb; 00350 ER ercd; 00351 00352 LOG_TSND_DTQ_ENTER(dtqid, data, tmout); 00353 CHECK_DISPATCH(); 00354 CHECK_DTQID(dtqid); 00355 CHECK_TMOUT(tmout); 00356 dtqcb = get_dtqcb(dtqid); 00357 00358 t_lock_cpu(); 00359 if ((tcb = send_data_rwait(dtqcb, data)) != NULL) { 00360 if (wait_complete(tcb)) { 00361 dispatch(); 00362 } 00363 ercd = E_OK; 00364 } 00365 else if (enqueue_data(dtqcb, data)) { 00366 ercd = E_OK; 00367 } 00368 else if (tmout == TMO_POL) { 00369 ercd = E_TMOUT; 00370 } 00371 else { 00372 winfo.data = data; 00373 wobj_make_wait_tmout((WOBJCB *) dtqcb, (WINFO_WOBJ *) &winfo, 00374 &tmevtb, tmout); 00375 dispatch(); 00376 ercd = winfo.winfo.wercd; 00377 } 00378 t_unlock_cpu(); 00379 00380 exit: 00381 LOG_TSND_DTQ_LEAVE(ercd); 00382 return(ercd); 00383 } 00384 00385 #endif /* __tsnd_dtq */ 00386 00387 /* 00388 * データキューへの強制送信 00389 */ 00390 #ifdef __fsnd_dtq 00391 00392 SYSCALL ER 00393 fsnd_dtq(ID dtqid, VP_INT data) 00394 { 00395 DTQCB *dtqcb; 00396 TCB *tcb; 00397 ER ercd; 00398 00399 LOG_FSND_DTQ_ENTER(dtqid, data); 00400 CHECK_TSKCTX_UNL(); 00401 CHECK_DTQID(dtqid); 00402 dtqcb = get_dtqcb(dtqid); 00403 CHECK_ILUSE(dtqcb->dtqinib->dtqcnt > 0); 00404 00405 t_lock_cpu(); 00406 if ((tcb = send_data_rwait(dtqcb, data)) != NULL) { 00407 if (wait_complete(tcb)) { 00408 dispatch(); 00409 } 00410 } 00411 else { 00412 force_enqueue_data(dtqcb, data); 00413 } 00414 ercd = E_OK; 00415 t_unlock_cpu(); 00416 00417 exit: 00418 LOG_FSND_DTQ_LEAVE(ercd); 00419 return(ercd); 00420 } 00421 00422 #endif /* __fsnd_dtq */ 00423 00424 /* 00425 * データキューへの強制送信(非タスクコンテキスト用) 00426 */ 00427 #ifdef __ifsnd_dtq 00428 00429 SYSCALL ER 00430 ifsnd_dtq(ID dtqid, VP_INT data) 00431 { 00432 DTQCB *dtqcb; 00433 TCB *tcb; 00434 ER ercd; 00435 00436 LOG_IFSND_DTQ_ENTER(dtqid, data); 00437 CHECK_INTCTX_UNL(); 00438 CHECK_DTQID(dtqid); 00439 dtqcb = get_dtqcb(dtqid); 00440 CHECK_ILUSE(dtqcb->dtqinib->dtqcnt > 0); 00441 00442 i_lock_cpu(); 00443 if ((tcb = send_data_rwait(dtqcb, data)) != NULL) { 00444 if (wait_complete(tcb)) { 00445 reqflg = TRUE; 00446 } 00447 } 00448 else { 00449 force_enqueue_data(dtqcb, data); 00450 } 00451 ercd = E_OK; 00452 i_unlock_cpu(); 00453 00454 exit: 00455 LOG_IFSND_DTQ_LEAVE(ercd); 00456 return(ercd); 00457 } 00458 00459 #endif /* __ifsnd_dtq */ 00460 00461 /* 00462 * データキューからの受信 00463 */ 00464 #ifdef __rcv_dtq 00465 00466 SYSCALL ER 00467 rcv_dtq(ID dtqid, VP_INT *p_data) 00468 { 00469 DTQCB *dtqcb; 00470 WINFO_DTQ winfo; 00471 TCB *tcb; 00472 VP_INT data; 00473 ER ercd; 00474 00475 LOG_RCV_DTQ_ENTER(dtqid, p_data); 00476 CHECK_DISPATCH(); 00477 CHECK_DTQID(dtqid); 00478 dtqcb = get_dtqcb(dtqid); 00479 00480 t_lock_cpu(); 00481 if (dequeue_data(dtqcb, p_data)) { 00482 if ((tcb = receive_data_swait(dtqcb, &data)) != NULL) { 00483 enqueue_data(dtqcb, data); 00484 if (wait_complete(tcb)) { 00485 dispatch(); 00486 } 00487 } 00488 ercd = E_OK; 00489 } 00490 else if ((tcb = receive_data_swait(dtqcb, p_data)) != NULL) { 00491 if (wait_complete(tcb)) { 00492 dispatch(); 00493 } 00494 ercd = E_OK; 00495 } 00496 else { 00497 runtsk->tstat = (TS_WAITING | TS_WAIT_WOBJ); 00498 make_wait(&(winfo.winfo)); 00499 queue_insert_prev(&(dtqcb->rwait_queue), 00500 &(runtsk->task_queue)); 00501 winfo.wobjcb = (WOBJCB *) dtqcb; 00502 LOG_TSKSTAT(runtsk); 00503 dispatch(); 00504 ercd = winfo.winfo.wercd; 00505 if (ercd == E_OK) { 00506 *p_data = winfo.data; 00507 } 00508 } 00509 t_unlock_cpu(); 00510 00511 exit: 00512 LOG_RCV_DTQ_LEAVE(ercd, *p_data); 00513 return(ercd); 00514 } 00515 00516 #endif /* __rcv_dtq */ 00517 00518 /* 00519 * データキューからの受信(ポーリング) 00520 */ 00521 #ifdef __prcv_dtq 00522 00523 SYSCALL ER 00524 prcv_dtq(ID dtqid, VP_INT *p_data) 00525 { 00526 DTQCB *dtqcb; 00527 TCB *tcb; 00528 VP_INT data; 00529 ER ercd; 00530 00531 LOG_PRCV_DTQ_ENTER(dtqid, p_data); 00532 CHECK_TSKCTX_UNL(); 00533 CHECK_DTQID(dtqid); 00534 dtqcb = get_dtqcb(dtqid); 00535 00536 t_lock_cpu(); 00537 if (dequeue_data(dtqcb, p_data)) { 00538 if ((tcb = receive_data_swait(dtqcb, &data)) != NULL) { 00539 enqueue_data(dtqcb, data); 00540 if (wait_complete(tcb)) { 00541 dispatch(); 00542 } 00543 } 00544 ercd = E_OK; 00545 } 00546 else if ((tcb = receive_data_swait(dtqcb, p_data)) != NULL) { 00547 if (wait_complete(tcb)) { 00548 dispatch(); 00549 } 00550 ercd = E_OK; 00551 } 00552 else { 00553 ercd = E_TMOUT; 00554 } 00555 t_unlock_cpu(); 00556 00557 exit: 00558 LOG_PRCV_DTQ_LEAVE(ercd, *p_data); 00559 return(ercd); 00560 } 00561 00562 #endif /* __prcv_dtq */ 00563 00564 /* 00565 * データキューからの受信(タイムアウトあり) 00566 */ 00567 #ifdef __trcv_dtq 00568 00569 SYSCALL ER 00570 trcv_dtq(ID dtqid, VP_INT *p_data, TMO tmout) 00571 { 00572 DTQCB *dtqcb; 00573 WINFO_DTQ winfo; 00574 TMEVTB tmevtb; 00575 TCB *tcb; 00576 VP_INT data; 00577 ER ercd; 00578 00579 LOG_TRCV_DTQ_ENTER(dtqid, p_data, tmout); 00580 CHECK_DISPATCH(); 00581 CHECK_DTQID(dtqid); 00582 CHECK_TMOUT(tmout); 00583 dtqcb = get_dtqcb(dtqid); 00584 00585 t_lock_cpu(); 00586 if (dequeue_data(dtqcb, p_data)) { 00587 if ((tcb = receive_data_swait(dtqcb, &data)) != NULL) { 00588 enqueue_data(dtqcb, data); 00589 if (wait_complete(tcb)) { 00590 dispatch(); 00591 } 00592 } 00593 ercd = E_OK; 00594 } 00595 else if ((tcb = receive_data_swait(dtqcb, p_data)) != NULL) { 00596 if (wait_complete(tcb)) { 00597 dispatch(); 00598 } 00599 ercd = E_OK; 00600 } 00601 else if (tmout == TMO_POL) { 00602 ercd = E_TMOUT; 00603 } 00604 else { 00605 runtsk->tstat = (TS_WAITING | TS_WAIT_WOBJ); 00606 make_wait_tmout(&(winfo.winfo), &tmevtb, tmout); 00607 queue_insert_prev(&(dtqcb->rwait_queue), 00608 &(runtsk->task_queue)); 00609 winfo.wobjcb = (WOBJCB *) dtqcb; 00610 LOG_TSKSTAT(runtsk); 00611 dispatch(); 00612 ercd = winfo.winfo.wercd; 00613 if (ercd == E_OK) { 00614 *p_data = winfo.data; 00615 } 00616 } 00617 t_unlock_cpu(); 00618 00619 exit: 00620 LOG_TRCV_DTQ_LEAVE(ercd, *p_data); 00621 return(ercd); 00622 } 00623 00624 #endif /* __trcv_dtq */ 00625 Copyright © 2006 by TAKAGI Nobuhisa. Copyright © 2006 by Kijineko Inc.. このページは Mon Dec 18 17:18:39 2006 に Doxygen によって生成されました。 データ入力からプログラム開発まで!様々なスキルを持ったメンバーが登録しています【@SOHO】 |