3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2005-2010 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
11 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
12 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
13 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
14 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
17 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
24 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
26 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
28 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
30 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
31 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
34 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
35 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
36 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
37 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
40 * @(#) $Id: pridataq.c 1774 2010-03-19 12:45:46Z ertl-hiro $
47 #include "kernel_impl.h"
56 #ifndef LOG_SND_PDQ_ENTER
57 #define LOG_SND_PDQ_ENTER(pdqid, data, datapri)
58 #endif /* LOG_SND_PDQ_ENTER */
60 #ifndef LOG_SND_PDQ_LEAVE
61 #define LOG_SND_PDQ_LEAVE(ercd)
62 #endif /* LOG_SND_PDQ_LEAVE */
64 #ifndef LOG_PSND_PDQ_ENTER
65 #define LOG_PSND_PDQ_ENTER(pdqid, data, datapri)
66 #endif /* LOG_PSND_PDQ_ENTER */
68 #ifndef LOG_PSND_PDQ_LEAVE
69 #define LOG_PSND_PDQ_LEAVE(ercd)
70 #endif /* LOG_PSND_PDQ_LEAVE */
72 #ifndef LOG_IPSND_PDQ_ENTER
73 #define LOG_IPSND_PDQ_ENTER(pdqid, data, datapri)
74 #endif /* LOG_IPSND_PDQ_ENTER */
76 #ifndef LOG_IPSND_PDQ_LEAVE
77 #define LOG_IPSND_PDQ_LEAVE(ercd)
78 #endif /* LOG_IPSND_PDQ_LEAVE */
80 #ifndef LOG_TSND_PDQ_ENTER
81 #define LOG_TSND_PDQ_ENTER(pdqid, data, datapri, tmout)
82 #endif /* LOG_TSND_PDQ_ENTER */
84 #ifndef LOG_TSND_PDQ_LEAVE
85 #define LOG_TSND_PDQ_LEAVE(ercd)
86 #endif /* LOG_TSND_PDQ_LEAVE */
88 #ifndef LOG_RCV_PDQ_ENTER
89 #define LOG_RCV_PDQ_ENTER(pdqid, p_data, p_datapri)
90 #endif /* LOG_RCV_PDQ_ENTER */
92 #ifndef LOG_RCV_PDQ_LEAVE
93 #define LOG_RCV_PDQ_LEAVE(ercd, data, datapri)
94 #endif /* LOG_RCV_PDQ_LEAVE */
96 #ifndef LOG_PRCV_PDQ_ENTER
97 #define LOG_PRCV_PDQ_ENTER(pdqid, p_data, p_datapri)
98 #endif /* LOG_PRCV_PDQ_ENTER */
100 #ifndef LOG_PRCV_PDQ_LEAVE
101 #define LOG_PRCV_PDQ_LEAVE(ercd, data, datapri)
102 #endif /* LOG_PRCV_PDQ_LEAVE */
104 #ifndef LOG_TRCV_PDQ_ENTER
105 #define LOG_TRCV_PDQ_ENTER(pdqid, p_data, p_datapri, tmout)
106 #endif /* LOG_TRCV_PDQ_ENTER */
108 #ifndef LOG_TRCV_PDQ_LEAVE
109 #define LOG_TRCV_PDQ_LEAVE(ercd, data, datapri)
110 #endif /* LOG_TRCV_PDQ_LEAVE */
112 #ifndef LOG_INI_PDQ_ENTER
113 #define LOG_INI_PDQ_ENTER(pdqid)
114 #endif /* LOG_INI_PDQ_ENTER */
116 #ifndef LOG_INI_PDQ_LEAVE
117 #define LOG_INI_PDQ_LEAVE(ercd)
118 #endif /* LOG_INI_PDQ_LEAVE */
120 #ifndef LOG_REF_PDQ_ENTER
121 #define LOG_REF_PDQ_ENTER(pdqid, pk_rpdq)
122 #endif /* LOG_REF_PDQ_ENTER */
124 #ifndef LOG_REF_PDQ_LEAVE
125 #define LOG_REF_PDQ_LEAVE(ercd, pk_rpdq)
126 #endif /* LOG_REF_PDQ_LEAVE */
131 #define tnum_pdq ((uint_t)(tmax_pdqid - TMIN_PDQID + 1))
134 * 優先度データキューIDから優先度データキュー管理ブロックを取り出すた
137 #define INDEX_PDQ(pdqid) ((uint_t)((pdqid) - TMIN_PDQID))
138 #define get_pdqcb(pdqid) (&(pdqcb_table[INDEX_PDQ(pdqid)]))
143 #ifdef TOPPERS_pdqini
146 initialize_pridataq(void)
151 for (p_pdqcb = pdqcb_table, i = 0; i < tnum_pdq; p_pdqcb++, i++) {
152 queue_initialize(&(p_pdqcb->swait_queue));
153 p_pdqcb->p_pdqinib = &(pdqinib_table[i]);
154 queue_initialize(&(p_pdqcb->rwait_queue));
156 p_pdqcb->p_head = NULL;
157 p_pdqcb->unused = 0U;
158 p_pdqcb->p_freelist = NULL;
162 #endif /* TOPPERS_pdqini */
165 * 優先度データキュー管理領域へのデータの格納
167 #ifdef TOPPERS_pdqenq
170 enqueue_pridata(PDQCB *p_pdqcb, intptr_t data, PRI datapri)
173 PDQMB **pp_prev_next, *p_next;
175 if (p_pdqcb->p_freelist != NULL) {
176 p_pdqmb = p_pdqcb->p_freelist;
177 p_pdqcb->p_freelist = p_pdqmb->p_next;
180 p_pdqmb = p_pdqcb->p_pdqinib->p_pdqmb + p_pdqcb->unused;
184 p_pdqmb->data = data;
185 p_pdqmb->datapri = datapri;
187 pp_prev_next = &(p_pdqcb->p_head);
188 while ((p_next = *pp_prev_next) != NULL) {
189 if (p_next->datapri > datapri) {
192 pp_prev_next = &(p_next->p_next);
194 p_pdqmb->p_next = p_next;
195 *pp_prev_next = p_pdqmb;
199 #endif /* TOPPERS_pdqenq */
202 * 優先度データキュー管理領域からのデータの取出し
204 #ifdef TOPPERS_pdqdeq
207 dequeue_pridata(PDQCB *p_pdqcb, intptr_t *p_data, PRI *p_datapri)
211 p_pdqmb = p_pdqcb->p_head;
212 p_pdqcb->p_head = p_pdqmb->p_next;
215 *p_data = p_pdqmb->data;
216 *p_datapri = p_pdqmb->datapri;
218 p_pdqmb->p_next = p_pdqcb->p_freelist;
219 p_pdqcb->p_freelist = p_pdqmb;
222 #endif /* TOPPERS_pdqdeq */
227 #ifdef TOPPERS_pdqsnd
230 send_pridata(PDQCB *p_pdqcb, intptr_t data, PRI datapri, bool_t *p_reqdsp)
234 if (!queue_empty(&(p_pdqcb->rwait_queue))) {
235 p_tcb = (TCB *) queue_delete_next(&(p_pdqcb->rwait_queue));
236 ((WINFO_PDQ *)(p_tcb->p_winfo))->data = data;
237 ((WINFO_PDQ *)(p_tcb->p_winfo))->datapri = datapri;
238 *p_reqdsp = wait_complete(p_tcb);
241 else if (p_pdqcb->count < p_pdqcb->p_pdqinib->pdqcnt) {
242 enqueue_pridata(p_pdqcb, data, datapri);
251 #endif /* TOPPERS_pdqsnd */
256 #ifdef TOPPERS_pdqrcv
259 receive_pridata(PDQCB *p_pdqcb, intptr_t *p_data,
260 PRI *p_datapri, bool_t *p_reqdsp)
266 if (p_pdqcb->count > 0U) {
267 dequeue_pridata(p_pdqcb, p_data, p_datapri);
268 if (!queue_empty(&(p_pdqcb->swait_queue))) {
269 p_tcb = (TCB *) queue_delete_next(&(p_pdqcb->swait_queue));
270 data = ((WINFO_PDQ *)(p_tcb->p_winfo))->data;
271 datapri = ((WINFO_PDQ *)(p_tcb->p_winfo))->datapri;
272 enqueue_pridata(p_pdqcb, data, datapri);
273 *p_reqdsp = wait_complete(p_tcb);
280 else if (!queue_empty(&(p_pdqcb->swait_queue))) {
281 p_tcb = (TCB *) queue_delete_next(&(p_pdqcb->swait_queue));
282 *p_data = ((WINFO_PDQ *)(p_tcb->p_winfo))->data;
283 *p_datapri = ((WINFO_PDQ *)(p_tcb->p_winfo))->datapri;
284 *p_reqdsp = wait_complete(p_tcb);
292 #endif /* TOPPERS_pdqrcv */
297 #ifdef TOPPERS_snd_pdq
300 snd_pdq(ID pdqid, intptr_t data, PRI datapri)
307 LOG_SND_PDQ_ENTER(pdqid, data, datapri);
310 p_pdqcb = get_pdqcb(pdqid);
311 CHECK_PAR(TMIN_DPRI <= datapri && datapri <= p_pdqcb->p_pdqinib->maxdpri);
314 if (send_pridata(p_pdqcb, data, datapri, &reqdsp)) {
321 winfo_pdq.data = data;
322 winfo_pdq.datapri = datapri;
323 p_runtsk->tstat = (TS_WAITING | TS_WAIT_SPDQ);
324 wobj_make_wait((WOBJCB *) p_pdqcb, (WINFO_WOBJ *) &winfo_pdq);
326 ercd = winfo_pdq.winfo.wercd;
331 LOG_SND_PDQ_LEAVE(ercd);
335 #endif /* TOPPERS_snd_pdq */
338 * 優先度データキューへの送信(ポーリング)
340 #ifdef TOPPERS_psnd_pdq
343 psnd_pdq(ID pdqid, intptr_t data, PRI datapri)
349 LOG_PSND_PDQ_ENTER(pdqid, data, datapri);
352 p_pdqcb = get_pdqcb(pdqid);
353 CHECK_PAR(TMIN_DPRI <= datapri && datapri <= p_pdqcb->p_pdqinib->maxdpri);
356 if (send_pridata(p_pdqcb, data, datapri, &reqdsp)) {
368 LOG_PSND_PDQ_LEAVE(ercd);
372 #endif /* TOPPERS_psnd_pdq */
375 * 優先度データキューへの送信(ポーリング,非タスクコンテキスト用)
377 #ifdef TOPPERS_ipsnd_pdq
380 ipsnd_pdq(ID pdqid, intptr_t data, PRI datapri)
386 LOG_IPSND_PDQ_ENTER(pdqid, data, datapri);
389 p_pdqcb = get_pdqcb(pdqid);
390 CHECK_PAR(TMIN_DPRI <= datapri && datapri <= p_pdqcb->p_pdqinib->maxdpri);
393 if (send_pridata(p_pdqcb, data, datapri, &reqdsp)) {
405 LOG_IPSND_PDQ_LEAVE(ercd);
409 #endif /* TOPPERS_ipsnd_pdq */
412 * 優先度データキューへの送信(タイムアウトあり)
414 #ifdef TOPPERS_tsnd_pdq
417 tsnd_pdq(ID pdqid, intptr_t data, PRI datapri, TMO tmout)
425 LOG_TSND_PDQ_ENTER(pdqid, data, datapri, tmout);
429 p_pdqcb = get_pdqcb(pdqid);
430 CHECK_PAR(TMIN_DPRI <= datapri && datapri <= p_pdqcb->p_pdqinib->maxdpri);
433 if (send_pridata(p_pdqcb, data, datapri, &reqdsp)) {
439 else if (tmout == TMO_POL) {
443 winfo_pdq.data = data;
444 winfo_pdq.datapri = datapri;
445 p_runtsk->tstat = (TS_WAITING | TS_WAIT_SPDQ);
446 wobj_make_wait_tmout((WOBJCB *) p_pdqcb, (WINFO_WOBJ *) &winfo_pdq,
449 ercd = winfo_pdq.winfo.wercd;
454 LOG_TSND_PDQ_LEAVE(ercd);
458 #endif /* TOPPERS_tsnd_pdq */
463 #ifdef TOPPERS_rcv_pdq
466 rcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri)
473 LOG_RCV_PDQ_ENTER(pdqid, p_data, p_datapri);
476 p_pdqcb = get_pdqcb(pdqid);
479 if (receive_pridata(p_pdqcb, p_data, p_datapri, &reqdsp)) {
486 p_runtsk->tstat = (TS_WAITING | TS_WAIT_RPDQ);
487 make_wait(&(winfo_pdq.winfo));
488 queue_insert_prev(&(p_pdqcb->rwait_queue), &(p_runtsk->task_queue));
489 winfo_pdq.p_pdqcb = p_pdqcb;
490 LOG_TSKSTAT(p_runtsk);
492 ercd = winfo_pdq.winfo.wercd;
494 *p_data = winfo_pdq.data;
495 *p_datapri = winfo_pdq.datapri;
501 LOG_RCV_PDQ_LEAVE(ercd, *p_data, *p_datapri);
505 #endif /* TOPPERS_rcv_pdq */
508 * 優先度データキューからの受信(ポーリング)
510 #ifdef TOPPERS_prcv_pdq
513 prcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri)
519 LOG_PRCV_PDQ_ENTER(pdqid, p_data, p_datapri);
522 p_pdqcb = get_pdqcb(pdqid);
525 if (receive_pridata(p_pdqcb, p_data, p_datapri, &reqdsp)) {
537 LOG_PRCV_PDQ_LEAVE(ercd, *p_data, *p_datapri);
541 #endif /* TOPPERS_prcv_pdq */
544 * 優先度データキューからの受信(タイムアウトあり)
546 #ifdef TOPPERS_trcv_pdq
549 trcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri, TMO tmout)
557 LOG_TRCV_PDQ_ENTER(pdqid, p_data, p_datapri, tmout);
561 p_pdqcb = get_pdqcb(pdqid);
564 if (receive_pridata(p_pdqcb, p_data, p_datapri, &reqdsp)) {
570 else if (tmout == TMO_POL) {
574 p_runtsk->tstat = (TS_WAITING | TS_WAIT_RPDQ);
575 make_wait_tmout(&(winfo_pdq.winfo), &tmevtb, tmout);
576 queue_insert_prev(&(p_pdqcb->rwait_queue), &(p_runtsk->task_queue));
577 winfo_pdq.p_pdqcb = p_pdqcb;
578 LOG_TSKSTAT(p_runtsk);
580 ercd = winfo_pdq.winfo.wercd;
582 *p_data = winfo_pdq.data;
583 *p_datapri = winfo_pdq.datapri;
589 LOG_TRCV_PDQ_LEAVE(ercd, *p_data, *p_datapri);
593 #endif /* TOPPERS_trcv_pdq */
598 #ifdef TOPPERS_ini_pdq
607 LOG_INI_PDQ_ENTER(pdqid);
610 p_pdqcb = get_pdqcb(pdqid);
613 dspreq = init_wait_queue(&(p_pdqcb->swait_queue));
614 if (init_wait_queue(&(p_pdqcb->rwait_queue))) {
618 p_pdqcb->p_head = NULL;
619 p_pdqcb->unused = 0U;
620 p_pdqcb->p_freelist = NULL;
628 LOG_INI_PDQ_LEAVE(ercd);
632 #endif /* TOPPERS_ini_pdq */
637 #ifdef TOPPERS_ref_pdq
640 ref_pdq(ID pdqid, T_RPDQ *pk_rpdq)
645 LOG_REF_PDQ_ENTER(pdqid, pk_rpdq);
648 p_pdqcb = get_pdqcb(pdqid);
651 pk_rpdq->stskid = wait_tskid(&(p_pdqcb->swait_queue));
652 pk_rpdq->rtskid = wait_tskid(&(p_pdqcb->rwait_queue));
653 pk_rpdq->spdqcnt = p_pdqcb->count;
658 LOG_REF_PDQ_LEAVE(ercd, pk_rpdq);
662 #endif /* TOPPERS_ref_pdq */