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: eventflag.c,v 1.1 2009/01/31 05:27:37 suikan Exp $
43 #include "jsp_kernel.h"
47 #include "eventflag.h"
50 * イベントフラグIDの最大値(kernel_cfg.c)
52 extern const ID tmax_flgid;
55 * イベントフラグ初期化ブロックのエリア(kernel_cfg.c)
57 extern const FLGINIB flginib_table[];
60 * イベントフラグ管理ブロックのエリア(kernel_cfg.c)
62 extern FLGCB flgcb_table[];
67 #define TNUM_FLG ((UINT)(tmax_flgid - TMIN_FLGID + 1))
70 * イベントフラグIDからイベントフラグ管理ブロックを取り出すためのマクロ
72 #define INDEX_FLG(flgid) ((UINT)((flgid) - TMIN_FLGID))
73 #define get_flgcb(flgid) (&(flgcb_table[INDEX_FLG(flgid)]))
78 * flgptn は,waiptn および wfmode と同時に使うことはないため,union
79 * を使えばメモリを節約することが可能である.
81 typedef struct eventflag_waiting_information {
82 WINFO winfo; /* 標準の待ち情報ブロック */
83 WOBJCB *wobjcb; /* 待ちオブジェクトの管理ブロック */
84 FLGPTN waiptn; /* 待ちパターン */
85 MODE wfmode; /* 待ちモード */
86 FLGPTN flgptn; /* 待ち解除時のパターン */
95 eventflag_initialize(void)
100 for (flgcb = flgcb_table, i = 0; i < TNUM_FLG; flgcb++, i++) {
101 queue_initialize(&(flgcb->wait_queue));
102 flgcb->flginib = &(flginib_table[i]);
103 flgcb->flgptn = flgcb->flginib->iflgptn;
107 #endif /* __flgini */
115 eventflag_cond(FLGCB *flgcb, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
117 if ((wfmode & TWF_ORW) != 0 ? (flgcb->flgptn & waiptn) != 0
118 : (flgcb->flgptn & waiptn) == waiptn) {
119 *p_flgptn = flgcb->flgptn;
120 if ((flgcb->flginib->flgatr & TA_CLR) != 0) {
128 #endif /* __flgcnd */
136 set_flg(ID flgid, FLGPTN setptn)
143 LOG_SET_FLG_ENTER(flgid, setptn);
146 flgcb = get_flgcb(flgid);
149 flgcb->flgptn |= setptn;
150 if (!(queue_empty(&(flgcb->wait_queue)))) {
151 tcb = (TCB *)(flgcb->wait_queue.next);
152 winfo = (WINFO_FLG *)(tcb->winfo);
153 if (eventflag_cond(flgcb, winfo->waiptn,
154 winfo->wfmode, &(winfo->flgptn))) {
155 queue_delete(&(tcb->task_queue));
156 if (wait_complete(tcb)) {
165 LOG_SET_FLG_LEAVE(ercd);
169 #endif /* __set_flg */
172 * イベントフラグのセット(非タスクコンテキスト用)
177 iset_flg(ID flgid, FLGPTN setptn)
184 LOG_ISET_FLG_ENTER(flgid, setptn);
187 flgcb = get_flgcb(flgid);
190 flgcb->flgptn |= setptn;
191 if (!(queue_empty(&(flgcb->wait_queue)))) {
192 tcb = (TCB *)(flgcb->wait_queue.next);
193 winfo = (WINFO_FLG *)(tcb->winfo);
194 if (eventflag_cond(flgcb, winfo->waiptn,
195 winfo->wfmode, &(winfo->flgptn))) {
196 queue_delete(&(tcb->task_queue));
197 if (wait_complete(tcb)) {
206 LOG_ISET_FLG_LEAVE(ercd);
210 #endif /* __iset_flg */
218 clr_flg(ID flgid, FLGPTN clrptn)
223 LOG_CLR_FLG_ENTER(flgid, clrptn);
226 flgcb = get_flgcb(flgid);
229 flgcb->flgptn &= clrptn;
234 LOG_CLR_FLG_LEAVE(ercd);
238 #endif /* __clr_flg */
246 wai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
252 LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
255 CHECK_PAR(waiptn != 0);
256 CHECK_PAR((wfmode & ~TWF_ORW) == 0);
257 flgcb = get_flgcb(flgid);
260 if (!(queue_empty(&(flgcb->wait_queue)))) {
263 else if (eventflag_cond(flgcb, waiptn, wfmode, p_flgptn)) {
267 winfo.waiptn = waiptn;
268 winfo.wfmode = wfmode;
269 wobj_make_wait((WOBJCB *) flgcb, (WINFO_WOBJ *) &winfo);
271 ercd = winfo.winfo.wercd;
273 *p_flgptn = winfo.flgptn;
279 LOG_WAI_FLG_LEAVE(ercd, *p_flgptn);
283 #endif /* __wai_flg */
291 pol_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
296 LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
299 CHECK_PAR(waiptn != 0);
300 CHECK_PAR((wfmode & ~TWF_ORW) == 0);
301 flgcb = get_flgcb(flgid);
304 if (!(queue_empty(&(flgcb->wait_queue)))) {
307 else if (eventflag_cond(flgcb, waiptn, wfmode, p_flgptn)) {
316 LOG_POL_FLG_LEAVE(ercd, *p_flgptn);
320 #endif /* __pol_flg */
323 * イベントフラグ待ち(タイムアウトあり)
328 twai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn, TMO tmout)
335 LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout);
338 CHECK_PAR(waiptn != 0);
339 CHECK_PAR((wfmode & ~TWF_ORW) == 0);
341 flgcb = get_flgcb(flgid);
344 if (!(queue_empty(&(flgcb->wait_queue)))) {
347 else if (eventflag_cond(flgcb, waiptn, wfmode, p_flgptn)) {
350 else if (tmout == TMO_POL) {
354 winfo.waiptn = waiptn;
355 winfo.wfmode = wfmode;
356 wobj_make_wait_tmout((WOBJCB *) flgcb, (WINFO_WOBJ *) &winfo,
359 ercd = winfo.winfo.wercd;
361 *p_flgptn = winfo.flgptn;
367 LOG_TWAI_FLG_LEAVE(ercd, *p_flgptn);
371 #endif /* __twai_flg */