⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bio.c

📁 美国mit操作系统课程所用的一个教学操作系统xv6
💻 C
字号:
// Buffer cache.//// The buffer cache is a linked list of buf structures holding// cached copies of disk block contents.  Caching disk blocks// in memory reduces the number of disk reads and also provides// a synchronization point for disk blocks used by multiple processes.// // Interface:// * To get a buffer for a particular disk block, call bread.// * After changing buffer data, call bwrite to flush it to disk.// * When done with the buffer, call brelse.// * Do not use the buffer after calling brelse.// * Only one process at a time can use a buffer,//     so do not keep them longer than necessary.// // The implementation uses three state flags internally:// * B_BUSY: the block has been returned from bread//     and has not been passed back to brelse.  // * B_VALID: the buffer data has been initialized//     with the associated disk block contents.// * B_DIRTY: the buffer data has been modified//     and needs to be written to disk.#include "types.h"#include "defs.h"#include "param.h"#include "spinlock.h"#include "buf.h"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;voidbinit(void){  struct buf *b;  initlock(&buf_table_lock, "buf_table");  // Create linked list of buffers  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;  }}// Look through buffer cache for sector on device dev.// If not found, allocate fresh block.// In either case, return locked buffer.static struct buf*bget(uint dev, uint sector){  struct buf *b;  acquire(&buf_table_lock); loop:  // Try for cached block.  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){        sleep(buf, &buf_table_lock);        goto loop;      }      b->flags |= B_BUSY;      release(&buf_table_lock);      return b;    }  }  // Allocate fresh block.  for(b = bufhead.prev; b != &bufhead; b = b->prev){    if((b->flags & B_BUSY) == 0){      b->flags = B_BUSY;      b->dev = dev;      b->sector = sector;      release(&buf_table_lock);      return b;    }  }  panic("bget: no buffers");}// Return a B_BUSY buf with the contents of the indicated disk sector.struct buf*bread(uint dev, uint sector){  struct buf *b;  b = bget(dev, sector);  if(!(b->flags & B_VALID))    ide_rw(b);  return b;}// Write buf's contents to disk.  Must be locked.voidbwrite(struct buf *b){  if((b->flags & B_BUSY) == 0)    panic("bwrite");  b->flags |= B_DIRTY;  ide_rw(b);}// Release the buffer buf.voidbrelse(struct buf *b){  if((b->flags & B_BUSY) == 0)    panic("brelse");  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);  release(&buf_table_lock);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -