|
|
1.1 ! root 1: /* (lgl- ! 2: * The information contained herein is a trade secret of Mark Williams ! 3: * Company, and is confidential information. It is provided under a ! 4: * license agreement, and may be copied or disclosed only under the ! 5: * terms of that agreement. Any reproduction or disclosure of this ! 6: * material without the express written authorization of Mark Williams ! 7: * Company or persuant to the license agreement is unlawful. ! 8: * ! 9: * COHERENT Version 2.3.37 ! 10: * Copyright (c) 1982, 1983, 1984. ! 11: * An unpublished work by Mark Williams Company, Chicago. ! 12: * All rights reserved. ! 13: -lgl) */ ! 14: /* ! 15: * Coherent. ! 16: * Process handling and scheduling. ! 17: * ! 18: * $Log: proc.c,v $ ! 19: * Revision 1.2 92/08/04 12:34:18 bin ! 20: * changed for ker 59 ! 21: * ! 22: * Revision 1.5 92/04/03 14:35:36 hal ! 23: * Kernel #49: piggy trace variable. ! 24: * ! 25: * Revision 1.4 92/02/03 17:00:09 piggy ! 26: * Send SIGHUP to all group members on death of group leader. ! 27: */ ! 28: #include <sys/coherent.h> ! 29: #include <acct.h> ! 30: #include <errno.h> ! 31: #include <sys/inode.h> ! 32: #include <sys/proc.h> ! 33: #include <sys/ptrace.h> ! 34: #include <sys/sched.h> ! 35: #include <sys/seg.h> ! 36: #include <signal.h> ! 37: #include <sys/stat.h> ! 38: ! 39: /* ! 40: * Initialization. ! 41: * Set up the hash table queues. ! 42: */ ! 43: pcsinit() ! 44: { ! 45: register PROC *pp; ! 46: register PLINK *lp; ! 47: ! 48: /* ! 49: * Explicitly initialize everything in the first process. ! 50: */ ! 51: pp = &procq; ! 52: SELF = pp; ! 53: procq.p_nforw = pp; ! 54: procq.p_nback = pp; ! 55: procq.p_lforw = pp; ! 56: procq.p_lback = pp; ! 57: ! 58: #ifdef _I386 ! 59: /* Segments are initialized in mchinit() and eveinit(). */ ! 60: ! 61: procq.p_uid = 0; /* Effective uid */ ! 62: procq.p_ruid = 0; /* Real uid */ ! 63: procq.p_rgid = 0; /* Real gid */ ! 64: procq.p_state = 0; /* Scheduling state */ ! 65: procq.p_flags = 0; /* Flags */ ! 66: procq.p_ssig = (sig_t) 0; /* Signals which have been set */ ! 67: #ifdef _I386 ! 68: procq.p_dfsig = (sig_t) 0xffffffff; /* All signals are defaulted. */ ! 69: procq.p_hsig = (sig_t) 0; /* Signals which are being held */ ! 70: procq.p_dsig = (sig_t) 0; /* Signals which are being deferred */ ! 71: #endif ! 72: procq.p_isig = (sig_t) 0; /* Signals which are being ignored */ ! 73: procq.p_event = NULL; /* Wakeup event channel */ ! 74: procq.p_alarm = 0; /* Timer for alarms */ ! 75: procq.p_group = 0; /* Process group */ ! 76: /* ! 77: * Set ttdev to null so that we do not accidentally set a tty for init. ! 78: */ ! 79: procq.p_ttdev = makedev(0,0); /* Controlling terminal */ ! 80: procq.p_nice = 0; /* Nice value */ ! 81: procq.p_cval = 0; /* Cpu schedule value */ ! 82: procq.p_sval = 0; /* Swap schedule value */ ! 83: procq.p_ival = 0; /* Importance value */ ! 84: procq.p_rval = 0; /* Response value */ ! 85: procq.p_lctim = 0; /* Last time cval was updated */ ! 86: procq.p_utime = 0L; /* User time (HZ) */ ! 87: procq.p_stime = 0L; /* System time */ ! 88: procq.p_cutime = 0L; /* Sum of childs user time */ ! 89: procq.p_cstime = 0L; /* Sum of childs system time */ ! 90: procq.p_exit = 0; /* Exit status */ ! 91: procq.p_polls = NULL; /* Enabled polls */ ! 92: /* Poll timer */ ! 93: procq.p_polltim.t_next = NULL; ! 94: procq.p_polltim.t_last = NULL; ! 95: procq.p_polltim.t_lbolt = 0L; ! 96: procq.p_polltim.t_func = NULL; ! 97: procq.p_polltim.t_farg = NULL; ! 98: #ifndef _I386 ! 99: procq.p_polltim.t_ldrv = 0; ! 100: #endif /* _I386 */ ! 101: ! 102: /* Alarm timer */ ! 103: procq.p_alrmtim.t_next = NULL; ! 104: procq.p_alrmtim.t_last = NULL; ! 105: procq.p_alrmtim.t_lbolt = 0L; ! 106: procq.p_alrmtim.t_func = NULL; ! 107: procq.p_alrmtim.t_farg = NULL; ! 108: #ifndef _I386 ! 109: procq.p_alrmtim.t_ldrv = 0; ! 110: #endif /* _I386 */ ! 111: ! 112: procq.p_prl = NULL; /* Pending record lock */ ! 113: #endif /* _I386 */ ! 114: ! 115: for (lp=&linkq[0]; lp<&linkq[NHPLINK]; lp++) { ! 116: lp->p_lforw = lp; ! 117: lp->p_lback = lp; ! 118: } ! 119: } ! 120: ! 121: /* ! 122: * Initiate a process. ! 123: */ ! 124: PROC * ! 125: #ifdef _I386 ! 126: process() ! 127: #else ! 128: process(f) ! 129: int (*f)(); ! 130: #endif ! 131: { ! 132: register PROC *pp1; ! 133: register PROC *pp; ! 134: register SEG *sp; ! 135: MCON mcon; ! 136: ! 137: if ((pp=kalloc(sizeof(PROC))) == NULL) ! 138: return (NULL); ! 139: ! 140: pp->p_flags = PFCORE; ! 141: pp->p_state = PSRUN; ! 142: pp->p_ttdev = NODEV; ! 143: #ifndef _I386 ! 144: /* ! 145: * What is this, and why is it 286 only? ! 146: */ ! 147: if (f != NULL) { ! 148: pp->p_flags |= PFKERN; ! 149: sp = salloc((fsize_t)UPASIZE, SFSYST|SFHIGH|SFNSWP); ! 150: if (sp == NULL) { ! 151: kfree(pp); ! 152: return (NULL); ! 153: } ! 154: pp->p_segp[SIUSERP] = sp; ! 155: msetsys(&mcon, f, FP_SEL(sp->s_faddr)); ! 156: kfcopy( (char *)&mcon, ! 157: sp->s_faddr + offset(uproc, u_syscon), ! 158: sizeof(mcon)); ! 159: } ! 160: #endif ! 161: lock(pnxgate); ! 162: next: ! 163: ! 164: /* ! 165: * Pick the next process id. ! 166: */ ! 167: /* DO NOT MESS WITH THE FOLLOWING CONDITIONAL UNLESS YOU ! 168: TEST THE RESULTS ON BOTH 286 AND 386 */ ! 169: #ifdef _I386 ! 170: if (++cpid >= NPID) ! 171: cpid = 2; ! 172: pp->p_pid = cpid; ! 173: #else ! 174: pp->p_pid = cpid++; ! 175: if (cpid >= NPID) ! 176: cpid = 2; ! 177: #endif ! 178: ! 179: /* ! 180: * Make sure that process id is not in use. ! 181: */ ! 182: pp1 = &procq; ! 183: while ((pp1=pp1->p_nforw) != &procq) { ! 184: if (pp1->p_pid < pp->p_pid) ! 185: break; ! 186: if (pp1->p_pid == pp->p_pid) ! 187: goto next; ! 188: } ! 189: ! 190: /* ! 191: * We've got a valid pid, so let's put this process into ! 192: * the process table. ! 193: */ ! 194: pp->p_nback = pp1->p_nback; ! 195: pp1->p_nback->p_nforw = pp; ! 196: pp->p_nforw = pp1; ! 197: pp1->p_nback = pp; ! 198: unlock(pnxgate); ! 199: return (pp); ! 200: } ! 201: ! 202: /* ! 203: * Remove a process from the next queue and release and space. ! 204: */ ! 205: relproc(pp) ! 206: register PROC *pp; ! 207: { ! 208: register SEG * sp; ! 209: ! 210: /* ! 211: * Child process still has a user-area. ! 212: */ ! 213: if ((sp = pp->p_segp[SIUSERP]) != NULL) { ! 214: ! 215: /* ! 216: * Detach user-area from child process. ! 217: */ ! 218: pp->p_segp[SIUSERP] = NULL; ! 219: ! 220: /* ! 221: * Child process is swapped out. ! 222: */ ! 223: if (pp->p_flags & PFSWAP) ! 224: sp->s_lrefc++; ! 225: ! 226: /* ! 227: * Release child's user-area. ! 228: */ ! 229: sfree(sp); ! 230: } ! 231: ! 232: /* ! 233: * Remove process from doubly-linked list of all processes. ! 234: * Release space allocated for proc structure. ! 235: */ ! 236: lock(pnxgate); ! 237: pp->p_nback->p_nforw = pp->p_nforw; ! 238: pp->p_nforw->p_nback = pp->p_nback; ! 239: unlock(pnxgate); ! 240: kfree(pp); ! 241: } ! 242: ! 243: /* ! 244: * Create a clone of ourselves. ! 245: * N.B. - consave(&mcon) returns twice; anything not initialized ! 246: * in automatic storage before the call to segadup() will not be ! 247: * initialized when the second return from consave() commences. ! 248: */ ! 249: pfork() ! 250: { ! 251: register PROC *cpp; ! 252: register PROC *pp; ! 253: register int s; ! 254: MCON mcon; ! 255: ! 256: #ifdef _I386 ! 257: if ((cpp=process()) == NULL) { ! 258: #else ! 259: if ((cpp=process(NULL)) == NULL) { ! 260: #endif ! 261: SET_U_ERROR( EAGAIN, "no more process table entries" ); ! 262: return -1; ! 263: } ! 264: ! 265: #ifndef _I386 ! 266: s = sphi(); ! 267: usave(); /* Put the current copy of uarea into its segment */ ! 268: spl(s); ! 269: #endif ! 270: ! 271: pp = SELF; ! 272: s = sphi(); /* put current interrupt level into s before segadup */ ! 273: spl(s); ! 274: /* ! 275: * As stated above, no auto variable may be changed between calls ! 276: * to segadup() and consave(). ! 277: */ ! 278: if (segadup(cpp) == 0) { ! 279: SET_U_ERROR( EAGAIN, "can not duplicate segments" ); ! 280: relproc(cpp); ! 281: return -1; ! 282: } ! 283: if (u.u_rdir != NULL) ! 284: u.u_rdir->i_refc++; ! 285: if (u.u_cdir != NULL) ! 286: u.u_cdir->i_refc++; ! 287: fdadupl(); ! 288: cpp->p_uid = pp->p_uid; ! 289: cpp->p_ruid = pp->p_ruid; ! 290: cpp->p_rgid = pp->p_rgid; ! 291: cpp->p_ppid = pp->p_pid; ! 292: cpp->p_ttdev = pp->p_ttdev; ! 293: cpp->p_group = pp->p_group; ! 294: cpp->p_ssig = pp->p_ssig; ! 295: #ifdef _I386 ! 296: cpp->p_dfsig = pp->p_dfsig; ! 297: cpp->p_dsig = pp->p_dsig; ! 298: cpp->p_hsig = pp->p_hsig; ! 299: #endif /* _I386 */ ! 300: cpp->p_isig = pp->p_isig; ! 301: cpp->p_cval = CVCHILD; ! 302: cpp->p_ival = IVCHILD; ! 303: cpp->p_sval = SVCHILD; ! 304: cpp->p_rval = RVCHILD; ! 305: #ifdef _I386 ! 306: cpp->p_prl = NULL; ! 307: #endif ! 308: ! 309: sphi(); /* s = sphi() was done before segadup() */ ! 310: consave(&mcon); ! 311: spl(s); ! 312: ! 313: /* ! 314: * Parent process. ! 315: */ ! 316: if ((pp = SELF) != cpp) { ! 317: segfinm(cpp->p_segp[SIUSERP]); ! 318: #ifdef _I386 ! 319: dmaout(sizeof(mcon), ! 320: MAPIO(cpp->p_segp[SIUSERP]->s_vmem,offset(uproc,u_syscon)), ! 321: (char *)&mcon); ! 322: #else ! 323: kfcopy((char *)&mcon, ! 324: cpp->p_segp[SIUSERP]->s_faddr + offset(uproc,u_syscon), ! 325: sizeof(mcon)); ! 326: #endif ! 327: mfixcon(cpp); ! 328: s = sphi(); ! 329: setrun(cpp); ! 330: spl(s); ! 331: #ifdef _I386 ! 332: u.u_rval2 = 0; ! 333: #endif ! 334: return(cpp->p_pid); ! 335: } ! 336: ! 337: /* ! 338: * Child process. ! 339: */ ! 340: else { ! 341: u.u_btime = timer.t_time; ! 342: u.u_flag = AFORK; ! 343: #ifdef _I386 ! 344: #ifdef UPROC_VERSION ! 345: u.u_version = UPROC_VERSION; ! 346: #endif /* UPROC_VERSION */ ! 347: u.u_sleep[0] = '\0'; /* We are not sleeping to start with. */ ! 348: sproto(0); ! 349: #else ! 350: sproto(); ! 351: #endif ! 352: segload(); ! 353: #ifdef _I386 ! 354: u.u_rval2 = SELF->p_ppid; ! 355: #endif ! 356: return 0; ! 357: } ! 358: } ! 359: ! 360: /* ! 361: * Die. ! 362: */ ! 363: pexit(s) ! 364: { ! 365: register PROC *pp1; ! 366: register PROC *pp; ! 367: register SEG *sp; ! 368: register int n; ! 369: PROC *parent; ! 370: ! 371: pp = SELF; ! 372: ! 373: T_PIGGY( 0x1, printf("%s:pexit(%x)", u.u_comm, s); ); ! 374: /* ! 375: * Cancel alarm and poll timers [if any]. ! 376: */ ! 377: timeout(&pp->p_alrmtim, 0, NULL, 0); ! 378: timeout(&pp->p_polltim, 0, NULL, 0); ! 379: ! 380: /* ! 381: * Write out accounting directory and close all files associated with ! 382: * this process. ! 383: */ ! 384: setacct(); ! 385: if (u.u_rdir) ! 386: ldetach(u.u_rdir); ! 387: if (u.u_cdir) ! 388: ldetach(u.u_cdir); ! 389: fdaclose(); ! 390: ! 391: /* ! 392: * Free all segments in reverse order, except for user-area. ! 393: */ ! 394: for (n = NUSEG; --n > 0;) { ! 395: if ((sp = pp->p_segp[n]) != NULL) { ! 396: pp->p_segp[n] = NULL; ! 397: sfree(sp); ! 398: } ! 399: } ! 400: ! 401: /* ! 402: * Wakeup our parent. If we have any children, init will become the ! 403: * new parent. If there are any children we are tracing who are ! 404: * waiting for us, we wake them up. ! 405: */ ! 406: pp1 = &procq; ! 407: while ((pp1=pp1->p_nforw) != &procq) { ! 408: if (pp1->p_pid == pp->p_ppid) { ! 409: parent = pp1; /* Remember our parent. */ ! 410: if (pp1->p_state==PSSLEEP && pp1->p_event==(char *)pp1) ! 411: wakeup((char *)pp1); ! 412: } ! 413: if (pp1->p_ppid == pp->p_pid) { ! 414: pp1->p_ppid = 1; ! 415: if (pp1->p_state == PSDEAD) ! 416: wakeup((char *)eprocp); ! 417: if ((pp1->p_flags&PFTRAC) != 0) ! 418: wakeup((char *)&pts.pt_req); ! 419: } ! 420: } ! 421: ! 422: /* ! 423: * Wake up swapper if swap timer is active. ! 424: */ ! 425: if (stimer.t_last != 0) ! 426: wakeup((char *) &stimer); ! 427: ! 428: /* ! 429: * Mark us as dead and give up the processor forever. ! 430: */ ! 431: pp->p_exit = s; ! 432: pp->p_state = PSDEAD; ! 433: ! 434: #ifdef _I386 ! 435: /* ! 436: * If this is a process group leader, inform all members of the group ! 437: * of the recent death with a HUP signal. ! 438: */ ! 439: if (pp->p_group == pp->p_pid) { ! 440: ukill(-pp->p_pid, SIGHUP); ! 441: } ! 442: #else ! 443: uasa = 0; ! 444: #endif ! 445: ! 446: #ifdef _I386 ! 447: T_PIGGY( 0x100, printf("<CHLD pid: %d ppid: %d>", ! 448: pp->p_pid, parent->p_pid); ); ! 449: ! 450: /* ! 451: * If the parent is ignoring SIGCHLD, ! 452: * remove the zombie right away. ! 453: */ ! 454: # define CHLDBIT (((sig_t) 1) << (SIGCHLD - 1)) ! 455: if (CHLDBIT & parent->p_isig) { ! 456: parent->p_cutime += pp->p_utime + pp->p_cutime; ! 457: parent->p_cstime += pp->p_stime + pp->p_cstime; ! 458: relproc(pp); ! 459: } else { ! 460: /* ! 461: * If SIGCHLD is not defaulted, notify our parent ! 462: * of our demise. ! 463: */ ! 464: if (!(CHLDBIT & parent->p_dfsig)) { ! 465: sendsig(SIGCHLD, parent ); ! 466: } ! 467: } ! 468: #endif /* _I386 */ ! 469: ! 470: dispatch(); ! 471: } ! 472: ! 473: #ifdef _I386 ! 474: /* ! 475: * Sleep verbosely. Put a short string describing our reason for sleeping ! 476: * into our U area, and then go to sleep. ! 477: */ ! 478: v_sleep(e, cl, sl, sr, msg) ! 479: char *e; ! 480: int cl, sl, sr; ! 481: char *msg; ! 482: { ! 483: int i; ! 484: ! 485: /* ! 486: * The descriptive string may be at most 10 characters long. ! 487: * It will only be NUL terminated if it has 9 or fewer characters. ! 488: */ ! 489: for (i = 0; i < 10; ++i) { ! 490: if ('\0' == (u.u_sleep[i] = msg[i])) { ! 491: break; ! 492: } ! 493: } ! 494: ! 495: sleep(e, cl, sl, sr); ! 496: } /* v_sleep() */ ! 497: #endif ! 498: ! 499: /* ! 500: * Sleep on the event `e'. This gives up the processor until someone ! 501: * wakes us up. Since it is possible for many people to sleep on the ! 502: * same event, the caller when awakened should make sure that what he ! 503: * was waiting for has completed and if not, go to sleep again. `cl' ! 504: * is the cpu value we get to get the cpu as soon as we are woken up. ! 505: * `sl' is the swap value we get to keep us in memory for the duration ! 506: * of the sleep. `sr' is the swap value that allows us to get swapped ! 507: * in if we have been swapped out. ! 508: */ ! 509: sleep(e, cl, sl, sr) ! 510: char *e; ! 511: { ! 512: register PROC *bp; ! 513: register PROC *fp; ! 514: register PROC *pp; ! 515: register int s; ! 516: ! 517: pp = SELF; ! 518: ! 519: /* ! 520: * See if we have a signal awaiting. ! 521: */ ! 522: if (cl<CVNOSIG && pp->p_ssig && nondsig()) { ! 523: sphi(); ! 524: envrest(&u.u_sigenv); ! 525: } ! 526: ! 527: /* ! 528: * Get ready to go to sleep and do so. ! 529: */ ! 530: s = sphi(); ! 531: pp->p_state = PSSLEEP; ! 532: pp->p_event = e; ! 533: pp->p_lctim = utimer; ! 534: addu(pp->p_cval, cl); ! 535: pp->p_ival = sl; ! 536: pp->p_rval = sr; ! 537: fp = &linkq[hash(e)]; ! 538: bp = fp->p_lback; ! 539: pp->p_lforw = fp; ! 540: fp->p_lback = pp; ! 541: pp->p_lback = bp; ! 542: bp->p_lforw = pp; ! 543: spl(s); ! 544: dispatch(); ! 545: ! 546: /* ! 547: * We have just woken up. Get ready to return. ! 548: */ ! 549: subu(pp->p_cval, cl); ! 550: pp->p_ival = 0; ! 551: pp->p_rval = 0; ! 552: ! 553: /* ! 554: * Since we are no longer asleep, we no longer need ! 555: * to publish a reason for sleeping. ! 556: */ ! 557: #ifdef _I386 ! 558: u.u_sleep[0] = '\0'; ! 559: #endif ! 560: ! 561: /* ! 562: * Check for an interrupted system call. ! 563: */ ! 564: if (cl<CVNOSIG && pp->p_ssig && nondsig()) { ! 565: sphi(); ! 566: envrest(&u.u_sigenv); ! 567: } ! 568: } ! 569: ! 570: /* ! 571: * Defer function to wake up all processes sleeping on the event `e'. ! 572: */ ! 573: wakeup(e) ! 574: char *e; ! 575: { ! 576: void dwakeup(); ! 577: ! 578: #ifdef TRACER ! 579: /* ! 580: * In diagnostic kernel, keep return addr on queue as well. ! 581: */ ! 582: int *r=(int*)(&e); ! 583: defer0(dwakeup, e, *(r-1)); ! 584: #else ! 585: defer(dwakeup, e); ! 586: #endif ! 587: } ! 588: ! 589: /* ! 590: * Wake up all processes sleeping on the event `e'. ! 591: */ ! 592: void ! 593: dwakeup(e) ! 594: char *e; ! 595: { ! 596: register PROC *pp; ! 597: register PROC *pp1; ! 598: register int s; ! 599: ! 600: /* ! 601: * Identify event queue to check. ! 602: * Disable interrupts. ! 603: */ ! 604: pp1 = &linkq[hash(e)]; ! 605: pp = pp1; ! 606: s = sphi(); ! 607: ! 608: /* ! 609: * Traverse doubly-linked circular event-queue. ! 610: */ ! 611: while ((pp = pp->p_lforw) != pp1) { ! 612: ! 613: /* ! 614: * Process is waiting on event 'e'. ! 615: */ ! 616: if (pp->p_event == e) { ! 617: /* ! 618: * Remove process from event queue. ! 619: * Update process priority. ! 620: * Insert process into run queue. ! 621: */ ! 622: pp->p_lback->p_lforw = pp->p_lforw; ! 623: pp->p_lforw->p_lback = pp->p_lback; ! 624: addu(pp->p_cval, (utimer-pp->p_lctim)*CVCLOCK); ! 625: setrun(pp); ! 626: ! 627: /* ! 628: * Enable interrupts. ! 629: * Restart search at start of event queue. ! 630: * Disable interrupts. ! 631: */ ! 632: spl(s); ! 633: pp = pp1; ! 634: s = sphi(); ! 635: } ! 636: } ! 637: spl(s); ! 638: } ! 639: ! 640: /* ! 641: * Reschedule the processor. ! 642: */ ! 643: dispatch() ! 644: { ! 645: register PROC *pp1; ! 646: register PROC *pp2; ! 647: register unsigned v; ! 648: register int s; ! 649: ! 650: s = sphi(); ! 651: pp1 = iprocp; ! 652: pp2 = &procq; ! 653: v = 0; ! 654: while ((pp2=pp2->p_lforw) != &procq) { ! 655: v -= pp2->p_cval; ! 656: if ((pp2->p_flags&PFCORE) == 0) ! 657: continue; ! 658: pp1 = pp2->p_lforw; ! 659: pp1->p_cval += pp2->p_cval; ! 660: pp2->p_cval = v; ! 661: pp1->p_lback = pp2->p_lback; ! 662: pp1->p_lback->p_lforw = pp1; ! 663: pp1 = pp2; ! 664: break; ! 665: } ! 666: spl(s); ! 667: ! 668: quantum = NCRTICK; ! 669: disflag = 0; ! 670: if (pp1 != SELF) { ! 671: /* ! 672: * Consave() returns twice. ! 673: * 1st time is after our context is saved in u.u_syscon, ! 674: * whereupon we should restore other proc's context. ! 675: * 2nd time is after our context is restored by another proc. ! 676: * Conrest() forces a context switch to a new process. ! 677: */ ! 678: s = sphi(); ! 679: SELF = pp1; ! 680: if (consave(&u.u_syscon) == 0) { ! 681: #ifdef _I386 ! 682: conrest(*pp1->p_segp[SIUSERP]->s_vmem, &u.u_syscon); ! 683: #else ! 684: conrest( ! 685: FP_SEL(pp1->p_u->s_faddr), offset(uproc,u_syscon)); ! 686: #endif ! 687: } ! 688: if (SELF->p_pid != 0) ! 689: segload(); ! 690: spl(s); ! 691: } ! 692: } ! 693: ! 694: /* ! 695: * Add a process to the run queue. ! 696: * This routine must be called at high priority. ! 697: */ ! 698: setrun(pp1) ! 699: register PROC *pp1; ! 700: { ! 701: register PROC *pp2; ! 702: register unsigned v; ! 703: ! 704: v = 0; ! 705: pp2 = &procq; ! 706: for (;;) { ! 707: pp2 = pp2->p_lback; ! 708: if ((v+=pp2->p_lforw->p_cval) >= pp1->p_cval) ! 709: break; ! 710: if (pp2 == &procq) ! 711: break; ! 712: } ! 713: pp2->p_lforw->p_lback = pp1; ! 714: pp1->p_lforw = pp2->p_lforw; ! 715: pp2->p_lforw = pp1; ! 716: pp1->p_lback = pp2; ! 717: v -= pp1->p_cval; ! 718: pp1->p_cval = v; ! 719: pp1->p_lforw->p_cval -= v; ! 720: pp1->p_state = PSRUN; ! 721: } ! 722: ! 723: /* ! 724: * Wait for the gate `g' to unlock, and then lock it. ! 725: */ ! 726: lock(g) ! 727: register GATE g; ! 728: { ! 729: register int s; ! 730: ! 731: s = sphi(); ! 732: while (g[0]) { ! 733: g[1] = 1; ! 734: v_sleep((char *)g, CVGATE, IVGATE, SVGATE, "lock"); ! 735: /* Waiting for a gate to unlock. */ ! 736: } ! 737: g[0] = 1; ! 738: spl(s); ! 739: } ! 740: ! 741: /* ! 742: * Unlock the gate `g'. ! 743: */ ! 744: unlock(g) ! 745: register GATE g; ! 746: { ! 747: g[0] = 0; ! 748: if (g[1]) { ! 749: g[1] = 0; ! 750: disflag = 1; ! 751: wakeup((char *)g); ! 752: } ! 753: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.