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