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