source: EcnlProtoTool/trunk/asp3_dcre/kernel/eventflag.c@ 429

Last change on this file since 429 was 429, checked in by coas-nagasima, 4 years ago

ASP3, TINET, mbed を更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 14.0 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-2018 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$
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_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, p_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, p_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, p_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#define tnum_sflg ((uint_t)(tmax_sflgid - TMIN_FLGID + 1))
133
134/*
135 * イベントフラグIDからイベントフラグ管理ブロックを取り出すためのマクロ
136 */
137#define INDEX_FLG(flgid) ((uint_t)((flgid) - TMIN_FLGID))
138#define get_flgcb(flgid) (&(flgcb_table[INDEX_FLG(flgid)]))
139
140#ifdef TOPPERS_flgini
141
142/*
143 * 使用していないイベントフラグ管理ブロックのリスト
144 */
145QUEUE free_flgcb;
146
147/*
148 * イベントフラグ機能の初期化
149 */
150void
151initialize_eventflag(void)
152{
153 uint_t i, j;
154 FLGCB *p_flgcb;
155 FLGINIB *p_flginib;
156
157 for (i = 0; i < tnum_sflg; i++) {
158 p_flgcb = &(flgcb_table[i]);
159 queue_initialize(&(p_flgcb->wait_queue));
160 p_flgcb->p_flginib = &(flginib_table[i]);
161 p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
162 }
163 queue_initialize(&free_flgcb);
164 for (j = 0; i < tnum_flg; i++, j++) {
165 p_flgcb = &(flgcb_table[i]);
166 p_flginib = &(aflginib_table[j]);
167 p_flginib->flgatr = TA_NOEXS;
168 p_flgcb->p_flginib = ((const FLGINIB *) p_flginib);
169 queue_insert_prev(&free_flgcb, &(p_flgcb->wait_queue));
170 }
171}
172
173#endif /* TOPPERS_flgini */
174
175/*
176 * イベントフラグ待ち解除条件のチェック
177 */
178#ifdef TOPPERS_flgcnd
179
180bool_t
181check_flg_cond(FLGCB *p_flgcb, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
182{
183 if ((wfmode & TWF_ORW) != 0U ? (p_flgcb->flgptn & waiptn) != 0U
184 : (p_flgcb->flgptn & waiptn) == waiptn) {
185 *p_flgptn = p_flgcb->flgptn;
186 if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
187 p_flgcb->flgptn = 0U;
188 }
189 return(true);
190 }
191 return(false);
192}
193
194#endif /* TOPPERS_flgcnd */
195
196/*
197 * イベントフラグの生成
198 *
199 * pk_cflg->iflgptnは,エラーチェックをせず,一度しか参照しないため,
200 * ローカル変数にコピーする必要がない(途中で書き換わっても支障がな
201 * い).
202 */
203#ifdef TOPPERS_acre_flg
204
205ER_UINT
206acre_flg(const T_CFLG *pk_cflg)
207{
208 FLGCB *p_flgcb;
209 FLGINIB *p_flginib;
210 ATR flgatr;
211 ER ercd;
212
213 LOG_ACRE_FLG_ENTER(pk_cflg);
214 CHECK_TSKCTX_UNL();
215
216 flgatr = pk_cflg->flgatr;
217
218 CHECK_VALIDATR(flgatr, TA_TPRI|TA_WMUL|TA_CLR);
219
220 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 = 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 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 ER ercd;
254
255 LOG_DEL_FLG_ENTER(flgid);
256 CHECK_TSKCTX_UNL();
257 CHECK_PAR(VALID_FLGID(flgid));
258 p_flgcb = get_flgcb(flgid);
259
260 lock_cpu();
261 if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
262 ercd = E_NOEXS;
263 }
264 else if (flgid <= tmax_sflgid) {
265 ercd = E_OBJ;
266 }
267 else {
268 init_wait_queue(&(p_flgcb->wait_queue));
269 p_flginib = (FLGINIB *)(p_flgcb->p_flginib);
270 p_flginib->flgatr = TA_NOEXS;
271 queue_insert_prev(&free_flgcb, &(p_flgcb->wait_queue));
272 if (p_runtsk != p_schedtsk) {
273 dispatch();
274 }
275 ercd = E_OK;
276 }
277 unlock_cpu();
278
279 error_exit:
280 LOG_DEL_FLG_LEAVE(ercd);
281 return(ercd);
282}
283
284#endif /* TOPPERS_del_flg */
285
286/*
287 * イベントフラグのセット
288 */
289#ifdef TOPPERS_set_flg
290
291ER
292set_flg(ID flgid, FLGPTN setptn)
293{
294 FLGCB *p_flgcb;
295 QUEUE *p_queue;
296 TCB *p_tcb;
297 WINFO_FLG *p_winfo_flg;
298 bool_t lock;
299 ER ercd;
300
301 LOG_SET_FLG_ENTER(flgid, setptn);
302 lock = sense_lock();
303 CHECK_ID(VALID_FLGID(flgid));
304 p_flgcb = get_flgcb(flgid);
305
306 if (!lock)
307 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->waiptn))) {
320 queue_delete(&(p_tcb->task_queue));
321 wait_complete(p_tcb);
322 if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
323 break;
324 }
325 }
326 }
327 if (p_runtsk != p_schedtsk) {
328 if (!sense_context()) {
329 dispatch();
330 }
331 else {
332 request_dispatch_retint();
333 }
334 }
335 ercd = E_OK;
336 }
337 if (!lock)
338 unlock_cpu();
339
340 error_exit:
341 LOG_SET_FLG_LEAVE(ercd);
342 return(ercd);
343}
344
345#endif /* TOPPERS_set_flg */
346
347/*
348 * イベントフラグのクリア
349 */
350#ifdef TOPPERS_clr_flg
351
352ER
353clr_flg(ID flgid, FLGPTN clrptn)
354{
355 FLGCB *p_flgcb;
356 bool_t lock;
357 ER ercd;
358
359 LOG_CLR_FLG_ENTER(flgid, clrptn);
360 lock = sense_lock();
361 CHECK_ID(VALID_FLGID(flgid));
362 p_flgcb = get_flgcb(flgid);
363
364 if (!lock)
365 lock_cpu();
366 if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
367 ercd = E_NOEXS;
368 }
369 else {
370 p_flgcb->flgptn &= clrptn;
371 ercd = E_OK;
372 }
373 if (!lock)
374 unlock_cpu();
375
376 error_exit:
377 LOG_CLR_FLG_LEAVE(ercd);
378 return(ercd);
379}
380
381#endif /* TOPPERS_clr_flg */
382
383/*
384 * イベントフラグ待ち
385 */
386#ifdef TOPPERS_wai_flg
387
388ER
389wai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
390{
391 FLGCB *p_flgcb;
392 WINFO_FLG winfo_flg;
393 ER ercd;
394
395 LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
396 CHECK_DISPATCH();
397 CHECK_ID(VALID_FLGID(flgid));
398 CHECK_PAR(waiptn != 0U);
399 CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
400 p_flgcb = get_flgcb(flgid);
401
402 lock_cpu_dsp();
403 if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
404 ercd = E_NOEXS;
405 }
406 else if (p_runtsk->raster) {
407 ercd = E_RASTER;
408 }
409 else if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
410 && !queue_empty(&(p_flgcb->wait_queue))) {
411 ercd = E_ILUSE;
412 }
413 else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
414 ercd = E_OK;
415 }
416 else {
417 winfo_flg.waiptn = waiptn;
418 winfo_flg.wfmode = wfmode;
419 wobj_make_wait((WOBJCB *) p_flgcb, TS_WAITING_FLG,
420 (WINFO_WOBJ *) &winfo_flg);
421 dispatch();
422 ercd = winfo_flg.winfo.wercd;
423 if (ercd == E_OK) {
424 *p_flgptn = winfo_flg.waiptn;
425 }
426 }
427 unlock_cpu_dsp();
428
429 error_exit:
430 LOG_WAI_FLG_LEAVE(ercd, p_flgptn);
431 return(ercd);
432}
433
434#endif /* TOPPERS_wai_flg */
435
436/*
437 * イベントフラグ待ち(ポーリング)
438 */
439#ifdef TOPPERS_pol_flg
440
441ER
442pol_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
443{
444 FLGCB *p_flgcb;
445 ER ercd;
446
447 LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
448 CHECK_TSKCTX_UNL();
449 CHECK_ID(VALID_FLGID(flgid));
450 CHECK_PAR(waiptn != 0U);
451 CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
452 p_flgcb = get_flgcb(flgid);
453
454 lock_cpu();
455 if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
456 ercd = E_NOEXS;
457 }
458 else if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
459 && !queue_empty(&(p_flgcb->wait_queue))) {
460 ercd = E_ILUSE;
461 }
462 else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
463 ercd = E_OK;
464 }
465 else {
466 ercd = E_TMOUT;
467 }
468 unlock_cpu();
469
470 error_exit:
471 LOG_POL_FLG_LEAVE(ercd, p_flgptn);
472 return(ercd);
473}
474
475#endif /* TOPPERS_pol_flg */
476
477/*
478 * イベントフラグ待ち(タイムアウトあり)
479 */
480#ifdef TOPPERS_twai_flg
481
482ER
483twai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn, TMO tmout)
484{
485 FLGCB *p_flgcb;
486 WINFO_FLG winfo_flg;
487 TMEVTB tmevtb;
488 ER ercd;
489
490 LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout);
491 CHECK_DISPATCH();
492 CHECK_ID(VALID_FLGID(flgid));
493 CHECK_PAR(waiptn != 0U);
494 CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
495 CHECK_PAR(VALID_TMOUT(tmout));
496 p_flgcb = get_flgcb(flgid);
497
498 lock_cpu_dsp();
499 if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
500 ercd = E_NOEXS;
501 }
502 else if (p_runtsk->raster) {
503 ercd = E_RASTER;
504 }
505 else if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
506 && !queue_empty(&(p_flgcb->wait_queue))) {
507 ercd = E_ILUSE;
508 }
509 else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
510 ercd = E_OK;
511 }
512 else if (tmout == TMO_POL) {
513 ercd = E_TMOUT;
514 }
515 else {
516 winfo_flg.waiptn = waiptn;
517 winfo_flg.wfmode = wfmode;
518 wobj_make_wait_tmout((WOBJCB *) p_flgcb, TS_WAITING_FLG,
519 (WINFO_WOBJ *) &winfo_flg, &tmevtb, tmout);
520 dispatch();
521 ercd = winfo_flg.winfo.wercd;
522 if (ercd == E_OK) {
523 *p_flgptn = winfo_flg.waiptn;
524 }
525 }
526 unlock_cpu_dsp();
527
528 error_exit:
529 LOG_TWAI_FLG_LEAVE(ercd, p_flgptn);
530 return(ercd);
531}
532
533#endif /* TOPPERS_twai_flg */
534
535/*
536 * イベントフラグの再初期化
537 */
538#ifdef TOPPERS_ini_flg
539
540ER
541ini_flg(ID flgid)
542{
543 FLGCB *p_flgcb;
544 ER ercd;
545
546 LOG_INI_FLG_ENTER(flgid);
547 CHECK_TSKCTX_UNL();
548 CHECK_ID(VALID_FLGID(flgid));
549 p_flgcb = get_flgcb(flgid);
550
551 lock_cpu();
552 if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
553 ercd = E_NOEXS;
554 }
555 else {
556 init_wait_queue(&(p_flgcb->wait_queue));
557 p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
558 if (p_runtsk != p_schedtsk) {
559 dispatch();
560 }
561 ercd = E_OK;
562 }
563 unlock_cpu();
564
565 error_exit:
566 LOG_INI_FLG_LEAVE(ercd);
567 return(ercd);
568}
569
570#endif /* TOPPERS_ini_flg */
571
572/*
573 * イベントフラグの状態参照
574 */
575#ifdef TOPPERS_ref_flg
576
577ER
578ref_flg(ID flgid, T_RFLG *pk_rflg)
579{
580 FLGCB *p_flgcb;
581 ER ercd;
582 bool_t lock;
583
584 LOG_REF_FLG_ENTER(flgid, pk_rflg);
585 lock = sense_lock();
586 CHECK_ID(VALID_FLGID(flgid));
587 p_flgcb = get_flgcb(flgid);
588
589 if (!lock)
590 lock_cpu();
591 if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
592 ercd = E_NOEXS;
593 }
594 else {
595 pk_rflg->wtskid = wait_tskid(&(p_flgcb->wait_queue));
596 pk_rflg->flgptn = p_flgcb->flgptn;
597 ercd = E_OK;
598 }
599 if (!lock)
600 unlock_cpu();
601
602 error_exit:
603 LOG_REF_FLG_LEAVE(ercd, pk_rflg);
604 return(ercd);
605}
606
607#endif /* TOPPERS_ref_flg */
Note: See TracBrowser for help on using the repository browser.