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