|
|
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.1.4 ! root 283: /* jr: copy ploadinfo */
! 284:
! 285: strcpy (p->cmdlin, curproc->cmdlin);
! 286:
! 287: strcpy (p->fname, curproc->fname);
! 288:
! 289:
! 290:
1.1 root 291: /* clear directory search info */
292:
293: zero((char *)p->srchdta, NUM_SEARCH * SIZEOF(DTABUF *));
294:
1.1.1.4 ! root 295: zero((char *)p->srchdir, SIZEOF(p->srchdir));
! 296:
1.1.1.3 root 297: p->searches = 0;
298:
1.1 root 299:
300:
301: /* copy memory */
302:
303: p->mem = (MEMREGION **) kmalloc(p->num_reg * SIZEOF(MEMREGION *));
304:
305: if (!p->mem) {
306:
307: dispose_proc(p);
308:
309: goto nomem;
310:
311: }
312:
313: p->addr = (virtaddr *)kmalloc(p->num_reg * SIZEOF(virtaddr));
314:
315: if (!p->addr) {
316:
317: kfree(p->mem);
318:
319: dispose_proc(p);
320:
321: goto nomem;
322:
323: }
324:
325:
326:
327: for (i = 0; i < curproc->num_reg; i++) {
328:
1.1.1.2 root 329: p->mem[i] = curproc->mem[i];
330:
331: if (p->mem[i] != 0)
1.1 root 332:
333: p->mem[i]->links++;
334:
335: p->addr[i] = curproc->addr[i];
336:
337: }
338:
339:
340:
1.1.1.3 root 341: /* now that memory ownership is copied, fill in page table */
342:
343: init_page_table(p);
344:
345:
346:
1.1.1.2 root 347: /* child isn't traced */
348:
349: p->ptracer = 0;
350:
351: p->ptraceflags = 0;
352:
353:
354:
1.1 root 355: p->starttime = Tgettime();
356:
357: p->startdate = Tgetdate();
358:
359:
360:
361: p->q_next = 0;
362:
363: p->wait_q = 0;
364:
365: p->gl_next = proclist;
366:
367: proclist = p; /* hook into the process list */
368:
369: return p;
370:
371: }
372:
373:
374:
375: /*
376:
377: * initialize the process table
378:
379: */
380:
381:
382:
383: void
384:
385: init_proc()
386:
387: {
388:
389: int i;
390:
391: FILESYS *fs;
392:
393: fcookie dir;
394:
1.1.1.3 root 395: long_desc *pthold;
396:
397: void *ptmemhold;
398:
1.1 root 399:
400:
401: rootproc = curproc = new_proc();
402:
403: assert(curproc);
404:
405:
406:
1.1.1.3 root 407: pthold = curproc->page_table;
408:
409: ptmemhold = curproc->pt_mem;
410:
1.1 root 411: zero((char *)curproc, (long)sizeof(PROC));
412:
1.1.1.3 root 413: curproc->page_table = pthold;
414:
415: curproc->pt_mem = ptmemhold;
416:
1.1 root 417:
418:
419: curproc->ppid = -1; /* no parent */
420:
421: curproc->domain = DOM_TOS; /* TOS domain */
422:
423: curproc->sysstack = (long) (curproc->stack+STKSIZE-12);
424:
425: curproc->magic = CTXT_MAGIC;
426:
1.1.1.3 root 427: curproc->memflags = F_PROT_S; /* default prot mode: super-only */
428:
1.1 root 429: ((long *)curproc->sysstack)[1] = FRAME_MAGIC;
430:
431: ((long *)curproc->sysstack)[2] = 0;
432:
433: ((long *)curproc->sysstack)[3] = 0;
434:
435:
436:
1.1.1.2 root 437: /* NOTE: in main.c this could be changed, later */
438:
439: curproc->base = _base;
1.1 root 440:
441:
442:
443: strcpy(curproc->name, "MiNT");
444:
445:
446:
447: /* get some memory */
448:
449: curproc->mem = (MEMREGION **)kmalloc(NUM_REGIONS*SIZEOF(MEMREGION *));
450:
451: curproc->addr = (virtaddr *)kmalloc(NUM_REGIONS*SIZEOF(virtaddr));
452:
453: assert(curproc->mem && curproc->addr);
454:
455:
456:
457: /* make sure it's filled with zeros */
458:
459: zero((char *)curproc->addr, NUM_REGIONS * SIZEOF(virtaddr));
460:
461: zero((char *)curproc->mem, NUM_REGIONS * SIZEOF(MEMREGION *));
462:
463: curproc->num_reg = NUM_REGIONS;
464:
465:
466:
467: /* get root and current directories for all drives */
468:
469: for (i = 0; i < NUM_DRIVES; i++) {
470:
471: if ((fs = drives[i]) != 0 && (*fs->root)(i, &dir) == E_OK) {
472:
1.1.1.3 root 473: dup_cookie(&curproc->curdir[i], &dir);
474:
475: curproc->root[i] = dir;
1.1 root 476:
477: } else {
478:
479: curproc->root[i].fs = curproc->curdir[i].fs = 0;
480:
481: curproc->root[i].dev = curproc->curdir[i].dev = i;
482:
483: }
484:
485: }
486:
487:
488:
1.1.1.3 root 489: init_page_table(curproc);
490:
491:
492:
1.1 root 493: /* Set the correct drive. The current directory we
494:
495: * set later, after all file systems have been loaded.
496:
497: */
498:
499:
500:
501: curproc->curdrv = Dgetdrv();
502:
503: proclist = curproc;
504:
505:
506:
507: curproc->umask = 0;
508:
509:
510:
511: /*
512:
513: * some more protection against job control; unless these signals are
514:
515: * re-activated by a shell that knows about job control, they'll have
516:
517: * no effect
518:
519: */
520:
521: curproc->sighandle[SIGTTIN] = curproc->sighandle[SIGTTOU] =
522:
523: curproc->sighandle[SIGTSTP] = SIG_IGN;
524:
525:
526:
527: /* set up some more per-process variables */
528:
529: curproc->starttime = Tgettime();
530:
531: curproc->startdate = Tgetdate();
532:
533: if (has_bconmap)
534:
535: curproc->bconmap = curbconmap;
536:
537: else
538:
539: curproc->bconmap = 1;
540:
541:
542:
543: curproc->logbase = (void *)Logbase();
544:
1.1.1.2 root 545: curproc->criticerr = *((long ARGS_ON_STACK (**) P_((long)))0x404L);
1.1 root 546:
547: }
548:
549:
550:
551: /*
552:
553: * reset all process priorities to their base level
554:
555: * called once per second, so that cpu hogs can get _some_ time
556:
557: * slices :-).
558:
559: */
560:
561:
562:
563: void
564:
565: reset_priorities()
566:
567: {
568:
569: PROC *p;
570:
571:
572:
573: for (p = proclist; p; p = p->gl_next) {
574:
575: p->curpri = p->pri;
576:
577: p->slices = SLICES(p->curpri);
578:
579: }
580:
581: }
582:
583:
584:
585: /*
586:
587: * more priority code stuff:
588:
589: * run_next(p, slices): schedule process "p" to run next, with "slices"
590:
591: * initial time slices; "p" does not actually start running until
592:
593: * the next context switch
594:
595: * fresh_slices(slices): give the current process "slices" more slices in
596:
597: * which to run
598:
599: */
600:
601:
602:
603: void
604:
605: run_next(p, slices)
606:
607: PROC *p;
608:
609: int slices; /* BUG: currently ignored */
610:
611: {
612:
1.1.1.2 root 613: UNUSED(slices);
614:
615:
616:
1.1 root 617: p->slices = 0;
618:
619: p->curpri = MAX_NICE;
620:
621: p->wait_q = READY_Q;
622:
623: p->q_next = sys_q[READY_Q];
624:
625: sys_q[READY_Q] = p;
626:
627: }
628:
629:
630:
631: void
632:
633: fresh_slices(slices)
634:
635: int slices;
636:
637: {
638:
639: curproc->slices = 0;
640:
641: curproc->curpri = MAX_NICE+1;
642:
643: proc_clock = slices;
644:
645: }
646:
647:
648:
649: /*
650:
651: * add a process to a wait (or ready) queue.
652:
653: *
654:
655: * processes go onto a queue in first in-first out order
656:
657: */
658:
659:
660:
661: void
662:
663: add_q(que, proc)
664:
665: int que;
666:
667: PROC *proc;
668:
669: {
670:
671: PROC *q, **lastq;
672:
673:
674:
675: /* "proc" should not already be on a list */
676:
677: assert(proc->wait_q == 0);
678:
679: assert(proc->q_next == 0);
680:
681:
682:
683: lastq = &sys_q[que];
684:
685: q = *lastq;
686:
687: while(q) {
688:
689: lastq = &q->q_next;
690:
691: q = *lastq;
692:
693: }
694:
695: *lastq = proc;
696:
697: proc->wait_q = que;
698:
699: if (que != READY_Q) {
700:
701: proc->curpri = proc->pri; /* reward the process */
702:
703: proc->slices = SLICES(proc->curpri);
704:
705: }
706:
707: }
708:
709:
710:
711: /*
712:
713: * remove a process from a queue
714:
715: */
716:
717:
718:
719: void
720:
721: rm_q(que, proc)
722:
723: int que;
724:
725: PROC *proc;
726:
727: {
728:
729: PROC *q;
730:
731: PROC *old = 0;
732:
733:
734:
735: assert(proc->wait_q == que);
736:
737:
738:
739: q = sys_q[que];
740:
741: while (q && q != proc) {
742:
743: old = q;
744:
745: q = q->q_next;
746:
747: }
748:
749: if (q == 0)
750:
751: FATAL("rm_q: unable to remove process from queue");
752:
753:
754:
755: if (old)
756:
757: old->q_next = proc->q_next;
758:
759: else
760:
761: sys_q[que] = proc->q_next;
762:
763:
764:
765: proc->wait_q = 0;
766:
767: proc->q_next = 0;
768:
769: }
770:
771:
772:
773: /*
774:
775: * preempt(): called by the vbl routine and/or the trap handlers when
776:
777: * they detect that a process has exceeded its time slice and hasn't
778:
779: * yielded gracefully. For now, it just does sleep(READY_Q); later,
780:
781: * we might want to keep track of statistics or something.
782:
783: */
784:
785:
786:
1.1.1.2 root 787: void ARGS_ON_STACK
1.1 root 788:
789: preempt()
790:
791: {
792:
793: extern short bconbsiz; /* in bios.c */
794:
795:
796:
797: if (bconbsiz)
798:
799: (void)bflush();
800:
801: else {
802:
803: /* punish the pre-empted process */
804:
805: if (curproc->curpri >= MIN_NICE)
806:
807: curproc->curpri -= 1;
808:
809: }
810:
811: sleep(READY_Q, curproc->wait_cond);
812:
813: }
814:
815:
816:
817: /*
818:
819: * sleep(que, cond): put the current process on the given queue, then switch
820:
821: * contexts. Before a new process runs, give it a fresh time slice. "cond"
822:
823: * is the condition for which the process is waiting, and is placed in
824:
825: * curproc->wait_cond
826:
827: */
828:
829:
830:
831: static void
832:
833: do_wakeup_things()
834:
835: {
836:
837: /*
838:
839: * check for stack underflow, just in case
840:
841: */
842:
843: auto int foo;
844:
1.1.1.2 root 845: PROC *p;
1.1 root 846:
847:
848:
1.1.1.2 root 849: p = curproc;
1.1 root 850:
1.1.1.2 root 851:
852:
853: if ( p->pid != 0 &&
854:
855: ((long)&foo) < (long)p->stack + ISTKSIZE + 512 ) {
856:
857: ALERT("stack underflow");
1.1 root 858:
859: handle_sig(SIGBUS);
860:
861: }
862:
1.1.1.2 root 863:
864:
865: /* see if process' time limit has been exceeded */
866:
867:
868:
869: if (p->maxcpu) {
870:
871: if (p->maxcpu <= p->systime + p->usrtime) {
872:
873: DEBUG(("cpu limit exceeded"));
874:
875: raise(SIGXCPU);
876:
877: }
878:
879: }
880:
881:
882:
1.1 root 883: /*
884:
1.1.1.2 root 885: * check for alarms and similar time out stuff (see timeout.c)
1.1 root 886:
887: */
888:
889:
890:
891: checkalarms();
892:
1.1.1.2 root 893: if (p->sigpending)
1.1 root 894:
1.1.1.2 root 895: check_sigs(); /* check for signals */
1.1 root 896:
897:
898:
899: proc_clock = TIME_SLICE; /* get a fresh time slice */
900:
1.1.1.2 root 901: p->slices = SLICES(p->curpri);
1.1 root 902:
903: }
904:
905:
906:
1.1.1.2 root 907: void ARGS_ON_STACK
1.1 root 908:
909: sleep(que, cond)
910:
911: int que;
912:
913: long cond;
914:
915: {
916:
917: PROC *p;
918:
919: short sr;
920:
921: extern short kintr; /* in bios.c */
922:
1.1.1.4 ! root 923: #ifndef MULTITOS
! 924:
1.1 root 925: #ifdef FASTTEXT
926:
927: extern int hardscroll; /* in fasttext.c */
928:
929: #endif
930:
1.1.1.4 ! root 931: #endif
! 932:
1.1 root 933:
934:
935: /*
936:
937: * if there have been keyboard interrupts since our last sleep, check for
938:
939: * special keys like CTRL-ALT-Fx
940:
941: */
942:
943:
944:
945: if (kintr) {
946:
947: (void)checkkeys();
948:
949: kintr = 0;
950:
951: }
952:
953:
954:
955: if (que == READY_Q && !sys_q[READY_Q]) {
956:
957: /* we're just going to wake up again right away! */
958:
959: do_wakeup_things();
960:
961: return;
962:
963: }
964:
965:
966:
967: sr = spl7();
968:
969:
970:
971: add_q(que, curproc);
972:
973: curproc->wait_cond = cond;
974:
975:
976:
977: if (!sys_q[READY_Q]) {
978:
979: /* hmm, no-one is ready to run. might be a deadlock, might not.
980:
981: * first, try waking up any napping processes; if that doesn't work,
982:
983: * run the root process, just so we have someone to charge time
984:
985: * to.
986:
987: */
988:
1.1.1.2 root 989: wake(SELECT_Q, (long)nap);
1.1 root 990:
991: if (!sys_q[READY_Q]) {
992:
993: p = rootproc; /* pid 0 */
994:
995: rm_q(p->wait_q, p);
996:
997: add_q(READY_Q, p);
998:
999: }
1000:
1001: }
1002:
1003:
1004:
1005: /*
1006:
1007: * Walk through the ready list, to find what process should run next.
1008:
1009: * Lower priority processes don't get to run every time through this
1010:
1011: * loop; if "p->slices" is positive, it's the number of times that they
1012:
1013: * will have to miss a turn before getting to run again
1014:
1015: */
1016:
1.1.1.3 root 1017:
1018:
1019: /*
1020:
1021: * Loop structure:
1022:
1023: * while (we haven't picked anybody) {
1024:
1025: * for (each process) {
1026:
1027: * if (sleeping off a penalty) {
1028:
1029: * decrement penalty counter
1030:
1031: * }
1032:
1033: * else {
1034:
1035: * pick this one and break out of both loops
1036:
1037: * }
1038:
1039: * }
1040:
1041: * }
1042:
1043: */
1044:
1.1 root 1045: p = 0;
1046:
1047:
1048:
1049: while (!p) {
1050:
1051: for (p = sys_q[READY_Q]; p; p = p->q_next) {
1052:
1053: if (p->slices > 0)
1054:
1055: p->slices--;
1056:
1057: else
1058:
1059: break;
1060:
1061: }
1062:
1063: }
1064:
1.1.1.3 root 1065:
1066:
1067: /* p is our victim */
1068:
1069:
1070:
1.1 root 1071: rm_q(READY_Q, p);
1072:
1073:
1074:
1075: spl(sr);
1076:
1077:
1078:
1079: if (save_context(&(curproc->ctxt[CURRENT]))) {
1080:
1081: /*
1082:
1083: * restore per-process variables here
1084:
1085: */
1086:
1.1.1.4 ! root 1087: #ifndef MULTITOS
! 1088:
1.1 root 1089: #ifdef FASTTEXT
1090:
1091: if (!hardscroll)
1092:
1093: #endif
1094:
1095: *((void **)0x44eL) = curproc->logbase;
1096:
1.1.1.4 ! root 1097: #endif
! 1098:
1.1 root 1099: do_wakeup_things();
1100:
1101: return;
1102:
1103: }
1104:
1105: /*
1106:
1107: * save per-process variables here
1108:
1109: */
1110:
1.1.1.4 ! root 1111: #ifndef MULTITOS
! 1112:
1.1 root 1113: #ifdef FASTTEXT
1114:
1115: if (!hardscroll)
1116:
1117: #endif
1118:
1119: curproc->logbase = *((void **)0x44eL);
1120:
1.1.1.4 ! root 1121: #endif
! 1122:
1.1 root 1123: curproc->ctxt[CURRENT].regs[0] = 1;
1124:
1125: curproc = p;
1126:
1127: proc_clock = TIME_SLICE; /* fresh time */
1128:
1129: if ((p->ctxt[CURRENT].sr & 0x2000) == 0) { /* user mode? */
1130:
1131: leave_kernel();
1132:
1133: }
1134:
1135: assert(p->magic == CTXT_MAGIC);
1136:
1.1.1.3 root 1137: change_context(&(p->ctxt[CURRENT]));
1.1 root 1138:
1139: }
1140:
1141:
1142:
1143: /*
1144:
1145: * wake(que, cond): wake up all processes on the given queue that are waiting
1146:
1147: * for the indicated condition
1148:
1149: */
1150:
1151:
1152:
1.1.1.2 root 1153: void ARGS_ON_STACK
1.1 root 1154:
1155: wake(que, cond)
1156:
1157: int que;
1158:
1159: long cond;
1160:
1161: {
1162:
1163: PROC *p;
1164:
1165:
1166:
1167: if (que == READY_Q) {
1168:
1169: ALERT("wake: why wake up ready processes??");
1170:
1171: return;
1172:
1173: }
1174:
1175: top:
1176:
1177: for(p = sys_q[que]; p; p = p->q_next) {
1178:
1179: if (p->wait_cond == cond) {
1180:
1.1.1.3 root 1181: short s = spl7();
1182:
1.1 root 1183: rm_q(que, p);
1184:
1185: add_q(READY_Q, p);
1186:
1.1.1.3 root 1187: spl(s);
1188:
1.1 root 1189: goto top;
1190:
1191: }
1192:
1193: }
1194:
1195: }
1196:
1197:
1198:
1199: /*
1200:
1201: * wakeselect(p): wake process p from a select() system call
1202:
1203: * may be called by an interrupt handler or whatever
1204:
1205: */
1206:
1207:
1208:
1.1.1.2 root 1209: void ARGS_ON_STACK
1.1 root 1210:
1211: wakeselect(param)
1212:
1213: long param;
1214:
1215: {
1216:
1217: PROC *p = (PROC *)param;
1218:
1219: short s;
1220:
1221:
1222:
1223: s = spl7(); /* block interrupts */
1224:
1.1.1.2 root 1225: if(p->wait_cond == (long)wakeselect) {
1.1 root 1226:
1227: p->wait_cond = 0;
1228:
1229: }
1230:
1231: if (p->wait_q == SELECT_Q) {
1232:
1233: rm_q(SELECT_Q, p);
1234:
1235: add_q(READY_Q, p);
1236:
1237: }
1238:
1239: spl(s);
1240:
1241: }
1242:
1243:
1244:
1245: /*
1246:
1247: * dump out information about processes
1248:
1249: */
1250:
1251:
1252:
1253: /*
1254:
1.1.1.3 root 1255: * kludge alert! In order to get the right pid printed by FORCE, we use
1.1 root 1256:
1257: * curproc as the loop variable.
1258:
1.1.1.3 root 1259: *
1260:
1261: * I have changed this function so it is more useful to a user, less to
1262:
1263: * somebody debugging MiNT. I haven't had any stack problems in MiNT
1264:
1265: * at all, so I consider all that stack info wasted space. -- AKP
1266:
1.1 root 1267: */
1268:
1269:
1270:
1.1.1.4 ! root 1271: #ifdef DEBUG_INFO
1.1.1.3 root 1272:
1273: static const char *qstring[] = {
1274:
1275: "run", "ready", "wait", "iowait", "zombie", "tsr", "stop", "select"
1276:
1277: };
1278:
1279:
1280:
1281: /* UNSAFE macro for qname, evaluates x 1, 2, or 3 times */
1282:
1283: #define qname(x) ((x >= 0 && x < NUM_QUEUES) ? qstring[x] : "unkn")
1284:
1285: #endif
1286:
1287:
1288:
1.1 root 1289: void
1290:
1291: DUMPPROC()
1292:
1293: {
1294:
1.1.1.4 ! root 1295: #ifdef DEBUG_INFO
1.1.1.2 root 1296:
1.1 root 1297: PROC *p = curproc;
1298:
1299:
1300:
1301: for (curproc = proclist; curproc; curproc = curproc->gl_next) {
1302:
1.1.1.3 root 1303: FORCE("state %s PC: %lx BP: %lx",
1.1 root 1304:
1.1.1.3 root 1305: qname(curproc->wait_q),
1.1 root 1306:
1307: curproc->ctxt[SYSCALL].pc,
1308:
1.1.1.3 root 1309: curproc->base);
1.1 root 1310:
1311: }
1312:
1313: curproc = p; /* restore the real curproc */
1314:
1.1.1.2 root 1315: #endif
1316:
1.1 root 1317: }
1318:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.