|
|
1.1 ! root 1: #include "sys/param.h" ! 2: #include "sys/systm.h" ! 3: #include "sys/user.h" ! 4: #include "sys/proc.h" ! 5: #include "sys/text.h" ! 6: #include "sys/inode.h" ! 7: #include "sys/buf.h" ! 8: #include "sys/pte.h" ! 9: #include "sys/vm.h" ! 10: #include "sys/cmap.h" ! 11: ! 12: /* ! 13: * relinquish use of the shared text segment ! 14: * of a process. ! 15: */ ! 16: xfree() ! 17: { ! 18: register struct text *xp, *xp1; ! 19: register struct inode *ip; ! 20: ! 21: if((xp=u.u_procp->p_textp) == NULL) ! 22: return; ! 23: xlock(xp); ! 24: ip = xp->x_iptr; ! 25: if(--xp->x_count==0) { ! 26: xunlink(u.u_procp); ! 27: xp->x_rssize -= vmemfree(tptopte(u.u_procp, 0), u.u_tsize); ! 28: if (xp->x_rssize != 0) ! 29: panic("xfree rssize"); ! 30: for (xp1 = text; xp1 < textNTEXT; xp1++) ! 31: if (xp1->x_iptr == ip && xp1 != xp) ! 32: break; ! 33: if (xp1 >= textNTEXT) ! 34: ip->i_flag &= ~ITEXT; ! 35: if (ip->i_flag&ILOCK) ! 36: ip->i_count--; ! 37: else ! 38: iput(ip); ! 39: while (xp->x_poip) ! 40: sleep((caddr_t)&xp->x_poip, PSWP+1); ! 41: vsxfree(xp, xp->x_size); ! 42: xp->x_flag &= ~XLOCK; ! 43: xp->x_iptr = NULL; ! 44: } else { ! 45: xp->x_flag &= ~XLOCK; ! 46: xccdec(xp, u.u_procp); ! 47: } ! 48: u.u_procp->p_textp = NULL; ! 49: } ! 50: ! 51: /* ! 52: * Attach to a shared text segment. ! 53: * If there is no shared text, just return. ! 54: * If there is, hook up to it: ! 55: * if it is not currently being used, it has to be read ! 56: * in from the inode (ip); the written bit is set to force it ! 57: * to be written out as appropriate. ! 58: * If it is being used, but is not currently in core, ! 59: * a swap has to be done to get it back. ! 60: */ ! 61: xalloc(ip, pagi) ! 62: register struct inode *ip; ! 63: { ! 64: register struct text *xp; ! 65: register clicks_t ts; ! 66: register struct text *xp1; ! 67: register struct proc *p = u.u_procp; ! 68: ! 69: if(u.u_exdata.ux_tsize == 0) ! 70: return; ! 71: again: ! 72: xp1 = NULL; ! 73: for (xp = text; xp < textNTEXT; xp++) { ! 74: if(xp->x_iptr == NULL) { ! 75: if (xp1 == NULL) { ! 76: xp1 = xp; ! 77: if (PTRACED(p)) ! 78: break; ! 79: } ! 80: continue; ! 81: } ! 82: /* don't attach if proc is traced */ ! 83: if (PTRACED(p)) ! 84: continue; ! 85: if (xp->x_iptr==ip && (xp->x_flag&XTRC)==0 && xp->x_count!=0) { ! 86: if (xp->x_flag&XLOCK) { ! 87: xwait(xp); ! 88: goto again; ! 89: } ! 90: xlock(xp); ! 91: xp->x_count++; ! 92: p->p_textp = xp; ! 93: xlink(p); ! 94: xunlock(xp); ! 95: return; ! 96: } ! 97: } ! 98: if((xp=xp1) == NULL) { ! 99: tablefull("text"); ! 100: psignal(p, SIGKILL); ! 101: return; ! 102: } ! 103: xp->x_flag = XLOAD|XLOCK; ! 104: if (PTRACED(p)) ! 105: xp->x_flag |= XTRC; /* if proc is traced, so is text */ ! 106: if (pagi) ! 107: xp->x_flag |= XPAGI; ! 108: ts = clrnd(btoc(u.u_exdata.ux_tsize)); ! 109: xp->x_size = ts; ! 110: if (vsxalloc(xp) == NULL) { ! 111: swkill(p, "xalloc"); ! 112: return; ! 113: } ! 114: xp->x_count = 1; ! 115: xp->x_ccount = 0; ! 116: xp->x_rssize = 0; ! 117: xp->x_iptr = ip; ! 118: ip->i_flag |= ITEXT; ! 119: ip->i_count++; ! 120: p->p_textp = xp; ! 121: xlink(p); ! 122: if (pagi == 0) { ! 123: u.u_count = u.u_exdata.ux_tsize; ! 124: if(u.u_exdata.ux_mag == 0413) /* 0413 on 4k file sys */ ! 125: u.u_offset = ltoL(BSIZE(0)); ! 126: else ! 127: u.u_offset = ltoL(sizeof(u.u_exdata)); ! 128: u.u_base = 0; ! 129: u.u_segflg = SEGUINST; ! 130: settprot(1); ! 131: p->p_flag |= SKEEP; ! 132: readi(ip); ! 133: p->p_flag &= ~SKEEP; ! 134: } ! 135: settprot(0); ! 136: u.u_segflg = SEGUDATA; ! 137: xp->x_flag |= XWRIT; ! 138: xp->x_flag &= ~XLOAD; ! 139: xunlock(xp); ! 140: } ! 141: ! 142: /* ! 143: * Lock and unlock a text segment from swapping ! 144: */ ! 145: xlock(xp) ! 146: register struct text *xp; ! 147: { ! 148: ! 149: while(xp->x_flag&XLOCK) { ! 150: xp->x_flag |= XWANT; ! 151: sleep((caddr_t)xp, PSWP); ! 152: } ! 153: xp->x_flag |= XLOCK; ! 154: } ! 155: ! 156: /* ! 157: * Wait for xp to be unlocked if it is currently locked. ! 158: */ ! 159: xwait(xp) ! 160: register struct text *xp; ! 161: { ! 162: ! 163: xlock(xp); ! 164: xunlock(xp); ! 165: } ! 166: ! 167: xunlock(xp) ! 168: register struct text *xp; ! 169: { ! 170: ! 171: if (xp->x_flag&XWANT) ! 172: wakeup((caddr_t)xp); ! 173: xp->x_flag &= ~(XLOCK|XWANT); ! 174: } ! 175: ! 176: /* ! 177: * Decrement the in-core usage count of a shared text segment. ! 178: * When it drops to zero, free the core space. ! 179: */ ! 180: xccdec(xp, p) ! 181: register struct text *xp; ! 182: register struct proc *p; ! 183: { ! 184: ! 185: if (xp==NULL || xp->x_ccount==0) ! 186: return; ! 187: xlock(xp); ! 188: if (--xp->x_ccount == 0) { ! 189: if (xp->x_flag & XWRIT) { ! 190: vsswap(p, tptopte(p, 0), CTEXT, 0, xp->x_size, (struct dmap *)0); ! 191: if (xp->x_flag & XPAGI) ! 192: swap(p, xp->x_ptdaddr, (caddr_t)tptopte(p, 0), ! 193: xp->x_size * sizeof (struct pte), ! 194: B_WRITE, B_PAGET, swapdev, 0); ! 195: xp->x_flag &= ~XWRIT; ! 196: } else ! 197: xp->x_rssize -= vmemfree(tptopte(p, 0), xp->x_size); ! 198: if (xp->x_rssize != 0) ! 199: panic("text rssize"); ! 200: } ! 201: xunlink(p); ! 202: xunlock(xp); ! 203: } ! 204: ! 205: /* ! 206: * free the swap image of all unused saved-text text segments ! 207: * which are in the same filesystem as ip ! 208: * called when unmounting ! 209: */ ! 210: xumount(ip) ! 211: register struct inode *ip; ! 212: { ! 213: register struct text *xp; ! 214: ! 215: for (xp = text; xp < textNTEXT; xp++) ! 216: if (xp->x_iptr!=NULL && ip->i_mpoint==xp->x_iptr->i_mpoint) ! 217: xuntext(xp); ! 218: } ! 219: ! 220: /* ! 221: * remove a shared text segment from the text table, if possible. ! 222: */ ! 223: xrele(ip) ! 224: register struct inode *ip; ! 225: { ! 226: register struct text *xp; ! 227: ! 228: if ((ip->i_flag&ITEXT)==0) ! 229: return; ! 230: for (xp = text; xp < textNTEXT; xp++) ! 231: if (ip==xp->x_iptr) ! 232: xuntext(xp); ! 233: } ! 234: ! 235: /* ! 236: * remove text image from the text table. ! 237: * the use count must be zero. ! 238: */ ! 239: xuntext(xp) ! 240: register struct text *xp; ! 241: { ! 242: register struct inode *ip; ! 243: ! 244: xlock(xp); ! 245: if (xp->x_count) { ! 246: xunlock(xp); ! 247: return; ! 248: } ! 249: ip = xp->x_iptr; ! 250: xp->x_flag &= ~XLOCK; ! 251: xp->x_iptr = NULL; ! 252: vsxfree(xp, xp->x_size); ! 253: ip->i_flag &= ~ITEXT; ! 254: if (ip->i_flag&ILOCK) ! 255: ip->i_count--; ! 256: else ! 257: iput(ip); ! 258: } ! 259: ! 260: /* ! 261: * Add a process to those sharing a text segment by ! 262: * getting the page tables and then linking to x_caddr. ! 263: */ ! 264: xlink(p) ! 265: register struct proc *p; ! 266: { ! 267: register struct text *xp = p->p_textp; ! 268: ! 269: if (xp == 0) ! 270: return; ! 271: vinitpt(p); ! 272: p->p_xlink = xp->x_caddr; ! 273: xp->x_caddr = p; ! 274: xp->x_ccount++; ! 275: } ! 276: ! 277: xunlink(p) ! 278: register struct proc *p; ! 279: { ! 280: register struct text *xp = p->p_textp; ! 281: register struct proc *q; ! 282: ! 283: if (xp == 0) ! 284: return; ! 285: if (xp->x_caddr == p) { ! 286: xp->x_caddr = p->p_xlink; ! 287: p->p_xlink = 0; ! 288: return; ! 289: } ! 290: for (q = xp->x_caddr; q->p_xlink; q = q->p_xlink) ! 291: if (q->p_xlink == p) { ! 292: q->p_xlink = p->p_xlink; ! 293: p->p_xlink = 0; ! 294: return; ! 295: } ! 296: panic("lost text"); ! 297: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.