13e12c5d1SDavid du Colombier #include "u.h"
23e12c5d1SDavid du Colombier #include "../port/lib.h"
33e12c5d1SDavid du Colombier #include "mem.h"
43e12c5d1SDavid du Colombier #include "dat.h"
53e12c5d1SDavid du Colombier #include "fns.h"
63e12c5d1SDavid du Colombier #include "../port/error.h"
73e12c5d1SDavid du Colombier
87dd7cddfSDavid du Colombier static int canflush(Proc*, Segment*);
97dd7cddfSDavid du Colombier static void executeio(void);
107dd7cddfSDavid du Colombier static int needpages(void*);
117dd7cddfSDavid du Colombier static void pageout(Proc*, Segment*);
127dd7cddfSDavid du Colombier static void pagepte(int, Page**);
137dd7cddfSDavid du Colombier static void pager(void*);
143e12c5d1SDavid du Colombier
153e12c5d1SDavid du Colombier Image swapimage;
16*d1be6b08SDavid du Colombier
173e12c5d1SDavid du Colombier static int swopen;
18bd389b36SDavid du Colombier static Page **iolist;
193e12c5d1SDavid du Colombier static int ioptr;
203e12c5d1SDavid du Colombier
21*d1be6b08SDavid du Colombier static ulong genage, genclock, gencount;
22*d1be6b08SDavid du Colombier static uvlong gensum;
23*d1be6b08SDavid du Colombier
24*d1be6b08SDavid du Colombier static void
gentick(void)25*d1be6b08SDavid du Colombier gentick(void)
26*d1be6b08SDavid du Colombier {
27*d1be6b08SDavid du Colombier genclock++;
28*d1be6b08SDavid du Colombier if(gencount)
29*d1be6b08SDavid du Colombier genage = gensum / gencount;
30*d1be6b08SDavid du Colombier else
31*d1be6b08SDavid du Colombier genage = 0;
32*d1be6b08SDavid du Colombier gensum = gencount = 0;
33*d1be6b08SDavid du Colombier }
34*d1be6b08SDavid du Colombier
353e12c5d1SDavid du Colombier void
swapinit(void)363e12c5d1SDavid du Colombier swapinit(void)
373e12c5d1SDavid du Colombier {
383e12c5d1SDavid du Colombier swapalloc.swmap = xalloc(conf.nswap);
393e12c5d1SDavid du Colombier swapalloc.top = &swapalloc.swmap[conf.nswap];
403e12c5d1SDavid du Colombier swapalloc.alloc = swapalloc.swmap;
413e12c5d1SDavid du Colombier swapalloc.last = swapalloc.swmap;
423e12c5d1SDavid du Colombier swapalloc.free = conf.nswap;
437dd7cddfSDavid du Colombier iolist = xalloc(conf.nswppo*sizeof(Page*));
44bd389b36SDavid du Colombier if(swapalloc.swmap == 0 || iolist == 0)
45bd389b36SDavid du Colombier panic("swapinit: not enough memory");
467dd7cddfSDavid du Colombier
477dd7cddfSDavid du Colombier swapimage.notext = 1;
483e12c5d1SDavid du Colombier }
493e12c5d1SDavid du Colombier
503e12c5d1SDavid du Colombier ulong
newswap(void)513e12c5d1SDavid du Colombier newswap(void)
523e12c5d1SDavid du Colombier {
533e12c5d1SDavid du Colombier uchar *look;
543e12c5d1SDavid du Colombier
553e12c5d1SDavid du Colombier lock(&swapalloc);
567dd7cddfSDavid du Colombier
577dd7cddfSDavid du Colombier if(swapalloc.free == 0){
587dd7cddfSDavid du Colombier unlock(&swapalloc);
597dd7cddfSDavid du Colombier return ~0;
607dd7cddfSDavid du Colombier }
613e12c5d1SDavid du Colombier
623e12c5d1SDavid du Colombier look = memchr(swapalloc.last, 0, swapalloc.top-swapalloc.last);
633e12c5d1SDavid du Colombier if(look == 0)
643e12c5d1SDavid du Colombier panic("inconsistent swap");
653e12c5d1SDavid du Colombier
663e12c5d1SDavid du Colombier *look = 1;
673e12c5d1SDavid du Colombier swapalloc.last = look;
683e12c5d1SDavid du Colombier swapalloc.free--;
693e12c5d1SDavid du Colombier unlock(&swapalloc);
703e12c5d1SDavid du Colombier return (look-swapalloc.swmap) * BY2PG;
713e12c5d1SDavid du Colombier }
723e12c5d1SDavid du Colombier
733e12c5d1SDavid du Colombier void
putswap(Page * p)743e12c5d1SDavid du Colombier putswap(Page *p)
753e12c5d1SDavid du Colombier {
763e12c5d1SDavid du Colombier uchar *idx;
773e12c5d1SDavid du Colombier
783e12c5d1SDavid du Colombier lock(&swapalloc);
793e12c5d1SDavid du Colombier idx = &swapalloc.swmap[((ulong)p)/BY2PG];
803e12c5d1SDavid du Colombier if(--(*idx) == 0) {
813e12c5d1SDavid du Colombier swapalloc.free++;
823e12c5d1SDavid du Colombier if(idx < swapalloc.last)
833e12c5d1SDavid du Colombier swapalloc.last = idx;
843e12c5d1SDavid du Colombier }
857dd7cddfSDavid du Colombier if(*idx >= 254)
86c9b6d007SDavid du Colombier panic("putswap %#p == %ud", p, *idx);
873e12c5d1SDavid du Colombier unlock(&swapalloc);
883e12c5d1SDavid du Colombier }
893e12c5d1SDavid du Colombier
903e12c5d1SDavid du Colombier void
dupswap(Page * p)913e12c5d1SDavid du Colombier dupswap(Page *p)
923e12c5d1SDavid du Colombier {
933e12c5d1SDavid du Colombier lock(&swapalloc);
947dd7cddfSDavid du Colombier if(++swapalloc.swmap[((ulong)p)/BY2PG] == 0)
957dd7cddfSDavid du Colombier panic("dupswap");
963e12c5d1SDavid du Colombier unlock(&swapalloc);
973e12c5d1SDavid du Colombier }
983e12c5d1SDavid du Colombier
997dd7cddfSDavid du Colombier int
swapcount(ulong daddr)1007dd7cddfSDavid du Colombier swapcount(ulong daddr)
1017dd7cddfSDavid du Colombier {
1027dd7cddfSDavid du Colombier return swapalloc.swmap[daddr/BY2PG];
1037dd7cddfSDavid du Colombier }
1047dd7cddfSDavid du Colombier
1053e12c5d1SDavid du Colombier void
kickpager(void)1063e12c5d1SDavid du Colombier kickpager(void)
1073e12c5d1SDavid du Colombier {
1083e12c5d1SDavid du Colombier static int started;
1093e12c5d1SDavid du Colombier
1103e12c5d1SDavid du Colombier if(started)
1113e12c5d1SDavid du Colombier wakeup(&swapalloc.r);
1123e12c5d1SDavid du Colombier else {
1133e12c5d1SDavid du Colombier kproc("pager", pager, 0);
1143e12c5d1SDavid du Colombier started = 1;
1153e12c5d1SDavid du Colombier }
1163e12c5d1SDavid du Colombier }
1173e12c5d1SDavid du Colombier
1187dd7cddfSDavid du Colombier static void
pager(void * junk)1193e12c5d1SDavid du Colombier pager(void *junk)
1203e12c5d1SDavid du Colombier {
1213e12c5d1SDavid du Colombier int i;
1227dd7cddfSDavid du Colombier Segment *s;
123219b2ee8SDavid du Colombier Proc *p, *ep;
1243e12c5d1SDavid du Colombier
1253e12c5d1SDavid du Colombier if(waserror())
126c9b6d007SDavid du Colombier panic("pager: os error");
1273e12c5d1SDavid du Colombier
1283e12c5d1SDavid du Colombier p = proctab(0);
1293e12c5d1SDavid du Colombier ep = &p[conf.nproc];
1303e12c5d1SDavid du Colombier
1313e12c5d1SDavid du Colombier loop:
1327dd7cddfSDavid du Colombier up->psstate = "Idle";
133*d1be6b08SDavid du Colombier wakeup(&palloc.r);
1343e12c5d1SDavid du Colombier sleep(&swapalloc.r, needpages, 0);
1353e12c5d1SDavid du Colombier
136219b2ee8SDavid du Colombier while(needpages(junk)) {
1377dd7cddfSDavid du Colombier if(swapimage.c) {
1383e12c5d1SDavid du Colombier p++;
139*d1be6b08SDavid du Colombier if(p >= ep){
1403e12c5d1SDavid du Colombier p = proctab(0);
141*d1be6b08SDavid du Colombier gentick();
142*d1be6b08SDavid du Colombier }
1433e12c5d1SDavid du Colombier
144b7b24591SDavid du Colombier if(p->state == Dead || p->noswap)
1453e12c5d1SDavid du Colombier continue;
1463e12c5d1SDavid du Colombier
1477dd7cddfSDavid du Colombier if(!canqlock(&p->seglock))
1487dd7cddfSDavid du Colombier continue; /* process changing its segments */
149219b2ee8SDavid du Colombier
1503e12c5d1SDavid du Colombier for(i = 0; i < NSEG; i++) {
1517dd7cddfSDavid du Colombier if(!needpages(junk)){
1527dd7cddfSDavid du Colombier qunlock(&p->seglock);
1533e12c5d1SDavid du Colombier goto loop;
1547dd7cddfSDavid du Colombier }
1553e12c5d1SDavid du Colombier
1563e12c5d1SDavid du Colombier if(s = p->seg[i]) {
1573e12c5d1SDavid du Colombier switch(s->type&SG_TYPE) {
1583e12c5d1SDavid du Colombier default:
1593e12c5d1SDavid du Colombier break;
1603e12c5d1SDavid du Colombier case SG_TEXT:
1613e12c5d1SDavid du Colombier pageout(p, s);
1623e12c5d1SDavid du Colombier break;
1633e12c5d1SDavid du Colombier case SG_DATA:
1643e12c5d1SDavid du Colombier case SG_BSS:
1653e12c5d1SDavid du Colombier case SG_STACK:
1663e12c5d1SDavid du Colombier case SG_SHARED:
1677dd7cddfSDavid du Colombier up->psstate = "Pageout";
1683e12c5d1SDavid du Colombier pageout(p, s);
1693e12c5d1SDavid du Colombier if(ioptr != 0) {
1707dd7cddfSDavid du Colombier up->psstate = "I/O";
1713e12c5d1SDavid du Colombier executeio();
1723e12c5d1SDavid du Colombier }
1737dd7cddfSDavid du Colombier break;
1743e12c5d1SDavid du Colombier }
1753e12c5d1SDavid du Colombier }
1763e12c5d1SDavid du Colombier }
1777dd7cddfSDavid du Colombier qunlock(&p->seglock);
178*d1be6b08SDavid du Colombier } else {
179*d1be6b08SDavid du Colombier print("out of memory\n");
180cd42b314SDavid du Colombier killbig("out of memory");
181*d1be6b08SDavid du Colombier freebroken(); /* can use the memory */
1823e12c5d1SDavid du Colombier
1833e12c5d1SDavid du Colombier /* Emulate the old system if no swap channel */
184*d1be6b08SDavid du Colombier if(!swapimage.c)
185dc5a79c1SDavid du Colombier tsleep(&up->sleep, return0, 0, 5000);
1863e12c5d1SDavid du Colombier }
1873e12c5d1SDavid du Colombier }
1883e12c5d1SDavid du Colombier goto loop;
1893e12c5d1SDavid du Colombier }
1903e12c5d1SDavid du Colombier
1917dd7cddfSDavid du Colombier static void
pageout(Proc * p,Segment * s)1923e12c5d1SDavid du Colombier pageout(Proc *p, Segment *s)
1933e12c5d1SDavid du Colombier {
1947dd7cddfSDavid du Colombier int type, i, size;
195*d1be6b08SDavid du Colombier ulong age;
1963e12c5d1SDavid du Colombier Pte *l;
1973e12c5d1SDavid du Colombier Page **pg, *entry;
1983e12c5d1SDavid du Colombier
1993e12c5d1SDavid du Colombier if(!canqlock(&s->lk)) /* We cannot afford to wait, we will surely deadlock */
2003e12c5d1SDavid du Colombier return;
2013e12c5d1SDavid du Colombier
2023e12c5d1SDavid du Colombier if(s->steal) { /* Protected by /dev/proc */
2033e12c5d1SDavid du Colombier qunlock(&s->lk);
2043e12c5d1SDavid du Colombier return;
2053e12c5d1SDavid du Colombier }
2063e12c5d1SDavid du Colombier
2073e12c5d1SDavid du Colombier if(!canflush(p, s)) { /* Able to invalidate all tlbs with references */
2083e12c5d1SDavid du Colombier qunlock(&s->lk);
2093e12c5d1SDavid du Colombier putseg(s);
2103e12c5d1SDavid du Colombier return;
2113e12c5d1SDavid du Colombier }
2123e12c5d1SDavid du Colombier
2133e12c5d1SDavid du Colombier if(waserror()) {
2143e12c5d1SDavid du Colombier qunlock(&s->lk);
2153e12c5d1SDavid du Colombier putseg(s);
2163e12c5d1SDavid du Colombier return;
2173e12c5d1SDavid du Colombier }
2183e12c5d1SDavid du Colombier
2193e12c5d1SDavid du Colombier /* Pass through the pte tables looking for memory pages to swap out */
2203e12c5d1SDavid du Colombier type = s->type&SG_TYPE;
2217dd7cddfSDavid du Colombier size = s->mapsize;
2227dd7cddfSDavid du Colombier for(i = 0; i < size; i++) {
2233e12c5d1SDavid du Colombier l = s->map[i];
2243e12c5d1SDavid du Colombier if(l == 0)
2253e12c5d1SDavid du Colombier continue;
2263e12c5d1SDavid du Colombier for(pg = l->first; pg < l->last; pg++) {
2273e12c5d1SDavid du Colombier entry = *pg;
2283e12c5d1SDavid du Colombier if(pagedout(entry))
2293e12c5d1SDavid du Colombier continue;
2303e12c5d1SDavid du Colombier
2313e12c5d1SDavid du Colombier if(entry->modref & PG_REF) {
2323e12c5d1SDavid du Colombier entry->modref &= ~PG_REF;
233*d1be6b08SDavid du Colombier entry->gen = genclock;
2343e12c5d1SDavid du Colombier }
2353e12c5d1SDavid du Colombier
236*d1be6b08SDavid du Colombier if(genclock < entry->gen)
237*d1be6b08SDavid du Colombier age = ~(entry->gen - genclock);
238*d1be6b08SDavid du Colombier else
239*d1be6b08SDavid du Colombier age = genclock - entry->gen;
240*d1be6b08SDavid du Colombier gensum += age;
241*d1be6b08SDavid du Colombier gencount++;
242*d1be6b08SDavid du Colombier if(age <= genage)
243*d1be6b08SDavid du Colombier continue;
244*d1be6b08SDavid du Colombier
2453e12c5d1SDavid du Colombier pagepte(type, pg);
2463e12c5d1SDavid du Colombier
2477dd7cddfSDavid du Colombier if(ioptr >= conf.nswppo)
2483e12c5d1SDavid du Colombier goto out;
2493e12c5d1SDavid du Colombier }
2503e12c5d1SDavid du Colombier }
2513e12c5d1SDavid du Colombier out:
2523e12c5d1SDavid du Colombier poperror();
2533e12c5d1SDavid du Colombier qunlock(&s->lk);
2543e12c5d1SDavid du Colombier putseg(s);
2553e12c5d1SDavid du Colombier }
2563e12c5d1SDavid du Colombier
2577dd7cddfSDavid du Colombier static int
canflush(Proc * p,Segment * s)2583e12c5d1SDavid du Colombier canflush(Proc *p, Segment *s)
2593e12c5d1SDavid du Colombier {
2603e12c5d1SDavid du Colombier int i;
2613e12c5d1SDavid du Colombier Proc *ep;
2623e12c5d1SDavid du Colombier
2633e12c5d1SDavid du Colombier lock(s);
2643e12c5d1SDavid du Colombier if(s->ref == 1) { /* Easy if we are the only user */
2653e12c5d1SDavid du Colombier s->ref++;
2663e12c5d1SDavid du Colombier unlock(s);
2673e12c5d1SDavid du Colombier return canpage(p);
2683e12c5d1SDavid du Colombier }
2693e12c5d1SDavid du Colombier s->ref++;
2703e12c5d1SDavid du Colombier unlock(s);
2713e12c5d1SDavid du Colombier
2723e12c5d1SDavid du Colombier /* Now we must do hardwork to ensure all processes which have tlb
2737dd7cddfSDavid du Colombier * entries for this segment will be flushed if we succeed in paging it out
2743e12c5d1SDavid du Colombier */
2753e12c5d1SDavid du Colombier p = proctab(0);
2763e12c5d1SDavid du Colombier ep = &p[conf.nproc];
2773e12c5d1SDavid du Colombier while(p < ep) {
2783e12c5d1SDavid du Colombier if(p->state != Dead) {
2793e12c5d1SDavid du Colombier for(i = 0; i < NSEG; i++)
2803e12c5d1SDavid du Colombier if(p->seg[i] == s)
2813e12c5d1SDavid du Colombier if(!canpage(p))
2823e12c5d1SDavid du Colombier return 0;
2833e12c5d1SDavid du Colombier }
2843e12c5d1SDavid du Colombier p++;
2853e12c5d1SDavid du Colombier }
2863e12c5d1SDavid du Colombier return 1;
2873e12c5d1SDavid du Colombier }
2883e12c5d1SDavid du Colombier
2897dd7cddfSDavid du Colombier static void
pagepte(int type,Page ** pg)2903e12c5d1SDavid du Colombier pagepte(int type, Page **pg)
2913e12c5d1SDavid du Colombier {
2923e12c5d1SDavid du Colombier ulong daddr;
2933e12c5d1SDavid du Colombier Page *outp;
2943e12c5d1SDavid du Colombier
2953e12c5d1SDavid du Colombier outp = *pg;
2963e12c5d1SDavid du Colombier switch(type) {
2973e12c5d1SDavid du Colombier case SG_TEXT: /* Revert to demand load */
2983e12c5d1SDavid du Colombier putpage(outp);
2993e12c5d1SDavid du Colombier *pg = 0;
3003e12c5d1SDavid du Colombier break;
3013e12c5d1SDavid du Colombier
3023e12c5d1SDavid du Colombier case SG_DATA:
3033e12c5d1SDavid du Colombier case SG_BSS:
3043e12c5d1SDavid du Colombier case SG_STACK:
3053e12c5d1SDavid du Colombier case SG_SHARED:
3067dd7cddfSDavid du Colombier /*
3077dd7cddfSDavid du Colombier * get a new swap address and clear any pages
3087dd7cddfSDavid du Colombier * referring to it from the cache
3097dd7cddfSDavid du Colombier */
3103e12c5d1SDavid du Colombier daddr = newswap();
3117dd7cddfSDavid du Colombier if(daddr == ~0)
3127dd7cddfSDavid du Colombier break;
3133e12c5d1SDavid du Colombier cachedel(&swapimage, daddr);
3143e12c5d1SDavid du Colombier
3157dd7cddfSDavid du Colombier lock(outp);
3167dd7cddfSDavid du Colombier
3177dd7cddfSDavid du Colombier /* forget anything that it used to cache */
3187dd7cddfSDavid du Colombier uncachepage(outp);
3197dd7cddfSDavid du Colombier
3207dd7cddfSDavid du Colombier /*
3217dd7cddfSDavid du Colombier * incr the reference count to make sure it sticks around while
3227dd7cddfSDavid du Colombier * being written
3237dd7cddfSDavid du Colombier */
3247dd7cddfSDavid du Colombier outp->ref++;
3257dd7cddfSDavid du Colombier
3267dd7cddfSDavid du Colombier /*
3277dd7cddfSDavid du Colombier * enter it into the cache so that a fault happening
3287dd7cddfSDavid du Colombier * during the write will grab the page from the cache
3297dd7cddfSDavid du Colombier * rather than one partially written to the disk
3303e12c5d1SDavid du Colombier */
3313e12c5d1SDavid du Colombier outp->daddr = daddr;
3323e12c5d1SDavid du Colombier cachepage(outp, &swapimage);
3333e12c5d1SDavid du Colombier *pg = (Page*)(daddr|PG_ONSWAP);
3347dd7cddfSDavid du Colombier unlock(outp);
3353e12c5d1SDavid du Colombier
3367dd7cddfSDavid du Colombier /* Add page to IO transaction list */
3373e12c5d1SDavid du Colombier iolist[ioptr++] = outp;
3387dd7cddfSDavid du Colombier break;
3393e12c5d1SDavid du Colombier }
3403e12c5d1SDavid du Colombier }
3413e12c5d1SDavid du Colombier
3423e12c5d1SDavid du Colombier void
pagersummary(void)3437dd7cddfSDavid du Colombier pagersummary(void)
3447dd7cddfSDavid du Colombier {
3457dd7cddfSDavid du Colombier print("%lud/%lud memory %lud/%lud swap %d iolist\n",
3467dd7cddfSDavid du Colombier palloc.user-palloc.freecount,
3477dd7cddfSDavid du Colombier palloc.user, conf.nswap-swapalloc.free, conf.nswap,
3487dd7cddfSDavid du Colombier ioptr);
3497dd7cddfSDavid du Colombier }
3507dd7cddfSDavid du Colombier
351*d1be6b08SDavid du Colombier static int
pageiocomp(void * a,void * b)352*d1be6b08SDavid du Colombier pageiocomp(void *a, void *b)
353*d1be6b08SDavid du Colombier {
354*d1be6b08SDavid du Colombier Page *p1, *p2;
355*d1be6b08SDavid du Colombier
356*d1be6b08SDavid du Colombier p1 = *(Page **)a;
357*d1be6b08SDavid du Colombier p2 = *(Page **)b;
358*d1be6b08SDavid du Colombier if(p1->daddr > p2->daddr)
359*d1be6b08SDavid du Colombier return 1;
360*d1be6b08SDavid du Colombier else
361*d1be6b08SDavid du Colombier return -1;
362*d1be6b08SDavid du Colombier }
363*d1be6b08SDavid du Colombier
3647dd7cddfSDavid du Colombier static void
executeio(void)3653e12c5d1SDavid du Colombier executeio(void)
3663e12c5d1SDavid du Colombier {
3673e12c5d1SDavid du Colombier Page *out;
3683e12c5d1SDavid du Colombier int i, n;
3693e12c5d1SDavid du Colombier Chan *c;
3703e12c5d1SDavid du Colombier char *kaddr;
3713e12c5d1SDavid du Colombier KMap *k;
3723e12c5d1SDavid du Colombier
3733e12c5d1SDavid du Colombier c = swapimage.c;
374*d1be6b08SDavid du Colombier qsort(iolist, ioptr, sizeof iolist[0], pageiocomp);
3753e12c5d1SDavid du Colombier for(i = 0; i < ioptr; i++) {
3767dd7cddfSDavid du Colombier if(ioptr > conf.nswppo)
377c9b6d007SDavid du Colombier panic("executeio: ioptr %d > %d", ioptr, conf.nswppo);
3783e12c5d1SDavid du Colombier out = iolist[i];
3793e12c5d1SDavid du Colombier k = kmap(out);
3803e12c5d1SDavid du Colombier kaddr = (char*)VA(k);
3813e12c5d1SDavid du Colombier
3823e12c5d1SDavid du Colombier if(waserror())
3833e12c5d1SDavid du Colombier panic("executeio: page out I/O error");
3843e12c5d1SDavid du Colombier
3857dd7cddfSDavid du Colombier n = devtab[c->type]->write(c, kaddr, BY2PG, out->daddr);
3863e12c5d1SDavid du Colombier if(n != BY2PG)
3873e12c5d1SDavid du Colombier nexterror();
3883e12c5d1SDavid du Colombier
3893e12c5d1SDavid du Colombier kunmap(k);
3903e12c5d1SDavid du Colombier poperror();
3913e12c5d1SDavid du Colombier
3923e12c5d1SDavid du Colombier /* Free up the page after I/O */
3933e12c5d1SDavid du Colombier lock(out);
3943e12c5d1SDavid du Colombier out->ref--;
3953e12c5d1SDavid du Colombier unlock(out);
3963e12c5d1SDavid du Colombier putpage(out);
3973e12c5d1SDavid du Colombier }
3983e12c5d1SDavid du Colombier ioptr = 0;
3993e12c5d1SDavid du Colombier }
4003e12c5d1SDavid du Colombier
4017dd7cddfSDavid du Colombier static int
needpages(void *)4027dd7cddfSDavid du Colombier needpages(void*)
4033e12c5d1SDavid du Colombier {
4043e12c5d1SDavid du Colombier return palloc.freecount < swapalloc.headroom;
4053e12c5d1SDavid du Colombier }
4063e12c5d1SDavid du Colombier
4073e12c5d1SDavid du Colombier void
setswapchan(Chan * c)4083e12c5d1SDavid du Colombier setswapchan(Chan *c)
4093e12c5d1SDavid du Colombier {
4109a747e4fSDavid du Colombier uchar dirbuf[sizeof(Dir)+100];
4117dd7cddfSDavid du Colombier Dir d;
4129a747e4fSDavid du Colombier int n;
4137dd7cddfSDavid du Colombier
4143e12c5d1SDavid du Colombier if(swapimage.c) {
4157dd7cddfSDavid du Colombier if(swapalloc.free != conf.nswap){
4167dd7cddfSDavid du Colombier cclose(c);
4173e12c5d1SDavid du Colombier error(Einuse);
4183e12c5d1SDavid du Colombier }
4197dd7cddfSDavid du Colombier cclose(swapimage.c);
4207dd7cddfSDavid du Colombier }
4217dd7cddfSDavid du Colombier
4227dd7cddfSDavid du Colombier /*
4237dd7cddfSDavid du Colombier * if this isn't a file, set the swap space
4247dd7cddfSDavid du Colombier * to be at most the size of the partition
4257dd7cddfSDavid du Colombier */
4267dd7cddfSDavid du Colombier if(devtab[c->type]->dc != L'M'){
4279a747e4fSDavid du Colombier n = devtab[c->type]->stat(c, dirbuf, sizeof dirbuf);
4289a747e4fSDavid du Colombier if(n <= 0){
4299a747e4fSDavid du Colombier cclose(c);
4309a747e4fSDavid du Colombier error("stat failed in setswapchan");
4319a747e4fSDavid du Colombier }
4329a747e4fSDavid du Colombier convM2D(dirbuf, n, &d, nil);
4337dd7cddfSDavid du Colombier if(d.length < conf.nswap*BY2PG){
4347dd7cddfSDavid du Colombier conf.nswap = d.length/BY2PG;
4357dd7cddfSDavid du Colombier swapalloc.top = &swapalloc.swmap[conf.nswap];
4367dd7cddfSDavid du Colombier swapalloc.free = conf.nswap;
4377dd7cddfSDavid du Colombier }
4387dd7cddfSDavid du Colombier }
4397dd7cddfSDavid du Colombier
4403e12c5d1SDavid du Colombier swapimage.c = c;
4413e12c5d1SDavid du Colombier }
4427dd7cddfSDavid du Colombier
4437dd7cddfSDavid du Colombier int
swapfull(void)4447dd7cddfSDavid du Colombier swapfull(void)
4457dd7cddfSDavid du Colombier {
4467dd7cddfSDavid du Colombier return swapalloc.free < conf.nswap/10;
4477dd7cddfSDavid du Colombier }
448