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
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 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
buf.h
View file

@ -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

2
fs.c
View file

@ -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;
}

View file

@ -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();