LRU disk cache replacement
This commit is contained in:
parent
22bac2cb9d
commit
cd93074e5b
5 changed files with 51 additions and 12 deletions
8
Notes
8
Notes
|
@ -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
37
bio.c
|
@ -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
2
buf.h
|
@ -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
2
fs.c
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
14
usertests.c
14
usertests.c
|
@ -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();
|
||||||
|
|
Loading…
Reference in a new issue