|
|
1.1 ! root 1: #include "sys/param.h" ! 2: #include "sys/systm.h" ! 3: #include "sys/user.h" ! 4: #include "sys/proc.h" ! 5: #include "sys/file.h" ! 6: #include "sys/inode.h" ! 7: #include "sys/vm.h" ! 8: #include "sys/pte.h" ! 9: #include "sys/mtpr.h" ! 10: ! 11: #define SQSIZE 0100 /* Must be power of 2 */ ! 12: #define HASH(x) (( (int) x >> 5) & (SQSIZE-1)) ! 13: struct proc *slpque[SQSIZE]; ! 14: ! 15: /* ! 16: * Give up the processor till a wakeup occurs ! 17: * on chan, at which time the process ! 18: * enters the scheduling queue at priority pri. ! 19: * The most important effect of pri is that when ! 20: * pri<=PZERO a signal cannot disturb the sleep; ! 21: * if pri>PZERO signals will be processed. ! 22: * Callers of this routine must be prepared for ! 23: * premature return, and check that the reason for ! 24: * sleeping has gone away. ! 25: */ ! 26: sleep(chan, pri) ! 27: caddr_t chan; ! 28: { ! 29: register struct proc *rp, **hp; ! 30: register s; ! 31: ! 32: rp = u.u_procp; ! 33: s = spl6(); ! 34: if (chan==0 || rp->p_stat != SRUN || rp->p_rlink) ! 35: panic("sleep"); ! 36: rp->p_wchan = chan; ! 37: rp->p_slptime = 0; ! 38: rp->p_pri = pri; ! 39: hp = &slpque[HASH(chan)]; ! 40: rp->p_link = *hp; ! 41: *hp = rp; ! 42: if(pri > PZERO) { ! 43: if(rp->p_sig && issig()) { ! 44: if (rp->p_wchan) ! 45: unsleep(rp); ! 46: rp->p_stat = SRUN; ! 47: (void) spl0(); ! 48: goto psig; ! 49: } ! 50: if (rp->p_wchan == 0) ! 51: goto out; ! 52: rp->p_stat = SSLEEP; ! 53: (void) spl0(); ! 54: swtch(); ! 55: if(rp->p_sig && issig()) ! 56: goto psig; ! 57: } else { ! 58: rp->p_stat = SSLEEP; ! 59: (void) spl0(); ! 60: swtch(); ! 61: } ! 62: out: ! 63: splx(s); ! 64: return; ! 65: ! 66: /* ! 67: * If priority was low (>PZERO) and ! 68: * there has been a signal, ! 69: * execute non-local goto to ! 70: * the qsav location. ! 71: * (see trap1/trap.c) ! 72: */ ! 73: psig: ! 74: longjmp(u.u_qsav); ! 75: /*NOTREACHED*/ ! 76: } ! 77: ! 78: /* ! 79: * Sleep on chan at pri. ! 80: * Return in no more than the indicated number of seconds. ! 81: * (If seconds==0, no timeout implied) ! 82: * Return TS_OK if chan was awakened normally ! 83: * TS_TIME if timeout occurred ! 84: * TS_SIG if asynchronous signal occurred ! 85: */ ! 86: tsleep(chan, pri, seconds) ! 87: caddr_t chan; ! 88: { ! 89: label_t lqsav; ! 90: register n, rval; ! 91: register struct proc *pp = u.u_procp; ! 92: ! 93: n = spl7(); ! 94: bcopy((caddr_t)u.u_qsav, (caddr_t)lqsav, sizeof (label_t)); ! 95: pp->p_tsleep = seconds; ! 96: if (setjmp(u.u_qsav)) ! 97: rval = TS_SIG; ! 98: else { ! 99: sleep(chan, pri); ! 100: if (pp->p_flag&STIMO) ! 101: rval = TS_TIME; ! 102: else ! 103: rval = TS_OK; ! 104: } ! 105: pp->p_flag &= ~STIMO; ! 106: bcopy((caddr_t)lqsav, (caddr_t)u.u_qsav, sizeof (label_t)); ! 107: splx(n); ! 108: return(rval); ! 109: } ! 110: ! 111: /* ! 112: * Remove a process from its wait queue ! 113: */ ! 114: unsleep(p) ! 115: register struct proc *p; ! 116: { ! 117: register struct proc **hp; ! 118: register s; ! 119: ! 120: s = spl6(); ! 121: if (p->p_wchan) { ! 122: hp = &slpque[HASH(p->p_wchan)]; ! 123: while (*hp != p) ! 124: hp = &(*hp)->p_link; ! 125: *hp = p->p_link; ! 126: p->p_wchan = 0; ! 127: } ! 128: splx(s); ! 129: } ! 130: ! 131: /* ! 132: * Wake up all processes sleeping on chan. ! 133: */ ! 134: wakeup(chan) ! 135: register caddr_t chan; ! 136: { ! 137: register struct proc *p, **q, **h; ! 138: int s; ! 139: ! 140: s = spl6(); ! 141: h = &slpque[HASH(chan)]; ! 142: restart: ! 143: for (q = h; p = *q; ) { ! 144: if (p->p_rlink || p->p_stat != SSLEEP && p->p_stat != SSTOP) ! 145: panic("wakeup"); ! 146: if (p->p_wchan==chan) { ! 147: p->p_wchan = 0; ! 148: *q = p->p_link; ! 149: p->p_slptime = 0; ! 150: p->p_tsleep = 0; ! 151: if (p->p_stat == SSLEEP) { ! 152: /* OPTIMIZED INLINE EXPANSION OF setrun(p) */ ! 153: p->p_stat = SRUN; ! 154: if (p->p_flag & SLOAD) ! 155: setrq(p); ! 156: if(p->p_pri < curpri) { ! 157: runrun++; ! 158: aston(); ! 159: } ! 160: if ((p->p_flag&SLOAD) == 0) { ! 161: if (runout != 0) { ! 162: runout = 0; ! 163: wakeup((caddr_t)&runout); ! 164: } ! 165: wantin++; ! 166: } ! 167: /* END INLINE EXPANSION */ ! 168: goto restart; ! 169: } ! 170: } else ! 171: q = &p->p_link; ! 172: } ! 173: splx(s); ! 174: } ! 175: ! 176: /* ! 177: * Initialize the (doubly-linked) run queues ! 178: * to be empty. ! 179: */ ! 180: rqinit() ! 181: { ! 182: register int i; ! 183: ! 184: for (i = 0; i < NQS; i++) ! 185: qs[i].ph_link = qs[i].ph_rlink = (struct proc *)&qs[i]; ! 186: } ! 187: ! 188: /* ! 189: * Set the process running; ! 190: * arrange for it to be swapped in if necessary. ! 191: */ ! 192: setrun(p) ! 193: register struct proc *p; ! 194: { ! 195: register s; ! 196: ! 197: s = spl6(); ! 198: switch (p->p_stat) { ! 199: default: ! 200: panic("setrun"); ! 201: ! 202: case SSTOP: ! 203: case SSLEEP: ! 204: unsleep(p); /* e.g. when sending signals */ ! 205: break; ! 206: ! 207: case SIDL: ! 208: break; ! 209: } ! 210: p->p_stat = SRUN; ! 211: if (p->p_flag & SLOAD) ! 212: setrq(p); ! 213: splx(s); ! 214: if(p->p_pri < curpri) { ! 215: runrun++; ! 216: aston(); ! 217: } ! 218: if ((p->p_flag&SLOAD) == 0) { ! 219: if(runout != 0) { ! 220: runout = 0; ! 221: wakeup((caddr_t)&runout); ! 222: } ! 223: wantin++; ! 224: } ! 225: } ! 226: ! 227: /* ! 228: * Set user priority. ! 229: * The rescheduling flag (runrun) ! 230: * is set if the priority is better ! 231: * than the currently running process. ! 232: */ ! 233: setpri(pp) ! 234: register struct proc *pp; ! 235: { ! 236: register int p; ! 237: ! 238: p = pp->p_cpu/4; ! 239: p += PUSER + 2*(pp->p_nice - NZERO); ! 240: if (pp->p_rssize > pp->p_maxrss && freemem < desfree) ! 241: p += 2*4; /* i.e. nice(4) */ ! 242: if (p > PRIMAX) ! 243: p = PRIMAX; ! 244: if(p < curpri) { ! 245: runrun++; ! 246: aston(); ! 247: } ! 248: pp->p_usrpri = p; ! 249: return(p); ! 250: } ! 251: ! 252: /* ! 253: * Create a new process-- ! 254: * the internal version of sys fork. ! 255: * supply a process slot and a pid. ! 256: * returns 1 in the new process, 0 in the old. ! 257: */ ! 258: newproc(rpp, pid) ! 259: register struct proc *rpp; ! 260: int pid; ! 261: { ! 262: register struct proc *rip; ! 263: register int n; ! 264: ! 265: /* ! 266: * init the proc entry ! 267: */ ! 268: if (rpp->p_stat != 0) ! 269: panic("newproc"); ! 270: rip = u.u_procp; ! 271: bzero((caddr_t)rpp, sizeof(*rpp)); ! 272: rpp->p_stat = SIDL; ! 273: rpp->p_flag = SLOAD | (rip->p_flag & (SSEXEC|SPAGI|STRC|SPROCTR)); ! 274: rpp->p_uid = rip->p_uid; ! 275: rpp->p_pgrp = rip->p_pgrp; ! 276: rpp->p_nice = rip->p_nice; ! 277: rpp->p_textp = rip->p_textp; ! 278: rpp->p_pid = pid; ! 279: rpp->p_ppid = rip->p_pid; ! 280: rpp->p_pptr = rip; ! 281: rpp->p_siga0 = rip->p_siga0; ! 282: rpp->p_siga1 = rip->p_siga1; ! 283: /* take along any pending signals, like stops? */ ! 284: rpp->p_tsize = rip->p_tsize; ! 285: rpp->p_dsize = rip->p_dsize; ! 286: rpp->p_ssize = rip->p_ssize; ! 287: rpp->p_szpt = rip->p_szpt; ! 288: rpp->p_maxrss = rip->p_maxrss; ! 289: /* ! 290: * duplicate file references and so on ! 291: */ ! 292: for(n=0; n<NOFILE; n++) ! 293: if(u.u_ofile[n] != NULL) ! 294: u.u_ofile[n]->f_count++; ! 295: u.u_cdir->i_count++; ! 296: if (u.u_rdir) ! 297: u.u_rdir->i_count++; ! 298: /* ! 299: * make the copy ! 300: * child returns 1 when made runnable ! 301: * parent makes child runnable and returns 0 ! 302: */ ! 303: rip->p_flag |= SKEEP; /* prevent parent from being swapped */ ! 304: if (procdup(rpp)) ! 305: return (1); ! 306: (void) spl6(); ! 307: rpp->p_stat = SRUN; ! 308: setrq(rpp); ! 309: (void) spl0(); ! 310: /* SSWAP NOT NEEDED IN THIS CASE AS u.u_pcb.pcb_sswap SUFFICES */ ! 311: /* rpp->p_flag |= SSWAP; */ ! 312: rip->p_flag &= ~SKEEP; ! 313: return (0); ! 314: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.