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