diff options
| -rw-r--r-- | sys/src/9/port/portdat.h | 1 | ||||
| -rw-r--r-- | sys/src/9/port/swap.c | 46 |
2 files changed, 37 insertions, 10 deletions
diff --git a/sys/src/9/port/portdat.h b/sys/src/9/port/portdat.h index ce3470e74..92e5af666 100644 --- a/sys/src/9/port/portdat.h +++ b/sys/src/9/port/portdat.h @@ -338,6 +338,7 @@ struct Swapalloc Rendez r; /* Pager kproc idle sleep */ ulong highwater; /* Pager start threshold */ ulong headroom; /* Space pager frees under highwater */ + ulong xref; /* Ref count for all map refs >= 255 */ }swapalloc; struct Image diff --git a/sys/src/9/port/swap.c b/sys/src/9/port/swap.c index 49bf67de9..5c1d449bb 100644 --- a/sys/src/9/port/swap.c +++ b/sys/src/9/port/swap.c @@ -40,6 +40,8 @@ swapinit(void) swapalloc.alloc = swapalloc.swmap; swapalloc.last = swapalloc.swmap; swapalloc.free = conf.nswap; + swapalloc.xref = 0; + iolist = xalloc(conf.nswppo*sizeof(Page*)); if(swapalloc.swmap == 0 || iolist == 0) panic("swapinit: not enough memory"); @@ -53,8 +55,7 @@ newswap(void) uchar *look; lock(&swapalloc); - - if(swapalloc.free == 0){ + if(swapalloc.free == 0) { unlock(&swapalloc); return ~0; } @@ -77,22 +78,46 @@ putswap(Page *p) lock(&swapalloc); idx = &swapalloc.swmap[((ulong)p)/BY2PG]; - if(--(*idx) == 0) { - swapalloc.free++; - if(idx < swapalloc.last) - swapalloc.last = idx; + if(*idx == 0) + panic("putswap %#p ref == 0", p); + + if(*idx == 255) { + if(swapalloc.xref == 0) + panic("putswap %#p xref == 0", p); + + if(--swapalloc.xref == 0) { + for(idx = swapalloc.swmap; idx < swapalloc.top; idx++) { + if(*idx == 255) { + *idx = 0; + swapalloc.free++; + if(idx < swapalloc.last) + swapalloc.last = idx; + } + } + } + } else { + if(--(*idx) == 0) { + swapalloc.free++; + if(idx < swapalloc.last) + swapalloc.last = idx; + } } - if(*idx >= 254) - panic("putswap %#p == %ud", p, *idx); unlock(&swapalloc); } void dupswap(Page *p) { + uchar *idx; + lock(&swapalloc); - if(++swapalloc.swmap[((ulong)p)/BY2PG] == 0) - panic("dupswap"); + idx = &swapalloc.swmap[((ulong)p)/BY2PG]; + if(*idx == 255) + swapalloc.xref++; + else { + if(++(*idx) == 255) + swapalloc.xref += 255; + } unlock(&swapalloc); } @@ -413,6 +438,7 @@ setswapchan(Chan *c) error(Einuse); } cclose(swapimage.c); + swapimage.c = nil; } /* |
