1: /*
   2:  *	SCCS id	@(#)text.c	2.1 (Berkeley)	8/29/83
   3:  */
   4: 
   5: #include "param.h"
   6: #include <sys/systm.h>
   7: #include <sys/map.h>
   8: #include <sys/dir.h>
   9: #include <sys/user.h>
  10: #include <sys/proc.h>
  11: #include <sys/text.h>
  12: #include <sys/inode.h>
  13: #include <sys/buf.h>
  14: #include <sys/seg.h>
  15: 
  16: /*
  17:  * Swap out process p.
  18:  * The ff flag causes its core to be freed--
  19:  * it may be off when called to create an image for a
  20:  * child process in newproc.
  21:  *
  22:  * panic: out of swap space
  23:  */
  24: #ifndef VIRUS_VFORK
  25: /*
  26:  * Os is the old size of the data area of the process,
  27:  * and is supplied during core expansion swaps.
  28:  */
  29: xswap(p, ff, os)
  30: register struct proc *p;
  31: #else
  32: /*
  33:  * Odata and ostack are the old data and stack sizes,
  34:  * supplied during core expansion swaps.
  35:  */
  36: xswap(p,ff,odata,ostack)
  37: register struct proc *p;
  38: unsigned odata, ostack;
  39: #endif
  40: {
  41: 
  42: #ifdef  VIRUS_VFORK
  43:     unsigned a[3];
  44: 
  45:     if (odata == X_OLDSIZE)
  46:         odata = p->p_dsize;
  47:     if (ostack == X_OLDSIZE)
  48:         ostack = p->p_ssize;
  49:     if (malloc3(swapmap,ctod(p->p_dsize),ctod(p->p_ssize),
  50:         ctod(USIZE),a) == NULL)
  51:         panic("out of swap space");
  52:     p->p_flag |= SLOCK;
  53:     xccdec(p->p_textp);
  54:     if (odata) {
  55:         swap(a[0], p->p_daddr, odata, B_WRITE);
  56:         if (ff == X_FREECORE)
  57:             mfree(coremap, odata, p->p_daddr);
  58:     }
  59:     if (ostack) {
  60:         swap(a[1], p->p_saddr, ostack, B_WRITE);
  61:         if(ff == X_FREECORE)
  62:             mfree(coremap, ostack, p->p_saddr);
  63:     }
  64:     swap(a[2], p->p_addr, USIZE, B_WRITE);
  65:     if(ff == X_FREECORE)
  66:         mfree(coremap, USIZE, p->p_addr);
  67:     p->p_daddr = a[0];
  68:     p->p_saddr = a[1];
  69:     p->p_addr = a[2];
  70:     p->p_flag &= ~(SLOAD|SLOCK);
  71:     p->p_time = 0;
  72:     if(runout) {
  73:         runout = 0;
  74:         wakeup((caddr_t)&runout);
  75:     }
  76: 
  77: #else   VIRUS_VFORK
  78:     register a;
  79: 
  80:     if(os == X_OLDSIZE)
  81:         os = p->p_size;
  82:     a = malloc(swapmap, ctod(p->p_size));
  83:     if(a == NULL)
  84:         panic("out of swap space");
  85:     p->p_flag |= SLOCK;
  86:     xccdec(p->p_textp);
  87:     swap(a, p->p_addr, os, B_WRITE);
  88:     if(ff == X_FREECORE)
  89:         mfree(coremap, os, p->p_addr);
  90:     p->p_addr = a;
  91:     p->p_flag &= ~(SLOAD|SLOCK);
  92:     p->p_time = 0;
  93:     if(runout) {
  94:         runout = 0;
  95:         wakeup((caddr_t)&runout);
  96:     }
  97: #endif	VIRUS_VFORK
  98: }
  99: 
 100: /*
 101:  * relinquish use of the shared text segment
 102:  * of a process.
 103:  */
 104: xfree()
 105: {
 106:     register struct text *xp;
 107:     register struct inode *ip;
 108:     register struct proc *p = u.u_procp;
 109: 
 110:     if((xp=p->p_textp) == NULL)
 111:         return;
 112:     xlock(xp);
 113:     ip = xp->x_iptr;
 114:     if(--xp->x_count == 0 && (ip->i_mode & ISVTX) == 0) {
 115:         /*
 116: 		 * Only safe to mfree first if we are guaranteed
 117: 		 * not to swap with locked text.
 118: 		 */
 119:         mfree(swapmap, ctod(xp->x_size), xp->x_daddr);
 120:         mfree(coremap, xp->x_size, xp->x_caddr);
 121:         ip->i_flag &= ~ITEXT;
 122:         if (ip->i_flag & ILOCK)
 123:             ip->i_count--;
 124:         else
 125:             iput(ip);
 126:         xp->x_iptr = NULL;
 127:         xunlock(xp);
 128:     } else {
 129:         xp->x_flag &= ~XLOCK;
 130:         xccdec(xp);
 131:     }
 132:     p->p_textp = NULL;
 133: }
 134: 
 135: /*
 136:  * Attach to a shared text segment.
 137:  * If there is no shared text, just return.
 138:  * If there is, hook up to it:
 139:  * if it is not currently being used, it has to be read
 140:  * in from the inode (ip); the written bit is set to force it
 141:  * to be written out as appropriate.
 142:  * If it is being used, but is not currently in core,
 143:  * a swap has to be done to get it back.
 144:  */
 145: xalloc(ip)
 146: register struct inode *ip;
 147: {
 148:     register struct text *xp;
 149:     register unsigned ts;
 150:     struct text *xp1;
 151: 
 152:     if(u.u_exdata.ux_tsize == 0)
 153:         return;
 154: again:
 155:     xp1 = NULL;
 156:     for (xp = text; xp < textNTEXT; xp++) {
 157:         if(xp->x_iptr == NULL) {
 158:             if(xp1 == NULL)
 159:                 xp1 = xp;
 160:             continue;
 161:         }
 162:         if(xp->x_iptr == ip) {
 163:             if (xp->x_flag & XLOCK) {
 164:                 /*
 165: 				 *  Wait for text entry to be unlocked,
 166: 				 *  then start over in case this text was
 167: 				 *  xfree'ed.
 168: 				 */
 169:                 xlock(xp);
 170:                 xunlock(xp);
 171:                 goto again;
 172:             }
 173:             xlock(xp);
 174:             xp->x_count++;
 175:             u.u_procp->p_textp = xp;
 176:             if (xp->x_ccount == 0)
 177:                 xexpand(xp);
 178:             else
 179:                 xp->x_ccount++;
 180:             xunlock(xp);
 181:             return;
 182:         }
 183:     }
 184:     if((xp=xp1) == NULL) {
 185:         tablefull("text");
 186:         psignal(u.u_procp, SIGKILL);
 187:         return;
 188:     }
 189:     xp->x_flag = XLOAD|XLOCK;
 190:     xp->x_count = 1;
 191:     xp->x_ccount = 0;
 192:     xp->x_iptr = ip;
 193:     ip->i_flag |= ITEXT;
 194:     ip->i_count++;
 195: #ifdef MENLO_OVLY
 196:     ts = btoc(u.u_exdata.ux_tsize);
 197:     if (u.u_ovdata.uo_ovbase)
 198:         xp->x_size = u.u_ovdata.uo_ov_offst[NOVL];
 199:     else
 200:         xp->x_size = ts;
 201:     if((xp->x_daddr = malloc(swapmap, (int)ctod(xp->x_size))) == NULL)
 202: #else
 203:     ts = btoc(u.u_exdata.ux_tsize);
 204:     xp->x_size = ts;
 205:     if((xp->x_daddr = malloc(swapmap, (int)ctod(ts))) == NULL)
 206: #endif
 207:         panic("out of swap space");
 208:     u.u_procp->p_textp = xp;
 209:     xexpand(xp);
 210:     estabur(ts, (unsigned)0, (unsigned)0, 0, RW);
 211:     u.u_count = u.u_exdata.ux_tsize;
 212:     u.u_offset = sizeof(u.u_exdata);
 213: #ifdef MENLO_OVLY
 214:     if (u.u_ovdata.uo_ovbase)
 215:         u.u_offset += (1 + NOVL) * sizeof(unsigned);
 216: #endif
 217:     u.u_base = 0;
 218:     u.u_segflg = 2;
 219:     u.u_procp->p_flag |= SLOCK;
 220:     readi(ip);
 221: #ifdef MENLO_OVLY
 222:     /* read in overlays if necessary */
 223: 
 224:     if (u.u_ovdata.uo_ovbase) {
 225:         register i;
 226:         for (i = 1; i < 1 + NOVL; i++) {
 227:             u.u_ovdata.uo_curov = i;
 228:             u.u_count = ctob(u.u_ovdata.uo_ov_offst[i]
 229:                   - u.u_ovdata.uo_ov_offst[i-1]);
 230:             u.u_base = ctob(stoc(u.u_ovdata.uo_ovbase));
 231:             if( u.u_count != 0) {
 232:                 choverlay(RW);
 233:                 readi(ip);
 234:             }
 235:         }
 236:     }
 237:     u.u_ovdata.uo_curov = 0;
 238: #endif
 239:     u.u_procp->p_flag &= ~SLOCK;
 240:     u.u_segflg = 0;
 241:     xp->x_flag = XWRIT;
 242: }
 243: 
 244: /*
 245:  * Assure core for text segment
 246:  * Text must be locked to keep someone else from
 247:  * freeing it in the meantime.
 248:  * x_ccount must be 0.
 249:  */
 250: xexpand(xp)
 251: register struct text *xp;
 252: {
 253:     if ((xp->x_caddr = malloc(coremap, xp->x_size)) != NULL) {
 254:         if ((xp->x_flag&XLOAD) == 0)
 255:             swap(xp->x_daddr, xp->x_caddr, xp->x_size, B_READ);
 256:         xp->x_ccount++;
 257:         xunlock(xp);
 258:         return;
 259:     }
 260:     if (save(u.u_ssav)) {
 261:         sureg();
 262:         return;
 263:     }
 264: #ifdef  VIRUS_VFORK
 265:     (void) xswap(u.u_procp, X_FREECORE, X_OLDSIZE, X_OLDSIZE);
 266: #else
 267:     (void) xswap(u.u_procp, X_FREECORE, X_OLDSIZE);
 268: #endif
 269:     xunlock(xp);
 270:     u.u_procp->p_flag |= SSWAP;
 271: #ifdef  MENLO_JCL
 272:     swtch();
 273: #else
 274:     qswtch();
 275: #endif
 276:     /* NOTREACHED */
 277: }
 278: 
 279: /*
 280:  * Lock and unlock a text segment from swapping
 281:  */
 282: xlock(xp)
 283: register struct text *xp;
 284: {
 285: 
 286:     while(xp->x_flag&XLOCK) {
 287:         xp->x_flag |= XWANT;
 288:         sleep((caddr_t)xp, PSWP);
 289:     }
 290:     xp->x_flag |= XLOCK;
 291: }
 292: 
 293: xunlock(xp)
 294: register struct text *xp;
 295: {
 296: 
 297:     if (xp->x_flag&XWANT)
 298:         wakeup((caddr_t)xp);
 299:     xp->x_flag &= ~(XLOCK|XWANT);
 300: }
 301: 
 302: /*
 303:  * Decrement the in-core usage count of a shared text segment.
 304:  * When it drops to zero, free the core space.
 305:  */
 306: xccdec(xp)
 307: register struct text *xp;
 308: {
 309: 
 310:     if (xp == NULL || xp->x_ccount == 0)
 311:         return;
 312:     xlock(xp);
 313:     if (--xp->x_ccount == 0) {
 314:         if (xp->x_flag&XWRIT) {
 315:             swap(xp->x_daddr, xp->x_caddr, xp->x_size, B_WRITE);
 316:             xp->x_flag &= ~XWRIT;
 317:         }
 318:         mfree(coremap, xp->x_size, xp->x_caddr);
 319:     }
 320:     xunlock(xp);
 321: }
 322: 
 323: /*
 324:  * Free the swap image of all unused saved-text text segments
 325:  * which are from device dev (used by umount system call).
 326:  * Free all unused text segments if dev == NODEV (from malloc).
 327:  */
 328: xumount(dev)
 329: register dev_t dev;
 330: {
 331:     register struct text *xp;
 332: 
 333:     for (xp = text; xp < textNTEXT; xp++)
 334:         if (xp->x_iptr!=NULL && (dev==xp->x_iptr->i_dev || dev==NODEV))
 335:             xuntext(xp);
 336: }
 337: 
 338: /*
 339:  * remove a shared text segment from the text table, if possible.
 340:  */
 341: xrele(ip)
 342: register struct inode *ip;
 343: {
 344:     register struct text *xp;
 345: 
 346:     if ((ip->i_flag&ITEXT) == 0)
 347:         return;
 348:     for (xp = text; xp < textNTEXT; xp++)
 349:         if (ip == xp->x_iptr)
 350:             xuntext(xp);
 351: }
 352: 
 353: /*
 354:  * remove text image from the text table.
 355:  * the use count must be zero.
 356:  */
 357: xuntext(xp)
 358: register struct text *xp;
 359: {
 360:     register struct inode *ip;
 361: 
 362:     xlock(xp);
 363:     if (xp->x_count) {
 364:         xunlock(xp);
 365:         return;
 366:     }
 367:     ip = xp->x_iptr;
 368:     xp->x_flag &= ~XLOCK;
 369:     xp->x_iptr = NULL;
 370:     mfree(swapmap, ctod(xp->x_size), xp->x_daddr);
 371:     ip->i_flag &= ~ITEXT;
 372:     if (ip->i_flag&ILOCK)
 373:         ip->i_count--;
 374:     else
 375:         iput(ip);
 376: }

Defined functions

xalloc defined in line 145; used 2 times
xccdec defined in line 306; used 3 times
xexpand defined in line 250; used 2 times
xfree defined in line 104; used 5 times
xlock defined in line 282; used 7 times
xrele defined in line 341; used 3 times
xswap defined in line 36; used 9 times
xumount defined in line 328; used 3 times
xunlock defined in line 293; used 12 times
xuntext defined in line 357; used 2 times
Last modified: 1983-08-30
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1266
Valid CSS Valid XHTML 1.0 Strict