source: anotherchoice/tags/jsp-1.4.4-full-UTF8/kernel/dataqueue.c@ 26

Last change on this file since 26 was 26, checked in by ykominami, 12 years ago

initial

File size: 12.7 KB
Line 
1/*
2 * TOPPERS/JSP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Just Standard Profile Kernel
5 *
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 *
9 * 上記著作権者
10は,以下の (1)〜(4) の条件か,Free Software Foundation
11 * によってå…
12¬è¡¨ã•ã‚Œã¦ã„ã‚‹ GNU General Public License の Version 2 に記
13 * 述されている条件を満たす場合に限り,本ソフトウェア(本ソフトウェア
14 * を改変したものを含む.以下同じ)を使用・複製・改変・再é…
15å¸ƒï¼ˆä»¥ä¸‹ï¼Œ
16 * 利用と呼ぶ)することを無償で許諾する.
17 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
18 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
19 * スコード中に含まれていること.
20 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
21 * 用できる形で再é…
22å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
23å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
24 * 者
25マニュアルなど)に,上記の著作権表示,この利用条件および下記
26 * の無保証規定を掲載すること.
27 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
28 * 用できない形で再é…
29å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
30 * と.
31 * (a) 再é…
32å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
33マニュアルなど)に,上記の著
34 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
35 * (b) 再é…
36å¸ƒã®å½¢æ…
37‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
38 * 報告すること.
39 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
40 * 害からも,上記著作権者
41およびTOPPERSプロジェクトをå…
42è²¬ã™ã‚‹ã“と.
43 *
44 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
45お
46 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,その適用可能性も
47 * 含めて,いかなる保証も行わない.また,本ソフトウェアの利用により直
48 * 接的または間接的に生じたいかなる損害に関しても,その責任を負わない.
49 *
50 * @(#) $Id: dataqueue.c,v 1.9 2003/06/04 01:46:16 hiro Exp $
51 */
52
53/*
54 * データキュー機能
55 */
56
57#include "jsp_kernel.h"
58#include "check.h"
59#include "task.h"
60#include "wait.h"
61#include "dataqueue.h"
62
63/*
64 * データキューIDの最大値(kernel_cfg.c)
65 */
66extern const ID tmax_dtqid;
67
68/*
69 * データキュー初期化ブロックのエリア(kernel_cfg.c)
70 */
71extern const DTQINIB dtqinib_table[];
72
73/*
74 * データキューの数
75 */
76#define TNUM_DTQ ((UINT)(tmax_dtqid - TMIN_DTQID + 1))
77
78/*
79 * データキュー管理ブロックのエリア(kernel_cfg.c)
80 */
81extern DTQCB dtqcb_table[];
82
83/*
84 * データキューIDからデータキュー管理ブロックを取り出すためのマクロ
85 */
86#define INDEX_DTQ(dtqid) ((UINT)((dtqid) - TMIN_DTQID))
87#define get_dtqcb(dtqid) (&(dtqcb_table[INDEX_DTQ(dtqid)]))
88
89/*
90 * データキュー待
91ち情
92報ブロックの定義
93 *
94 * データキューへの送信待
95ちとデータキューからの受信待
96ちで,同じ待
97ち情
98
99 * 報ブロックを使う.
100 */
101typedef struct dataqueue_waiting_information {
102 WINFO winfo; /* 標準の待
103ち情
104報ブロック */
105 WOBJCB *wobjcb; /* 待
106ちオブジェクトの管理ブロック */
107 VP_INT data; /* 送受信データ */
108} WINFO_DTQ;
109
110/*
111 * データキュー機能の初期化
112 */
113#ifdef __dtqini
114
115void
116dataqueue_initialize(void)
117{
118 UINT i;
119 DTQCB *dtqcb;
120
121 for (dtqcb = dtqcb_table, i = 0; i < TNUM_DTQ; dtqcb++, i++) {
122 queue_initialize(&(dtqcb->swait_queue));
123 dtqcb->dtqinib = &(dtqinib_table[i]);
124 queue_initialize(&(dtqcb->rwait_queue));
125 dtqcb->count = 0;
126 dtqcb->head = 0;
127 dtqcb->tail = 0;
128 }
129}
130
131#endif /* __dtqini */
132
133/*
134 * データキュー領域にデータを格納
135 */
136#ifdef __dtqenq
137
138BOOL
139enqueue_data(DTQCB *dtqcb, VP_INT data)
140{
141 if (dtqcb->count < dtqcb->dtqinib->dtqcnt) {
142 *((VP_INT *)(dtqcb->dtqinib->dtq) + dtqcb->tail) = data;
143 dtqcb->count++;
144 dtqcb->tail++;
145 if (dtqcb->tail >= dtqcb->dtqinib->dtqcnt) {
146 dtqcb->tail = 0;
147 }
148 return(TRUE);
149 }
150 return(FALSE);
151}
152
153#endif /* __dtqenq */
154
155/*
156 * データキュー領域にデータを強制格納
157 */
158#ifdef __dtqfenq
159
160void
161force_enqueue_data(DTQCB *dtqcb, VP_INT data)
162{
163 *((VP_INT *)(dtqcb->dtqinib->dtq) + dtqcb->tail) = data;
164 dtqcb->tail++;
165 if (dtqcb->tail >= dtqcb->dtqinib->dtqcnt) {
166 dtqcb->tail = 0;
167 }
168 if (dtqcb->count < dtqcb->dtqinib->dtqcnt) {
169 dtqcb->count++;
170 }
171 else {
172 dtqcb->head = dtqcb->tail;
173 }
174}
175
176#endif /* __dtqfenq */
177
178/*
179 * データキュー領域からデータを取出し
180 */
181#ifdef __dtqdeq
182
183BOOL
184dequeue_data(DTQCB *dtqcb, VP_INT *p_data)
185{
186 if (dtqcb->count > 0) {
187 *p_data = *((VP_INT *)(dtqcb->dtqinib->dtq) + dtqcb->head);
188 dtqcb->count--;
189 dtqcb->head++;
190 if (dtqcb->head >= dtqcb->dtqinib->dtqcnt) {
191 dtqcb->head = 0;
192 }
193 return(TRUE);
194 }
195 return(FALSE);
196}
197
198#endif /* __dtqdeq */
199
200/*
201 * 受信待
202ちキューのå…
203ˆé ­ã‚¿ã‚¹ã‚¯ã¸ã®ãƒ‡ãƒ¼ã‚¿é€ä¿¡
204 */
205#ifdef __dtqsnd
206
207TCB *
208send_data_rwait(DTQCB *dtqcb, VP_INT data)
209{
210 TCB *tcb;
211
212 if (!(queue_empty(&(dtqcb->rwait_queue)))) {
213 tcb = (TCB *) queue_delete_next(&(dtqcb->rwait_queue));
214 ((WINFO_DTQ *)(tcb->winfo))->data = data;
215 return(tcb);
216 }
217 return(NULL);
218}
219
220#endif /* __dtqsnd */
221
222/*
223 * 送信待
224ちキューのå…
225ˆé ­ã‚¿ã‚¹ã‚¯ã‹ã‚‰ã®ãƒ‡ãƒ¼ã‚¿å—ä¿¡
226 */
227#ifdef __dtqrcv
228
229TCB *
230receive_data_swait(DTQCB *dtqcb, VP_INT *p_data)
231{
232 TCB *tcb;
233
234 if (!(queue_empty(&(dtqcb->swait_queue)))) {
235 tcb = (TCB *) queue_delete_next(&(dtqcb->swait_queue));
236 *p_data = ((WINFO_DTQ *)(tcb->winfo))->data;
237 return(tcb);
238 }
239 return(NULL);
240}
241
242#endif /* __dtqrcv */
243
244/*
245 * データキューへの送信
246 */
247#ifdef __snd_dtq
248
249SYSCALL ER
250snd_dtq(ID dtqid, VP_INT data)
251{
252 DTQCB *dtqcb;
253 WINFO_DTQ winfo;
254 TCB *tcb;
255 ER ercd;
256
257 LOG_SND_DTQ_ENTER(dtqid, data);
258 CHECK_DISPATCH();
259 CHECK_DTQID(dtqid);
260 dtqcb = get_dtqcb(dtqid);
261
262 t_lock_cpu();
263 if ((tcb = send_data_rwait(dtqcb, data)) != NULL) {
264 if (wait_complete(tcb)) {
265 dispatch();
266 }
267 ercd = E_OK;
268 }
269 else if (enqueue_data(dtqcb, data)) {
270 ercd = E_OK;
271 }
272 else {
273 winfo.data = data;
274 wobj_make_wait((WOBJCB *) dtqcb, (WINFO_WOBJ *) &winfo);
275 dispatch();
276 ercd = winfo.winfo.wercd;
277 }
278 t_unlock_cpu();
279
280 exit:
281 LOG_SND_DTQ_LEAVE(ercd);
282 return(ercd);
283}
284
285#endif /* __snd_dtq */
286
287/*
288 * データキューへの送信(ポーリング)
289 */
290#ifdef __psnd_dtq
291
292SYSCALL ER
293psnd_dtq(ID dtqid, VP_INT data)
294{
295 DTQCB *dtqcb;
296 TCB *tcb;
297 ER ercd;
298
299 LOG_PSND_DTQ_ENTER(dtqid, data);
300 CHECK_TSKCTX_UNL();
301 CHECK_DTQID(dtqid);
302 dtqcb = get_dtqcb(dtqid);
303
304 t_lock_cpu();
305 if ((tcb = send_data_rwait(dtqcb, data)) != NULL) {
306 if (wait_complete(tcb)) {
307 dispatch();
308 }
309 ercd = E_OK;
310 }
311 else if (enqueue_data(dtqcb, data)) {
312 ercd = E_OK;
313 }
314 else {
315 ercd = E_TMOUT;
316 }
317 t_unlock_cpu();
318
319 exit:
320 LOG_PSND_DTQ_LEAVE(ercd);
321 return(ercd);
322}
323
324#endif /* __psnd_dtq */
325
326/*
327 * データキューへの送信(ポーリング,非タスクコンテキスト用)
328 */
329#ifdef __ipsnd_dtq
330
331SYSCALL ER
332ipsnd_dtq(ID dtqid, VP_INT data)
333{
334 DTQCB *dtqcb;
335 TCB *tcb;
336 ER ercd;
337
338 LOG_IPSND_DTQ_ENTER(dtqid, data);
339 CHECK_INTCTX_UNL();
340 CHECK_DTQID(dtqid);
341 dtqcb = get_dtqcb(dtqid);
342
343 i_lock_cpu();
344 if ((tcb = send_data_rwait(dtqcb, data)) != NULL) {
345 if (wait_complete(tcb)) {
346 reqflg = TRUE;
347 }
348 ercd = E_OK;
349 }
350 else if (enqueue_data(dtqcb, data)) {
351 ercd = E_OK;
352 }
353 else {
354 ercd = E_TMOUT;
355 }
356 i_unlock_cpu();
357
358 exit:
359 LOG_IPSND_DTQ_LEAVE(ercd);
360 return(ercd);
361}
362
363#endif /* __ipsnd_dtq */
364
365/*
366 * データキューへの送信(タイムアウトあり)
367 */
368#ifdef __tsnd_dtq
369
370SYSCALL ER
371tsnd_dtq(ID dtqid, VP_INT data, TMO tmout)
372{
373 DTQCB *dtqcb;
374 WINFO_DTQ winfo;
375 TMEVTB tmevtb;
376 TCB *tcb;
377 ER ercd;
378
379 LOG_TSND_DTQ_ENTER(dtqid, data, tmout);
380 CHECK_DISPATCH();
381 CHECK_DTQID(dtqid);
382 CHECK_TMOUT(tmout);
383 dtqcb = get_dtqcb(dtqid);
384
385 t_lock_cpu();
386 if ((tcb = send_data_rwait(dtqcb, data)) != NULL) {
387 if (wait_complete(tcb)) {
388 dispatch();
389 }
390 ercd = E_OK;
391 }
392 else if (enqueue_data(dtqcb, data)) {
393 ercd = E_OK;
394 }
395 else if (tmout == TMO_POL) {
396 ercd = E_TMOUT;
397 }
398 else {
399 winfo.data = data;
400 wobj_make_wait_tmout((WOBJCB *) dtqcb, (WINFO_WOBJ *) &winfo,
401 &tmevtb, tmout);
402 dispatch();
403 ercd = winfo.winfo.wercd;
404 }
405 t_unlock_cpu();
406
407 exit:
408 LOG_TSND_DTQ_LEAVE(ercd);
409 return(ercd);
410}
411
412#endif /* __tsnd_dtq */
413
414/*
415 * データキューへの強制送信
416 */
417#ifdef __fsnd_dtq
418
419SYSCALL ER
420fsnd_dtq(ID dtqid, VP_INT data)
421{
422 DTQCB *dtqcb;
423 TCB *tcb;
424 ER ercd;
425
426 LOG_FSND_DTQ_ENTER(dtqid, data);
427 CHECK_TSKCTX_UNL();
428 CHECK_DTQID(dtqid);
429 dtqcb = get_dtqcb(dtqid);
430 CHECK_ILUSE(dtqcb->dtqinib->dtqcnt > 0);
431
432 t_lock_cpu();
433 if ((tcb = send_data_rwait(dtqcb, data)) != NULL) {
434 if (wait_complete(tcb)) {
435 dispatch();
436 }
437 }
438 else {
439 force_enqueue_data(dtqcb, data);
440 }
441 ercd = E_OK;
442 t_unlock_cpu();
443
444 exit:
445 LOG_FSND_DTQ_LEAVE(ercd);
446 return(ercd);
447}
448
449#endif /* __fsnd_dtq */
450
451/*
452 * データキューへの強制送信(非タスクコンテキスト用)
453 */
454#ifdef __ifsnd_dtq
455
456SYSCALL ER
457ifsnd_dtq(ID dtqid, VP_INT data)
458{
459 DTQCB *dtqcb;
460 TCB *tcb;
461 ER ercd;
462
463 LOG_IFSND_DTQ_ENTER(dtqid, data);
464 CHECK_INTCTX_UNL();
465 CHECK_DTQID(dtqid);
466 dtqcb = get_dtqcb(dtqid);
467 CHECK_ILUSE(dtqcb->dtqinib->dtqcnt > 0);
468
469 i_lock_cpu();
470 if ((tcb = send_data_rwait(dtqcb, data)) != NULL) {
471 if (wait_complete(tcb)) {
472 reqflg = TRUE;
473 }
474 }
475 else {
476 force_enqueue_data(dtqcb, data);
477 }
478 ercd = E_OK;
479 i_unlock_cpu();
480
481 exit:
482 LOG_IFSND_DTQ_LEAVE(ercd);
483 return(ercd);
484}
485
486#endif /* __ifsnd_dtq */
487
488/*
489 * データキューからの受信
490 */
491#ifdef __rcv_dtq
492
493SYSCALL ER
494rcv_dtq(ID dtqid, VP_INT *p_data)
495{
496 DTQCB *dtqcb;
497 WINFO_DTQ winfo;
498 TCB *tcb;
499 VP_INT data;
500 ER ercd;
501
502 LOG_RCV_DTQ_ENTER(dtqid, p_data);
503 CHECK_DISPATCH();
504 CHECK_DTQID(dtqid);
505 dtqcb = get_dtqcb(dtqid);
506
507 t_lock_cpu();
508 if (dequeue_data(dtqcb, p_data)) {
509 if ((tcb = receive_data_swait(dtqcb, &data)) != NULL) {
510 enqueue_data(dtqcb, data);
511 if (wait_complete(tcb)) {
512 dispatch();
513 }
514 }
515 ercd = E_OK;
516 }
517 else if ((tcb = receive_data_swait(dtqcb, p_data)) != NULL) {
518 if (wait_complete(tcb)) {
519 dispatch();
520 }
521 ercd = E_OK;
522 }
523 else {
524 runtsk->tstat = (TS_WAITING | TS_WAIT_WOBJ);
525 make_wait(&(winfo.winfo));
526 queue_insert_prev(&(dtqcb->rwait_queue),
527 &(runtsk->task_queue));
528 winfo.wobjcb = (WOBJCB *) dtqcb;
529 LOG_TSKSTAT(runtsk);
530 dispatch();
531 ercd = winfo.winfo.wercd;
532 if (ercd == E_OK) {
533 *p_data = winfo.data;
534 }
535 }
536 t_unlock_cpu();
537
538 exit:
539 LOG_RCV_DTQ_LEAVE(ercd, *p_data);
540 return(ercd);
541}
542
543#endif /* __rcv_dtq */
544
545/*
546 * データキューからの受信(ポーリング)
547 */
548#ifdef __prcv_dtq
549
550SYSCALL ER
551prcv_dtq(ID dtqid, VP_INT *p_data)
552{
553 DTQCB *dtqcb;
554 TCB *tcb;
555 VP_INT data;
556 ER ercd;
557
558 LOG_PRCV_DTQ_ENTER(dtqid, p_data);
559 CHECK_TSKCTX_UNL();
560 CHECK_DTQID(dtqid);
561 dtqcb = get_dtqcb(dtqid);
562
563 t_lock_cpu();
564 if (dequeue_data(dtqcb, p_data)) {
565 if ((tcb = receive_data_swait(dtqcb, &data)) != NULL) {
566 enqueue_data(dtqcb, data);
567 if (wait_complete(tcb)) {
568 dispatch();
569 }
570 }
571 ercd = E_OK;
572 }
573 else if ((tcb = receive_data_swait(dtqcb, p_data)) != NULL) {
574 if (wait_complete(tcb)) {
575 dispatch();
576 }
577 ercd = E_OK;
578 }
579 else {
580 ercd = E_TMOUT;
581 }
582 t_unlock_cpu();
583
584 exit:
585 LOG_PRCV_DTQ_LEAVE(ercd, *p_data);
586 return(ercd);
587}
588
589#endif /* __prcv_dtq */
590
591/*
592 * データキューからの受信(タイムアウトあり)
593 */
594#ifdef __trcv_dtq
595
596SYSCALL ER
597trcv_dtq(ID dtqid, VP_INT *p_data, TMO tmout)
598{
599 DTQCB *dtqcb;
600 WINFO_DTQ winfo;
601 TMEVTB tmevtb;
602 TCB *tcb;
603 VP_INT data;
604 ER ercd;
605
606 LOG_TRCV_DTQ_ENTER(dtqid, p_data, tmout);
607 CHECK_DISPATCH();
608 CHECK_DTQID(dtqid);
609 CHECK_TMOUT(tmout);
610 dtqcb = get_dtqcb(dtqid);
611
612 t_lock_cpu();
613 if (dequeue_data(dtqcb, p_data)) {
614 if ((tcb = receive_data_swait(dtqcb, &data)) != NULL) {
615 enqueue_data(dtqcb, data);
616 if (wait_complete(tcb)) {
617 dispatch();
618 }
619 }
620 ercd = E_OK;
621 }
622 else if ((tcb = receive_data_swait(dtqcb, p_data)) != NULL) {
623 if (wait_complete(tcb)) {
624 dispatch();
625 }
626 ercd = E_OK;
627 }
628 else if (tmout == TMO_POL) {
629 ercd = E_TMOUT;
630 }
631 else {
632 runtsk->tstat = (TS_WAITING | TS_WAIT_WOBJ);
633 make_wait_tmout(&(winfo.winfo), &tmevtb, tmout);
634 queue_insert_prev(&(dtqcb->rwait_queue),
635 &(runtsk->task_queue));
636 winfo.wobjcb = (WOBJCB *) dtqcb;
637 LOG_TSKSTAT(runtsk);
638 dispatch();
639 ercd = winfo.winfo.wercd;
640 if (ercd == E_OK) {
641 *p_data = winfo.data;
642 }
643 }
644 t_unlock_cpu();
645
646 exit:
647 LOG_TRCV_DTQ_LEAVE(ercd, *p_data);
648 return(ercd);
649}
650
651#endif /* __trcv_dtq */
Note: See TracBrowser for help on using the repository browser.