summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/uvm/uvm_amap.c28
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);
}