source: asp_wo_cfg/trunk/kernel/eventflag.c@ 49

Last change on this file since 49 was 49, checked in by ertl-hiro, 12 years ago

asp_wo_kernelをコミット。

  • Property svn:keywords set to Id
File size: 12.1 KB
Line 
1/*
2 * TOPPERS/ASP Kernel
3 * Toyohashi Open Platform for Embedded Real-Time Systems/
4 * Advanced Standard Profile Kernel
5 *
6 * Copyright (C) 2000-2003 by Embedded and Real-Time Systems Laboratory
7 * Toyohashi Univ. of Technology, JAPAN
8 * Copyright (C) 2005-2012 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 * 上記著作権者は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
12 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
13 * 変・再配布(以下,利用と呼ぶ)することを無償で許諾する.
14 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
15 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
16 * スコード中に含まれていること.
17 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
18 * 用できる形で再配布する場合には,再配布に伴うドキュメント(利用
19 * 者マニュアルなど)に,上記の著作権表示,この利用条件および下記
20 * の無保証規定を掲載すること.
21 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
22 * 用できない形で再配布する場合には,次のいずれかの条件を満たすこ
23 * と.
24 * (a) 再配布に伴うドキュメント(利用者マニュアルなど)に,上記の著
25 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
26 * (b) 再配布の形態を,別に定める方法によって,TOPPERSプロジェクトに
27 * 報告すること.
28 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
29 * 害からも,上記著作権者およびTOPPERSプロジェクトを免責すること.
30 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
31 * 由に基づく請求からも,上記著作権者およびTOPPERSプロジェクトを
32 * 免責すること.
33 *
34 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者お
35 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
36 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
37 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
38 * の責任を負わない.
39 *
40 * @(#) $Id: eventflag.c 49 2012-09-06 04:41:53Z ertl-hiro $
41 */
42
43/*
44 * イベントフラグ機能
45 */
46
47#include "kernel_impl.h"
48#include "check.h"
49#include "task.h"
50#include "wait.h"
51#include "eventflag.h"
52
53/*
54 * トレースログマクロのデフォルト定義
55 */
56#ifndef LOG_CRE_FLG_ENTER
57#define LOG_CRE_FLG_ENTER(flgid, pk_cflg)
58#endif /* LOG_CRE_FLG_ENTER */
59
60#ifndef LOG_CRE_FLG_LEAVE
61#define LOG_CRE_FLG_LEAVE(ercd)
62#endif /* LOG_CRE_FLG_LEAVE */
63
64#ifndef LOG_SET_FLG_ENTER
65#define LOG_SET_FLG_ENTER(flgid, setptn)
66#endif /* LOG_SET_FLG_ENTER */
67
68#ifndef LOG_SET_FLG_LEAVE
69#define LOG_SET_FLG_LEAVE(ercd)
70#endif /* LOG_SET_FLG_LEAVE */
71
72#ifndef LOG_ISET_FLG_ENTER
73#define LOG_ISET_FLG_ENTER(flgid, setptn)
74#endif /* LOG_ISET_FLG_ENTER */
75
76#ifndef LOG_ISET_FLG_LEAVE
77#define LOG_ISET_FLG_LEAVE(ercd)
78#endif /* LOG_ISET_FLG_LEAVE */
79
80#ifndef LOG_CLR_FLG_ENTER
81#define LOG_CLR_FLG_ENTER(flgid, clrptn)
82#endif /* LOG_CLR_FLG_ENTER */
83
84#ifndef LOG_CLR_FLG_LEAVE
85#define LOG_CLR_FLG_LEAVE(ercd)
86#endif /* LOG_CLR_FLG_LEAVE */
87
88#ifndef LOG_WAI_FLG_ENTER
89#define LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn)
90#endif /* LOG_WAI_FLG_ENTER */
91
92#ifndef LOG_WAI_FLG_LEAVE
93#define LOG_WAI_FLG_LEAVE(ercd, flgptn)
94#endif /* LOG_WAI_FLG_LEAVE */
95
96#ifndef LOG_POL_FLG_ENTER
97#define LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn)
98#endif /* LOG_POL_FLG_ENTER */
99
100#ifndef LOG_POL_FLG_LEAVE
101#define LOG_POL_FLG_LEAVE(ercd, flgptn)
102#endif /* LOG_POL_FLG_LEAVE */
103
104#ifndef LOG_TWAI_FLG_ENTER
105#define LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout)
106#endif /* LOG_TWAI_FLG_ENTER */
107
108#ifndef LOG_TWAI_FLG_LEAVE
109#define LOG_TWAI_FLG_LEAVE(ercd, flgptn)
110#endif /* LOG_TWAI_FLG_LEAVE */
111
112#ifndef LOG_INI_FLG_ENTER
113#define LOG_INI_FLG_ENTER(flgid)
114#endif /* LOG_INI_FLG_ENTER */
115
116#ifndef LOG_INI_FLG_LEAVE
117#define LOG_INI_FLG_LEAVE(ercd)
118#endif /* LOG_INI_FLG_LEAVE */
119
120#ifndef LOG_REF_FLG_ENTER
121#define LOG_REF_FLG_ENTER(flgid, pk_rflg)
122#endif /* LOG_REF_FLG_ENTER */
123
124#ifndef LOG_REF_FLG_LEAVE
125#define LOG_REF_FLG_LEAVE(ercd, pk_rflg)
126#endif /* LOG_REF_FLG_LEAVE */
127
128/*
129 * イベントフラグの数
130 */
131#define tnum_flg ((uint_t)(tmax_flgid - TMIN_FLGID + 1))
132
133/*
134 * イベントフラグIDからイベントフラグ管理ブロックを取り出すためのマクロ
135 */
136#define INDEX_FLG(flgid) ((uint_t)((flgid) - TMIN_FLGID))
137#define get_flgcb(flgid) (&(flgcb_table[INDEX_FLG(flgid)]))
138
139/*
140 * イベントフラグ機能の初期化
141 */
142#ifdef TOPPERS_flgini
143
144void
145initialize_eventflag(void)
146{
147 uint_t i;
148 FLGCB *p_flgcb;
149 FLGINIB *p_flginib;
150
151 for (i = 0; i < tnum_flg; i++) {
152 p_flgcb = &(flgcb_table[i]);
153 p_flginib = &(flginib_table[i]);
154 p_flginib->flgatr = TA_NOEXS;
155 p_flgcb->p_flginib = ((const FLGINIB *) p_flginib);
156 }
157}
158
159#endif /* TOPPERS_flgini */
160
161/*
162 * イベントフラグの生成
163 */
164#ifdef TOPPERS_cre_flg
165
166ER
167cre_flg(ID flgid, const T_CFLG *pk_cflg)
168{
169 FLGCB *p_flgcb;
170 FLGINIB *p_flginib;
171 ER ercd;
172
173 LOG_CRE_FLG_ENTER(flgid, pk_cflg);
174 CHECK_INIRTN();
175 CHECK_FLGID(flgid);
176 CHECK_RSATR(pk_cflg->flgatr, TA_TPRI|TA_WMUL|TA_CLR);
177 p_flgcb = get_flgcb(flgid);
178
179 if (p_flgcb->p_flginib->flgatr != TA_NOEXS) {
180 ercd = E_OBJ;
181 }
182 else {
183 p_flginib = (FLGINIB *)(p_flgcb->p_flginib);
184 p_flginib->flgatr = pk_cflg->flgatr;
185 p_flginib->iflgptn = pk_cflg->iflgptn;
186
187 queue_initialize(&(p_flgcb->wait_queue));
188 p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
189 ercd = E_OK;
190 }
191
192 error_exit:
193 LOG_CRE_FLG_LEAVE(ercd);
194 return(ercd);
195}
196
197#endif /* TOPPERS_cre_flg */
198
199/*
200 * イベントフラグ待ち解除条件のチェック
201 */
202#ifdef TOPPERS_flgcnd
203
204bool_t
205check_flg_cond(FLGCB *p_flgcb, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
206{
207 if ((wfmode & TWF_ORW) != 0U ? (p_flgcb->flgptn & waiptn) != 0U
208 : (p_flgcb->flgptn & waiptn) == waiptn) {
209 *p_flgptn = p_flgcb->flgptn;
210 if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
211 p_flgcb->flgptn = 0U;
212 }
213 return(true);
214 }
215 return(false);
216}
217
218#endif /* TOPPERS_flgcnd */
219
220/*
221 * イベントフラグのセット
222 */
223#ifdef TOPPERS_set_flg
224
225ER
226set_flg(ID flgid, FLGPTN setptn)
227{
228 FLGCB *p_flgcb;
229 QUEUE *p_queue;
230 TCB *p_tcb;
231 WINFO_FLG *p_winfo_flg;
232 bool_t dspreq = false;
233 ER ercd;
234
235 LOG_SET_FLG_ENTER(flgid, setptn);
236 CHECK_TSKCTX_UNL();
237 CHECK_FLGID(flgid);
238 p_flgcb = get_flgcb(flgid);
239 CHECK_NOEXS(p_flgcb->p_flginib->flgatr);
240
241 t_lock_cpu();
242 p_flgcb->flgptn |= setptn;
243 p_queue = p_flgcb->wait_queue.p_next;
244 while (p_queue != &(p_flgcb->wait_queue)) {
245 p_tcb = (TCB *) p_queue;
246 p_queue = p_queue->p_next;
247 p_winfo_flg = (WINFO_FLG *)(p_tcb->p_winfo);
248 if (check_flg_cond(p_flgcb, p_winfo_flg->waiptn,
249 p_winfo_flg->wfmode, &(p_winfo_flg->flgptn))) {
250 queue_delete(&(p_tcb->task_queue));
251 if (wait_complete(p_tcb)) {
252 dspreq = true;
253 }
254 if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
255 break;
256 }
257 }
258 }
259 if (dspreq) {
260 dispatch();
261 }
262 ercd = E_OK;
263 t_unlock_cpu();
264
265 error_exit:
266 LOG_SET_FLG_LEAVE(ercd);
267 return(ercd);
268}
269
270#endif /* TOPPERS_set_flg */
271
272/*
273 * イベントフラグのセット(非タスクコンテキスト用)
274 */
275#ifdef TOPPERS_iset_flg
276
277ER
278iset_flg(ID flgid, FLGPTN setptn)
279{
280 FLGCB *p_flgcb;
281 QUEUE *p_queue;
282 TCB *p_tcb;
283 WINFO_FLG *p_winfo_flg;
284 ER ercd;
285
286 LOG_ISET_FLG_ENTER(flgid, setptn);
287 CHECK_INTCTX_UNL();
288 CHECK_FLGID(flgid);
289 p_flgcb = get_flgcb(flgid);
290 CHECK_NOEXS(p_flgcb->p_flginib->flgatr);
291
292 i_lock_cpu();
293 p_flgcb->flgptn |= setptn;
294 p_queue = p_flgcb->wait_queue.p_next;
295 while (p_queue != &(p_flgcb->wait_queue)) {
296 p_tcb = (TCB *) p_queue;
297 p_queue = p_queue->p_next;
298 p_winfo_flg = (WINFO_FLG *)(p_tcb->p_winfo);
299 if (check_flg_cond(p_flgcb, p_winfo_flg->waiptn,
300 p_winfo_flg->wfmode, &(p_winfo_flg->flgptn))) {
301 queue_delete(&(p_tcb->task_queue));
302 if (wait_complete(p_tcb)) {
303 reqflg = true;
304 }
305 if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
306 break;
307 }
308 }
309 }
310 ercd = E_OK;
311 i_unlock_cpu();
312
313 error_exit:
314 LOG_ISET_FLG_LEAVE(ercd);
315 return(ercd);
316}
317
318#endif /* TOPPERS_iset_flg */
319
320/*
321 * イベントフラグのクリア
322 */
323#ifdef TOPPERS_clr_flg
324
325ER
326clr_flg(ID flgid, FLGPTN clrptn)
327{
328 FLGCB *p_flgcb;
329 ER ercd;
330
331 LOG_CLR_FLG_ENTER(flgid, clrptn);
332 CHECK_TSKCTX_UNL();
333 CHECK_FLGID(flgid);
334 p_flgcb = get_flgcb(flgid);
335 CHECK_NOEXS(p_flgcb->p_flginib->flgatr);
336
337 t_lock_cpu();
338 p_flgcb->flgptn &= clrptn;
339 ercd = E_OK;
340 t_unlock_cpu();
341
342 error_exit:
343 LOG_CLR_FLG_LEAVE(ercd);
344 return(ercd);
345}
346
347#endif /* TOPPERS_clr_flg */
348
349/*
350 * イベントフラグ待ち
351 */
352#ifdef TOPPERS_wai_flg
353
354ER
355wai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
356{
357 FLGCB *p_flgcb;
358 WINFO_FLG winfo_flg;
359 ER ercd;
360
361 LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
362 CHECK_DISPATCH();
363 CHECK_FLGID(flgid);
364 CHECK_PAR(waiptn != 0U);
365 CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
366 p_flgcb = get_flgcb(flgid);
367 CHECK_NOEXS(p_flgcb->p_flginib->flgatr);
368
369 t_lock_cpu();
370 if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
371 && !queue_empty(&(p_flgcb->wait_queue))) {
372 ercd = E_ILUSE;
373 }
374 else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
375 ercd = E_OK;
376 }
377 else {
378 winfo_flg.waiptn = waiptn;
379 winfo_flg.wfmode = wfmode;
380 p_runtsk->tstat = (TS_WAITING | TS_WAIT_FLG);
381 wobj_make_wait((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg);
382 dispatch();
383 ercd = winfo_flg.winfo.wercd;
384 if (ercd == E_OK) {
385 *p_flgptn = winfo_flg.flgptn;
386 }
387 }
388 t_unlock_cpu();
389
390 error_exit:
391 LOG_WAI_FLG_LEAVE(ercd, *p_flgptn);
392 return(ercd);
393}
394
395#endif /* TOPPERS_wai_flg */
396
397/*
398 * イベントフラグ待ち(ポーリング)
399 */
400#ifdef TOPPERS_pol_flg
401
402ER
403pol_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
404{
405 FLGCB *p_flgcb;
406 ER ercd;
407
408 LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
409 CHECK_TSKCTX_UNL();
410 CHECK_FLGID(flgid);
411 CHECK_PAR(waiptn != 0U);
412 CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
413 p_flgcb = get_flgcb(flgid);
414 CHECK_NOEXS(p_flgcb->p_flginib->flgatr);
415
416 t_lock_cpu();
417 if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
418 && !queue_empty(&(p_flgcb->wait_queue))) {
419 ercd = E_ILUSE;
420 }
421 else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
422 ercd = E_OK;
423 }
424 else {
425 ercd = E_TMOUT;
426 }
427 t_unlock_cpu();
428
429 error_exit:
430 LOG_POL_FLG_LEAVE(ercd, *p_flgptn);
431 return(ercd);
432}
433
434#endif /* TOPPERS_pol_flg */
435
436/*
437 * イベントフラグ待ち(タイムアウトあり)
438 */
439#ifdef TOPPERS_twai_flg
440
441ER
442twai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn, TMO tmout)
443{
444 FLGCB *p_flgcb;
445 WINFO_FLG winfo_flg;
446 TMEVTB tmevtb;
447 ER ercd;
448
449 LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout);
450 CHECK_DISPATCH();
451 CHECK_FLGID(flgid);
452 CHECK_PAR(waiptn != 0U);
453 CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
454 CHECK_TMOUT(tmout);
455 p_flgcb = get_flgcb(flgid);
456 CHECK_NOEXS(p_flgcb->p_flginib->flgatr);
457
458 t_lock_cpu();
459 if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
460 && !queue_empty(&(p_flgcb->wait_queue))) {
461 ercd = E_ILUSE;
462 }
463 else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
464 ercd = E_OK;
465 }
466 else if (tmout == TMO_POL) {
467 ercd = E_TMOUT;
468 }
469 else {
470 winfo_flg.waiptn = waiptn;
471 winfo_flg.wfmode = wfmode;
472 p_runtsk->tstat = (TS_WAITING | TS_WAIT_FLG);
473 wobj_make_wait_tmout((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg,
474 &tmevtb, tmout);
475 dispatch();
476 ercd = winfo_flg.winfo.wercd;
477 if (ercd == E_OK) {
478 *p_flgptn = winfo_flg.flgptn;
479 }
480 }
481 t_unlock_cpu();
482
483 error_exit:
484 LOG_TWAI_FLG_LEAVE(ercd, *p_flgptn);
485 return(ercd);
486}
487
488#endif /* TOPPERS_twai_flg */
489
490/*
491 * イベントフラグの再初期化
492 */
493#ifdef TOPPERS_ini_flg
494
495ER
496ini_flg(ID flgid)
497{
498 FLGCB *p_flgcb;
499 bool_t dspreq;
500 ER ercd;
501
502 LOG_INI_FLG_ENTER(flgid);
503 CHECK_TSKCTX_UNL();
504 CHECK_FLGID(flgid);
505 p_flgcb = get_flgcb(flgid);
506 CHECK_NOEXS(p_flgcb->p_flginib->flgatr);
507
508 t_lock_cpu();
509 dspreq = init_wait_queue(&(p_flgcb->wait_queue));
510 p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
511 if (dspreq) {
512 dispatch();
513 }
514 ercd = E_OK;
515 t_unlock_cpu();
516
517 error_exit:
518 LOG_INI_FLG_LEAVE(ercd);
519 return(ercd);
520}
521
522#endif /* TOPPERS_ini_flg */
523
524/*
525 * イベントフラグの状態参照
526 */
527#ifdef TOPPERS_ref_flg
528
529ER
530ref_flg(ID flgid, T_RFLG *pk_rflg)
531{
532 FLGCB *p_flgcb;
533 ER ercd;
534
535 LOG_REF_FLG_ENTER(flgid, pk_rflg);
536 CHECK_TSKCTX_UNL();
537 CHECK_FLGID(flgid);
538 p_flgcb = get_flgcb(flgid);
539 CHECK_NOEXS(p_flgcb->p_flginib->flgatr);
540
541 t_lock_cpu();
542 pk_rflg->wtskid = wait_tskid(&(p_flgcb->wait_queue));
543 pk_rflg->flgptn = p_flgcb->flgptn;
544 ercd = E_OK;
545 t_unlock_cpu();
546
547 error_exit:
548 LOG_REF_FLG_LEAVE(ercd, pk_rflg);
549 return(ercd);
550}
551
552#endif /* TOPPERS_ref_flg */
Note: See TracBrowser for help on using the repository browser.