|
|
1.1 ! root 1: /* $Header: /usr/src/sys/ker/RCS/swap.c,v 1.1 88/03/24 16:19:51 src Exp $ */ ! 2: /* (lgl- ! 3: * The information contained herein is a trade secret of Mark Williams ! 4: * Company, and is confidential information. It is provided under a ! 5: * license agreement, and may be copied or disclosed only under the ! 6: * terms of that agreement. Any reproduction or disclosure of this ! 7: * material without the express written authorization of Mark Williams ! 8: * Company or persuant to the license agreement is unlawful. ! 9: * ! 10: * COHERENT Version 2.3.37 ! 11: * Copyright (c) 1982, 1983, 1984. ! 12: * An unpublished work by Mark Williams Company, Chicago. ! 13: * All rights reserved. ! 14: -lgl) */ ! 15: /* ! 16: * Coherent. ! 17: * Swapper. ! 18: * ! 19: * $Log: /usr/src/sys/ker/RCS/swap.c,v $ ! 20: * Revision 1.1 88/03/24 16:19:51 src ! 21: * Initial revision ! 22: * ! 23: * 87/01/05 Allan Cornish /usr/src/sys/ker/swap.c ! 24: * Swap() now waits for all processes to be swapped in before exit on signal. ! 25: */ ! 26: #include <coherent.h> ! 27: #include <proc.h> ! 28: #include <sched.h> ! 29: #include <sys/seg.h> ! 30: #include <sys/uproc.h> ! 31: #include <sys/buf.h> ! 32: ! 33: /* ! 34: * Functions. ! 35: */ ! 36: SEG *xmalloc(); ! 37: SEG *xdalloc(); ! 38: ! 39: swap() ! 40: { ! 41: register SEG *sp; ! 42: register PROC *pp1; ! 43: register PROC *pp2; ! 44: register PROC *pp3; ! 45: register unsigned s; ! 46: register unsigned n; ! 47: register unsigned t; ! 48: register unsigned v; ! 49: register unsigned m; ! 50: register int i; ! 51: static unsigned ltimer; ! 52: ! 53: if (sexflag != 0) ! 54: uexit(1); ! 55: sexflag++; ! 56: while (1) { ! 57: lock(pnxgate); ! 58: t = (utimer-ltimer)/NSUTICK; ! 59: v = t*SVCLOCK; ! 60: ltimer += t*NSUTICK; ! 61: m = 0; ! 62: pp2 = NULL; ! 63: for (pp1=procq.p_nback; pp1!=&procq; pp1=pp1->p_nback) { ! 64: if ((pp1->p_flags&PFCORE) != 0) { ! 65: pp1->p_sval >>= t; ! 66: pp1->p_ival -= t; ! 67: if (pp1->p_ival < -30000) ! 68: pp1->p_ival = -30000; ! 69: continue; ! 70: } ! 71: addu(pp1->p_sval, v); ! 72: if (pp1->p_state != PSRUN) ! 73: continue; ! 74: s = 0; ! 75: for (i=0; i<NUSEG+1; i++) ! 76: if ((sp=pp1->p_segp[i]) != NULL) ! 77: if ((sp->s_flags&SFCORE) == 0) ! 78: s += sp->s_size; ! 79: if ((s=ctokrd(s)) == 0) ! 80: s = 1; ! 81: n = (pp1->p_sval+pp1->p_rval)/s; ! 82: if (n > m) { ! 83: m = n; ! 84: pp2 = pp1; ! 85: } ! 86: } ! 87: unlock(pnxgate); ! 88: if (pp2 == NULL) { ! 89: if ( SELF->p_ssig != 0 ) ! 90: break; ! 91: goto con; ! 92: } ! 93: #ifndef NOMONITOR ! 94: if (swmflag) ! 95: printf("Swapin(%p, %d)\n", pp2, pp2->p_pid); ! 96: #endif ! 97: xxx: ! 98: while (testcore(pp2)==0 || proccore(pp2)!=0) { ! 99: if ((pp2->p_flags&PFAUXM) != 0) { ! 100: auxmdisk(pp2); ! 101: goto xxx; ! 102: } ! 103: procdisk(pp2); ! 104: i = 32767; ! 105: pp3 = NULL; ! 106: lock(pnxgate); ! 107: for (pp1=procq.p_nforw; pp1!=&procq; pp1=pp1->p_nforw){ ! 108: if (pp1->p_flags&(PFSWIO|PFLOCK|PFKERN)) ! 109: continue; ! 110: if ((pp1->p_flags&PFAUXM) != 0) { ! 111: auxmdisk(pp1); ! 112: unlock(pnxgate); ! 113: goto xxx; ! 114: } ! 115: if ((pp1->p_flags&PFCORE) == 0) { ! 116: if (procdisk(pp1) != 0) { ! 117: unlock(pnxgate); ! 118: goto xxx; ! 119: } ! 120: continue; ! 121: } ! 122: if (pp1->p_ival>-64 && pp1->p_sval!=0) ! 123: continue; ! 124: if (pp1->p_ival < i) { ! 125: i = pp1->p_ival; ! 126: pp3 = pp1; ! 127: } ! 128: } ! 129: unlock(pnxgate); ! 130: if (pp3 == NULL) { ! 131: #ifndef NOMONITOR ! 132: if (swmflag) ! 133: printf("No one to swap out\n"); ! 134: #endif ! 135: break; ! 136: } ! 137: if (i > 0) { ! 138: #ifndef NOMONITOR ! 139: if (swmflag) ! 140: printf("Dispatch(%p, %d)\n", ! 141: pp3, pp3->p_pid); ! 142: #endif ! 143: pp3->p_flags |= PFDISP; ! 144: break; ! 145: } ! 146: #ifndef NOMONITOR ! 147: if (swmflag) ! 148: printf("Swapout(%p, %d)\n", pp3, pp3->p_pid); ! 149: #endif ! 150: procdisk(pp3); ! 151: } ! 152: #ifndef NOMONITOR ! 153: if (swmflag) ! 154: printf("Swapdone\n"); ! 155: #endif ! 156: con: ! 157: timeout(&stimer, NSRTICK, wakeup, (char *)&stimer); ! 158: sleep((char *)&stimer, CVSWAP, IVSWAP, SVSWAP); ! 159: } ! 160: --sexflag; ! 161: uexit(1); ! 162: } ! 163: ! 164: /* ! 165: * See if the given process may fit in core. ! 166: */ ! 167: testcore(pp) ! 168: register PROC *pp; ! 169: { ! 170: register SEG *sp; ! 171: register saddr_t s; ! 172: register saddr_t s1; ! 173: register saddr_t s2; ! 174: register int i; ! 175: ! 176: s = 0; ! 177: for (i=0; i<NUSEG+1; i++) { ! 178: if ((sp=pp->p_segp[i]) == NULL) ! 179: continue; ! 180: if ((sp->s_flags&SFCORE) != 0) ! 181: continue; ! 182: if (sp->s_size > s) ! 183: s = sp->s_size; ! 184: } ! 185: s1 = corebot; ! 186: sp = &segmq; ! 187: do { ! 188: sp = sp->s_forw; ! 189: s2 = sp->s_mbase; ! 190: if (s2-s1 >= s) ! 191: return (1); ! 192: s1 = sp->s_mbase + sp->s_size; ! 193: } while (sp != &segmq); ! 194: return (0); ! 195: } ! 196: ! 197: /* ! 198: * Swap all segments associated with a particular process into core. ! 199: * The number of segments still swapped out is returned. ! 200: */ ! 201: proccore(pp) ! 202: register PROC *pp; ! 203: { ! 204: register SEG *sp; ! 205: register int i; ! 206: register int n; ! 207: register int f; ! 208: ! 209: n = 0; ! 210: f = pp->p_flags&PFSWAP; ! 211: for (i=0; i<NUSEG+1; i++) { ! 212: if ((sp=pp->p_segp[i]) == NULL) ! 213: continue; ! 214: if (f != 0) ! 215: sp->s_lrefc++; ! 216: if ((sp->s_flags&SFCORE)==0 && segcore(sp)==0) ! 217: n++; ! 218: } ! 219: if (n == 0) ! 220: pp->p_flags |= PFCORE; ! 221: pp->p_flags &= ~PFSWAP; ! 222: return (n); ! 223: } ! 224: ! 225: /* ! 226: * Swap out all segments associated with a given process. ! 227: */ ! 228: procdisk(pp) ! 229: register PROC *pp; ! 230: { ! 231: register SEG *sp; ! 232: register int i; ! 233: register int f; ! 234: int n; ! 235: ! 236: n = 0; ! 237: f = pp->p_flags&PFSWAP; ! 238: pp->p_flags &= ~PFCORE; ! 239: for (i=0; i<NUSEG+1; i++) { ! 240: if ((sp=pp->p_segp[i]) == NULL) ! 241: continue; ! 242: if (f == 0) ! 243: --sp->s_lrefc; ! 244: if ((sp->s_flags&SFCORE) == 0) ! 245: continue; ! 246: if (sp->s_lrefc == 0) ! 247: if (segdisk(sp) != 0) ! 248: n++; ! 249: } ! 250: pp->p_flags |= PFSWAP; ! 251: return (n); ! 252: } ! 253: ! 254: /* ! 255: * Swap out all auxiliary segments used by a process. ! 256: */ ! 257: auxmdisk(pp) ! 258: register PROC *pp; ! 259: { ! 260: register SEG *sp; ! 261: register int i; ! 262: register int f; ! 263: register int m; ! 264: SEG *segl[NUSEG]; ! 265: ! 266: #ifndef NOMONITOR ! 267: if (swmflag) ! 268: printf("Auxiliary(%p, %d)\n", pp, pp->p_pid); ! 269: #endif ! 270: sp = pp->p_segp[SIUSERP]; ! 271: if ((sp->s_flags&SFCORE) == 0) { ! 272: panic("We may be in trouble"); ! 273: return; ! 274: } ! 275: m = pp->p_flags&PFCORE; ! 276: f = pp->p_flags&PFAUXM; ! 277: pp->p_flags &= ~(PFAUXM|PFCORE); ! 278: skcopy(sp, offset(uproc, u_sege[0]), segl, sizeof(u.u_sege)); ! 279: for (i=0; i<NUSEG; i++) { ! 280: if ((sp=segl[i]) == NULL) ! 281: continue; ! 282: if (f != 0) ! 283: --sp->s_lrefc; ! 284: if ((sp->s_flags&SFCORE) == 0) ! 285: continue; ! 286: if (sp->s_lrefc == 0) ! 287: segdisk(sp); ! 288: } ! 289: pp->p_flags |= m; ! 290: } ! 291: ! 292: /* ! 293: * Swap the given segment into core. ! 294: */ ! 295: segcore(sp1) ! 296: register SEG *sp1; ! 297: { ! 298: register SEG *sp2; ! 299: ! 300: lock(seglink); ! 301: sp2 = xmalloc(sp1->s_size); ! 302: unlock(seglink); ! 303: if (sp2 == NULL) ! 304: return (0); ! 305: sp1->s_lrefc++; ! 306: swapio(0, sp2->s_mbase, sp1->s_dbase, sp2->s_size); ! 307: lock(seglink); ! 308: sp1->s_back->s_forw = sp1->s_forw; ! 309: sp1->s_forw->s_back = sp1->s_back; ! 310: sp2->s_back->s_forw = sp1; ! 311: sp1->s_back = sp2->s_back; ! 312: sp2->s_forw->s_back = sp1; ! 313: sp1->s_forw = sp2->s_forw; ! 314: sp1->s_flags |= SFCORE; ! 315: sp1->s_mbase = sp2->s_mbase; ! 316: --sp1->s_lrefc; ! 317: unlock(seglink); ! 318: return (1); ! 319: } ! 320: ! 321: /* ! 322: * Swap the given segment out onto disk. ! 323: */ ! 324: segdisk(sp1) ! 325: register SEG *sp1; ! 326: { ! 327: register SEG *sp2; ! 328: ! 329: lock(seglink); ! 330: sp2 = xdalloc(sp1->s_size); ! 331: unlock(seglink); ! 332: if (sp2 == NULL) ! 333: return (0); ! 334: sp1->s_lrefc++; ! 335: swapio(1, sp1->s_mbase, sp2->s_dbase, sp1->s_size); ! 336: lock(seglink); ! 337: sp1->s_back->s_forw = sp1->s_forw; ! 338: sp1->s_forw->s_back = sp1->s_back; ! 339: sp2->s_back->s_forw = sp1; ! 340: sp1->s_back = sp2->s_back; ! 341: sp2->s_forw->s_back = sp1; ! 342: sp1->s_forw = sp2->s_forw; ! 343: sp1->s_flags &= ~SFCORE; ! 344: sp1->s_dbase = sp2->s_dbase; ! 345: --sp1->s_lrefc; ! 346: unlock(seglink); ! 347: return (1); ! 348: } ! 349: ! 350: /* ! 351: * Allocate a segment on disk that is `n' clicks long. ! 352: * The `seglink' gate should be locked before this routine is called. ! 353: * This routine is the same as `sdalloc' except that we can't run out of ! 354: * alloc space to allocate the segment and we allocate in high regions. ! 355: */ ! 356: SEG * ! 357: xdalloc(s) ! 358: saddr_t s; ! 359: { ! 360: register SEG *sp1; ! 361: register SEG *sp2; ! 362: register daddr_t d; ! 363: register daddr_t d1; ! 364: register daddr_t d2; ! 365: ! 366: d = stod(s); ! 367: d2 = swaptop; ! 368: sp1 = &segdq; ! 369: do { ! 370: if ((sp1=sp1->s_back) != &segdq) ! 371: d1 = sp1->s_dbase + stod(sp1->s_size); ! 372: else ! 373: d1 = swapbot; ! 374: if (d2-d1 >= d) { ! 375: sp2 = &segswap; ! 376: kclear((char *)sp2, sizeof(SEG)); ! 377: sp1->s_forw->s_back = sp2; ! 378: sp2->s_forw = sp1->s_forw; ! 379: sp1->s_forw = sp2; ! 380: sp2->s_back = sp1; ! 381: sp2->s_urefc = 1; ! 382: sp2->s_lrefc = 1; ! 383: sp2->s_size = s; ! 384: sp2->s_dbase = d2 - d; ! 385: return (sp2); ! 386: } ! 387: d2 = sp1->s_dbase; ! 388: } while (sp1 != &segdq); ! 389: return (NULL); ! 390: } ! 391: ! 392: /* ! 393: * Allocate a segment in memory that is `n' clicks long. ! 394: * The `seglink' gate should be locked before this routine is called. ! 395: * This routine is the same as `smalloc' except that we can't run out of ! 396: * alloc space to allocate the segment. ! 397: */ ! 398: SEG * ! 399: xmalloc(s) ! 400: register saddr_t s; ! 401: { ! 402: register SEG *sp1; ! 403: register SEG *sp2; ! 404: register saddr_t s1; ! 405: register saddr_t s2; ! 406: ! 407: s1 = corebot; ! 408: sp1 = &segmq; ! 409: do { ! 410: if ((sp1=sp1->s_forw) != &segmq) ! 411: s2 = sp1->s_mbase; ! 412: else ! 413: s2 = coretop; ! 414: if (s2-s1 >= s) { ! 415: sp2 = &segswap; ! 416: kclear((char *)sp2, sizeof(SEG)); ! 417: sp1->s_back->s_forw = sp2; ! 418: sp2->s_back = sp1->s_back; ! 419: sp1->s_back = sp2; ! 420: sp2->s_forw = sp1; ! 421: sp2->s_urefc = 1; ! 422: sp2->s_lrefc = 1; ! 423: sp2->s_size = s; ! 424: sp2->s_mbase = s1; ! 425: return (sp2); ! 426: } ! 427: s1 = sp1->s_mbase + sp1->s_size; ! 428: } while (sp1 != &segmq); ! 429: return (NULL); ! 430: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.