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