1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
13:
14: 15: 16: 17:
18:
19: #include "kernel.h"
20: #include "wait.h"
21: #include "check.h"
22: #include "eventflag.h"
23:
24: #if USE_EVENTFLAG == 1
25:
26: Noinit(EXPORT FLGCB knl_flgcb_table[NUM_FLGID]);
27: Noinit(EXPORT QUEUE knl_free_flgcb);
28:
29:
30: 31: 32:
33: EXPORT ER knl_eventflag_initialize( void )
34: {
35: FLGCB *flgcb, *end;
36:
37:
38: if ( NUM_FLGID < 1 ) {
39: return E_SYS;
40: }
41:
42:
43: QueInit(&knl_free_flgcb);
44: end = knl_flgcb_table + NUM_FLGID;
45: for ( flgcb = knl_flgcb_table; flgcb < end; flgcb++ ) {
46: flgcb->flgid = 0;
47: QueInsert(&flgcb->wait_queue, &knl_free_flgcb);
48: }
49:
50: return E_OK;
51: }
52:
53: 54: 55:
56: SYSCALL ID tk_cre_flg( CONST T_CFLG *pk_cflg )
57: {
58: #if CHK_RSATR
59: const ATR VALID_FLGATR = {
60: TA_TPRI
61: |TA_WMUL
62: #if USE_OBJECT_NAME
63: |TA_DSNAME
64: #endif
65: };
66: #endif
67: FLGCB *flgcb;
68: ID flgid;
69: ER ercd;
70:
71: CHECK_RSATR(pk_cflg->flgatr, VALID_FLGATR);
72:
73: BEGIN_CRITICAL_SECTION;
74:
75: flgcb = (FLGCB*)QueRemoveNext(&knl_free_flgcb);
76: if ( flgcb == NULL ) {
77: ercd = E_LIMIT;
78: } else {
79: flgid = ID_FLG(flgcb - knl_flgcb_table);
80:
81:
82: QueInit(&flgcb->wait_queue);
83: flgcb->flgid = flgid;
84: flgcb->exinf = pk_cflg->exinf;
85: flgcb->flgatr = pk_cflg->flgatr;
86: flgcb->flgptn = pk_cflg->iflgptn;
87: #if USE_OBJECT_NAME
88: if ( (pk_cflg->flgatr & TA_DSNAME) != 0 ) {
89: knl_strncpy((char*)flgcb->name, (char*)pk_cflg->dsname,
90: OBJECT_NAME_LENGTH);
91: }
92: #endif
93: ercd = flgid;
94: }
95: END_CRITICAL_SECTION;
96:
97: return ercd;
98: }
99:
100: #ifdef USE_FUNC_TK_DEL_FLG
101: 102: 103:
104: SYSCALL ER tk_del_flg( ID flgid )
105: {
106: FLGCB *flgcb;
107: ER ercd = E_OK;
108:
109: CHECK_FLGID(flgid);
110:
111: flgcb = get_flgcb(flgid);
112:
113: BEGIN_CRITICAL_SECTION;
114: if ( flgcb->flgid == 0 ) {
115: ercd = E_NOEXS;
116: } else {
117:
118: knl_wait_delete(&flgcb->wait_queue);
119:
120:
121: QueInsert(&flgcb->wait_queue, &knl_free_flgcb);
122: flgcb->flgid = 0;
123: }
124: END_CRITICAL_SECTION;
125:
126: return ercd;
127: }
128: #endif
129:
130: 131: 132:
133: SYSCALL ER tk_set_flg( ID flgid, UINT setptn )
134: {
135: FLGCB *flgcb;
136: TCB *tcb;
137: QUEUE *queue;
138: UINT wfmode, waiptn;
139: ER ercd = E_OK;
140:
141: CHECK_FLGID(flgid);
142:
143: flgcb = get_flgcb(flgid);
144:
145: BEGIN_CRITICAL_SECTION;
146: if ( flgcb->flgid == 0 ) {
147: ercd = E_NOEXS;
148: goto error_exit;
149: }
150:
151:
152: flgcb->flgptn |= setptn;
153:
154:
155: queue = flgcb->wait_queue.next;
156: while ( queue != &flgcb->wait_queue ) {
157: tcb = (TCB*)queue;
158: queue = queue->next;
159:
160:
161: waiptn = tcb->winfo.flg.waiptn;
162: wfmode = tcb->winfo.flg.wfmode;
163: if ( knl_eventflag_cond(flgcb, waiptn, wfmode) ) {
164:
165:
166: *tcb->winfo.flg.p_flgptn = flgcb->flgptn;
167: knl_wait_release_ok(tcb);
168:
169:
170: if ( (wfmode & TWF_BITCLR) != 0 ) {
171: if ( (flgcb->flgptn &= ~waiptn) == 0 ) {
172: break;
173: }
174: }
175: if ( (wfmode & TWF_CLR) != 0 ) {
176: flgcb->flgptn = 0;
177: break;
178: }
179: }
180: }
181:
182: error_exit:
183: END_CRITICAL_SECTION;
184:
185: return ercd;
186: }
187:
188: 189: 190:
191: SYSCALL ER tk_clr_flg( ID flgid, UINT clrptn )
192: {
193: FLGCB *flgcb;
194: ER ercd = E_OK;
195:
196: CHECK_FLGID(flgid);
197:
198: flgcb = get_flgcb(flgid);
199:
200: BEGIN_CRITICAL_SECTION;
201: if ( flgcb->flgid == 0 ) {
202: ercd = E_NOEXS;
203: } else {
204: flgcb->flgptn &= clrptn;
205: }
206: END_CRITICAL_SECTION;
207:
208: return ercd;
209: }
210:
211: 212: 213:
214: LOCAL void flg_chg_pri( TCB *tcb, INT oldpri )
215: {
216: FLGCB *flgcb;
217:
218: flgcb = get_flgcb(tcb->wid);
219: knl_gcb_change_priority((GCB*)flgcb, tcb);
220: }
221:
222: 223: 224:
225: LOCAL CONST WSPEC knl_wspec_flg_tfifo = { TTW_FLG, NULL, NULL };
226: LOCAL CONST WSPEC knl_wspec_flg_tpri = { TTW_FLG, flg_chg_pri, NULL };
227:
228: 229: 230:
231: SYSCALL ER tk_wai_flg( ID flgid, UINT waiptn, UINT wfmode, UINT *p_flgptn, TMO tmout )
232: {
233: FLGCB *flgcb;
234: ER ercd = E_OK;
235:
236: CHECK_FLGID(flgid);
237: CHECK_PAR(waiptn != 0);
238: CHECK_PAR((wfmode & ~(TWF_ORW|TWF_CLR|TWF_BITCLR)) == 0);
239: CHECK_TMOUT(tmout);
240: CHECK_DISPATCH();
241:
242: flgcb = get_flgcb(flgid);
243:
244: BEGIN_CRITICAL_SECTION;
245: if ( flgcb->flgid == 0 ) {
246: ercd = E_NOEXS;
247: goto error_exit;
248: }
249: if ( (flgcb->flgatr & TA_WMUL) == 0 && !isQueEmpty(&flgcb->wait_queue) ) {
250:
251: ercd = E_OBJ;
252: goto error_exit;
253: }
254:
255:
256: if ( knl_eventflag_cond(flgcb, waiptn, wfmode) ) {
257: *p_flgptn = flgcb->flgptn;
258:
259:
260: if ( (wfmode & TWF_BITCLR) != 0 ) {
261: flgcb->flgptn &= ~waiptn;
262: }
263: if ( (wfmode & TWF_CLR) != 0 ) {
264: flgcb->flgptn = 0;
265: }
266: } else {
267:
268: knl_ctxtsk->wspec = ( (flgcb->flgatr & TA_TPRI) != 0 )?
269: &knl_wspec_flg_tpri: &knl_wspec_flg_tfifo;
270: knl_ctxtsk->wercd = &ercd;
271: knl_ctxtsk->winfo.flg.waiptn = waiptn;
272: knl_ctxtsk->winfo.flg.wfmode = wfmode;
273: knl_ctxtsk->winfo.flg.p_flgptn = p_flgptn;
274: knl_gcb_make_wait((GCB*)flgcb, tmout);
275: }
276:
277: error_exit:
278: END_CRITICAL_SECTION;
279:
280: return ercd;
281: }
282:
283: #ifdef USE_FUNC_TK_REF_FLG
284: 285: 286:
287: SYSCALL ER tk_ref_flg( ID flgid, T_RFLG *pk_rflg )
288: {
289: FLGCB *flgcb;
290: ER ercd = E_OK;
291:
292: CHECK_FLGID(flgid);
293:
294: flgcb = get_flgcb(flgid);
295:
296: BEGIN_CRITICAL_SECTION;
297: if ( flgcb->flgid == 0 ) {
298: ercd = E_NOEXS;
299: } else {
300: pk_rflg->exinf = flgcb->exinf;
301: pk_rflg->wtsk = knl_wait_tskid(&flgcb->wait_queue);
302: pk_rflg->flgptn = flgcb->flgptn;
303: }
304: END_CRITICAL_SECTION;
305:
306: return ercd;
307: }
308: #endif
309:
310:
311: 312: 313:
314: #if USE_DBGSPT
315:
316: #if USE_OBJECT_NAME
317: 318: 319:
320: EXPORT ER knl_eventflag_getname(ID id, UB **name)
321: {
322: FLGCB *flgcb;
323: ER ercd = E_OK;
324:
325: CHECK_FLGID(id);
326:
327: BEGIN_DISABLE_INTERRUPT;
328: flgcb = get_flgcb(id);
329: if ( flgcb->flgid == 0 ) {
330: ercd = E_NOEXS;
331: goto error_exit;
332: }
333: if ( (flgcb->flgatr & TA_DSNAME) == 0 ) {
334: ercd = E_OBJ;
335: goto error_exit;
336: }
337: *name = flgcb->name;
338:
339: error_exit:
340: END_DISABLE_INTERRUPT;
341:
342: return ercd;
343: }
344: #endif
345:
346: #ifdef USE_FUNC_TD_LST_FLG
347: 348: 349:
350: SYSCALL INT td_lst_flg( ID list[], INT nent )
351: {
352: FLGCB *flgcb, *end;
353: INT n = 0;
354:
355: BEGIN_DISABLE_INTERRUPT;
356: end = knl_flgcb_table + NUM_FLGID;
357: for ( flgcb = knl_flgcb_table; flgcb < end; flgcb++ ) {
358: if ( flgcb->flgid == 0 ) {
359: continue;
360: }
361:
362: if ( n++ < nent ) {
363: *list++ = flgcb->flgid;
364: }
365: }
366: END_DISABLE_INTERRUPT;
367:
368: return n;
369: }
370: #endif
371:
372: #ifdef USE_FUNC_TD_REF_FLG
373: 374: 375:
376: SYSCALL ER td_ref_flg( ID flgid, TD_RFLG *pk_rflg )
377: {
378: FLGCB *flgcb;
379: ER ercd = E_OK;
380:
381: CHECK_FLGID(flgid);
382:
383: flgcb = get_flgcb(flgid);
384:
385: BEGIN_DISABLE_INTERRUPT;
386: if ( flgcb->flgid == 0 ) {
387: ercd = E_NOEXS;
388: } else {
389: pk_rflg->exinf = flgcb->exinf;
390: pk_rflg->wtsk = knl_wait_tskid(&flgcb->wait_queue);
391: pk_rflg->flgptn = flgcb->flgptn;
392: }
393: END_DISABLE_INTERRUPT;
394:
395: return ercd;
396: }
397: #endif
398:
399: #ifdef USE_FUNC_TD_FLG_QUE
400: 401: 402:
403: SYSCALL INT td_flg_que( ID flgid, ID list[], INT nent )
404: {
405: FLGCB *flgcb;
406: QUEUE *q;
407: ER ercd = E_OK;
408:
409: CHECK_FLGID(flgid);
410:
411: flgcb = get_flgcb(flgid);
412:
413: BEGIN_DISABLE_INTERRUPT;
414: if ( flgcb->flgid == 0 ) {
415: ercd = E_NOEXS;
416: } else {
417: INT n = 0;
418: for ( q = flgcb->wait_queue.next; q != &flgcb->wait_queue; q = q->next ) {
419: if ( n++ < nent ) {
420: *list++ = ((TCB*)q)->tskid;
421: }
422: }
423: ercd = n;
424: }
425: END_DISABLE_INTERRUPT;
426:
427: return ercd;
428: }
429: #endif
430:
431: #endif
432: #endif