source: asp_ewarm/asp-1.7.0/kernel/eventflag.c@ 165

Last change on this file since 165 was 61, checked in by ertl-honda, 11 years ago

ASP for EWARM のコミット.

File size: 11.4 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-2008 by Embedded and Real-Time Systems Laboratory
9 * Graduate School of Information Science, Nagoya Univ., JAPAN
10 *
11 * ã‹L’˜ìŒ ŽÒ‚́CˆÈ‰º‚Ì(1)`(4)‚ÌðŒ‚ð–ž‚½‚·ê‡‚ÉŒÀ‚èC–{ƒ\ƒtƒgƒEƒF
12 * ƒAi–{ƒ\ƒtƒgƒEƒFƒA‚ð‰ü•Ï‚µ‚½‚à‚Ì‚ðŠÜ‚ށDˆÈ‰º“¯‚¶j‚ðŽg—pE•¡»E‰ü
13 * •ÏEÄ”z•ziˆÈ‰ºC—˜—p‚ƌĂԁj‚·‚邱‚Ƃ𖳏ž‚Å‹–‘ø‚·‚éD
14 * (1) –{ƒ\ƒtƒgƒEƒFƒA‚ðƒ\[ƒXƒR[ƒh‚ÌŒ`‚Å—˜—p‚·‚éê‡‚ɂ́Cã‹L‚Ì’˜ì
15 * Œ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’肪C‚»‚Ì‚Ü‚Ü‚ÌŒ`‚Ń\[
16 * ƒXƒR[ƒh’†‚ÉŠÜ‚Ü‚ê‚Ä‚¢‚邱‚ƁD
17 * (2) –{ƒ\ƒtƒgƒEƒFƒA‚ðCƒ‰ƒCƒuƒ‰ƒŠŒ`Ž®‚ȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
18 * —p‚Å‚«‚éŒ`‚ōĔz•z‚·‚éê‡‚ɂ́CÄ”z•z‚É”º‚¤ƒhƒLƒ…
19ƒƒ“ƒgi—˜—p
20 * ŽÒƒ}ƒjƒ…
21ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L
22 * ‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
23 * (3) –{ƒ\ƒtƒgƒEƒFƒA‚ðC‹@Ší‚É‘g‚ݍž‚ނȂǁC‘¼‚̃\ƒtƒgƒEƒFƒAŠJ”­‚ÉŽg
24 * —p‚Å‚«‚È‚¢Œ`‚ōĔz•z‚·‚éê‡‚ɂ́CŽŸ‚Ì‚¢‚¸‚ê‚©‚ÌðŒ‚ð–ž‚½‚·‚±
25 * ‚ƁD
26 * (a) Ä”z•z‚É”º‚¤ƒhƒLƒ…
27ƒƒ“ƒgi—˜—pŽÒƒ}ƒjƒ…
28ƒAƒ‹‚Ȃǁj‚ɁCã‹L‚Ì’˜
29 * ìŒ •\Ž¦C‚±‚Ì—˜—pðŒ‚¨‚æ‚щº‹L‚Ì–³•ÛØ‹K’è‚ðŒfÚ‚·‚邱‚ƁD
30 * (b) Ä”z•z‚ÌŒ`‘Ô‚ðC•Ê‚É’è‚ß‚é•û–@‚É‚æ‚Á‚āCTOPPERSƒvƒƒWƒFƒNƒg‚É
31 * •ñ‚·‚邱‚ƁD
32 * (4) –{ƒ\ƒtƒgƒEƒFƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚é‚¢‚©‚Ȃ鑹
33 * ŠQ‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð–Ɛӂ·‚邱‚ƁD
34 * ‚Ü‚½C–{ƒ\ƒtƒgƒEƒFƒA‚̃†[ƒU‚Ü‚½‚̓Gƒ“ƒhƒ†[ƒU‚©‚ç‚Ì‚¢‚©‚Ȃ闝
35 * —R‚ÉŠî‚­¿‹‚©‚ç‚àCã‹L’˜ìŒ ŽÒ‚¨‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚ð
36 * –Ɛӂ·‚邱‚ƁD
37 *
38 * –{ƒ\ƒtƒgƒEƒFƒA‚́C–³•ÛØ‚Å’ñ‹Ÿ‚³‚ê‚Ä‚¢‚é‚à‚Ì‚Å‚ ‚éDã‹L’˜ìŒ ŽÒ‚¨
39 * ‚æ‚ÑTOPPERSƒvƒƒWƒFƒNƒg‚́C–{ƒ\ƒtƒgƒEƒFƒA‚ÉŠÖ‚µ‚āC“Á’è‚ÌŽg—p–Ú“I
40 * ‚ɑ΂·‚é“K‡«‚àŠÜ‚߂āC‚¢‚©‚È‚é•ÛØ‚às‚í‚È‚¢D‚Ü‚½C–{ƒ\ƒtƒgƒEƒF
41 * ƒA‚Ì—˜—p‚É‚æ‚è’¼Ú“I‚Ü‚½‚͊ԐړI‚ɐ¶‚¶‚½‚¢‚©‚Ȃ鑹ŠQ‚ÉŠÖ‚µ‚Ä‚àC‚»
42 * ‚̐ӔC‚𕉂í‚È‚¢D
43 *
44 * @(#) $Id: eventflag.c 748 2008-03-07 17:18:06Z hiro $
45 */
46
47/*
48 * ƒCƒxƒ“ƒgƒtƒ‰ƒO‹@”\
49 */
50
51#include "kernel_impl.h"
52#include "check.h"
53#include "task.h"
54#include "wait.h"
55#include "eventflag.h"
56
57/*
58 * ƒgƒŒ[ƒXƒƒOƒ}ƒNƒ‚̃fƒtƒHƒ‹ƒg’è‹`
59 */
60#ifndef LOG_SET_FLG_ENTER
61#define LOG_SET_FLG_ENTER(flgid, setptn)
62#endif /* LOG_SET_FLG_ENTER */
63
64#ifndef LOG_SET_FLG_LEAVE
65#define LOG_SET_FLG_LEAVE(ercd)
66#endif /* LOG_SET_FLG_LEAVE */
67
68#ifndef LOG_ISET_FLG_ENTER
69#define LOG_ISET_FLG_ENTER(flgid, setptn)
70#endif /* LOG_ISET_FLG_ENTER */
71
72#ifndef LOG_ISET_FLG_LEAVE
73#define LOG_ISET_FLG_LEAVE(ercd)
74#endif /* LOG_ISET_FLG_LEAVE */
75
76#ifndef LOG_CLR_FLG_ENTER
77#define LOG_CLR_FLG_ENTER(flgid, clrptn)
78#endif /* LOG_CLR_FLG_ENTER */
79
80#ifndef LOG_CLR_FLG_LEAVE
81#define LOG_CLR_FLG_LEAVE(ercd)
82#endif /* LOG_CLR_FLG_LEAVE */
83
84#ifndef LOG_WAI_FLG_ENTER
85#define LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn)
86#endif /* LOG_WAI_FLG_ENTER */
87
88#ifndef LOG_WAI_FLG_LEAVE
89#define LOG_WAI_FLG_LEAVE(ercd, flgptn)
90#endif /* LOG_WAI_FLG_LEAVE */
91
92#ifndef LOG_POL_FLG_ENTER
93#define LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn)
94#endif /* LOG_POL_FLG_ENTER */
95
96#ifndef LOG_POL_FLG_LEAVE
97#define LOG_POL_FLG_LEAVE(ercd, flgptn)
98#endif /* LOG_POL_FLG_LEAVE */
99
100#ifndef LOG_TWAI_FLG_ENTER
101#define LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout)
102#endif /* LOG_TWAI_FLG_ENTER */
103
104#ifndef LOG_TWAI_FLG_LEAVE
105#define LOG_TWAI_FLG_LEAVE(ercd, flgptn)
106#endif /* LOG_TWAI_FLG_LEAVE */
107
108#ifndef LOG_INI_FLG_ENTER
109#define LOG_INI_FLG_ENTER(flgid)
110#endif /* LOG_INI_FLG_ENTER */
111
112#ifndef LOG_INI_FLG_LEAVE
113#define LOG_INI_FLG_LEAVE(ercd)
114#endif /* LOG_INI_FLG_LEAVE */
115
116#ifndef LOG_REF_FLG_ENTER
117#define LOG_REF_FLG_ENTER(flgid, pk_rflg)
118#endif /* LOG_REF_FLG_ENTER */
119
120#ifndef LOG_REF_FLG_LEAVE
121#define LOG_REF_FLG_LEAVE(ercd, pk_rflg)
122#endif /* LOG_REF_FLG_LEAVE */
123
124/*
125 * ƒCƒxƒ“ƒgƒtƒ‰ƒO‚̐”
126 */
127#define tnum_flg ((uint_t)(tmax_flgid - TMIN_FLGID + 1))
128
129/*
130 * ƒCƒxƒ“ƒgƒtƒ‰ƒOID‚©‚çƒCƒxƒ“ƒgƒtƒ‰ƒOŠÇ—ƒuƒƒbƒN‚ðŽæ‚èo‚·‚½‚߂̃}ƒNƒ
131 */
132#define INDEX_FLG(flgid) ((uint_t)((flgid) - TMIN_FLGID))
133#define get_flgcb(flgid) (&(flgcb_table[INDEX_FLG(flgid)]))
134
135/*
136 * ƒCƒxƒ“ƒgƒtƒ‰ƒO‹@”\‚̏‰Šú‰»
137 */
138#ifdef TOPPERS_flgini
139
140void
141initialize_eventflag(void)
142{
143 uint_t i;
144 FLGCB *p_flgcb;
145
146 for (p_flgcb = flgcb_table, i = 0; i < tnum_flg; p_flgcb++, i++) {
147 queue_initialize(&(p_flgcb->wait_queue));
148 p_flgcb->p_flginib = &(flginib_table[i]);
149 p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
150 }
151}
152
153#endif /* TOPPERS_flgini */
154
155/*
156 * ƒCƒxƒ“ƒgƒtƒ‰ƒO‘Ò‚¿‰ðœðŒ‚̃`ƒFƒbƒN
157 */
158#ifdef TOPPERS_flgcnd
159
160bool_t
161check_flg_cond(FLGCB *p_flgcb, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
162{
163 if ((wfmode & TWF_ORW) != 0U ? (p_flgcb->flgptn & waiptn) != 0U
164 : (p_flgcb->flgptn & waiptn) == waiptn) {
165 *p_flgptn = p_flgcb->flgptn;
166 if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
167 p_flgcb->flgptn = 0U;
168 }
169 return(true);
170 }
171 return(false);
172}
173
174#endif /* TOPPERS_flgcnd */
175
176/*
177 * ƒCƒxƒ“ƒgƒtƒ‰ƒO‚̃Zƒbƒg
178 */
179#ifdef TOPPERS_set_flg
180
181ER
182set_flg(ID flgid, FLGPTN setptn)
183{
184 FLGCB *p_flgcb;
185 QUEUE *p_queue;
186 TCB *p_tcb;
187 WINFO_FLG *p_winfo_flg;
188 bool_t dspreq = false;
189 ER ercd;
190
191 LOG_SET_FLG_ENTER(flgid, setptn);
192 CHECK_TSKCTX_UNL();
193 CHECK_FLGID(flgid);
194 p_flgcb = get_flgcb(flgid);
195
196 t_lock_cpu();
197 p_flgcb->flgptn |= setptn;
198 p_queue = p_flgcb->wait_queue.p_next;
199 while (p_queue != &(p_flgcb->wait_queue)) {
200 p_tcb = (TCB *) p_queue;
201 p_queue = p_queue->p_next;
202 p_winfo_flg = (WINFO_FLG *)(p_tcb->p_winfo);
203 if (check_flg_cond(p_flgcb, p_winfo_flg->waiptn,
204 p_winfo_flg->wfmode, &(p_winfo_flg->flgptn))) {
205 queue_delete(&(p_tcb->task_queue));
206 if (wait_complete(p_tcb)) {
207 dspreq = true;
208 }
209 if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
210 break;
211 }
212 }
213 }
214 if (dspreq) {
215 dispatch();
216 }
217 ercd = E_OK;
218 t_unlock_cpu();
219
220 error_exit:
221 LOG_SET_FLG_LEAVE(ercd);
222 return(ercd);
223}
224
225#endif /* TOPPERS_set_flg */
226
227/*
228 * ƒCƒxƒ“ƒgƒtƒ‰ƒO‚̃Zƒbƒgi”ñƒ^ƒXƒNƒRƒ“ƒeƒLƒXƒg—pj
229 */
230#ifdef TOPPERS_iset_flg
231
232ER
233iset_flg(ID flgid, FLGPTN setptn)
234{
235 FLGCB *p_flgcb;
236 QUEUE *p_queue;
237 TCB *p_tcb;
238 WINFO_FLG *p_winfo_flg;
239 ER ercd;
240
241 LOG_ISET_FLG_ENTER(flgid, setptn);
242 CHECK_INTCTX_UNL();
243 CHECK_FLGID(flgid);
244 p_flgcb = get_flgcb(flgid);
245
246 i_lock_cpu();
247 p_flgcb->flgptn |= setptn;
248 p_queue = p_flgcb->wait_queue.p_next;
249 while (p_queue != &(p_flgcb->wait_queue)) {
250 p_tcb = (TCB *) p_queue;
251 p_queue = p_queue->p_next;
252 p_winfo_flg = (WINFO_FLG *)(p_tcb->p_winfo);
253 if (check_flg_cond(p_flgcb, p_winfo_flg->waiptn,
254 p_winfo_flg->wfmode, &(p_winfo_flg->flgptn))) {
255 queue_delete(&(p_tcb->task_queue));
256 if (wait_complete(p_tcb)) {
257 reqflg = true;
258 }
259 if ((p_flgcb->p_flginib->flgatr & TA_CLR) != 0U) {
260 break;
261 }
262 }
263 }
264 ercd = E_OK;
265 i_unlock_cpu();
266
267 error_exit:
268 LOG_ISET_FLG_LEAVE(ercd);
269 return(ercd);
270}
271
272#endif /* TOPPERS_iset_flg */
273
274/*
275 * ƒCƒxƒ“ƒgƒtƒ‰ƒO‚̃NƒŠƒA
276 */
277#ifdef TOPPERS_clr_flg
278
279ER
280clr_flg(ID flgid, FLGPTN clrptn)
281{
282 FLGCB *p_flgcb;
283 ER ercd;
284
285 LOG_CLR_FLG_ENTER(flgid, clrptn);
286 CHECK_TSKCTX_UNL();
287 CHECK_FLGID(flgid);
288 p_flgcb = get_flgcb(flgid);
289
290 t_lock_cpu();
291 p_flgcb->flgptn &= clrptn;
292 ercd = E_OK;
293 t_unlock_cpu();
294
295 error_exit:
296 LOG_CLR_FLG_LEAVE(ercd);
297 return(ercd);
298}
299
300#endif /* TOPPERS_clr_flg */
301
302/*
303 * ƒCƒxƒ“ƒgƒtƒ‰ƒO‘Ò‚¿
304 */
305#ifdef TOPPERS_wai_flg
306
307ER
308wai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
309{
310 FLGCB *p_flgcb;
311 WINFO_FLG winfo_flg;
312 ER ercd;
313
314 LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
315 CHECK_DISPATCH();
316 CHECK_FLGID(flgid);
317 CHECK_PAR(waiptn != 0U);
318 CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
319 p_flgcb = get_flgcb(flgid);
320
321 t_lock_cpu();
322 if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
323 && !queue_empty(&(p_flgcb->wait_queue))) {
324 ercd = E_ILUSE;
325 }
326 else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
327 ercd = E_OK;
328 }
329 else {
330 winfo_flg.waiptn = waiptn;
331 winfo_flg.wfmode = wfmode;
332 p_runtsk->tstat = (TS_WAITING | TS_WAIT_FLG);
333 wobj_make_wait((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg);
334 dispatch();
335 ercd = winfo_flg.winfo.wercd;
336 if (ercd == E_OK) {
337 *p_flgptn = winfo_flg.flgptn;
338 }
339 }
340 t_unlock_cpu();
341
342 error_exit:
343 LOG_WAI_FLG_LEAVE(ercd, *p_flgptn);
344 return(ercd);
345}
346
347#endif /* TOPPERS_wai_flg */
348
349/*
350 * ƒCƒxƒ“ƒgƒtƒ‰ƒO‘Ò‚¿iƒ|[ƒŠƒ“ƒOj
351 */
352#ifdef TOPPERS_pol_flg
353
354ER
355pol_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
356{
357 FLGCB *p_flgcb;
358 ER ercd;
359
360 LOG_POL_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
361 CHECK_TSKCTX_UNL();
362 CHECK_FLGID(flgid);
363 CHECK_PAR(waiptn != 0U);
364 CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
365 p_flgcb = get_flgcb(flgid);
366
367 t_lock_cpu();
368 if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
369 && !queue_empty(&(p_flgcb->wait_queue))) {
370 ercd = E_ILUSE;
371 }
372 else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
373 ercd = E_OK;
374 }
375 else {
376 ercd = E_TMOUT;
377 }
378 t_unlock_cpu();
379
380 error_exit:
381 LOG_POL_FLG_LEAVE(ercd, *p_flgptn);
382 return(ercd);
383}
384
385#endif /* TOPPERS_pol_flg */
386
387/*
388 * ƒCƒxƒ“ƒgƒtƒ‰ƒO‘Ò‚¿iƒ^ƒCƒ€ƒAƒEƒg‚ ‚èj
389 */
390#ifdef TOPPERS_twai_flg
391
392ER
393twai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn, TMO tmout)
394{
395 FLGCB *p_flgcb;
396 WINFO_FLG winfo_flg;
397 TMEVTB tmevtb;
398 ER ercd;
399
400 LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout);
401 CHECK_DISPATCH();
402 CHECK_FLGID(flgid);
403 CHECK_PAR(waiptn != 0U);
404 CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
405 CHECK_TMOUT(tmout);
406 p_flgcb = get_flgcb(flgid);
407
408 t_lock_cpu();
409 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 if (tmout == TMO_POL) {
417 ercd = E_TMOUT;
418 }
419 else {
420 winfo_flg.waiptn = waiptn;
421 winfo_flg.wfmode = wfmode;
422 p_runtsk->tstat = (TS_WAITING | TS_WAIT_FLG);
423 wobj_make_wait_tmout((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg,
424 &tmevtb, tmout);
425 dispatch();
426 ercd = winfo_flg.winfo.wercd;
427 if (ercd == E_OK) {
428 *p_flgptn = winfo_flg.flgptn;
429 }
430 }
431 t_unlock_cpu();
432
433 error_exit:
434 LOG_TWAI_FLG_LEAVE(ercd, *p_flgptn);
435 return(ercd);
436}
437
438#endif /* TOPPERS_twai_flg */
439
440/*
441 * ƒCƒxƒ“ƒgƒtƒ‰ƒO‚̍ú‰»
442 */
443#ifdef TOPPERS_ini_flg
444
445ER
446ini_flg(ID flgid)
447{
448 FLGCB *p_flgcb;
449 bool_t dspreq;
450 ER ercd;
451
452 LOG_INI_FLG_ENTER(flgid);
453 CHECK_TSKCTX_UNL();
454 CHECK_FLGID(flgid);
455 p_flgcb = get_flgcb(flgid);
456
457 t_lock_cpu();
458 dspreq = init_wait_queue(&(p_flgcb->wait_queue));
459 p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
460 if (dspreq) {
461 dispatch();
462 }
463 ercd = E_OK;
464 t_unlock_cpu();
465
466 error_exit:
467 LOG_INI_FLG_LEAVE(ercd);
468 return(ercd);
469}
470
471#endif /* TOPPERS_ini_flg */
472
473/*
474 * ƒCƒxƒ“ƒgƒtƒ‰ƒO‚̏ó‘ÔŽQÆ
475 */
476#ifdef TOPPERS_ref_flg
477
478ER
479ref_flg(ID flgid, T_RFLG *pk_rflg)
480{
481 FLGCB *p_flgcb;
482 ER ercd;
483
484 LOG_REF_FLG_ENTER(flgid, pk_rflg);
485 CHECK_TSKCTX_UNL();
486 CHECK_FLGID(flgid);
487 p_flgcb = get_flgcb(flgid);
488
489 t_lock_cpu();
490 pk_rflg->wtskid = wait_tskid(&(p_flgcb->wait_queue));
491 pk_rflg->flgptn = p_flgcb->flgptn;
492 ercd = E_OK;
493 t_unlock_cpu();
494
495 error_exit:
496 LOG_REF_FLG_LEAVE(ercd, pk_rflg);
497 return(ercd);
498}
499
500#endif /* TOPPERS_ref_flg */
Note: See TracBrowser for help on using the repository browser.