git: 9front

Download patch

ref: 3d8f7832675e77e1daea2bb7486a851a711ff500
parent: 5d9083dca82597b7692e1e0b7ff33ff6255a6568
author: cinap_lenrek <cinap_lenrek@gmx.de>
date: Sat Aug 3 13:37:20 EDT 2013

page: maintain a lru list and do unloading from oldest to newest

--- a/sys/src/cmd/page.c
+++ b/sys/src/cmd/page.c
@@ -22,6 +22,9 @@
 	Page	*next;
 	Page	*down;
 	Page	*tail;
+
+	Page	*lnext;
+	Page	*lprev;
 };
 
 int zoom = 1;
@@ -32,6 +35,7 @@
 int viewgen;
 Point resize, pos;
 Page *root, *current;
+Page lru;
 QLock pagelock;
 int nullfd;
 
@@ -137,10 +141,6 @@
 	p->open = popen;
 	p->fd = fd;
 
-	p->down = nil;
-	p->tail = nil;
-	p->next = nil;
-
 	qlock(&pagelock);
 	if(p->up = up){
 		if(up->tail == nil)
@@ -829,11 +829,30 @@
 	return Dy(i->r)*bytesperline(i->r, i->depth);
 }
 
+static void
+lunlink(Page *p)
+{
+	if(p->lnext == nil || p->lnext == p)
+		return;
+	p->lnext->lprev = p->lprev;
+	p->lprev->lnext = p->lnext;
+	p->lnext = nil;
+	p->lprev = nil;
+}
+
 void
 loadpage(Page *p)
 {
 	int fd;
 
+	qlock(&lru);
+	lunlink(p);
+	p->lnext = lru.lnext;
+	p->lprev = &lru;
+	p->lnext->lprev = p;
+	p->lprev->lnext = p;
+	qunlock(&lru);
+
 	if(p->open && p->image == nil){
 		fd = openpage(p);
 		if(fd >= 0){
@@ -854,6 +873,10 @@
 void
 unloadpage(Page *p)
 {
+	qlock(&lru);
+	lunlink(p);
+	qunlock(&lru);
+
 	if(p->open == nil || p->image == nil)
 		return;
 	lockdisplay(display);
@@ -868,7 +891,7 @@
 {
 	Page *p;
 
-	for(p = root->down; p && imemsize >= limit; p = nextpage(p)){
+	while(imemsize >= limit && (p = lru.lprev) != &lru){
 		qlock(p);
 		unloadpage(p);
 		qunlock(p);
@@ -1500,6 +1523,8 @@
 	memset(&m, 0, sizeof(m));
 	if((nullfd = open("/dev/null", ORDWR)) < 0)
 		sysfatal("open: %r");
+	lru.lprev = &lru;
+	lru.lnext = &lru;
 	current = root = addpage(nil, "", nil, nil, -1);
 	if(*argv == nil && !imode)
 		addpage(root, "stdin", popenfile, strdup("/fd/0"), -1);
--