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