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