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