ref: 9073565b4482a85a72d82508adb76496975734d6
parent: 72614a53c48950b8100c4fbe5b693fac53e912e5
author: 9ferno <[email protected]>
date: Sun Oct 23 00:54:27 EDT 2022
stopped searching through the whole linked list to find an Iobuf to steal try to use the oldest Iobuf and if that is not good enough, use a new Iobuf.
--- a/iobuf.c
+++ b/iobuf.c
@@ -31,6 +31,21 @@
return p;
}
+Iobuf *
+changelru(Iobuf *lru, Iobuf *p)
+{
+ /* remove p from its current position in the lru circular buffer */
+ p->back->fore = p->fore;
+ p->fore->back = p->back;
+
+ /* make p the hb->link and put it at the back of existing link */
+ p->fore = lru;
+ p->back = lru->back;
+ lru->back = p;
+ p->back->fore = p;
+ return p;
+}
+
/*
Get the Iobuf of the disk block at addr from the buffer cache
for my use.
@@ -51,7 +66,7 @@
getbuf(u64 blkno, u8 readonly, u8 freshalloc)
{
Hiob *hp;
- Iobuf *s, *p;
+ Iobuf *s, *p, *steal;
s8 ncollisions;
hp = &hiob[blkno%nbuckets];
@@ -61,6 +76,7 @@
" hiob 0x%p hp 0x%p readonly %d\n",
blkno, blkno%nbuckets, getcallerpc(&blkno),
hiob, hp, readonly);
+ steal = nil;
qlock(hp);
s = hp->link;
if(s == nil)
@@ -69,16 +85,7 @@
ncollisions++;
if(p->blkno == blkno){
if(p != s){
- /* remove p from its current position in the lru circular buffer */
- p->back->fore = p->fore;
- p->fore->back = p->back;
-
- /* make p the hb->link and put it at the back of existing link */
- p->fore = s;
- p->back = s->back;
- s->back = p;
- p->back->fore = p;
- hp->link = p;
+ hp->link = changelru(s, p);
}
incref(p);
qunlock(hp);
@@ -98,6 +105,9 @@
decref(p);
return p;
}
+ if(p->readers == 0 && p->writer == 0 &&
+ p->ref == 0 && p->dirties == 0)
+ steal = p;
p = p->fore;
if(p == s)
break;
@@ -104,26 +114,24 @@
}
/* maxed out our allowed number of collisions,
- try to steal an older Iobuf without any ref's.
+ try to steal the oldest Iobuf without any ref's.
Ncollisions is a soft limit.
*/
- if(ncollisions >= Ncollisions){
-Another:
- do{
- p = s->back;
- if(p->ref == 0 && p->dirties == 0 && canwlock(p)){
- if(p->dirties > 0){
- wunlock(p);
- goto Another;
- }
- hp->link = p;
- if(chatty9p > 4)
- dprint(" stealing iobuf 0x%p for blkno %llud\n",
- p, blkno);
- goto found; /* p is wlock() */
- }
- s = p;
- }while(p != hp->link);
+ if(ncollisions >= Ncollisions &&
+ steal != nil && canwlock(steal)){
+ if(steal->readers == 0 && steal->writer == 0 &&
+ steal->ref == 0 && steal->dirties == 0){
+ hp->link = p = changelru(s, steal);
+ if(chatty9p > 4)
+ dprint(" stealing iobuf 0x%p for blkno %llud\n",
+ p, blkno);
+ goto found; /* p is wlock() */
+ } else
+ /* cannot use steal, just use a new buffer
+ instead of seearching through the linked list
+ to find another unused Iobuf.
+ */
+ wunlock(steal);
}
/* no unlocked blocks available; add a new one */