3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Just Standard Profile Kernel
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
9 * 上記著作権者は,以下の (1)〜(4) の条件か,Free Software Foundation
10 * によって公表されている GNU General Public License の Version 2 に記
11 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
12 * を改変したものを含む.以下同じ)を使用・複製・改変・再配布(以下,
14 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
24 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
26 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
28 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
31 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
32 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
33 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
34 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
36 * @(#) $Id: dataqueue.c,v 1.1 2009/01/31 05:27:37 suikan Exp $
43 #include "jsp_kernel.h"
47 #include "dataqueue.h"
50 * データキューIDの最大値(kernel_cfg.c)
52 extern const ID tmax_dtqid;
55 * データキュー初期化ブロックのエリア(kernel_cfg.c)
57 extern const DTQINIB dtqinib_table[];
62 #define TNUM_DTQ ((UINT)(tmax_dtqid - TMIN_DTQID + 1))
65 * データキュー管理ブロックのエリア(kernel_cfg.c)
67 extern DTQCB dtqcb_table[];
70 * データキューIDからデータキュー管理ブロックを取り出すためのマクロ
72 #define INDEX_DTQ(dtqid) ((UINT)((dtqid) - TMIN_DTQID))
73 #define get_dtqcb(dtqid) (&(dtqcb_table[INDEX_DTQ(dtqid)]))
78 * データキューへの送信待ちとデータキューからの受信待ちで,同じ待ち情
81 typedef struct dataqueue_waiting_information {
82 WINFO winfo; /* 標準の待ち情報ブロック */
83 WOBJCB *wobjcb; /* 待ちオブジェクトの管理ブロック */
84 VP_INT data; /* 送受信データ */
93 dataqueue_initialize(void)
98 for (dtqcb = dtqcb_table, i = 0; i < TNUM_DTQ; dtqcb++, i++) {
99 queue_initialize(&(dtqcb->swait_queue));
100 dtqcb->dtqinib = &(dtqinib_table[i]);
101 queue_initialize(&(dtqcb->rwait_queue));
108 #endif /* __dtqini */
116 enqueue_data(DTQCB *dtqcb, VP_INT data)
118 if (dtqcb->count < dtqcb->dtqinib->dtqcnt) {
119 *((VP_INT *)(dtqcb->dtqinib->dtq) + dtqcb->tail) = data;
122 if (dtqcb->tail >= dtqcb->dtqinib->dtqcnt) {
130 #endif /* __dtqenq */
138 force_enqueue_data(DTQCB *dtqcb, VP_INT data)
140 *((VP_INT *)(dtqcb->dtqinib->dtq) + dtqcb->tail) = data;
142 if (dtqcb->tail >= dtqcb->dtqinib->dtqcnt) {
145 if (dtqcb->count < dtqcb->dtqinib->dtqcnt) {
149 dtqcb->head = dtqcb->tail;
153 #endif /* __dtqfenq */
161 dequeue_data(DTQCB *dtqcb, VP_INT *p_data)
163 if (dtqcb->count > 0) {
164 *p_data = *((VP_INT *)(dtqcb->dtqinib->dtq) + dtqcb->head);
167 if (dtqcb->head >= dtqcb->dtqinib->dtqcnt) {
175 #endif /* __dtqdeq */
178 * 受信待ちキューの先頭タスクへのデータ送信
183 send_data_rwait(DTQCB *dtqcb, VP_INT data)
187 if (!(queue_empty(&(dtqcb->rwait_queue)))) {
188 tcb = (TCB *) queue_delete_next(&(dtqcb->rwait_queue));
189 ((WINFO_DTQ *)(tcb->winfo))->data = data;
195 #endif /* __dtqsnd */
198 * 送信待ちキューの先頭タスクからのデータ受信
203 receive_data_swait(DTQCB *dtqcb, VP_INT *p_data)
207 if (!(queue_empty(&(dtqcb->swait_queue)))) {
208 tcb = (TCB *) queue_delete_next(&(dtqcb->swait_queue));
209 *p_data = ((WINFO_DTQ *)(tcb->winfo))->data;
215 #endif /* __dtqrcv */
223 snd_dtq(ID dtqid, VP_INT data)
230 LOG_SND_DTQ_ENTER(dtqid, data);
233 dtqcb = get_dtqcb(dtqid);
236 if ((tcb = send_data_rwait(dtqcb, data)) != NULL) {
237 if (wait_complete(tcb)) {
242 else if (enqueue_data(dtqcb, data)) {
247 wobj_make_wait((WOBJCB *) dtqcb, (WINFO_WOBJ *) &winfo);
249 ercd = winfo.winfo.wercd;
254 LOG_SND_DTQ_LEAVE(ercd);
258 #endif /* __snd_dtq */
266 psnd_dtq(ID dtqid, VP_INT data)
272 LOG_PSND_DTQ_ENTER(dtqid, data);
275 dtqcb = get_dtqcb(dtqid);
278 if ((tcb = send_data_rwait(dtqcb, data)) != NULL) {
279 if (wait_complete(tcb)) {
284 else if (enqueue_data(dtqcb, data)) {
293 LOG_PSND_DTQ_LEAVE(ercd);
297 #endif /* __psnd_dtq */
300 * データキューへの送信(ポーリング,非タスクコンテキスト用)
305 ipsnd_dtq(ID dtqid, VP_INT data)
311 LOG_IPSND_DTQ_ENTER(dtqid, data);
314 dtqcb = get_dtqcb(dtqid);
317 if ((tcb = send_data_rwait(dtqcb, data)) != NULL) {
318 if (wait_complete(tcb)) {
323 else if (enqueue_data(dtqcb, data)) {
332 LOG_IPSND_DTQ_LEAVE(ercd);
336 #endif /* __ipsnd_dtq */
339 * データキューへの送信(タイムアウトあり)
344 tsnd_dtq(ID dtqid, VP_INT data, TMO tmout)
352 LOG_TSND_DTQ_ENTER(dtqid, data, tmout);
356 dtqcb = get_dtqcb(dtqid);
359 if ((tcb = send_data_rwait(dtqcb, data)) != NULL) {
360 if (wait_complete(tcb)) {
365 else if (enqueue_data(dtqcb, data)) {
368 else if (tmout == TMO_POL) {
373 wobj_make_wait_tmout((WOBJCB *) dtqcb, (WINFO_WOBJ *) &winfo,
376 ercd = winfo.winfo.wercd;
381 LOG_TSND_DTQ_LEAVE(ercd);
385 #endif /* __tsnd_dtq */
393 fsnd_dtq(ID dtqid, VP_INT data)
399 LOG_FSND_DTQ_ENTER(dtqid, data);
402 dtqcb = get_dtqcb(dtqid);
403 CHECK_ILUSE(dtqcb->dtqinib->dtqcnt > 0);
406 if ((tcb = send_data_rwait(dtqcb, data)) != NULL) {
407 if (wait_complete(tcb)) {
412 force_enqueue_data(dtqcb, data);
418 LOG_FSND_DTQ_LEAVE(ercd);
422 #endif /* __fsnd_dtq */
425 * データキューへの強制送信(非タスクコンテキスト用)
430 ifsnd_dtq(ID dtqid, VP_INT data)
436 LOG_IFSND_DTQ_ENTER(dtqid, data);
439 dtqcb = get_dtqcb(dtqid);
440 CHECK_ILUSE(dtqcb->dtqinib->dtqcnt > 0);
443 if ((tcb = send_data_rwait(dtqcb, data)) != NULL) {
444 if (wait_complete(tcb)) {
449 force_enqueue_data(dtqcb, data);
455 LOG_IFSND_DTQ_LEAVE(ercd);
459 #endif /* __ifsnd_dtq */
467 rcv_dtq(ID dtqid, VP_INT *p_data)
475 LOG_RCV_DTQ_ENTER(dtqid, p_data);
478 dtqcb = get_dtqcb(dtqid);
481 if (dequeue_data(dtqcb, p_data)) {
482 if ((tcb = receive_data_swait(dtqcb, &data)) != NULL) {
483 enqueue_data(dtqcb, data);
484 if (wait_complete(tcb)) {
490 else if ((tcb = receive_data_swait(dtqcb, p_data)) != NULL) {
491 if (wait_complete(tcb)) {
497 runtsk->tstat = (TS_WAITING | TS_WAIT_WOBJ);
498 make_wait(&(winfo.winfo));
499 queue_insert_prev(&(dtqcb->rwait_queue),
500 &(runtsk->task_queue));
501 winfo.wobjcb = (WOBJCB *) dtqcb;
504 ercd = winfo.winfo.wercd;
506 *p_data = winfo.data;
512 LOG_RCV_DTQ_LEAVE(ercd, *p_data);
516 #endif /* __rcv_dtq */
524 prcv_dtq(ID dtqid, VP_INT *p_data)
531 LOG_PRCV_DTQ_ENTER(dtqid, p_data);
534 dtqcb = get_dtqcb(dtqid);
537 if (dequeue_data(dtqcb, p_data)) {
538 if ((tcb = receive_data_swait(dtqcb, &data)) != NULL) {
539 enqueue_data(dtqcb, data);
540 if (wait_complete(tcb)) {
546 else if ((tcb = receive_data_swait(dtqcb, p_data)) != NULL) {
547 if (wait_complete(tcb)) {
558 LOG_PRCV_DTQ_LEAVE(ercd, *p_data);
562 #endif /* __prcv_dtq */
565 * データキューからの受信(タイムアウトあり)
570 trcv_dtq(ID dtqid, VP_INT *p_data, TMO tmout)
579 LOG_TRCV_DTQ_ENTER(dtqid, p_data, tmout);
583 dtqcb = get_dtqcb(dtqid);
586 if (dequeue_data(dtqcb, p_data)) {
587 if ((tcb = receive_data_swait(dtqcb, &data)) != NULL) {
588 enqueue_data(dtqcb, data);
589 if (wait_complete(tcb)) {
595 else if ((tcb = receive_data_swait(dtqcb, p_data)) != NULL) {
596 if (wait_complete(tcb)) {
601 else if (tmout == TMO_POL) {
605 runtsk->tstat = (TS_WAITING | TS_WAIT_WOBJ);
606 make_wait_tmout(&(winfo.winfo), &tmevtb, tmout);
607 queue_insert_prev(&(dtqcb->rwait_queue),
608 &(runtsk->task_queue));
609 winfo.wobjcb = (WOBJCB *) dtqcb;
612 ercd = winfo.winfo.wercd;
614 *p_data = winfo.data;
620 LOG_TRCV_DTQ_LEAVE(ercd, *p_data);
624 #endif /* __trcv_dtq */