|
|
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.