From 5753553213df8f9de851adb68377db43faecb91f Mon Sep 17 00:00:00 2001 From: Robert Morris Date: Tue, 11 Jun 2019 09:57:14 -0400 Subject: separate source into kernel/ user/ mkfs/ --- bio.c | 145 ------------------------------------------------------------------ 1 file changed, 145 deletions(-) delete mode 100644 bio.c (limited to 'bio.c') diff --git a/bio.c b/bio.c deleted file mode 100644 index 90f9af9..0000000 --- a/bio.c +++ /dev/null @@ -1,145 +0,0 @@ -// 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 write 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 two state flags internally: -// * B_VALID: the buffer data has been read from the disk. -// * B_DIRTY: the buffer data has been modified -// and needs to be written to disk. - -#include "types.h" -#include "param.h" -#include "spinlock.h" -#include "sleeplock.h" -#include "riscv.h" -#include "defs.h" -#include "fs.h" -#include "buf.h" - -struct { - struct spinlock lock; - struct buf buf[NBUF]; - - // Linked list of all buffers, through prev/next. - // head.next is most recently used. - struct buf head; -} bcache; - -void -binit(void) -{ - struct buf *b; - - initlock(&bcache.lock, "bcache"); - -//PAGEBREAK! - // Create linked list of buffers - bcache.head.prev = &bcache.head; - bcache.head.next = &bcache.head; - for(b = bcache.buf; b < bcache.buf+NBUF; b++){ - b->next = bcache.head.next; - b->prev = &bcache.head; - initsleeplock(&b->lock, "buffer"); - bcache.head.next->prev = b; - bcache.head.next = b; - } -} - -// Look through buffer cache for block on device dev. -// If not found, allocate a buffer. -// In either case, return locked buffer. -static struct buf* -bget(uint dev, uint blockno) -{ - struct buf *b; - - acquire(&bcache.lock); - - // Is the block already cached? - for(b = bcache.head.next; b != &bcache.head; b = b->next){ - if(b->dev == dev && b->blockno == blockno){ - b->refcnt++; - release(&bcache.lock); - acquiresleep(&b->lock); - return b; - } - } - - // Not cached; recycle an unused buffer. - // Even if refcnt==0, B_DIRTY indicates a buffer is in use - // because log.c has modified it but not yet committed it. - for(b = bcache.head.prev; b != &bcache.head; b = b->prev){ - if(b->refcnt == 0 && (b->flags & B_DIRTY) == 0) { - b->dev = dev; - b->blockno = blockno; - b->flags = 0; - b->refcnt = 1; - release(&bcache.lock); - acquiresleep(&b->lock); - return b; - } - } - panic("bget: no buffers"); -} - -// Return a locked buf with the contents of the indicated block. -struct buf* -bread(uint dev, uint blockno) -{ - struct buf *b; - - b = bget(dev, blockno); - if((b->flags & B_VALID) == 0) { - ramdiskrw(b); - } - return b; -} - -// Write b's contents to disk. Must be locked. -void -bwrite(struct buf *b) -{ - if(!holdingsleep(&b->lock)) - panic("bwrite"); - b->flags |= B_DIRTY; - ramdiskrw(b); -} - -// Release a locked buffer. -// Move to the head of the MRU list. -void -brelse(struct buf *b) -{ - if(!holdingsleep(&b->lock)) - panic("brelse"); - - releasesleep(&b->lock); - - acquire(&bcache.lock); - b->refcnt--; - if (b->refcnt == 0) { - // no one is waiting for it. - b->next->prev = b->prev; - b->prev->next = b->next; - b->next = bcache.head.next; - b->prev = &bcache.head; - bcache.head.next->prev = b; - bcache.head.next = b; - } - - release(&bcache.lock); -} -//PAGEBREAK! -// Blank page. - -- cgit v1.2.3