diff options
author | rtm <rtm> | 2006-08-12 22:34:13 +0000 |
---|---|---|
committer | rtm <rtm> | 2006-08-12 22:34:13 +0000 |
commit | cd93074e5bed8fdbc84f2960c3219c7cf791b020 (patch) | |
tree | 1c08629ac66cb608ed03601ca0edce0170f71546 | |
parent | 22bac2cb9d0b8050573a4b5c6cb5d8f460ee4167 (diff) | |
download | xv6-labs-cd93074e5bed8fdbc84f2960c3219c7cf791b020.tar.gz xv6-labs-cd93074e5bed8fdbc84f2960c3219c7cf791b020.tar.bz2 xv6-labs-cd93074e5bed8fdbc84f2960c3219c7cf791b020.zip |
LRU disk cache replacement
-rw-r--r-- | Notes | 8 | ||||
-rw-r--r-- | bio.c | 37 | ||||
-rw-r--r-- | buf.h | 2 | ||||
-rw-r--r-- | fs.c | 2 | ||||
-rw-r--r-- | usertests.c | 14 |
5 files changed, 51 insertions, 12 deletions
@@ -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? @@ -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); @@ -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 @@ -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(); |