LRU disk cache replacement

This commit is contained in:
rtm 2006-08-12 22:34:13 +00:00
parent 22bac2cb9d
commit cd93074e5b
5 changed files with 51 additions and 12 deletions

8
Notes
View file

@ -357,3 +357,11 @@ OH! recursive interrupts will use up any amount of cpu[].stack!
better buffer cache replacement better buffer cache replacement
read/write of open file that's been unlinked 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?

37
bio.c
View file

@ -10,27 +10,41 @@
struct buf buf[NBUF]; struct buf buf[NBUF];
struct spinlock buf_table_lock; 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 void
binit(void) binit(void)
{ {
struct buf *b;
initlock(&buf_table_lock, "buf_table"); 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 * struct buf *
getblk(uint dev, uint sector) getblk(uint dev, uint sector)
{ {
struct buf *b; struct buf *b;
static struct buf *scan = buf;
int i;
acquire(&buf_table_lock); acquire(&buf_table_lock);
while(1){ 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) if((b->flags & (B_BUSY|B_VALID)) && b->dev == dev && b->sector == sector)
break; break;
if(b < buf+NBUF){ if(b != &bufhead){
if(b->flags & B_BUSY){ if(b->flags & B_BUSY){
sleep(buf, &buf_table_lock); sleep(buf, &buf_table_lock);
} else { } else {
@ -39,10 +53,7 @@ getblk(uint dev, uint sector)
return b; return b;
} }
} else { } else {
for(i = 0; i < NBUF; i++){ for(b = bufhead.prev; b != &bufhead; b = b->prev){
b = scan++;
if(scan >= buf+NBUF)
scan = buf;
if((b->flags & B_BUSY) == 0){ if((b->flags & B_BUSY) == 0){
b->flags = B_BUSY; b->flags = B_BUSY;
b->dev = dev; b->dev = dev;
@ -64,8 +75,9 @@ bread(uint dev, uint sector)
extern struct spinlock ide_lock; extern struct spinlock ide_lock;
b = getblk(dev, sector); b = getblk(dev, sector);
if(b->flags & B_VALID) if(b->flags & B_VALID){
return b; return b;
}
acquire(&ide_lock); acquire(&ide_lock);
c = ide_start_rw(dev & 0xff, sector, b->data, 1, 1); c = ide_start_rw(dev & 0xff, sector, b->data, 1, 1);
@ -99,6 +111,13 @@ brelse(struct buf *b)
acquire(&buf_table_lock); 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; b->flags &= ~B_BUSY;
wakeup(buf); wakeup(buf);

2
buf.h
View file

@ -2,6 +2,8 @@ struct buf {
int flags; int flags;
uint dev; uint dev;
uint sector; uint sector;
struct buf *prev;
struct buf *next;
uchar data[512]; uchar data[512];
}; };
#define B_BUSY 0x1 #define B_BUSY 0x1

2
fs.c
View file

@ -505,7 +505,7 @@ unlink(char *cp)
if ((ip = namei(cp, &pinum)) == 0) { 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; return -1;
} }

View file

@ -303,7 +303,7 @@ createdelete()
void void
unlinkread() unlinkread()
{ {
int fd; int fd, fd1;
fd = open("unlinkread", O_CREATE | O_RDWR); fd = open("unlinkread", O_CREATE | O_RDWR);
if(fd < 0){ if(fd < 0){
@ -322,15 +322,25 @@ unlinkread()
puts("unlink unlinkread failed\n"); puts("unlink unlinkread failed\n");
exit(); exit();
} }
fd1 = open("xxx", O_CREATE | O_RDWR);
write(fd1, "yyy", 3);
close(fd1);
if(read(fd, buf, sizeof(buf)) != 5){ if(read(fd, buf, sizeof(buf)) != 5){
puts("unlinkread read failed"); puts("unlinkread read failed");
exit(); exit();
} }
if(buf[0] != 'h'){
puts("unlinkread wrong data\n");
exit();
}
if(write(fd, buf, 10) != 10){ if(write(fd, buf, 10) != 10){
puts("unlinkread write failed\n"); puts("unlinkread write failed\n");
exit(); exit();
} }
close(fd); close(fd);
unlink("xxx");
puts("unlinkread ok\n"); puts("unlinkread ok\n");
} }
@ -339,7 +349,7 @@ main(int argc, char *argv[])
{ {
puts("usertests starting\n"); puts("usertests starting\n");
//unlinkread(); unlinkread();
createdelete(); createdelete();
twofiles(); twofiles();
sharedfd(); sharedfd();