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