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