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 <tm/tmonitor.h>
23:
24: #include "../sysdepend/cpu_task.h"
25:
26: 27: 28:
29: SYSCALL ID tk_cre_tsk( CONST T_CTSK *pk_ctsk )
30: {
31: #if CHK_RSATR
32: const ATR VALID_TSKATR = {
33: TA_HLNG
34: |TA_RNG3
35: |TA_USERBUF
36: |TA_COPS
37: #if USE_OBJECT_NAME
38: |TA_DSNAME
39: #endif
40: };
41: #endif
42: TCB *tcb;
43: W sstksz;
44: void *stack;
45: ER ercd;
46:
47: CHECK_RSATR(pk_ctsk->tskatr, VALID_TSKATR);
48: #if !USE_IMALLOC
49:
50: CHECK_PAR((pk_ctsk->tskatr & TA_USERBUF) != 0);
51: #endif
52: CHECK_PRI(pk_ctsk->itskpri);
53:
54: sstksz = pk_ctsk->stksz + DEFAULT_SYS_STKSZ;
55: CHECK_PAR(sstksz >= MIN_SYS_STACK_SIZE);
56:
57: if ( (pk_ctsk->tskatr & TA_USERBUF) != 0 ) {
58:
59: stack = pk_ctsk->bufptr;
60: } else {
61: #if USE_IMALLOC
62:
63: sstksz = (sstksz + 7) / 8 * 8;
64: stack = knl_Imalloc((UW)sstksz);
65: if ( stack == NULL ) {
66: return E_NOMEM;
67: }
68: #endif
69: }
70:
71: BEGIN_CRITICAL_SECTION;
72:
73: tcb = (TCB*)QueRemoveNext(&knl_free_tcb);
74: if ( tcb == NULL ) {
75: ercd = E_LIMIT;
76: goto error_exit;
77: }
78:
79:
80: tcb->exinf = pk_ctsk->exinf;
81: tcb->tskatr = pk_ctsk->tskatr;
82: tcb->task = pk_ctsk->task;
83: tcb->ipriority = (UB)int_priority(pk_ctsk->itskpri);
84: tcb->sstksz = sstksz;
85: #if USE_OBJECT_NAME
86: if ( (pk_ctsk->tskatr & TA_DSNAME) != 0 ) {
87: knl_strncpy((char*)tcb->name, (char*)pk_ctsk->dsname, OBJECT_NAME_LENGTH);
88: }
89: #endif
90:
91:
92: tcb->isstack = (VB*)stack + sstksz;
93:
94:
95: tcb->isysmode = 1;
96: tcb->sysmode = 1;
97:
98:
99: knl_make_dormant(tcb);
100:
101: ercd = tcb->tskid;
102:
103: error_exit:
104: END_CRITICAL_SECTION;
105:
106: #if USE_IMALLOC
107: if ( (ercd < E_OK) && ((pk_ctsk->tskatr & TA_USERBUF) == 0) ) {
108: knl_Ifree(stack);
109: }
110: #endif
111:
112: return ercd;
113: }
114:
115: 116: 117: 118:
119: LOCAL void knl_del_tsk( TCB *tcb )
120: {
121: #if USE_IMALLOC
122: if ( (tcb->tskatr & TA_USERBUF) == 0 ) {
123:
124:
125: void *stack = (VB*)tcb->isstack - tcb->sstksz;
126: knl_Ifree(stack);
127: }
128: #endif
129:
130:
131: QueInsert(&tcb->tskque, &knl_free_tcb);
132: tcb->state = TS_NONEXIST;
133: }
134:
135: #ifdef USE_FUNC_TK_DEL_TSK
136: 137: 138:
139: SYSCALL ER tk_del_tsk( ID tskid )
140: {
141: TCB *tcb;
142: TSTAT state;
143: ER ercd = E_OK;
144:
145: CHECK_TSKID(tskid);
146: CHECK_NONSELF(tskid);
147:
148: tcb = get_tcb(tskid);
149:
150: BEGIN_CRITICAL_SECTION;
151: state = (TSTAT)tcb->state;
152: if ( state != TS_DORMANT ) {
153: ercd = ( state == TS_NONEXIST )? E_NOEXS: E_OBJ;
154: } else {
155: knl_del_tsk(tcb);
156: }
157: END_CRITICAL_SECTION;
158:
159: return ercd;
160: }
161: #endif
162:
163:
164:
165: 166: 167:
168: SYSCALL ER tk_sta_tsk( ID tskid, INT stacd )
169: {
170: TCB *tcb;
171: TSTAT state;
172: ER ercd = E_OK;
173:
174: CHECK_TSKID(tskid);
175: CHECK_NONSELF(tskid);
176:
177: tcb = get_tcb(tskid);
178:
179: BEGIN_CRITICAL_SECTION;
180: state = (TSTAT)tcb->state;
181: if ( state != TS_DORMANT ) {
182: ercd = ( state == TS_NONEXIST )? E_NOEXS: E_OBJ;
183: } else {
184: knl_setup_stacd(tcb, stacd);
185: knl_make_ready(tcb);
186: }
187: END_CRITICAL_SECTION;
188:
189: return ercd;
190: }
191:
192: 193: 194: 195:
196: LOCAL void knl_ter_tsk( TCB *tcb )
197: {
198: TSTAT state;
199:
200: state = (TSTAT)tcb->state;
201: if ( state == TS_READY ) {
202: knl_make_non_ready(tcb);
203:
204: } else if ( (state & TS_WAIT) != 0 ) {
205: knl_wait_cancel(tcb);
206: if ( tcb->wspec->rel_wai_hook != NULL ) {
207: (*tcb->wspec->rel_wai_hook)(tcb);
208: }
209: }
210:
211: #if USE_MUTEX == 1
212:
213: knl_signal_all_mutex(tcb);
214: #endif
215:
216: knl_cleanup_context(tcb);
217: }
218:
219: #ifdef USE_FUNC_TK_EXT_TSK
220: 221: 222:
223: SYSCALL void tk_ext_tsk( void )
224: {
225: #ifdef DORMANT_STACK_SIZE
226: 227:
228: volatile VB _dummy[DORMANT_STACK_SIZE];
229: #endif
230:
231:
232: #if CHK_CTX2
233: if ( in_indp() ) {
234: SYSTEM_MESSAGE("tk_ext_tsk was called in the task independent\n");
235: return;
236: }
237: #endif
238: #if CHK_CTX1
239: if ( in_ddsp() ) {
240: SYSTEM_MESSAGE("tk_ext_tsk was called in the dispatch disabled\n");
241: }
242: #endif
243:
244: DISABLE_INTERRUPT;
245: knl_ter_tsk(knl_ctxtsk);
246: knl_make_dormant(knl_ctxtsk);
247:
248: knl_force_dispatch();
249:
250:
251: #ifdef DORMANT_STACK_SIZE
252:
253: _dummy[0] = _dummy[0];
254: #endif
255: }
256: #endif
257:
258: #ifdef USE_FUNC_TK_EXD_TSK
259: 260: 261:
262: SYSCALL void tk_exd_tsk( void )
263: {
264:
265: #if CHK_CTX2
266: if ( in_indp() ) {
267: SYSTEM_MESSAGE("tk_exd_tsk was called in the task independent\n");
268: return;
269: }
270: #endif
271: #if CHK_CTX1
272: if ( in_ddsp() ) {
273: SYSTEM_MESSAGE("tk_exd_tsk was called in the dispatch disabled\n");
274: }
275: #endif
276:
277: DISABLE_INTERRUPT;
278: knl_ter_tsk(knl_ctxtsk);
279: knl_del_tsk(knl_ctxtsk);
280:
281: knl_force_dispatch();
282:
283: }
284: #endif
285:
286: #ifdef USE_FUNC_TK_TER_TSK
287: 288: 289:
290: SYSCALL ER tk_ter_tsk( ID tskid )
291: {
292: TCB *tcb;
293: TSTAT state;
294: ER ercd = E_OK;
295:
296: CHECK_TSKID(tskid);
297: CHECK_NONSELF(tskid);
298:
299: tcb = get_tcb(tskid);
300:
301: BEGIN_CRITICAL_SECTION;
302: state = (TSTAT)tcb->state;
303: if ( !knl_task_alive(state) ) {
304: ercd = ( state == TS_NONEXIST )? E_NOEXS: E_OBJ;
305: } else if ( tcb->klocked ) {
306: 307: 308: 309: 310:
311: ercd = E_OBJ;
312: } else {
313: knl_ter_tsk(tcb);
314: knl_make_dormant(tcb);
315: }
316: END_CRITICAL_SECTION;
317:
318: return ercd;
319: }
320: #endif
321:
322:
323:
324: #ifdef USE_FUNC_TK_CHG_PRI
325: 326: 327:
328: SYSCALL ER tk_chg_pri( ID tskid, PRI tskpri )
329: {
330: TCB *tcb;
331: INT priority;
332: ER ercd;
333:
334: CHECK_TSKID_SELF(tskid);
335: CHECK_PRI_INI(tskpri);
336:
337: tcb = get_tcb_self(tskid);
338:
339: BEGIN_CRITICAL_SECTION;
340: if ( tcb->state == TS_NONEXIST ) {
341: ercd = E_NOEXS;
342: goto error_exit;
343: }
344:
345:
346: if ( tskpri == TPRI_INI ) {
347: priority = tcb->ipriority;
348: } else {
349: priority = int_priority(tskpri);
350: }
351:
352: #if USE_MUTEX == 1
353:
354: ercd = knl_chg_pri_mutex(tcb, priority);
355: if ( ercd < E_OK ) {
356: goto error_exit;
357: }
358:
359: tcb->bpriority = (UB)priority;
360: priority = ercd;
361: #else
362: tcb->bpriority = priority;
363: #endif
364:
365:
366: knl_change_task_priority(tcb, priority);
367:
368: ercd = E_OK;
369: error_exit:
370: END_CRITICAL_SECTION;
371:
372: return ercd;
373: }
374: #endif
375:
376: #ifdef USE_FUNC_TK_ROT_RDQ
377: 378: 379:
380: SYSCALL ER tk_rot_rdq( PRI tskpri )
381: {
382: CHECK_PRI_RUN(tskpri);
383:
384: BEGIN_CRITICAL_SECTION;
385: if ( tskpri == TPRI_RUN ) {
386: if ( in_indp() ) {
387: knl_rotate_ready_queue_run();
388: } else {
389: knl_rotate_ready_queue(knl_ctxtsk->priority);
390: }
391: } else {
392: knl_rotate_ready_queue(int_priority(tskpri));
393: }
394: END_CRITICAL_SECTION;
395:
396: return E_OK;
397: }
398: #endif
399:
400:
401:
402: #ifdef USE_FUNC_TK_GET_TID
403: 404: 405:
406: SYSCALL ID tk_get_tid( void )
407: {
408: return ( knl_ctxtsk == NULL )? 0: knl_ctxtsk->tskid;
409: }
410: #endif
411:
412: #ifdef USE_FUNC_TK_REF_TSK
413: 414: 415:
416: SYSCALL ER tk_ref_tsk( ID tskid, T_RTSK *pk_rtsk )
417: {
418: TCB *tcb;
419: TSTAT state;
420: ER ercd = E_OK;
421:
422: CHECK_TSKID_SELF(tskid);
423:
424: tcb = get_tcb_self(tskid);
425:
426: knl_memset(pk_rtsk, 0, sizeof(*pk_rtsk));
427:
428: BEGIN_CRITICAL_SECTION;
429: state = (TSTAT)tcb->state;
430: if ( state == TS_NONEXIST ) {
431: ercd = E_NOEXS;
432: } else {
433: if ( ( state == TS_READY ) && ( tcb == knl_ctxtsk ) ) {
434: pk_rtsk->tskstat = TTS_RUN;
435: } else {
436: pk_rtsk->tskstat = (UINT)state << 1;
437: }
438: if ( (state & TS_WAIT) != 0 ) {
439: pk_rtsk->tskwait = tcb->wspec->tskwait;
440: pk_rtsk->wid = tcb->wid;
441: }
442: pk_rtsk->exinf = tcb->exinf;
443: pk_rtsk->tskpri = ext_tskpri(tcb->priority);
444: pk_rtsk->tskbpri = ext_tskpri(tcb->bpriority);
445: pk_rtsk->wupcnt = tcb->wupcnt;
446: pk_rtsk->suscnt = tcb->suscnt;
447: }
448: END_CRITICAL_SECTION;
449:
450: return ercd;
451: }
452: #endif
453:
454:
455:
456:
457: #ifdef USE_FUNC_TK_REL_WAI
458: 459: 460:
461: SYSCALL ER tk_rel_wai( ID tskid )
462: {
463: TCB *tcb;
464: TSTAT state;
465: ER ercd = E_OK;
466:
467: CHECK_TSKID(tskid);
468:
469: tcb = get_tcb(tskid);
470:
471: BEGIN_CRITICAL_SECTION;
472: state = (TSTAT)tcb->state;
473: if ( (state & TS_WAIT) == 0 ) {
474: ercd = ( state == TS_NONEXIST )? E_NOEXS: E_OBJ;
475: } else {
476: knl_wait_release_ng(tcb, E_RLWAI);
477: }
478: END_CRITICAL_SECTION;
479:
480: return ercd;
481: }
482: #endif
483:
484:
485: 486: 487:
488: #if USE_DBGSPT
489:
490: #if USE_OBJECT_NAME
491: 492: 493:
494: EXPORT ER knl_task_getname(ID id, UB **name)
495: {
496: TCB *tcb;
497: ER ercd = E_OK;
498:
499: CHECK_TSKID_SELF(id);
500:
501: BEGIN_DISABLE_INTERRUPT;
502: tcb = get_tcb_self(id);
503: if ( tcb->state == TS_NONEXIST ) {
504: ercd = E_NOEXS;
505: goto error_exit;
506: }
507: if ( (tcb->tskatr & TA_DSNAME) == 0 ) {
508: ercd = E_OBJ;
509: goto error_exit;
510: }
511: *name = tcb->name;
512:
513: error_exit:
514: END_DISABLE_INTERRUPT;
515:
516: return ercd;
517: }
518: #endif
519:
520: #ifdef USE_FUNC_TD_LST_TSK
521: 522: 523:
524: SYSCALL INT td_lst_tsk( ID list[], INT nent )
525: {
526: TCB *tcb, *end;
527: INT n = 0;
528:
529: BEGIN_DISABLE_INTERRUPT;
530: end = knl_tcb_table + NUM_TSKID;
531: for ( tcb = knl_tcb_table; tcb < end; tcb++ ) {
532: if ( tcb->state == TS_NONEXIST ) {
533: continue;
534: }
535:
536: if ( n++ < nent ) {
537: *list++ = tcb->tskid;
538: }
539: }
540: END_DISABLE_INTERRUPT;
541:
542: return n;
543: }
544: #endif
545:
546: #ifdef USE_FUNC_TD_REF_TSK
547: 548: 549:
550: SYSCALL ER td_ref_tsk( ID tskid, TD_RTSK *pk_rtsk )
551: {
552: TCB *tcb;
553: TSTAT state;
554: ER ercd = E_OK;
555:
556: CHECK_TSKID_SELF(tskid);
557:
558: tcb = get_tcb_self(tskid);
559:
560: knl_memset(pk_rtsk, 0, sizeof(*pk_rtsk));
561:
562: BEGIN_DISABLE_INTERRUPT;
563: state = (TSTAT)tcb->state;
564: if ( state == TS_NONEXIST ) {
565: ercd = E_NOEXS;
566: } else {
567: if ( ( state == TS_READY ) && ( tcb == knl_ctxtsk ) ) {
568: pk_rtsk->tskstat = TTS_RUN;
569: } else {
570: pk_rtsk->tskstat = (UINT)state << 1;
571: }
572: if ( (state & TS_WAIT) != 0 ) {
573: pk_rtsk->tskwait = tcb->wspec->tskwait;
574: pk_rtsk->wid = tcb->wid;
575: }
576: pk_rtsk->exinf = tcb->exinf;
577: pk_rtsk->tskpri = ext_tskpri(tcb->priority);
578: pk_rtsk->tskbpri = ext_tskpri(tcb->bpriority);
579: pk_rtsk->wupcnt = tcb->wupcnt;
580: pk_rtsk->suscnt = tcb->suscnt;
581:
582: pk_rtsk->task = tcb->task;
583: pk_rtsk->stksz = tcb->sstksz;
584: pk_rtsk->istack = tcb->isstack;
585: }
586: END_DISABLE_INTERRUPT;
587:
588: return ercd;
589: }
590: #endif
591:
592: #ifdef USE_FUNC_TD_INF_TSK
593: 594: 595:
596: SYSCALL ER td_inf_tsk( ID tskid, TD_ITSK *pk_itsk, BOOL clr )
597: {
598: TCB *tcb;
599: ER ercd = E_OK;
600:
601: CHECK_TSKID_SELF(tskid);
602:
603: tcb = get_tcb_self(tskid);
604:
605: BEGIN_DISABLE_INTERRUPT;
606: if ( tcb->state == TS_NONEXIST ) {
607: ercd = E_NOEXS;
608: } else {
609: pk_itsk->stime = tcb->stime;
610: pk_itsk->utime = tcb->utime;
611: if ( clr ) {
612: tcb->stime = 0;
613: tcb->utime = 0;
614: }
615: }
616: END_DISABLE_INTERRUPT;
617:
618: return ercd;
619: }
620: #endif
621:
622: #endif