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