diff options
-rw-r--r-- | sys/uvm/uvm_amap.c | 28 |
1 files changed, 16 insertions, 12 deletions
diff --git a/sys/uvm/uvm_amap.c b/sys/uvm/uvm_amap.c index 0b38ac13faf..de6bea7db3e 100644 --- a/sys/uvm/uvm_amap.c +++ b/sys/uvm/uvm_amap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_amap.c,v 1.22 2002/02/12 18:36:53 provos Exp $ */ +/* $OpenBSD: uvm_amap.c,v 1.23 2002/02/19 17:57:34 provos Exp $ */ /* $NetBSD: uvm_amap.c,v 1.27 2000/11/25 06:27:59 chs Exp $ */ /* @@ -933,19 +933,16 @@ amap_pp_adjref(amap, curslot, slotlen, adjval) vsize_t slotlen; int adjval; { - int stopslot, *ppref, lcv; - int ref, len; - - /* - * get init values - */ + int stopslot, *ppref, lcv, prevlcv; + int ref, len, prevref, prevlen; stopslot = curslot + slotlen; ppref = amap->am_ppref; + prevlcv = -1; /* - * first advance to the correct place in the ppref array, fragment - * if needed. + * first advance to the correct place in the ppref array, + * fragment if needed. */ for (lcv = 0 ; lcv < curslot ; lcv += len) { @@ -955,10 +952,13 @@ amap_pp_adjref(amap, curslot, slotlen, adjval) pp_setreflen(ppref, curslot, ref, len - (curslot -lcv)); len = curslot - lcv; /* new length of entry @ lcv */ } + prevlcv = lcv; } + pp_getreflen(ppref, prevlcv, &prevref, &prevlen); /* - * now adjust reference counts in range (make sure we dont overshoot) + * now adjust reference counts in range. merge the first + * changed entry with the last unchanged entry if possible. */ if (lcv != curslot) @@ -972,10 +972,14 @@ amap_pp_adjref(amap, curslot, slotlen, adjval) len - (stopslot - lcv)); len = stopslot - lcv; } - ref = ref + adjval; /* ADJUST! */ + ref += adjval; if (ref < 0) panic("amap_pp_adjref: negative reference count"); - pp_setreflen(ppref, lcv, ref, len); + if (lcv == prevlcv + prevlen && ref == prevref) { + pp_setreflen(ppref, prevlcv, ref, prevlen + len); + } else { + pp_setreflen(ppref, lcv, ref, len); + } if (ref == 0) amap_wiperange(amap, lcv, len); } |