1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14:
15:
16: 17: 18: 19:
20:
21: #include "kernel.h"
22: #include "task.h"
23: #include "check.h"
24: #include <sys/bitop.h>
25: #include <sys/rominfo.h>
26:
27: EXPORT ID max_ssyid;
28: EXPORT PRI max_ssypri;
29: EXPORT ID max_resid;
30:
31: typedef INT (*SVC)( void *pk_para, FN fncd );
32: typedef void (*BrkFN)( ID tskid );
33: typedef void (*StuFN)( ID resid, INT info );
34: typedef void (*CluFN)( ID resid, INT info );
35: typedef ER (*EvtFN)( INT evttyp, ID resid, INT info );
36:
37: 38: 39:
40: typedef struct subsystem_control_block SSYCB;
41: struct subsystem_control_block {
42: SSYCB *link;
43: ATR ssyatr;
44: PRI ssypri;
45: SVC svchdr;
46: BrkFN breakfn;
47: StuFN startupfn;
48: CluFN cleanupfn;
49: EvtFN eventfn;
50: INT resblksz;
51: void *resblk;
52: #if TA_GP
53: void *gp;
54: #endif
55: };
56:
57: LOCAL SSYCB *ssycb_table;
58:
59: #define get_ssycb(id) ( &ssycb_table[INDEX_SSY(id)] )
60:
61: 62: 63:
64: LOCAL SSYCB **ssypri_table;
65:
66: #define ssypri_index(ssypri) ( (ssypri) - MIN_SSYPRI )
67:
68: 69: 70: 71:
72: LOCAL UW *resid_bitmap;
73:
74: 75: 76:
77: #define index_to_resid(index) ( (index) + MIN_RESID )
78: #define resid_to_index(resid) ( (resid) - MIN_RESID )
79:
80: 81: 82:
83: #define ROUND_RESBLKSZ(resblksz) ( ((resblksz) + 3) & ~0x00000003U )
84:
85: 86: 87:
88: IMPORT INT no_support();
89:
90: 91: 92:
93: EXPORT ER subsystem_initialize( void )
94: {
95: INT i;
96:
97:
98: i = _tk_get_cfn(SCTAG_TMAXSSYID, &max_ssyid, 1);
99: if ( i < 1 || NUM_SSYID < 1 ) {
100: return E_SYS;
101: }
102: i = _tk_get_cfn(SCTAG_TMAXSSYPRI, &max_ssypri, 1);
103: if ( i < 1 || NUM_SSYPRI < 1 ) {
104: return E_SYS;
105: }
106:
107:
108: ssycb_table = Imalloc((UINT)NUM_SSYID * sizeof(SSYCB));
109: if ( ssycb_table == NULL ) {
110: goto err_ret1;
111: }
112:
113:
114: ssypri_table = Imalloc((UINT)NUM_SSYPRI * sizeof(SSYCB*));
115: if ( ssypri_table == NULL ) {
116: goto err_ret2;
117: }
118:
119: for ( i = 0; i < NUM_SSYID; i++ ) {
120: ssycb_table[i].svchdr = no_support;
121: ssycb_table[i].breakfn = NULL;
122: ssycb_table[i].startupfn = NULL;
123: ssycb_table[i].cleanupfn = NULL;
124: ssycb_table[i].eventfn = NULL;
125: }
126:
127: for ( i = 0; i < NUM_SSYPRI; i++ ) {
128: ssypri_table[i] = NULL;
129: }
130:
131: return E_OK;
132:
133: err_ret2:
134: Ifree(ssycb_table);
135: err_ret1:
136: return E_NOMEM;
137: }
138:
139:
140: 141: 142:
143: IMPORT void call_brkhdr( TCB *tcb );
144:
145:
146: 147: 148:
149: SYSCALL ER _tk_def_ssy P2( ID ssid, CONST T_DSSY *pk_dssy )
150: {
151: SSYCB *ssycb;
152: void *resblk;
153: SSYCB **prev;
154: INT i;
155: ER ercd = E_OK;
156:
157: CHECK_SSYID(ssid);
158: #if CHK_PAR
159: if ( pk_dssy != NULL ) {
160: CHECK_RSATR(pk_dssy->ssyatr, TA_NULL|TA_GP);
161: CHECK_SSYPRI(pk_dssy->ssypri);
162: CHECK_PAR(pk_dssy->resblksz >= 0);
163: }
164: #endif
165:
166: ssycb = get_ssycb(ssid);
167:
168: resblk = NULL;
169: if ( pk_dssy != NULL ) {
170: if ( pk_dssy->resblksz > 0 ) {
171:
172: i = ROUND_RESBLKSZ(pk_dssy->resblksz);
173: resblk = Icalloc((UINT)NUM_RESID, (UINT)i);
174: if ( resblk == NULL ) {
175: return E_NOMEM;
176: }
177: }
178: }
179:
180: BEGIN_CRITICAL_SECTION;
181: if ( pk_dssy != NULL ) {
182:
183: if ( ssycb->svchdr != no_support ) {
184: ercd = E_OBJ;
185: goto error_exit;
186: }
187: ssycb->ssyatr = pk_dssy->ssyatr;
188: ssycb->ssypri = pk_dssy->ssypri;
189: ssycb->svchdr = (SVC)pk_dssy->svchdr;
190: ssycb->breakfn = (BrkFN)pk_dssy->breakfn;
191: ssycb->startupfn = (StuFN)pk_dssy->startupfn;
192: ssycb->cleanupfn = (CluFN)pk_dssy->cleanupfn;
193: ssycb->eventfn = (EvtFN)pk_dssy->eventfn;
194: ssycb->resblksz = pk_dssy->resblksz;
195: ssycb->resblk = resblk;
196: #if TA_GP
197: if ( (pk_dssy->ssyatr & TA_GP) != 0 ) {
198: gp = pk_dssy->gp;
199: }
200: ssycb->gp = gp;
201: #endif
202:
203:
204: i = ssypri_index(ssycb->ssypri);
205: ssycb->link = ssypri_table[i];
206: ssypri_table[i] = ssycb;
207: } else {
208:
209: if ( ssycb->svchdr == no_support ) {
210: ercd = E_NOEXS;
211: goto error_exit;
212: }
213:
214:
215: prev = &ssypri_table[ssypri_index(ssycb->ssypri)];
216: while ( *prev != NULL ) {
217: if ( *prev == ssycb ) {
218: *prev = ssycb->link;
219: break;
220: }
221: prev = &(*prev)->link;
222: }
223:
224: resblk = ssycb->resblk;
225: ssycb->svchdr = no_support;
226: ssycb->breakfn = NULL;
227: ssycb->startupfn = NULL;
228: ssycb->cleanupfn = NULL;
229: ssycb->eventfn = NULL;
230: }
231:
232: error_exit:
233: END_CRITICAL_SECTION;
234:
235: if ( ercd < E_OK || pk_dssy == NULL ) {
236: if ( resblk != NULL ) {
237: Ifree(resblk);
238: }
239: }
240:
241: return ercd;
242: }
243:
244: 245: 246:
247: SYSCALL ER _tk_sta_ssy( ID ssid, ID resid, INT info )
248: {
249: SSYCB *ssycb;
250: StuFN startupfn;
251: UH save_texflg;
252: INT i;
253: ER ercd = E_OK;
254:
255: CHECK_SSYID_ALL(ssid);
256: CHECK_RESID(resid);
257: CHECK_DISPATCH();
258:
259: DISABLE_INTERRUPT;
260:
261: save_texflg = ctxtsk->texflg;
262: ctxtsk->texflg |= SSFN_RUNNING;
263: ctxtsk->sysmode++;
264: ENABLE_INTERRUPT;
265:
266: if ( ssid > 0 ) {
267:
268: ssycb = get_ssycb(ssid);
269: if ( ssycb->svchdr == no_support ) {
270: ercd = E_NOEXS;
271: } else {
272: startupfn = ssycb->startupfn;
273: if ( startupfn != NULL ) {
274: CallUserHandlerP2(resid, info,
275: startupfn, ssycb);
276: }
277: }
278: } else {
279:
280: for ( i = 0; i < NUM_SSYPRI; ++i ) {
281: ssycb = ssypri_table[i];
282: while ( ssycb != NULL ) {
283: startupfn = ssycb->startupfn;
284: if ( startupfn != NULL ) {
285: CallUserHandlerP2(resid, info,
286: startupfn, ssycb);
287: }
288: ssycb = ssycb->link;
289: }
290: }
291: }
292:
293: DISABLE_INTERRUPT;
294: ctxtsk->sysmode--;
295: ctxtsk->texflg = save_texflg;
296: ENABLE_INTERRUPT;
297:
298: 299:
300: if ( ctxtsk->exectex != 0 ) {
301: call_brkhdr(ctxtsk);
302: }
303:
304: return ercd;
305: }
306:
307: 308: 309:
310: LOCAL void clean_resblk( SSYCB *ssycb, ID idx )
311: {
312: INT sz;
313:
314: if ( ssycb->resblk != NULL ) {
315: sz = ROUND_RESBLKSZ(ssycb->resblksz);
316: MEMSET((B*)ssycb->resblk + sz * idx, 0, (size_t)sz);
317: }
318: }
319:
320: 321: 322:
323: SYSCALL ER _tk_cln_ssy( ID ssid, ID resid, INT info )
324: {
325: SSYCB *ssycb;
326: CluFN cleanupfn;
327: UH save_texflg;
328: INT i, idx;
329: ER ercd = E_OK;
330:
331: CHECK_SSYID_ALL(ssid);
332: CHECK_RESID(resid);
333: CHECK_DISPATCH();
334:
335: DISABLE_INTERRUPT;
336:
337: save_texflg = ctxtsk->texflg;
338: ctxtsk->texflg |= SSFN_RUNNING;
339: ctxtsk->sysmode++;
340: ENABLE_INTERRUPT;
341:
342: idx = resid_to_index(resid);
343:
344: if ( ssid > 0 ) {
345:
346: ssycb = get_ssycb(ssid);
347: if ( ssycb->svchdr == no_support ) {
348: ercd = E_NOEXS;
349: } else {
350: cleanupfn = ssycb->cleanupfn;
351: if ( cleanupfn != NULL ) {
352: CallUserHandlerP2(resid, info,
353: cleanupfn, ssycb);
354: }
355: clean_resblk(ssycb, idx);
356: }
357: } else {
358:
359: for ( i = NUM_SSYPRI-1; i >= 0; --i ) {
360: ssycb = ssypri_table[i];
361: while ( ssycb != NULL ) {
362: cleanupfn = ssycb->cleanupfn;
363: if ( cleanupfn != NULL ) {
364: CallUserHandlerP2(resid, info,
365: cleanupfn, ssycb);
366: }
367: clean_resblk(ssycb, idx);
368: ssycb = ssycb->link;
369: }
370: }
371: }
372:
373: DISABLE_INTERRUPT;
374: ctxtsk->sysmode--;
375: ctxtsk->texflg = save_texflg;
376: ENABLE_INTERRUPT;
377:
378: 379:
380: if ( ctxtsk->exectex != 0 ) {
381: call_brkhdr(ctxtsk);
382: }
383:
384: return ercd;
385: }
386:
387: 388: 389:
390: SYSCALL ER _tk_evt_ssy( ID ssid, INT evttyp, ID resid, INT info )
391: {
392: SSYCB *ssycb;
393: EvtFN eventfn;
394: UH save_texflg;
395: INT i, e, d;
396: ER ercd = E_OK;
397: ER er = E_OK;
398:
399: CHECK_SSYID_ALL(ssid);
400: CHECK_RESID_ANY(resid);
401: CHECK_DISPATCH();
402:
403: DISABLE_INTERRUPT;
404:
405: save_texflg = ctxtsk->texflg;
406: ctxtsk->texflg |= SSFN_RUNNING;
407: ctxtsk->sysmode++;
408: ENABLE_INTERRUPT;
409:
410: if ( ssid > 0 ) {
411:
412: ssycb = get_ssycb(ssid);
413: if ( ssycb->svchdr == no_support ) {
414: ercd = E_NOEXS;
415: } else {
416: eventfn = ssycb->eventfn;
417: if ( eventfn != NULL ) {
418: ercd = CallUserHandlerP3(evttyp, resid, info,
419: eventfn, ssycb);
420: }
421: }
422: } else {
423: if ( (evttyp % 2) == 0 ) {
424: 425:
426: i = NUM_SSYPRI-1;
427: e = -1;
428: d = -1;
429: } else {
430: 431:
432: i = 0;
433: e = NUM_SSYPRI;
434: d = +1;
435: }
436: for ( ; i != e; i += d ) {
437: ssycb = ssypri_table[i];
438: while ( ssycb != NULL ) {
439: eventfn = ssycb->eventfn;
440: if ( eventfn != NULL ) {
441: er = CallUserHandlerP3(evttyp,resid,info,
442: eventfn, ssycb);
443: if ( er < 0 ) {
444: ercd = er;
445: }
446: }
447: ssycb = ssycb->link;
448: }
449: }
450: }
451:
452: DISABLE_INTERRUPT;
453: ctxtsk->sysmode--;
454: ctxtsk->texflg = save_texflg;
455: ENABLE_INTERRUPT;
456:
457: 458:
459: if ( ctxtsk->exectex != 0 ) {
460: call_brkhdr(ctxtsk);
461: }
462:
463: return ercd;
464: }
465:
466: 467: 468:
469: SYSCALL ER _tk_ref_ssy( ID ssid, T_RSSY *pk_rssy )
470: {
471: SSYCB *ssycb;
472: ER ercd = E_OK;
473:
474: CHECK_SSYID(ssid);
475:
476: ssycb = get_ssycb(ssid);
477:
478: BEGIN_CRITICAL_SECTION;
479: if ( ssycb->svchdr == no_support ) {
480: ercd = E_NOEXS;
481: } else {
482: pk_rssy->ssypri = ssycb->ssypri;
483: pk_rssy->resblksz = ssycb->resblksz;
484: }
485: END_CRITICAL_SECTION;
486:
487: return ercd;
488: }
489:
490: #if USE_DBGSPT
491:
492: 493: 494:
495: SYSCALL INT _td_lst_ssy( ID list[], INT nent )
496: {
497: SSYCB *ssycb, *end;
498: INT n = 0;
499:
500: BEGIN_DISABLE_INTERRUPT;
501: end = ssycb_table + NUM_SSYID;
502: for ( ssycb = ssycb_table; ssycb < end; ssycb++ ) {
503: if ( ssycb->svchdr == no_support ) {
504: continue;
505: }
506:
507: if ( n++ < nent ) {
508: *list++ = ID_SSY(ssycb - ssycb_table);
509: }
510: }
511: END_DISABLE_INTERRUPT;
512:
513: return n;
514: }
515:
516: 517: 518:
519: SYSCALL ER _td_ref_ssy( ID ssid, TD_RSSY *pk_rssy )
520: {
521: SSYCB *ssycb;
522: ER ercd = E_OK;
523:
524: CHECK_SSYID(ssid);
525:
526: ssycb = get_ssycb(ssid);
527:
528: BEGIN_DISABLE_INTERRUPT;
529: if ( ssycb->svchdr == no_support ) {
530: ercd = E_NOEXS;
531: } else {
532: pk_rssy->ssypri = ssycb->ssypri;
533: pk_rssy->resblksz = ssycb->resblksz;
534: }
535: END_DISABLE_INTERRUPT;
536:
537: return ercd;
538: }
539: #endif
540:
541: 542: 543:
544: EXPORT ER svc_ientry P2GP( void *pk_para, FN fncd )
545: {
546: ID ssid;
547: SSYCB *ssycb;
548: ID save_execssid;
549: UINT save_waitmask;
550: UINT save_exectex;
551: ER ercd;
552:
553:
554: ssid = fncd & 0xff;
555: if ( ssid < 1 || ssid > MAX_SSYID ) {
556: return E_RSFN;
557: }
558:
559: ssycb = get_ssycb(ssid);
560:
561: if ( in_indp() ) {
562:
563: ercd = CallUserHandlerP2_GP(pk_para, fncd,
564: ssycb->svchdr, ssycb);
565: } else {
566:
567: LockSVC(&ctxtsk->svclock);
568:
569: if ( (ctxtsk->waitmask & TTX_SVC) != 0 ) {
570: UnlockSVC();
571: return E_DISWAI;
572: }
573:
574: DISABLE_INTERRUPT;
575: save_execssid = ctxtsk->execssid;
576: save_waitmask = ctxtsk->waitmask;
577: save_exectex = ctxtsk->exectex;
578: ctxtsk->execssid = ssid;
579: ctxtsk->waitmask = 0;
580: 581: 582:
583: if ( save_execssid < 0 ) {
584: ctxtsk->exectex = 0;
585: }
586: ctxtsk->sysmode++;
587: ENABLE_INTERRUPT;
588:
589: UnlockSVC();
590:
591:
592: ercd = CallUserHandlerP2_GP(pk_para, fncd,
593: ssycb->svchdr, ssycb);
594:
595:
596: LockSVC(&ctxtsk->svclock);
597:
598: DISABLE_INTERRUPT;
599: ctxtsk->sysmode--;
600: ctxtsk->execssid = save_execssid;
601: ctxtsk->waitmask = save_waitmask;
602: ctxtsk->exectex |= save_exectex;
603: ENABLE_INTERRUPT;
604:
605: UnlockSVC();
606:
607: if ( ctxtsk->exectex != 0 ) {
608: call_brkhdr(ctxtsk);
609: }
610: }
611:
612: return ercd;
613: }
614:
615:
616: 617: 618:
619:
620: 621: 622:
623: SYSCALL ER _tk_def_tex( ID tskid, CONST T_DTEX *pk_dtex )
624: {
625: TCB *tcb;
626: ER ercd = E_OK;
627:
628: CHECK_TSKID_SELF(tskid);
629: #if CHK_PAR
630: if ( pk_dtex != NULL ) {
631: CHECK_RSATR(pk_dtex->texatr, TA_NULL);
632: }
633: #endif
634:
635: tcb = get_tcb_self(tskid);
636:
637: BEGIN_CRITICAL_SECTION;
638: if ( tcb->state == TS_NONEXIST ) {
639: ercd = E_NOEXS;
640: goto error_exit;
641: }
642: if ( (tcb->tskatr & TA_RNG3) == TA_RNG0 ) {
643: ercd = E_OBJ;
644: goto error_exit;
645: }
646:
647:
648: tcb->pendtex = 0;
649: tcb->exectex = 0;
650: tcb->texmask = 0;
651: tcb->texhdr = ( pk_dtex != NULL )? pk_dtex->texhdr: NULL;
652:
653: error_exit:
654: END_CRITICAL_SECTION;
655:
656: return ercd;
657: }
658:
659: 660: 661:
662: LOCAL ER set_tex_mask( ID tskid, UINT texmsk, BOOL enable )
663: {
664: TCB *tcb;
665: ER ercd = E_OK;
666:
667: CHECK_TSKID_SELF(tskid);
668:
669: tcb = get_tcb_self(tskid);
670:
671: BEGIN_CRITICAL_SECTION;
672: if ( tcb->state == TS_NONEXIST || tcb->texhdr == NULL ) {
673: ercd = E_NOEXS;
674: goto error_exit;
675: }
676:
677: if ( enable ) {
678: tcb->texmask |= texmsk;
679: } else {
680: tcb->texmask &= ~texmsk;
681: }
682:
683:
684: tcb->pendtex &= tcb->texmask;
685:
686: error_exit:
687: END_CRITICAL_SECTION;
688:
689: return ercd;
690: }
691:
692: 693: 694:
695: SYSCALL ER _tk_dis_tex( ID tskid, UINT texptn )
696: {
697: return set_tex_mask(tskid, texptn, FALSE);
698: }
699:
700: 701: 702:
703: SYSCALL ER _tk_ena_tex( ID tskid, UINT texptn )
704: {
705: return set_tex_mask(tskid, texptn, TRUE);
706: }
707:
708:
709: 710: 711: 712:
713: EXPORT void call_brkhdr( TCB *tcb )
714: {
715: SSYCB *ssycb;
716: BrkFN breakfn = NULL;
717: UH save_texflg = 0;
718: INT priority;
719: #if TA_GP
720: void *ssy_gp = NULL;
721: #endif
722:
723: BEGIN_CRITICAL_SECTION;
724: 725: 726:
727: if ( (tcb->texflg & SSFN_RUNNING) != 0 ) {
728: goto not_call;
729: }
730:
731: 732:
733:
734: if ( !(tcb->exectex != 0 && tcb->execssid > 0) ) {
735: goto not_call;
736: }
737:
738:
739: ssycb = get_ssycb(tcb->execssid);
740:
741: tcb->execssid |= BREAK_RAN;
742:
743:
744: breakfn = ssycb->breakfn;
745: if ( breakfn == NULL ) {
746: goto not_call;
747: }
748: #if TA_GP
749: ssy_gp = ssycb->gp;
750: #endif
751:
752: if ( tcb->priority < ctxtsk->priority ) {
753: 754:
755: change_task_priority(ctxtsk, tcb->priority);
756: }
757:
758:
759: save_texflg = ctxtsk->texflg;
760: ctxtsk->texflg |= SSFN_RUNNING;
761: ctxtsk->sysmode++;
762:
763: not_call:
764: END_CRITICAL_SECTION;
765: if ( breakfn == NULL ) {
766: return;
767: }
768:
769:
770: #if TA_GP
771: CallUserHandler(tcb->tskid, 0, 0, breakfn, ssy_gp);
772: #else
773: (*breakfn)(tcb->tskid);
774: #endif
775:
776: BEGIN_CRITICAL_SECTION;
777: ctxtsk->sysmode--;
778: ctxtsk->texflg = save_texflg;
779:
780:
781: #ifdef NUM_MTXID
782: priority = chg_pri_mutex(ctxtsk, ctxtsk->bpriority);
783: #else
784: priority = ctxtsk->bpriority;
785: #endif
786: if ( ctxtsk->priority != priority ) {
787: change_task_priority(ctxtsk, priority);
788: }
789: END_CRITICAL_SECTION;
790: }
791:
792:
793: 794: 795:
796: SYSCALL ER _tk_ras_tex( ID tskid, INT texcd )
797: {
798: TCB *tcb;
799: BOOL rastex = FALSE;
800: ER ercd = E_OK;
801:
802: CHECK_INTSK();
803: CHECK_TSKID_SELF(tskid);
804: CHECK_PAR(texcd >= 0 && texcd <= 31);
805: CHECK_DISPATCH();
806:
807: tcb = get_tcb_self(tskid);
808:
809:
810: LockSVC(&tcb->svclock);
811:
812: BEGIN_CRITICAL_SECTION;
813: if ( tcb->state == TS_NONEXIST || tcb->texhdr == NULL ) {
814: ercd = E_NOEXS;
815: goto error_exit;
816: }
817: if ( tcb->state == TS_DORMANT ) {
818: ercd = E_OBJ;
819: goto error_exit;
820: }
821:
822:
823: if ( (tcb->texflg & TEX0_RUNNING) != 0 ) {
824: goto error_exit;
825: }
826:
827: tcb->pendtex |= (UINT)(1 << texcd) & tcb->texmask;
828: if ( tcb->pendtex == 0 ) {
829: goto error_exit;
830: }
831:
832: 833: 834:
835: if ( (tcb->pendtex & 0x00000001U) != 0 || (tcb->texflg & TEX1_RUNNING) == 0 ) {
836:
837: tcb->exectex |= tcb->pendtex;
838: rastex = TRUE;
839:
840:
841: request_tex(tcb);
842: }
843:
844: error_exit:
845: END_CRITICAL_SECTION;
846:
847: if ( rastex ) {
848:
849: call_brkhdr(tcb);
850: }
851:
852: UnlockSVC();
853:
854: if ( rastex ) {
855: 856:
857: if ( ctxtsk->exectex != 0 ) {
858: call_brkhdr(ctxtsk);
859: }
860: }
861:
862: return ercd;
863: }
864:
865: 866: 867:
868: SYSCALL INT _tk_end_tex( BOOL enatex )
869: {
870: INT texcd = 0;
871: UINT texptn;
872:
873: CHECK_DISPATCH();
874: if ( (ctxtsk->texflg & (TEX0_RUNNING|TEX1_RUNNING)) != TEX1_RUNNING ) {
875: return E_CTX;
876: }
877:
878: BEGIN_CRITICAL_SECTION;
879: texptn = ctxtsk->pendtex & ~0x00000001U;
880: if ( texptn != 0 ) {
881: while ( (texptn & 1) == 0 ) {
882: texcd++;
883: texptn >>= 1;
884: }
885: }
886:
887: 888: 889:
890: if ( enatex || texcd == 0 ) {
891: ctxtsk->texflg &= ~TEX1_RUNNING;
892: ctxtsk->exectex |= ctxtsk->pendtex;
893:
894: if ( texcd > 0 ) {
895: 896:
897: request_tex(ctxtsk);
898: }
899: } else {
900:
901: ctxtsk->pendtex &= ~(UINT)(1 << texcd);
902: }
903: END_CRITICAL_SECTION;
904:
905: return texcd;
906: }
907:
908: 909: 910:
911: SYSCALL ER _tk_ref_tex( ID tskid, T_RTEX *pk_rtex )
912: {
913: TCB *tcb;
914: ER ercd = E_OK;
915:
916: CHECK_TSKID_SELF(tskid);
917:
918: tcb = get_tcb_self(tskid);
919:
920: BEGIN_CRITICAL_SECTION;
921: if ( tcb->state == TS_NONEXIST ) {
922: ercd = E_NOEXS;
923: } else {
924: pk_rtex->pendtex = tcb->pendtex;
925: pk_rtex->texmask = tcb->texmask;
926: }
927: END_CRITICAL_SECTION;
928:
929: return ercd;
930: }
931:
932: #if USE_DBGSPT
933: 934: 935:
936: SYSCALL ER _td_ref_tex( ID tskid, TD_RTEX *pk_rtex )
937: {
938: TCB *tcb;
939: ER ercd = E_OK;
940:
941: CHECK_TSKID_SELF(tskid);
942:
943: tcb = get_tcb_self(tskid);
944:
945: BEGIN_DISABLE_INTERRUPT;
946: if ( tcb->state == TS_NONEXIST ) {
947: ercd = E_NOEXS;
948: } else {
949: pk_rtex->pendtex = tcb->pendtex;
950: pk_rtex->texmask = tcb->texmask;
951: }
952: END_DISABLE_INTERRUPT;
953:
954: return ercd;
955: }
956: #endif
957:
958:
959: 960: 961:
962:
963: 964: 965:
966: EXPORT ER resource_group_initialize( void )
967: {
968: W n;
969:
970:
971: n = _tk_get_cfn(SCTAG_TMAXRESID, &max_resid, 1);
972: if ( n < 1 || NUM_RESID < 1 ) {
973: return E_SYS;
974: }
975:
976:
977: resid_bitmap = Icalloc(1, (UINT)((NUM_RESID + 31) / 32));
978: if ( resid_bitmap == NULL ) {
979: return E_NOMEM;
980: }
981:
982:
983: BitSet(resid_bitmap, resid_to_index(SYS_RESID));
984:
985: return E_OK;
986: }
987:
988: 989: 990:
991: SYSCALL ID _tk_cre_res( void )
992: {
993: INT n;
994: ER ercd;
995:
996: BEGIN_CRITICAL_SECTION;
997: n = BitSearch0_w(resid_bitmap, 0, NUM_RESID);
998: if ( n < 0 ) {
999: ercd = E_LIMIT;
1000: } else {
1001: BitSet(resid_bitmap, n);
1002: ercd = index_to_resid(n);
1003: }
1004: END_CRITICAL_SECTION;
1005:
1006: return ercd;
1007: }
1008:
1009: 1010: 1011:
1012: SYSCALL ER _tk_del_res( ID resid )
1013: {
1014: INT idx;
1015: ER ercd = E_OK;
1016:
1017: CHECK_RESID(resid);
1018: if ( resid == SYS_RESID ) {
1019: return E_ID;
1020: }
1021:
1022: BEGIN_CRITICAL_SECTION;
1023: idx = resid_to_index(resid);
1024: if ( !BitTest(resid_bitmap, idx) ) {
1025: ercd = E_NOEXS;
1026: } else {
1027: BitClr(resid_bitmap, idx);
1028: }
1029: END_CRITICAL_SECTION;
1030:
1031: return ercd;
1032: }
1033:
1034: 1035: 1036:
1037: SYSCALL ER _tk_get_res( ID resid, ID ssid, void **p_resblk )
1038: {
1039: INT idx;
1040: SSYCB *ssycb;
1041: ER ercd = E_OK;
1042:
1043: CHECK_RESID(resid);
1044: CHECK_SSYID(ssid);
1045:
1046: idx = resid_to_index(resid);
1047: ssycb = get_ssycb(ssid);
1048:
1049: BEGIN_CRITICAL_SECTION;
1050: if ( !BitTest(resid_bitmap, idx) || ssycb->svchdr == no_support ) {
1051: ercd = E_NOEXS;
1052: goto error_exit;
1053: }
1054:
1055:
1056: *p_resblk = (B*)ssycb->resblk + ROUND_RESBLKSZ(ssycb->resblksz) * idx;
1057:
1058: error_exit:
1059: END_CRITICAL_SECTION;
1060:
1061: return ercd;
1062: }