source: asp3_wo_tecs/trunk/kernel/eventflag.c@ 302

Last change on this file since 302 was 302, checked in by ertl-honda, 7 years ago

TECSレスのASP3の開発のため以下のtrunkからコピー
http://dev.toppers.jp/svn/asp3/branches/WO_TECS-3.C.0

File size: 10.9 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-2015 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 * 上記著作権者
12は,以下の(1)〜(4)の条件を満たす場合に限り,本ソフトウェ
13 * ア(本ソフトウェアを改変したものを含む.以下同じ)を使用・複製・改
14 * 変・再é…
15å¸ƒï¼ˆä»¥ä¸‹ï¼Œåˆ©ç”¨ã¨å‘¼ã¶ï¼‰ã™ã‚‹ã“とを無償で許諾する.
16 * (1) 本ソフトウェアをソースコードの形で利用する場合には,上記の著作
17 * 権表示,この利用条件および下記の無保証規定が,そのままの形でソー
18 * スコード中に含まれていること.
19 * (2) 本ソフトウェアを,ライブラリ形式など,他のソフトウェア開発に使
20 * 用できる形で再é…
21å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œå†é…
22å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨
23 * 者
24マニュアルなど)に,上記の著作権表示,この利用条件および下記
25 * の無保証規定を掲載すること.
26 * (3) 本ソフトウェアを,機器に組み込むなど,他のソフトウェア開発に使
27 * 用できない形で再é…
28å¸ƒã™ã‚‹å ´åˆã«ã¯ï¼Œæ¬¡ã®ã„ずれかの条件を満たすこ
29 * と.
30 * (a) 再é…
31å¸ƒã«ä¼´ã†ãƒ‰ã‚­ãƒ¥ãƒ¡ãƒ³ãƒˆï¼ˆåˆ©ç”¨è€…
32マニュアルなど)に,上記の著
33 * 作権表示,この利用条件および下記の無保証規定を掲載すること.
34 * (b) 再é…
35å¸ƒã®å½¢æ…
36‹ã‚’,別に定める方法によって,TOPPERSプロジェクトに
37 * 報告すること.
38 * (4) 本ソフトウェアの利用により直接的または間接的に生じるいかなる損
39 * 害からも,上記著作権者
40およびTOPPERSプロジェクトをå…
41è²¬ã™ã‚‹ã“と.
42 * また,本ソフトウェアのユーザまたはエンドユーザからのいかなる理
43 * 由に基づく請求からも,上記著作権者
44およびTOPPERSプロジェクトを
45 * å…
46è²¬ã™ã‚‹ã“と.
47 *
48 * 本ソフトウェアは,無保証で提供されているものである.上記著作権者
49お
50 * よびTOPPERSプロジェクトは,本ソフトウェアに関して,特定の使用目的
51 * に対する適合性も含めて,いかなる保証も行わない.また,本ソフトウェ
52 * アの利用により直接的または間接的に生じたいかなる損害に関しても,そ
53 * の責任を負わない.
54 *
55 * $Id: eventflag.c 471 2015-12-30 10:03:16Z ertl-hiro $
56 */
57
58/*
59 * イベントフラグ機能
60 */
61
62#include "kernel_impl.h"
63#include "check.h"
64#include "task.h"
65#include "wait.h"
66#include "eventflag.h"
67
68/*
69 * トレースログマクロのデフォルト定義
70 */
71#ifndef LOG_SET_FLG_ENTER
72#define LOG_SET_FLG_ENTER(flgid, setptn)
73#endif /* LOG_SET_FLG_ENTER */
74
75#ifndef LOG_SET_FLG_LEAVE
76#define LOG_SET_FLG_LEAVE(ercd)
77#endif /* LOG_SET_FLG_LEAVE */
78
79#ifndef LOG_CLR_FLG_ENTER
80#define LOG_CLR_FLG_ENTER(flgid, clrptn)
81#endif /* LOG_CLR_FLG_ENTER */
82
83#ifndef LOG_CLR_FLG_LEAVE
84#define LOG_CLR_FLG_LEAVE(ercd)
85#endif /* LOG_CLR_FLG_LEAVE */
86
87#ifndef LOG_WAI_FLG_ENTER
88#define LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn)
89#endif /* LOG_WAI_FLG_ENTER */
90
91#ifndef LOG_WAI_FLG_LEAVE
92#define LOG_WAI_FLG_LEAVE(ercd, p_flgptn)
93#endif /* LOG_WAI_FLG_LEAVE */
94
95#ifndef LOG_POL_FLG_ENTER
96#define LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn)
97#endif /* LOG_POL_FLG_ENTER */
98
99#ifndef LOG_POL_FLG_LEAVE
100#define LOG_POL_FLG_LEAVE(ercd, p_flgptn)
101#endif /* LOG_POL_FLG_LEAVE */
102
103#ifndef LOG_TWAI_FLG_ENTER
104#define LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout)
105#endif /* LOG_TWAI_FLG_ENTER */
106
107#ifndef LOG_TWAI_FLG_LEAVE
108#define LOG_TWAI_FLG_LEAVE(ercd, p_flgptn)
109#endif /* LOG_TWAI_FLG_LEAVE */
110
111#ifndef LOG_INI_FLG_ENTER
112#define LOG_INI_FLG_ENTER(flgid)
113#endif /* LOG_INI_FLG_ENTER */
114
115#ifndef LOG_INI_FLG_LEAVE
116#define LOG_INI_FLG_LEAVE(ercd)
117#endif /* LOG_INI_FLG_LEAVE */
118
119#ifndef LOG_REF_FLG_ENTER
120#define LOG_REF_FLG_ENTER(flgid, pk_rflg)
121#endif /* LOG_REF_FLG_ENTER */
122
123#ifndef LOG_REF_FLG_LEAVE
124#define LOG_REF_FLG_LEAVE(ercd, pk_rflg)
125#endif /* LOG_REF_FLG_LEAVE */
126
127/*
128 * イベントフラグの数
129 */
130#define tnum_flg ((uint_t)(tmax_flgid - TMIN_FLGID + 1))
131
132/*
133 * イベントフラグIDからイベントフラグ管理ブロックを取り出すためのマクロ
134 */
135#define INDEX_FLG(flgid) ((uint_t)((flgid) - TMIN_FLGID))
136#define get_flgcb(flgid) (&(flgcb_table[INDEX_FLG(flgid)]))
137
138/*
139 * イベントフラグ機能の初期化
140 */
141#ifdef TOPPERS_flgini
142
143void
144initialize_eventflag(void)
145{
146 uint_t i;
147 FLGCB *p_flgcb;
148
149 for (i = 0; i < tnum_flg; i++) {
150 p_flgcb = &(flgcb_table[i]);
151 queue_initialize(&(p_flgcb->wait_queue));
152 p_flgcb->p_flginib = &(flginib_table[i]);
153 p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
154 }
155}
156
157#endif /* TOPPERS_flgini */
158
159/*
160 * イベントフラグ待
161ち解除条件のチェック
162 */
163#ifdef TOPPERS_flgcnd
164
165bool_t
166check_flg_cond(FLGCB *p_flgcb, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
167{
168 if ((wfmode & TWF_ORW) != 0U ? (p_flgcb->flgptn & waiptn) != 0U
169 : (p_flgcb->flgptn & waiptn) == waiptn) {
170 *p_flgptn = p_flgcb->flgptn;
171 if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
172 p_flgcb->flgptn = 0U;
173 }
174 return(true);
175 }
176 return(false);
177}
178
179#endif /* TOPPERS_flgcnd */
180
181/*
182 * イベントフラグのセット
183 */
184#ifdef TOPPERS_set_flg
185
186ER
187set_flg(ID flgid, FLGPTN setptn)
188{
189 FLGCB *p_flgcb;
190 QUEUE *p_queue;
191 TCB *p_tcb;
192 WINFO_FLG *p_winfo_flg;
193 ER ercd;
194
195 LOG_SET_FLG_ENTER(flgid, setptn);
196 CHECK_UNL();
197 CHECK_ID(VALID_FLGID(flgid));
198 p_flgcb = get_flgcb(flgid);
199
200 lock_cpu();
201 p_flgcb->flgptn |= setptn;
202 p_queue = p_flgcb->wait_queue.p_next;
203 while (p_queue != &(p_flgcb->wait_queue)) {
204 p_tcb = (TCB *) p_queue;
205 p_queue = p_queue->p_next;
206 p_winfo_flg = (WINFO_FLG *)(p_tcb->p_winfo);
207 if (check_flg_cond(p_flgcb, p_winfo_flg->waiptn,
208 p_winfo_flg->wfmode, &(p_winfo_flg->waiptn))) {
209 queue_delete(&(p_tcb->task_queue));
210 wait_complete(p_tcb);
211 if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
212 break;
213 }
214 }
215 }
216 if (p_runtsk != p_schedtsk) {
217 if (!sense_context()) {
218 dispatch();
219 }
220 else {
221 request_dispatch();
222 }
223 }
224 ercd = E_OK;
225 unlock_cpu();
226
227 error_exit:
228 LOG_SET_FLG_LEAVE(ercd);
229 return(ercd);
230}
231
232#endif /* TOPPERS_set_flg */
233
234/*
235 * イベントフラグのクリア
236 */
237#ifdef TOPPERS_clr_flg
238
239ER
240clr_flg(ID flgid, FLGPTN clrptn)
241{
242 FLGCB *p_flgcb;
243 ER ercd;
244
245 LOG_CLR_FLG_ENTER(flgid, clrptn);
246 CHECK_TSKCTX_UNL();
247 CHECK_ID(VALID_FLGID(flgid));
248 p_flgcb = get_flgcb(flgid);
249
250 lock_cpu();
251 p_flgcb->flgptn &= clrptn;
252 ercd = E_OK;
253 unlock_cpu();
254
255 error_exit:
256 LOG_CLR_FLG_LEAVE(ercd);
257 return(ercd);
258}
259
260#endif /* TOPPERS_clr_flg */
261
262/*
263 * イベントフラグ待
264ち
265 */
266#ifdef TOPPERS_wai_flg
267
268ER
269wai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
270{
271 FLGCB *p_flgcb;
272 WINFO_FLG winfo_flg;
273 ER ercd;
274
275 LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
276 CHECK_DISPATCH();
277 CHECK_ID(VALID_FLGID(flgid));
278 CHECK_PAR(waiptn != 0U);
279 CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
280 p_flgcb = get_flgcb(flgid);
281
282 lock_cpu_dsp();
283 if (p_runtsk->raster) {
284 ercd = E_RASTER;
285 }
286 else if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
287 && !queue_empty(&(p_flgcb->wait_queue))) {
288 ercd = E_ILUSE;
289 }
290 else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
291 ercd = E_OK;
292 }
293 else {
294 winfo_flg.waiptn = waiptn;
295 winfo_flg.wfmode = wfmode;
296 p_runtsk->tstat = TS_WAITING_FLG;
297 wobj_make_wait((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg);
298 dispatch();
299 ercd = winfo_flg.winfo.wercd;
300 if (ercd == E_OK) {
301 *p_flgptn = winfo_flg.waiptn;
302 }
303 }
304 unlock_cpu_dsp();
305
306 error_exit:
307 LOG_WAI_FLG_LEAVE(ercd, p_flgptn);
308 return(ercd);
309}
310
311#endif /* TOPPERS_wai_flg */
312
313/*
314 * イベントフラグ待
315ち(ポーリング)
316 */
317#ifdef TOPPERS_pol_flg
318
319ER
320pol_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
321{
322 FLGCB *p_flgcb;
323 ER ercd;
324
325 LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
326 CHECK_TSKCTX_UNL();
327 CHECK_ID(VALID_FLGID(flgid));
328 CHECK_PAR(waiptn != 0U);
329 CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
330 p_flgcb = get_flgcb(flgid);
331
332 lock_cpu();
333 if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
334 && !queue_empty(&(p_flgcb->wait_queue))) {
335 ercd = E_ILUSE;
336 }
337 else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
338 ercd = E_OK;
339 }
340 else {
341 ercd = E_TMOUT;
342 }
343 unlock_cpu();
344
345 error_exit:
346 LOG_POL_FLG_LEAVE(ercd, p_flgptn);
347 return(ercd);
348}
349
350#endif /* TOPPERS_pol_flg */
351
352/*
353 * イベントフラグ待
354ち(タイムアウトあり)
355 */
356#ifdef TOPPERS_twai_flg
357
358ER
359twai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn, TMO tmout)
360{
361 FLGCB *p_flgcb;
362 WINFO_FLG winfo_flg;
363 TMEVTB tmevtb;
364 ER ercd;
365
366 LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout);
367 CHECK_DISPATCH();
368 CHECK_ID(VALID_FLGID(flgid));
369 CHECK_PAR(waiptn != 0U);
370 CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
371 CHECK_PAR(VALID_TMOUT(tmout));
372 p_flgcb = get_flgcb(flgid);
373
374 lock_cpu_dsp();
375 if (p_runtsk->raster) {
376 ercd = E_RASTER;
377 }
378 else if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
379 && !queue_empty(&(p_flgcb->wait_queue))) {
380 ercd = E_ILUSE;
381 }
382 else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
383 ercd = E_OK;
384 }
385 else if (tmout == TMO_POL) {
386 ercd = E_TMOUT;
387 }
388 else {
389 winfo_flg.waiptn = waiptn;
390 winfo_flg.wfmode = wfmode;
391 p_runtsk->tstat = TS_WAITING_FLG;
392 wobj_make_wait_tmout((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg,
393 &tmevtb, tmout);
394 dispatch();
395 ercd = winfo_flg.winfo.wercd;
396 if (ercd == E_OK) {
397 *p_flgptn = winfo_flg.waiptn;
398 }
399 }
400 unlock_cpu_dsp();
401
402 error_exit:
403 LOG_TWAI_FLG_LEAVE(ercd, p_flgptn);
404 return(ercd);
405}
406
407#endif /* TOPPERS_twai_flg */
408
409/*
410 * イベントフラグの再初期化
411 */
412#ifdef TOPPERS_ini_flg
413
414ER
415ini_flg(ID flgid)
416{
417 FLGCB *p_flgcb;
418 ER ercd;
419
420 LOG_INI_FLG_ENTER(flgid);
421 CHECK_TSKCTX_UNL();
422 CHECK_ID(VALID_FLGID(flgid));
423 p_flgcb = get_flgcb(flgid);
424
425 lock_cpu();
426 init_wait_queue(&(p_flgcb->wait_queue));
427 p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
428 if (p_runtsk != p_schedtsk) {
429 dispatch();
430 }
431 ercd = E_OK;
432 unlock_cpu();
433
434 error_exit:
435 LOG_INI_FLG_LEAVE(ercd);
436 return(ercd);
437}
438
439#endif /* TOPPERS_ini_flg */
440
441/*
442 * イベントフラグの状æ…
443‹å‚ç…
444§
445 */
446#ifdef TOPPERS_ref_flg
447
448ER
449ref_flg(ID flgid, T_RFLG *pk_rflg)
450{
451 FLGCB *p_flgcb;
452 ER ercd;
453
454 LOG_REF_FLG_ENTER(flgid, pk_rflg);
455 CHECK_TSKCTX_UNL();
456 CHECK_ID(VALID_FLGID(flgid));
457 p_flgcb = get_flgcb(flgid);
458
459 lock_cpu();
460 pk_rflg->wtskid = wait_tskid(&(p_flgcb->wait_queue));
461 pk_rflg->flgptn = p_flgcb->flgptn;
462 ercd = E_OK;
463 unlock_cpu();
464
465 error_exit:
466 LOG_REF_FLG_LEAVE(ercd, pk_rflg);
467 return(ercd);
468}
469
470#endif /* TOPPERS_ref_flg */
Note: See TracBrowser for help on using the repository browser.