#include "../include/BufferCache.h"
#include "../include/Kernel.h"
#include "../include/VirtualProcess.h"
#include "../include/Logcat.h"
void BufferCache::setDiskDriver(DiskDriver *diskDriver)
{
this->diskDriver = diskDriver;
}
int BufferCache::mount()
{
initialize();
return diskDriver->mount();
}
void BufferCache::unmount()
{
Bflush();
diskDriver->unmount();
} //unmount
/**
*
*/
void BufferCache::initialize()
{
int i;
Buf *bp;
this->bFreeList.b_forw = this->bFreeList.b_back = &(this->bFreeList);
this->bFreeList.av_forw = this->bFreeList.av_back = &(this->bFreeList);
for (i = 0; i < BUFFER_CACHE_NUM; i++)
{
bp = &(this->m_Buf[i]);
bp->b_blkno = -1;
bp->b_dev = -1;
bp->b_addr = &Buffer[i];
/* NODEV */
//bp->b_back = &(this->bFreeList);
//bp->b_forw = this->bFreeList.b_forw;
//this->bFreeList.b_forw->b_back = bp;
//this->bFreeList.b_forw = bp;
/* */
bp->b_flags = Buf::B_BUSY;
Brelse(bp); //
}
}
/**
* diskBlockPool
*/
Buf *BufferCache::Bread(int blkno)
{
Buf *bp;
/* */
bp = this->GetBlk(blkno);
/* B_DONEI/O */
if (bp->b_flags & Buf::B_DONE) //DONE
{
return bp; //
}
/* I/O */
bp->b_flags |= Buf::B_READ;
bp->b_wcount = DISK_BLOCK_SIZE;
diskDriver->readBlk(blkno, bp->b_addr);
bp->b_flags |= Buf::B_DONE;
return bp;
}
/**
*
*/
void BufferCache::Bwrite(Buf *bp)
{
unsigned int flags;
flags = bp->b_flags;
bp->b_flags &= ~(Buf::B_READ | Buf::B_DONE | Buf::B_ERROR | Buf::B_DELWRI);
bp->b_wcount = DISK_BLOCK_SIZE;
//this->m_DeviceManager->GetBlockDevice(Utility::GetMajor(bp->b_dev)).Strategy(bp);
if ((flags & Buf::B_DELWRI) == 0)
{
/*
*
*
* GetError()
*
*/
Logcat::log("BufferCache", "bwrite");
}
else
{
diskDriver->writeBlk(bp->b_blkno, *bp->b_addr);
bp->b_flags |= Buf::B_DONE;
std::cout b_blkno b_flags |= (Buf::B_DELWRI | Buf::B_DONE);
this->Brelse(bp);
return;
}
/**
* dev.
*/
void BufferCache::Bflush()
{
Buf *bp;
for (bp = this->bFreeList.b_forw; bp != &(this->bFreeList); bp = bp->b_forw)
{
/* */
if ((bp->b_flags & Buf::B_DELWRI))
{
//bwriteB_DELWRI
//this->NotAvail(bp);
this->Bwrite(bp);
//this->Brelse(bp);
//std::cout b_blkno getUser();
/*
*
*
*/
/* NODEV */
/* */
for (bp = bFreeList.b_forw; bp != &bFreeList; bp = bp->b_forw)
{
/* */
if (bp->b_blkno != blkno)
continue;
/* */
this->NotAvail(bp);
return bp; //
}
/* */
bp = this->bFreeList.av_forw;
this->NotAvail(bp);
/* */
if (bp->b_flags & Buf::B_DELWRI)
{
this->Bwrite(bp);
}
/* : B_BUSY */
bp->b_flags = Buf::B_BUSY; //bit
bp->b_blkno = blkno;
memset(bp->b_addr, 0, DISK_BLOCK_SIZE);
if (bp->b_dev != devno)
{
//
bp->b_back = &(this->bFreeList);
bp->b_forw = this->bFreeList.b_forw;
this->bFreeList.b_forw->b_back = bp;
this->bFreeList.b_forw = bp;
bp->b_dev = devno;
}
return bp;
}
/**
* Buf
*/
Buf &BufferCache::GetBFreeList()
{
return this->bFreeList;
}
//TODO bug
void BufferCache::NotAvail(Buf *bp)
{
/* */
bp->av_back->av_forw = bp->av_forw;
bp->av_forw->av_back = bp->av_back;
/* B_BUSY */
bp->b_flags |= Buf::B_BUSY;
return;
}
/**
*
* B_DELWRIB_WRITEB_READB_DONE
* B_DELWRI
* B_DONE
*/
void BufferCache::Brelse(Buf *bp)
{
bp->b_flags &= ~(Buf::B_WANTED | Buf::B_BUSY | Buf::B_ASYNC); //
(this->bFreeList.av_back)->av_forw = bp;
bp->av_back = this->bFreeList.av_back;
bp->av_forw = &(this->bFreeList);
this->bFreeList.av_back = bp;
return;
}