summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrtm <rtm>2006-08-12 22:34:13 +0000
committerrtm <rtm>2006-08-12 22:34:13 +0000
commitcd93074e5bed8fdbc84f2960c3219c7cf791b020 (patch)
tree1c08629ac66cb608ed03601ca0edce0170f71546
parent22bac2cb9d0b8050573a4b5c6cb5d8f460ee4167 (diff)
downloadxv6-labs-cd93074e5bed8fdbc84f2960c3219c7cf791b020.tar.gz
xv6-labs-cd93074e5bed8fdbc84f2960c3219c7cf791b020.tar.bz2
xv6-labs-cd93074e5bed8fdbc84f2960c3219c7cf791b020.zip
LRU disk cache replacement
-rw-r--r--Notes8
-rw-r--r--bio.c37
-rw-r--r--buf.h2
-rw-r--r--fs.c2
-rw-r--r--usertests.c14
5 files changed, 51 insertions, 12 deletions
diff --git a/Notes b/Notes
index e1d763d..7d8ac14 100644
--- a/Notes
+++ b/Notes
@@ -357,3 +357,11 @@ OH! recursive interrupts will use up any amount of cpu[].stack!
better buffer cache replacement
read/write of open file that's been unlinked
+disk scheduling
+mkdir
+more than one directory content block
+sh arguments
+sh redirection
+indirect blocks
+two bugs in unlink
+how come unlink xxx fails? iput problem?
diff --git a/bio.c b/bio.c
index 2db9694..e344343 100644
--- a/bio.c
+++ b/bio.c
@@ -10,27 +10,41 @@
struct buf buf[NBUF];
struct spinlock buf_table_lock;
+// linked list of all buffers, through prev/next.
+// bufhead->next is most recently used.
+// bufhead->tail is least recently used.
+struct buf bufhead;
+
void
binit(void)
{
+ struct buf *b;
+
initlock(&buf_table_lock, "buf_table");
+
+ bufhead.prev = &bufhead;
+ bufhead.next = &bufhead;
+ for(b = buf; b < buf+NBUF; b++){
+ b->next = bufhead.next;
+ b->prev = &bufhead;
+ bufhead.next->prev = b;
+ bufhead.next = b;
+ }
}
struct buf *
getblk(uint dev, uint sector)
{
struct buf *b;
- static struct buf *scan = buf;
- int i;
acquire(&buf_table_lock);
while(1){
- for(b = buf; b < buf+NBUF; b++)
+ for(b = bufhead.next; b != &bufhead; b = b->next)
if((b->flags & (B_BUSY|B_VALID)) && b->dev == dev && b->sector == sector)
break;
- if(b < buf+NBUF){
+ if(b != &bufhead){
if(b->flags & B_BUSY){
sleep(buf, &buf_table_lock);
} else {
@@ -39,10 +53,7 @@ getblk(uint dev, uint sector)
return b;
}
} else {
- for(i = 0; i < NBUF; i++){
- b = scan++;
- if(scan >= buf+NBUF)
- scan = buf;
+ for(b = bufhead.prev; b != &bufhead; b = b->prev){
if((b->flags & B_BUSY) == 0){
b->flags = B_BUSY;
b->dev = dev;
@@ -64,8 +75,9 @@ bread(uint dev, uint sector)
extern struct spinlock ide_lock;
b = getblk(dev, sector);
- if(b->flags & B_VALID)
+ if(b->flags & B_VALID){
return b;
+ }
acquire(&ide_lock);
c = ide_start_rw(dev & 0xff, sector, b->data, 1, 1);
@@ -99,6 +111,13 @@ brelse(struct buf *b)
acquire(&buf_table_lock);
+ b->next->prev = b->prev;
+ b->prev->next = b->next;
+ b->next = bufhead.next;
+ b->prev = &bufhead;
+ bufhead.next->prev = b;
+ bufhead.next = b;
+
b->flags &= ~B_BUSY;
wakeup(buf);
diff --git a/buf.h b/buf.h
index 7ab352a..a2a3ec1 100644
--- a/buf.h
+++ b/buf.h
@@ -2,6 +2,8 @@ struct buf {
int flags;
uint dev;
uint sector;
+ struct buf *prev;
+ struct buf *next;
uchar data[512];
};
#define B_BUSY 0x1
diff --git a/fs.c b/fs.c
index 4d32aa8..b042bb2 100644
--- a/fs.c
+++ b/fs.c
@@ -505,7 +505,7 @@ unlink(char *cp)
if ((ip = namei(cp, &pinum)) == 0) {
- cprintf("file to be unlinked doesn't exist\n");
+ cprintf("unlink(%s) it doesn't exist\n", cp);
return -1;
}
diff --git a/usertests.c b/usertests.c
index 9bd144c..3cb4a37 100644
--- a/usertests.c
+++ b/usertests.c
@@ -303,7 +303,7 @@ createdelete()
void
unlinkread()
{
- int fd;
+ int fd, fd1;
fd = open("unlinkread", O_CREATE | O_RDWR);
if(fd < 0){
@@ -322,15 +322,25 @@ unlinkread()
puts("unlink unlinkread failed\n");
exit();
}
+
+ fd1 = open("xxx", O_CREATE | O_RDWR);
+ write(fd1, "yyy", 3);
+ close(fd1);
+
if(read(fd, buf, sizeof(buf)) != 5){
puts("unlinkread read failed");
exit();
}
+ if(buf[0] != 'h'){
+ puts("unlinkread wrong data\n");
+ exit();
+ }
if(write(fd, buf, 10) != 10){
puts("unlinkread write failed\n");
exit();
}
close(fd);
+ unlink("xxx");
puts("unlinkread ok\n");
}
@@ -339,7 +349,7 @@ main(int argc, char *argv[])
{
puts("usertests starting\n");
- //unlinkread();
+ unlinkread();
createdelete();
twofiles();
sharedfd();