|
|
1.1 root 1: /*
2:
1.1.1.3 ! root 3: Copyright 1990,1991,1992 Eric R. Smith.
! 4:
! 5: Copyright 1992 Atari Corporation.
! 6:
! 7: All rights reserved.
1.1 root 8:
9: */
10:
11:
12:
13: /* routines for handling processes */
14:
15:
16:
17: #include "mint.h"
18:
19: #include "xbra.h"
20:
21:
22:
23: static void do_wakeup_things P_((void));
24:
25:
26:
27: extern short proc_clock;
28:
29:
30:
31: /* global process variables */
32:
33: PROC *proclist; /* list of all active processes */
34:
35: PROC *curproc; /* current process */
36:
37: PROC *rootproc; /* pid 0 -- MiNT itself */
38:
39: PROC *sys_q[NUM_QUEUES];
40:
41:
42:
1.1.1.3 ! root 43: short time_slice = 2; /* default; actual value comes from mint.cnf */
! 44:
! 45:
! 46:
! 47: #if 0
! 48:
! 49: #define TIME_SLICE 2 /* number of 20ms ticks before process is
1.1 root 50:
51: pre-empted */
52:
1.1.1.3 ! root 53: #else
! 54:
! 55: #define TIME_SLICE time_slice
1.1 root 56:
1.1.1.3 ! root 57: #endif
1.1 root 58:
59:
60:
61: /* macro for calculating number of missed time slices, based on a
62:
63: * process' priority
64:
65: */
66:
67: #define SLICES(pri) (((pri) >= 0) ? 0 : -(pri))
68:
69:
70:
71: extern FILESYS bios_filesys;
72:
73:
74:
75: /*
76:
77: * get a new process struct
78:
79: */
80:
81:
82:
83: PROC *
84:
85: new_proc()
86:
87: {
88:
89: PROC *p;
90:
1.1.1.3 ! root 91: void *pt;
! 92:
! 93:
! 94:
! 95: pt = kmalloc(page_table_size + 16);
! 96:
! 97: if (!pt) return 0;
! 98:
1.1 root 99:
100:
101: p = (PROC *)kmalloc(SIZEOF(PROC));
102:
1.1.1.3 ! root 103: if (!p) {
! 104:
! 105: kfree(pt);
! 106:
! 107: return 0;
! 108:
! 109: }
! 110:
! 111: /* page tables must be on 16 byte boundaries, so we
! 112:
! 113: * round off by 16 for that; however, we will want to
! 114:
! 115: * kfree that memory at some point, so we squirrel
! 116:
! 117: * away the original address for later use
! 118:
! 119: */
! 120:
! 121: p->page_table = ROUND16(pt);
! 122:
! 123: p->pt_mem = pt;
! 124:
1.1 root 125: return p;
126:
127: }
128:
129:
130:
131: /*
132:
133: * dispose of an old proc
134:
135: */
136:
137:
138:
139: void
140:
141: dispose_proc(p)
142:
143: PROC *p;
144:
145: {
146:
1.1.1.3 ! root 147: TRACELOW(("dispose_proc"));
! 148:
! 149: kfree(p->pt_mem);
! 150:
1.1 root 151: kfree(p);
152:
153: }
154:
155:
156:
157: /*
158:
159: * create a new process that is (practically) a duplicate of the
160:
161: * current one
162:
163: */
164:
165:
166:
167: PROC *
168:
169: fork_proc()
170:
171: {
172:
173: PROC *p;
174:
175: int i;
176:
177: FILEPTR *f;
178:
1.1.1.3 ! root 179: long_desc *pthold;
! 180:
! 181: void *ptmemhold;
! 182:
1.1 root 183:
184:
1.1.1.2 root 185: if ((p = new_proc()) == 0) {
1.1 root 186:
187: nomem:
188:
1.1.1.2 root 189: DEBUG(("fork_proc: insufficient memory"));
1.1 root 190:
191: mint_errno = ENSMEM; return 0;
192:
193: }
194:
195:
196:
1.1.1.3 ! root 197: /* child shares most things with parent, but hold on to page table ptr */
! 198:
! 199: pthold = p->page_table;
! 200:
! 201: ptmemhold = p->pt_mem;
! 202:
! 203: *p = *curproc;
! 204:
! 205: p->page_table = pthold;
1.1 root 206:
1.1.1.3 ! root 207: p->pt_mem = ptmemhold;
1.1 root 208:
209:
1.1.1.3 ! root 210:
! 211: /* these things are not inherited */
1.1 root 212:
213: p->ppid = curproc->pid;
214:
215: p->pid = newpid();
216:
217: p->sigpending = 0;
218:
219: p->sysstack = (long)(p->stack + STKSIZE - 12);
220:
221: p->ctxt[CURRENT].ssp = p->sysstack;
222:
223: p->ctxt[SYSCALL].ssp = (long)(p->stack + ISTKSIZE);
224:
225: p->alarmtim = 0;
226:
227: p->curpri = p->pri;
228:
229: p->slices = SLICES(p->pri);
230:
231: p->starttime = timestamp;
232:
233: p->startdate = datestamp;
234:
235:
236:
237: ((long *)p->sysstack)[1] = FRAME_MAGIC;
238:
239: ((long *)p->sysstack)[2] = 0;
240:
241: ((long *)p->sysstack)[3] = 0;
242:
243:
244:
245: p->usrtime = p->systime = p->chldstime = p->chldutime = 0;
246:
247:
248:
249: /* copy open handles */
250:
251: for (i = MIN_HANDLE; i < MAX_OPEN; i++) {
252:
253: if ((f = p->handle[i]) != 0) {
254:
255: if (f->flags & O_NOINHERIT)
256:
257: /* oops, we didn't really want to copy this handle */
258:
259: p->handle[i] = 0;
260:
261: else
262:
263: f->links++;
264:
265: }
266:
267: }
268:
269:
270:
1.1.1.3 ! root 271: /* copy root and current directories */
! 272:
! 273: for (i = 0; i < NUM_DRIVES; i++) {
! 274:
! 275: dup_cookie(&p->root[i], &curproc->root[i]);
! 276:
! 277: dup_cookie(&p->curdir[i], &curproc->curdir[i]);
! 278:
! 279: }
! 280:
! 281:
! 282:
1.1 root 283: /* clear directory search info */
284:
285: zero((char *)p->srchdta, NUM_SEARCH * SIZEOF(DTABUF *));
286:
1.1.1.3 ! root 287: p->searches = 0;
! 288:
1.1 root 289:
290:
291: /* copy memory */
292:
293: p->mem = (MEMREGION **) kmalloc(p->num_reg * SIZEOF(MEMREGION *));
294:
295: if (!p->mem) {
296:
297: dispose_proc(p);
298:
299: goto nomem;
300:
301: }
302:
303: p->addr = (virtaddr *)kmalloc(p->num_reg * SIZEOF(virtaddr));
304:
305: if (!p->addr) {
306:
307: kfree(p->mem);
308:
309: dispose_proc(p);
310:
311: goto nomem;
312:
313: }
314:
315:
316:
317: for (i = 0; i < curproc->num_reg; i++) {
318:
1.1.1.2 root 319: p->mem[i] = curproc->mem[i];
320:
321: if (p->mem[i] != 0)
1.1 root 322:
323: p->mem[i]->links++;
324:
325: p->addr[i] = curproc->addr[i];
326:
327: }
328:
329:
330:
1.1.1.3 ! root 331: /* now that memory ownership is copied, fill in page table */
! 332:
! 333: init_page_table(p);
! 334:
! 335:
! 336:
1.1.1.2 root 337: /* child isn't traced */
338:
339: p->ptracer = 0;
340:
341: p->ptraceflags = 0;
342:
343:
344:
1.1 root 345: p->starttime = Tgettime();
346:
347: p->startdate = Tgetdate();
348:
349:
350:
351: p->q_next = 0;
352:
353: p->wait_q = 0;
354:
355: p->gl_next = proclist;
356:
357: proclist = p; /* hook into the process list */
358:
359: return p;
360:
361: }
362:
363:
364:
365: /*
366:
367: * initialize the process table
368:
369: */
370:
371:
372:
373: void
374:
375: init_proc()
376:
377: {
378:
379: int i;
380:
381: FILESYS *fs;
382:
383: fcookie dir;
384:
1.1.1.3 ! root 385: long_desc *pthold;
! 386:
! 387: void *ptmemhold;
! 388:
1.1 root 389:
390:
391: rootproc = curproc = new_proc();
392:
393: assert(curproc);
394:
395:
396:
1.1.1.3 ! root 397: pthold = curproc->page_table;
! 398:
! 399: ptmemhold = curproc->pt_mem;
! 400:
1.1 root 401: zero((char *)curproc, (long)sizeof(PROC));
402:
1.1.1.3 ! root 403: curproc->page_table = pthold;
! 404:
! 405: curproc->pt_mem = ptmemhold;
! 406:
1.1 root 407:
408:
409: curproc->ppid = -1; /* no parent */
410:
411: curproc->domain = DOM_TOS; /* TOS domain */
412:
413: curproc->sysstack = (long) (curproc->stack+STKSIZE-12);
414:
415: curproc->magic = CTXT_MAGIC;
416:
1.1.1.3 ! root 417: curproc->memflags = F_PROT_S; /* default prot mode: super-only */
! 418:
1.1 root 419: ((long *)curproc->sysstack)[1] = FRAME_MAGIC;
420:
421: ((long *)curproc->sysstack)[2] = 0;
422:
423: ((long *)curproc->sysstack)[3] = 0;
424:
425:
426:
1.1.1.2 root 427: /* NOTE: in main.c this could be changed, later */
428:
429: curproc->base = _base;
1.1 root 430:
431:
432:
433: strcpy(curproc->name, "MiNT");
434:
435:
436:
437: /* get some memory */
438:
439: curproc->mem = (MEMREGION **)kmalloc(NUM_REGIONS*SIZEOF(MEMREGION *));
440:
441: curproc->addr = (virtaddr *)kmalloc(NUM_REGIONS*SIZEOF(virtaddr));
442:
443: assert(curproc->mem && curproc->addr);
444:
445:
446:
447: /* make sure it's filled with zeros */
448:
449: zero((char *)curproc->addr, NUM_REGIONS * SIZEOF(virtaddr));
450:
451: zero((char *)curproc->mem, NUM_REGIONS * SIZEOF(MEMREGION *));
452:
453: curproc->num_reg = NUM_REGIONS;
454:
455:
456:
457: /* get root and current directories for all drives */
458:
459: for (i = 0; i < NUM_DRIVES; i++) {
460:
461: if ((fs = drives[i]) != 0 && (*fs->root)(i, &dir) == E_OK) {
462:
1.1.1.3 ! root 463: dup_cookie(&curproc->curdir[i], &dir);
! 464:
! 465: curproc->root[i] = dir;
1.1 root 466:
467: } else {
468:
469: curproc->root[i].fs = curproc->curdir[i].fs = 0;
470:
471: curproc->root[i].dev = curproc->curdir[i].dev = i;
472:
473: }
474:
475: }
476:
477:
478:
1.1.1.3 ! root 479: init_page_table(curproc);
! 480:
! 481:
! 482:
1.1 root 483: /* Set the correct drive. The current directory we
484:
485: * set later, after all file systems have been loaded.
486:
487: */
488:
489:
490:
491: curproc->curdrv = Dgetdrv();
492:
493: proclist = curproc;
494:
495:
496:
497: curproc->umask = 0;
498:
499:
500:
501: /*
502:
503: * some more protection against job control; unless these signals are
504:
505: * re-activated by a shell that knows about job control, they'll have
506:
507: * no effect
508:
509: */
510:
511: curproc->sighandle[SIGTTIN] = curproc->sighandle[SIGTTOU] =
512:
513: curproc->sighandle[SIGTSTP] = SIG_IGN;
514:
515:
516:
517: /* set up some more per-process variables */
518:
519: curproc->starttime = Tgettime();
520:
521: curproc->startdate = Tgetdate();
522:
523: if (has_bconmap)
524:
525: curproc->bconmap = curbconmap;
526:
527: else
528:
529: curproc->bconmap = 1;
530:
531:
532:
533: curproc->logbase = (void *)Logbase();
534:
1.1.1.2 root 535: curproc->criticerr = *((long ARGS_ON_STACK (**) P_((long)))0x404L);
1.1 root 536:
537: }
538:
539:
540:
541: /*
542:
543: * reset all process priorities to their base level
544:
545: * called once per second, so that cpu hogs can get _some_ time
546:
547: * slices :-).
548:
549: */
550:
551:
552:
553: void
554:
555: reset_priorities()
556:
557: {
558:
559: PROC *p;
560:
561:
562:
563: for (p = proclist; p; p = p->gl_next) {
564:
565: p->curpri = p->pri;
566:
567: p->slices = SLICES(p->curpri);
568:
569: }
570:
571: }
572:
573:
574:
575: /*
576:
577: * more priority code stuff:
578:
579: * run_next(p, slices): schedule process "p" to run next, with "slices"
580:
581: * initial time slices; "p" does not actually start running until
582:
583: * the next context switch
584:
585: * fresh_slices(slices): give the current process "slices" more slices in
586:
587: * which to run
588:
589: */
590:
591:
592:
593: void
594:
595: run_next(p, slices)
596:
597: PROC *p;
598:
599: int slices; /* BUG: currently ignored */
600:
601: {
602:
1.1.1.2 root 603: UNUSED(slices);
604:
605:
606:
1.1 root 607: p->slices = 0;
608:
609: p->curpri = MAX_NICE;
610:
611: p->wait_q = READY_Q;
612:
613: p->q_next = sys_q[READY_Q];
614:
615: sys_q[READY_Q] = p;
616:
617: }
618:
619:
620:
621: void
622:
623: fresh_slices(slices)
624:
625: int slices;
626:
627: {
628:
629: curproc->slices = 0;
630:
631: curproc->curpri = MAX_NICE+1;
632:
633: proc_clock = slices;
634:
635: }
636:
637:
638:
639: /*
640:
641: * add a process to a wait (or ready) queue.
642:
643: *
644:
645: * processes go onto a queue in first in-first out order
646:
647: */
648:
649:
650:
651: void
652:
653: add_q(que, proc)
654:
655: int que;
656:
657: PROC *proc;
658:
659: {
660:
661: PROC *q, **lastq;
662:
663:
664:
665: /* "proc" should not already be on a list */
666:
667: assert(proc->wait_q == 0);
668:
669: assert(proc->q_next == 0);
670:
671:
672:
673: lastq = &sys_q[que];
674:
675: q = *lastq;
676:
677: while(q) {
678:
679: lastq = &q->q_next;
680:
681: q = *lastq;
682:
683: }
684:
685: *lastq = proc;
686:
687: proc->wait_q = que;
688:
689: if (que != READY_Q) {
690:
691: proc->curpri = proc->pri; /* reward the process */
692:
693: proc->slices = SLICES(proc->curpri);
694:
695: }
696:
697: }
698:
699:
700:
701: /*
702:
703: * remove a process from a queue
704:
705: */
706:
707:
708:
709: void
710:
711: rm_q(que, proc)
712:
713: int que;
714:
715: PROC *proc;
716:
717: {
718:
719: PROC *q;
720:
721: PROC *old = 0;
722:
723:
724:
725: assert(proc->wait_q == que);
726:
727:
728:
729: q = sys_q[que];
730:
731: while (q && q != proc) {
732:
733: old = q;
734:
735: q = q->q_next;
736:
737: }
738:
739: if (q == 0)
740:
741: FATAL("rm_q: unable to remove process from queue");
742:
743:
744:
745: if (old)
746:
747: old->q_next = proc->q_next;
748:
749: else
750:
751: sys_q[que] = proc->q_next;
752:
753:
754:
755: proc->wait_q = 0;
756:
757: proc->q_next = 0;
758:
759: }
760:
761:
762:
763: /*
764:
765: * preempt(): called by the vbl routine and/or the trap handlers when
766:
767: * they detect that a process has exceeded its time slice and hasn't
768:
769: * yielded gracefully. For now, it just does sleep(READY_Q); later,
770:
771: * we might want to keep track of statistics or something.
772:
773: */
774:
775:
776:
1.1.1.2 root 777: void ARGS_ON_STACK
1.1 root 778:
779: preempt()
780:
781: {
782:
783: extern short bconbsiz; /* in bios.c */
784:
785:
786:
787: if (bconbsiz)
788:
789: (void)bflush();
790:
791: else {
792:
793: /* punish the pre-empted process */
794:
795: if (curproc->curpri >= MIN_NICE)
796:
797: curproc->curpri -= 1;
798:
799: }
800:
801: sleep(READY_Q, curproc->wait_cond);
802:
803: }
804:
805:
806:
807: /*
808:
809: * sleep(que, cond): put the current process on the given queue, then switch
810:
811: * contexts. Before a new process runs, give it a fresh time slice. "cond"
812:
813: * is the condition for which the process is waiting, and is placed in
814:
815: * curproc->wait_cond
816:
817: */
818:
819:
820:
821: static void
822:
823: do_wakeup_things()
824:
825: {
826:
827: /*
828:
829: * check for stack underflow, just in case
830:
831: */
832:
833: auto int foo;
834:
1.1.1.2 root 835: PROC *p;
1.1 root 836:
837:
838:
1.1.1.2 root 839: p = curproc;
1.1 root 840:
1.1.1.2 root 841:
842:
843: if ( p->pid != 0 &&
844:
845: ((long)&foo) < (long)p->stack + ISTKSIZE + 512 ) {
846:
847: ALERT("stack underflow");
1.1 root 848:
849: handle_sig(SIGBUS);
850:
851: }
852:
1.1.1.2 root 853:
854:
855: /* see if process' time limit has been exceeded */
856:
857:
858:
859: if (p->maxcpu) {
860:
861: if (p->maxcpu <= p->systime + p->usrtime) {
862:
863: DEBUG(("cpu limit exceeded"));
864:
865: raise(SIGXCPU);
866:
867: }
868:
869: }
870:
871:
872:
1.1 root 873: /*
874:
1.1.1.2 root 875: * check for alarms and similar time out stuff (see timeout.c)
1.1 root 876:
877: */
878:
879:
880:
881: checkalarms();
882:
1.1.1.2 root 883: if (p->sigpending)
1.1 root 884:
1.1.1.2 root 885: check_sigs(); /* check for signals */
1.1 root 886:
887:
888:
889: proc_clock = TIME_SLICE; /* get a fresh time slice */
890:
1.1.1.2 root 891: p->slices = SLICES(p->curpri);
1.1 root 892:
893: }
894:
895:
896:
1.1.1.2 root 897: void ARGS_ON_STACK
1.1 root 898:
899: sleep(que, cond)
900:
901: int que;
902:
903: long cond;
904:
905: {
906:
907: PROC *p;
908:
909: short sr;
910:
911: extern short kintr; /* in bios.c */
912:
913: #ifdef FASTTEXT
914:
915: extern int hardscroll; /* in fasttext.c */
916:
917: #endif
918:
919:
920:
921: /*
922:
923: * if there have been keyboard interrupts since our last sleep, check for
924:
925: * special keys like CTRL-ALT-Fx
926:
927: */
928:
929:
930:
931: if (kintr) {
932:
933: (void)checkkeys();
934:
935: kintr = 0;
936:
937: }
938:
939:
940:
941: if (que == READY_Q && !sys_q[READY_Q]) {
942:
943: /* we're just going to wake up again right away! */
944:
945: do_wakeup_things();
946:
947: return;
948:
949: }
950:
951:
952:
953: sr = spl7();
954:
955:
956:
957: add_q(que, curproc);
958:
959: curproc->wait_cond = cond;
960:
961:
962:
963: if (!sys_q[READY_Q]) {
964:
965: /* hmm, no-one is ready to run. might be a deadlock, might not.
966:
967: * first, try waking up any napping processes; if that doesn't work,
968:
969: * run the root process, just so we have someone to charge time
970:
971: * to.
972:
973: */
974:
1.1.1.2 root 975: wake(SELECT_Q, (long)nap);
1.1 root 976:
977: if (!sys_q[READY_Q]) {
978:
979: p = rootproc; /* pid 0 */
980:
981: rm_q(p->wait_q, p);
982:
983: add_q(READY_Q, p);
984:
985: }
986:
987: }
988:
989:
990:
991: /*
992:
993: * Walk through the ready list, to find what process should run next.
994:
995: * Lower priority processes don't get to run every time through this
996:
997: * loop; if "p->slices" is positive, it's the number of times that they
998:
999: * will have to miss a turn before getting to run again
1000:
1001: */
1002:
1.1.1.3 ! root 1003:
! 1004:
! 1005: /*
! 1006:
! 1007: * Loop structure:
! 1008:
! 1009: * while (we haven't picked anybody) {
! 1010:
! 1011: * for (each process) {
! 1012:
! 1013: * if (sleeping off a penalty) {
! 1014:
! 1015: * decrement penalty counter
! 1016:
! 1017: * }
! 1018:
! 1019: * else {
! 1020:
! 1021: * pick this one and break out of both loops
! 1022:
! 1023: * }
! 1024:
! 1025: * }
! 1026:
! 1027: * }
! 1028:
! 1029: */
! 1030:
1.1 root 1031: p = 0;
1032:
1033:
1034:
1035: while (!p) {
1036:
1037: for (p = sys_q[READY_Q]; p; p = p->q_next) {
1038:
1039: if (p->slices > 0)
1040:
1041: p->slices--;
1042:
1043: else
1044:
1045: break;
1046:
1047: }
1048:
1049: }
1050:
1.1.1.3 ! root 1051:
! 1052:
! 1053: /* p is our victim */
! 1054:
! 1055:
! 1056:
1.1 root 1057: rm_q(READY_Q, p);
1058:
1059:
1060:
1061: spl(sr);
1062:
1063:
1064:
1065: if (save_context(&(curproc->ctxt[CURRENT]))) {
1066:
1067: /*
1068:
1069: * restore per-process variables here
1070:
1071: */
1072:
1073: #ifdef FASTTEXT
1074:
1075: if (!hardscroll)
1076:
1077: #endif
1078:
1079: *((void **)0x44eL) = curproc->logbase;
1080:
1081: do_wakeup_things();
1082:
1083: return;
1084:
1085: }
1086:
1087: /*
1088:
1089: * save per-process variables here
1090:
1091: */
1092:
1093: #ifdef FASTTEXT
1094:
1095: if (!hardscroll)
1096:
1097: #endif
1098:
1099: curproc->logbase = *((void **)0x44eL);
1100:
1101: curproc->ctxt[CURRENT].regs[0] = 1;
1102:
1103: curproc = p;
1104:
1105: proc_clock = TIME_SLICE; /* fresh time */
1106:
1107: if ((p->ctxt[CURRENT].sr & 0x2000) == 0) { /* user mode? */
1108:
1109: leave_kernel();
1110:
1111: }
1112:
1113: assert(p->magic == CTXT_MAGIC);
1114:
1.1.1.3 ! root 1115: change_context(&(p->ctxt[CURRENT]));
1.1 root 1116:
1117: }
1118:
1119:
1120:
1121: /*
1122:
1123: * wake(que, cond): wake up all processes on the given queue that are waiting
1124:
1125: * for the indicated condition
1126:
1127: */
1128:
1129:
1130:
1.1.1.2 root 1131: void ARGS_ON_STACK
1.1 root 1132:
1133: wake(que, cond)
1134:
1135: int que;
1136:
1137: long cond;
1138:
1139: {
1140:
1141: PROC *p;
1142:
1143:
1144:
1145: if (que == READY_Q) {
1146:
1147: ALERT("wake: why wake up ready processes??");
1148:
1149: return;
1150:
1151: }
1152:
1153: top:
1154:
1155: for(p = sys_q[que]; p; p = p->q_next) {
1156:
1157: if (p->wait_cond == cond) {
1158:
1.1.1.3 ! root 1159: short s = spl7();
! 1160:
1.1 root 1161: rm_q(que, p);
1162:
1163: add_q(READY_Q, p);
1164:
1.1.1.3 ! root 1165: spl(s);
! 1166:
1.1 root 1167: goto top;
1168:
1169: }
1170:
1171: }
1172:
1173: }
1174:
1175:
1176:
1177: /*
1178:
1179: * wakeselect(p): wake process p from a select() system call
1180:
1181: * may be called by an interrupt handler or whatever
1182:
1183: */
1184:
1185:
1186:
1.1.1.2 root 1187: void ARGS_ON_STACK
1.1 root 1188:
1189: wakeselect(param)
1190:
1191: long param;
1192:
1193: {
1194:
1195: PROC *p = (PROC *)param;
1196:
1197: short s;
1198:
1199:
1200:
1201: s = spl7(); /* block interrupts */
1202:
1.1.1.2 root 1203: if(p->wait_cond == (long)wakeselect) {
1.1 root 1204:
1205: p->wait_cond = 0;
1206:
1207: }
1208:
1209: if (p->wait_q == SELECT_Q) {
1210:
1211: rm_q(SELECT_Q, p);
1212:
1213: add_q(READY_Q, p);
1214:
1215: }
1216:
1217: spl(s);
1218:
1219: }
1220:
1221:
1222:
1223: /*
1224:
1225: * dump out information about processes
1226:
1227: */
1228:
1229:
1230:
1231: /*
1232:
1.1.1.3 ! root 1233: * kludge alert! In order to get the right pid printed by FORCE, we use
1.1 root 1234:
1235: * curproc as the loop variable.
1236:
1.1.1.3 ! root 1237: *
! 1238:
! 1239: * I have changed this function so it is more useful to a user, less to
! 1240:
! 1241: * somebody debugging MiNT. I haven't had any stack problems in MiNT
! 1242:
! 1243: * at all, so I consider all that stack info wasted space. -- AKP
! 1244:
1.1 root 1245: */
1246:
1247:
1248:
1.1.1.3 ! root 1249: #ifndef NO_DEBUG_INFO
! 1250:
! 1251: static const char *qstring[] = {
! 1252:
! 1253: "run", "ready", "wait", "iowait", "zombie", "tsr", "stop", "select"
! 1254:
! 1255: };
! 1256:
! 1257:
! 1258:
! 1259: /* UNSAFE macro for qname, evaluates x 1, 2, or 3 times */
! 1260:
! 1261: #define qname(x) ((x >= 0 && x < NUM_QUEUES) ? qstring[x] : "unkn")
! 1262:
! 1263: #endif
! 1264:
! 1265:
! 1266:
1.1 root 1267: void
1268:
1269: DUMPPROC()
1270:
1271: {
1272:
1.1.1.2 root 1273: #ifndef NO_DEBUG_INFO
1274:
1.1 root 1275: PROC *p = curproc;
1276:
1277:
1278:
1279: for (curproc = proclist; curproc; curproc = curproc->gl_next) {
1280:
1.1.1.3 ! root 1281: FORCE("state %s PC: %lx BP: %lx",
1.1 root 1282:
1.1.1.3 ! root 1283: qname(curproc->wait_q),
1.1 root 1284:
1285: curproc->ctxt[SYSCALL].pc,
1286:
1.1.1.3 ! root 1287: curproc->base);
1.1 root 1288:
1289: }
1290:
1291: curproc = p; /* restore the real curproc */
1292:
1.1.1.2 root 1293: #endif
1294:
1.1 root 1295: }
1296:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.