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