source: UsbWattMeter/trunk/asp_dcre/kernel/eventflag.c@ 473

Last change on this file since 473 was 167, checked in by coas-nagasima, 8 years ago

MIMEにSJISを設定

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc; charset=SHIFT_JIS
File size: 13.8 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-2014 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 167 2016-03-08 11:37:45Z coas-nagasima $
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_ACRE_FLG_ENTER
57#define LOG_ACRE_FLG_ENTER(pk_cflg)
58#endif /* LOG_ACRE_FLG_ENTER */
59
60#ifndef LOG_ACRE_FLG_LEAVE
61#define LOG_ACRE_FLG_LEAVE(ercd)
62#endif /* LOG_ACRE_FLG_LEAVE */
63
64#ifndef LOG_DEL_FLG_ENTER
65#define LOG_DEL_FLG_ENTER(flgid)
66#endif /* LOG_DEL_FLG_ENTER */
67
68#ifndef LOG_DEL_FLG_LEAVE
69#define LOG_DEL_FLG_LEAVE(ercd)
70#endif /* LOG_DEL_FLG_LEAVE */
71
72#ifndef LOG_SET_FLG_ENTER
73#define LOG_SET_FLG_ENTER(flgid, setptn)
74#endif /* LOG_SET_FLG_ENTER */
75
76#ifndef LOG_SET_FLG_LEAVE
77#define LOG_SET_FLG_LEAVE(ercd)
78#endif /* LOG_SET_FLG_LEAVE */
79
80#ifndef LOG_ISET_FLG_ENTER
81#define LOG_ISET_FLG_ENTER(flgid, setptn)
82#endif /* LOG_ISET_FLG_ENTER */
83
84#ifndef LOG_ISET_FLG_LEAVE
85#define LOG_ISET_FLG_LEAVE(ercd)
86#endif /* LOG_ISET_FLG_LEAVE */
87
88#ifndef LOG_CLR_FLG_ENTER
89#define LOG_CLR_FLG_ENTER(flgid, clrptn)
90#endif /* LOG_CLR_FLG_ENTER */
91
92#ifndef LOG_CLR_FLG_LEAVE
93#define LOG_CLR_FLG_LEAVE(ercd)
94#endif /* LOG_CLR_FLG_LEAVE */
95
96#ifndef LOG_WAI_FLG_ENTER
97#define LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn)
98#endif /* LOG_WAI_FLG_ENTER */
99
100#ifndef LOG_WAI_FLG_LEAVE
101#define LOG_WAI_FLG_LEAVE(ercd, flgptn)
102#endif /* LOG_WAI_FLG_LEAVE */
103
104#ifndef LOG_POL_FLG_ENTER
105#define LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn)
106#endif /* LOG_POL_FLG_ENTER */
107
108#ifndef LOG_POL_FLG_LEAVE
109#define LOG_POL_FLG_LEAVE(ercd, flgptn)
110#endif /* LOG_POL_FLG_LEAVE */
111
112#ifndef LOG_TWAI_FLG_ENTER
113#define LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout)
114#endif /* LOG_TWAI_FLG_ENTER */
115
116#ifndef LOG_TWAI_FLG_LEAVE
117#define LOG_TWAI_FLG_LEAVE(ercd, flgptn)
118#endif /* LOG_TWAI_FLG_LEAVE */
119
120#ifndef LOG_INI_FLG_ENTER
121#define LOG_INI_FLG_ENTER(flgid)
122#endif /* LOG_INI_FLG_ENTER */
123
124#ifndef LOG_INI_FLG_LEAVE
125#define LOG_INI_FLG_LEAVE(ercd)
126#endif /* LOG_INI_FLG_LEAVE */
127
128#ifndef LOG_REF_FLG_ENTER
129#define LOG_REF_FLG_ENTER(flgid, pk_rflg)
130#endif /* LOG_REF_FLG_ENTER */
131
132#ifndef LOG_REF_FLG_LEAVE
133#define LOG_REF_FLG_LEAVE(ercd, pk_rflg)
134#endif /* LOG_REF_FLG_LEAVE */
135
136/*
137 * イベントフラグの数
138 */
139#define tnum_flg ((uint_t)(tmax_flgid - TMIN_FLGID + 1))
140#define tnum_sflg ((uint_t)(tmax_sflgid - TMIN_FLGID + 1))
141
142/*
143 * イベントフラグIDからイベントフラグ管理ブロックを取り出すためのマクロ
144 */
145#define INDEX_FLG(flgid) ((uint_t)((flgid) - TMIN_FLGID))
146#define get_flgcb(flgid) (&(flgcb_table[INDEX_FLG(flgid)]))
147
148#ifdef TOPPERS_flgini
149
150/*
151 * 使用していないイベントフラグ管理ブロックのリスト
152 */
153QUEUE free_flgcb;
154
155/*
156 * イベントフラグ機能の初期化
157 */
158void
159initialize_eventflag(void)
160{
161 uint_t i, j;
162 FLGCB *p_flgcb;
163 FLGINIB *p_flginib;
164
165 for (i = 0; i < tnum_sflg; i++) {
166 p_flgcb = &(flgcb_table[i]);
167 queue_initialize(&(p_flgcb->wait_queue));
168 p_flgcb->p_flginib = &(flginib_table[i]);
169 p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
170 }
171 queue_initialize(&free_flgcb);
172 for (j = 0; i < tnum_flg; i++, j++) {
173 p_flgcb = &(flgcb_table[i]);
174 p_flginib = &(aflginib_table[j]);
175 p_flginib->flgatr = TA_NOEXS;
176 p_flgcb->p_flginib = ((const FLGINIB *) p_flginib);
177 queue_insert_prev(&free_flgcb, &(p_flgcb->wait_queue));
178 }
179}
180
181#endif /* TOPPERS_flgini */
182
183/*
184 * イベントフラグ待ち解除条件のチェック
185 */
186#ifdef TOPPERS_flgcnd
187
188bool_t
189check_flg_cond(FLGCB *p_flgcb, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
190{
191 if ((wfmode & TWF_ORW) != 0U ? (p_flgcb->flgptn & waiptn) != 0U
192 : (p_flgcb->flgptn & waiptn) == waiptn) {
193 *p_flgptn = p_flgcb->flgptn;
194 if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
195 p_flgcb->flgptn = 0U;
196 }
197 return(true);
198 }
199 return(false);
200}
201
202#endif /* TOPPERS_flgcnd */
203
204/*
205 * イベントフラグの生成
206 */
207#ifdef TOPPERS_acre_flg
208
209ER_UINT
210acre_flg(const T_CFLG *pk_cflg)
211{
212 FLGCB *p_flgcb;
213 FLGINIB *p_flginib;
214 ER ercd;
215
216 LOG_ACRE_FLG_ENTER(pk_cflg);
217 CHECK_TSKCTX_UNL();
218 CHECK_RSATR(pk_cflg->flgatr, TA_TPRI|TA_WMUL|TA_CLR);
219
220 t_lock_cpu();
221 if (tnum_flg == 0 || queue_empty(&free_flgcb)) {
222 ercd = E_NOID;
223 }
224 else {
225 p_flgcb = ((FLGCB *) queue_delete_next(&free_flgcb));
226 p_flginib = (FLGINIB *)(p_flgcb->p_flginib);
227 p_flginib->flgatr = pk_cflg->flgatr;
228 p_flginib->iflgptn = pk_cflg->iflgptn;
229
230 queue_initialize(&(p_flgcb->wait_queue));
231 p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
232 ercd = FLGID(p_flgcb);
233 }
234 t_unlock_cpu();
235
236 error_exit:
237 LOG_ACRE_FLG_LEAVE(ercd);
238 return(ercd);
239}
240
241#endif /* TOPPERS_acre_flg */
242
243/*
244 * イベントフラグの削除
245 */
246#ifdef TOPPERS_del_flg
247
248ER
249del_flg(ID flgid)
250{
251 FLGCB *p_flgcb;
252 FLGINIB *p_flginib;
253 bool_t dspreq;
254 ER ercd;
255
256 LOG_DEL_FLG_ENTER(flgid);
257 CHECK_TSKCTX_UNL();
258 CHECK_FLGID(flgid);
259 p_flgcb = get_flgcb(flgid);
260
261 t_lock_cpu();
262 if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
263 ercd = E_NOEXS;
264 }
265 else if (FLGID(p_flgcb) > tmax_sflgid) {
266 dspreq = init_wait_queue(&(p_flgcb->wait_queue));
267 p_flginib = (FLGINIB *)(p_flgcb->p_flginib);
268 p_flginib->flgatr = TA_NOEXS;
269 queue_insert_prev(&free_flgcb, &(p_flgcb->wait_queue));
270 if (dspreq) {
271 dispatch();
272 }
273 ercd = E_OK;
274 }
275 else {
276 ercd = E_OBJ;
277 }
278 t_unlock_cpu();
279
280 error_exit:
281 LOG_DEL_FLG_LEAVE(ercd);
282 return(ercd);
283}
284
285#endif /* TOPPERS_del_flg */
286
287/*
288 * イベントフラグのセット
289 */
290#ifdef TOPPERS_set_flg
291
292ER
293set_flg(ID flgid, FLGPTN setptn)
294{
295 FLGCB *p_flgcb;
296 QUEUE *p_queue;
297 TCB *p_tcb;
298 WINFO_FLG *p_winfo_flg;
299 bool_t dspreq = false;
300 ER ercd;
301
302 LOG_SET_FLG_ENTER(flgid, setptn);
303 CHECK_TSKCTX_UNL();
304 CHECK_FLGID(flgid);
305 p_flgcb = get_flgcb(flgid);
306
307 t_lock_cpu();
308 if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
309 ercd = E_NOEXS;
310 }
311 else {
312 p_flgcb->flgptn |= setptn;
313 p_queue = p_flgcb->wait_queue.p_next;
314 while (p_queue != &(p_flgcb->wait_queue)) {
315 p_tcb = (TCB *) p_queue;
316 p_queue = p_queue->p_next;
317 p_winfo_flg = (WINFO_FLG *)(p_tcb->p_winfo);
318 if (check_flg_cond(p_flgcb, p_winfo_flg->waiptn,
319 p_winfo_flg->wfmode, &(p_winfo_flg->flgptn))) {
320 queue_delete(&(p_tcb->task_queue));
321 if (wait_complete(p_tcb)) {
322 dspreq = true;
323 }
324 if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
325 break;
326 }
327 }
328 }
329 if (dspreq) {
330 dispatch();
331 }
332 ercd = E_OK;
333 }
334 t_unlock_cpu();
335
336 error_exit:
337 LOG_SET_FLG_LEAVE(ercd);
338 return(ercd);
339}
340
341#endif /* TOPPERS_set_flg */
342
343/*
344 * イベントフラグのセット(非タスクコンテキスト用)
345 */
346#ifdef TOPPERS_iset_flg
347
348ER
349iset_flg(ID flgid, FLGPTN setptn)
350{
351 FLGCB *p_flgcb;
352 QUEUE *p_queue;
353 TCB *p_tcb;
354 WINFO_FLG *p_winfo_flg;
355 ER ercd;
356
357 LOG_ISET_FLG_ENTER(flgid, setptn);
358 CHECK_INTCTX_UNL();
359 CHECK_FLGID(flgid);
360 p_flgcb = get_flgcb(flgid);
361
362 i_lock_cpu();
363 if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
364 ercd = E_NOEXS;
365 }
366 else {
367 p_flgcb->flgptn |= setptn;
368 p_queue = p_flgcb->wait_queue.p_next;
369 while (p_queue != &(p_flgcb->wait_queue)) {
370 p_tcb = (TCB *) p_queue;
371 p_queue = p_queue->p_next;
372 p_winfo_flg = (WINFO_FLG *)(p_tcb->p_winfo);
373 if (check_flg_cond(p_flgcb, p_winfo_flg->waiptn,
374 p_winfo_flg->wfmode, &(p_winfo_flg->flgptn))) {
375 queue_delete(&(p_tcb->task_queue));
376 if (wait_complete(p_tcb)) {
377 reqflg = true;
378 }
379 if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
380 break;
381 }
382 }
383 }
384 ercd = E_OK;
385 }
386 i_unlock_cpu();
387
388 error_exit:
389 LOG_ISET_FLG_LEAVE(ercd);
390 return(ercd);
391}
392
393#endif /* TOPPERS_iset_flg */
394
395/*
396 * イベントフラグのクリア
397 */
398#ifdef TOPPERS_clr_flg
399
400ER
401clr_flg(ID flgid, FLGPTN clrptn)
402{
403 FLGCB *p_flgcb;
404 ER ercd;
405
406 LOG_CLR_FLG_ENTER(flgid, clrptn);
407 CHECK_TSKCTX_UNL();
408 CHECK_FLGID(flgid);
409 p_flgcb = get_flgcb(flgid);
410
411 t_lock_cpu();
412 if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
413 ercd = E_NOEXS;
414 }
415 else {
416 p_flgcb->flgptn &= clrptn;
417 ercd = E_OK;
418 }
419 t_unlock_cpu();
420
421 error_exit:
422 LOG_CLR_FLG_LEAVE(ercd);
423 return(ercd);
424}
425
426#endif /* TOPPERS_clr_flg */
427
428/*
429 * イベントフラグ待ち
430 */
431#ifdef TOPPERS_wai_flg
432
433ER
434wai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
435{
436 FLGCB *p_flgcb;
437 WINFO_FLG winfo_flg;
438 ER ercd;
439
440 LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
441 CHECK_DISPATCH();
442 CHECK_FLGID(flgid);
443 CHECK_PAR(waiptn != 0U);
444 CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
445 p_flgcb = get_flgcb(flgid);
446
447 t_lock_cpu();
448 if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
449 ercd = E_NOEXS;
450 }
451 else if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
452 && !queue_empty(&(p_flgcb->wait_queue))) {
453 ercd = E_ILUSE;
454 }
455 else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
456 ercd = E_OK;
457 }
458 else {
459 winfo_flg.waiptn = waiptn;
460 winfo_flg.wfmode = wfmode;
461 p_runtsk->tstat = (TS_WAITING | TS_WAIT_FLG);
462 wobj_make_wait((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg);
463 dispatch();
464 ercd = winfo_flg.winfo.wercd;
465 if (ercd == E_OK) {
466 *p_flgptn = winfo_flg.flgptn;
467 }
468 }
469 t_unlock_cpu();
470
471 error_exit:
472 LOG_WAI_FLG_LEAVE(ercd, *p_flgptn);
473 return(ercd);
474}
475
476#endif /* TOPPERS_wai_flg */
477
478/*
479 * イベントフラグ待ち(ポーリング)
480 */
481#ifdef TOPPERS_pol_flg
482
483ER
484pol_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
485{
486 FLGCB *p_flgcb;
487 ER ercd;
488
489 LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
490 CHECK_TSKCTX_UNL();
491 CHECK_FLGID(flgid);
492 CHECK_PAR(waiptn != 0U);
493 CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
494 p_flgcb = get_flgcb(flgid);
495
496 t_lock_cpu();
497 if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
498 ercd = E_NOEXS;
499 }
500 else if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
501 && !queue_empty(&(p_flgcb->wait_queue))) {
502 ercd = E_ILUSE;
503 }
504 else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
505 ercd = E_OK;
506 }
507 else {
508 ercd = E_TMOUT;
509 }
510 t_unlock_cpu();
511
512 error_exit:
513 LOG_POL_FLG_LEAVE(ercd, *p_flgptn);
514 return(ercd);
515}
516
517#endif /* TOPPERS_pol_flg */
518
519/*
520 * イベントフラグ待ち(タイムアウトあり)
521 */
522#ifdef TOPPERS_twai_flg
523
524ER
525twai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn, TMO tmout)
526{
527 FLGCB *p_flgcb;
528 WINFO_FLG winfo_flg;
529 TMEVTB tmevtb;
530 ER ercd;
531
532 LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout);
533 CHECK_DISPATCH();
534 CHECK_FLGID(flgid);
535 CHECK_PAR(waiptn != 0U);
536 CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
537 CHECK_TMOUT(tmout);
538 p_flgcb = get_flgcb(flgid);
539
540 t_lock_cpu();
541 if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
542 ercd = E_NOEXS;
543 }
544 else if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
545 && !queue_empty(&(p_flgcb->wait_queue))) {
546 ercd = E_ILUSE;
547 }
548 else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
549 ercd = E_OK;
550 }
551 else if (tmout == TMO_POL) {
552 ercd = E_TMOUT;
553 }
554 else {
555 winfo_flg.waiptn = waiptn;
556 winfo_flg.wfmode = wfmode;
557 p_runtsk->tstat = (TS_WAITING | TS_WAIT_FLG);
558 wobj_make_wait_tmout((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg,
559 &tmevtb, tmout);
560 dispatch();
561 ercd = winfo_flg.winfo.wercd;
562 if (ercd == E_OK) {
563 *p_flgptn = winfo_flg.flgptn;
564 }
565 }
566 t_unlock_cpu();
567
568 error_exit:
569 LOG_TWAI_FLG_LEAVE(ercd, *p_flgptn);
570 return(ercd);
571}
572
573#endif /* TOPPERS_twai_flg */
574
575/*
576 * イベントフラグの再初期化
577 */
578#ifdef TOPPERS_ini_flg
579
580ER
581ini_flg(ID flgid)
582{
583 FLGCB *p_flgcb;
584 bool_t dspreq;
585 ER ercd;
586
587 LOG_INI_FLG_ENTER(flgid);
588 CHECK_TSKCTX_UNL();
589 CHECK_FLGID(flgid);
590 p_flgcb = get_flgcb(flgid);
591
592 t_lock_cpu();
593 if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
594 ercd = E_NOEXS;
595 }
596 else {
597 dspreq = init_wait_queue(&(p_flgcb->wait_queue));
598 p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
599 if (dspreq) {
600 dispatch();
601 }
602 ercd = E_OK;
603 }
604 t_unlock_cpu();
605
606 error_exit:
607 LOG_INI_FLG_LEAVE(ercd);
608 return(ercd);
609}
610
611#endif /* TOPPERS_ini_flg */
612
613/*
614 * イベントフラグの状態参照
615 */
616#ifdef TOPPERS_ref_flg
617
618ER
619ref_flg(ID flgid, T_RFLG *pk_rflg)
620{
621 FLGCB *p_flgcb;
622 ER ercd;
623
624 LOG_REF_FLG_ENTER(flgid, pk_rflg);
625 CHECK_TSKCTX_UNL();
626 CHECK_FLGID(flgid);
627 p_flgcb = get_flgcb(flgid);
628
629 t_lock_cpu();
630 if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
631 ercd = E_NOEXS;
632 }
633 else {
634 pk_rflg->wtskid = wait_tskid(&(p_flgcb->wait_queue));
635 pk_rflg->flgptn = p_flgcb->flgptn;
636 ercd = E_OK;
637 }
638 t_unlock_cpu();
639
640 error_exit:
641 LOG_REF_FLG_LEAVE(ercd, pk_rflg);
642 return(ercd);
643}
644
645#endif /* TOPPERS_ref_flg */
Note: See TracBrowser for help on using the repository browser.