2002-08-28 01:34:19 +00:00
|
|
|
#include <new.h>
|
2002-07-19 03:55:07 +00:00
|
|
|
#include <cacheManager.h>
|
2002-08-26 20:14:54 +00:00
|
|
|
#include <vpagePool.h>
|
2002-09-05 03:26:02 +00:00
|
|
|
#include "vmHeaderBlock.h"
|
2002-07-19 03:55:07 +00:00
|
|
|
|
2002-09-14 17:03:16 +00:00
|
|
|
bool cacheMemberIsLessThan(void *a,void *b)
|
|
|
|
|
{
|
|
|
|
|
vnode *v1 = reinterpret_cast<cacheMember *>(a)->vn;
|
|
|
|
|
vnode *v2 = reinterpret_cast<cacheMember *>(b)->vn;
|
|
|
|
|
if (v1->fd < v2->fd)
|
|
|
|
|
return true;
|
|
|
|
|
if ((v1->fd==v2->fd) && (v1->offset<v2->offset))
|
|
|
|
|
return true;
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
2002-09-05 03:26:02 +00:00
|
|
|
extern vmHeaderBlock *vmBlock;
|
2002-08-28 03:26:23 +00:00
|
|
|
// TODO - we need to (somehow) make sure that the same vnodes here are shared with mmap.
|
|
|
|
|
// Maybe a vnode manager...
|
2002-08-26 20:14:54 +00:00
|
|
|
cacheManager::cacheManager(void) : area ()
|
2002-07-19 03:55:07 +00:00
|
|
|
{
|
2002-08-28 03:26:23 +00:00
|
|
|
myLock=create_sem(1,"Cache Manager Semaphore");
|
2002-07-19 03:55:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void *cacheManager::findBlock(vnode *target,bool readOnly)
|
|
|
|
|
{
|
|
|
|
|
if (!cacheMembers.rock)
|
|
|
|
|
return NULL;
|
|
|
|
|
for (struct cacheMember *cur=((cacheMember *)cacheMembers.rock);cur;cur=((cacheMember *)cur->next))
|
|
|
|
|
{
|
|
|
|
|
if ((target==cur->vn) && (readOnly || (cur->vp->getProtection()>=writable)))
|
|
|
|
|
return (cur->vp->getStartAddress());
|
|
|
|
|
}
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void *cacheManager::createBlock(vnode *target,bool readOnly)
|
|
|
|
|
{
|
|
|
|
|
bool foundSpot=false;
|
|
|
|
|
vpage *prev=NULL,*cur=NULL;
|
|
|
|
|
unsigned long begin=CACHE_BEGIN;
|
2002-09-14 17:03:16 +00:00
|
|
|
// Find a place in the cache's virtual space to put this vnode...
|
2002-07-19 03:55:07 +00:00
|
|
|
if (vpages.rock)
|
|
|
|
|
for (cur=((vpage *)(vpages.rock));!foundSpot && cur;cur=(vpage *)(cur->next))
|
|
|
|
|
if (cur->getStartAddress()!=(void *)begin)
|
|
|
|
|
foundSpot=true;
|
|
|
|
|
else // no joy
|
|
|
|
|
{
|
|
|
|
|
begin+=PAGE_SIZE;
|
|
|
|
|
prev=cur;
|
|
|
|
|
}
|
2002-07-25 01:27:00 +00:00
|
|
|
lock();
|
2002-07-19 03:55:07 +00:00
|
|
|
// Create a vnode here
|
2002-09-05 03:26:02 +00:00
|
|
|
vpage *newPage = new (vmBlock->vpagePool->get()) vpage;
|
2002-08-26 20:14:54 +00:00
|
|
|
newPage->setup(begin,target,NULL,((readOnly)?readable:writable),NO_LOCK);
|
2002-07-19 03:55:07 +00:00
|
|
|
vpages.add(newPage);
|
|
|
|
|
cacheMembers.add(newPage);
|
2002-07-25 01:27:00 +00:00
|
|
|
unlock();
|
2002-07-19 03:55:07 +00:00
|
|
|
// return address from this vnode
|
|
|
|
|
return (void *)begin;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void *cacheManager::readBlock(vnode *target)
|
|
|
|
|
{
|
|
|
|
|
void *destination=findBlock(target,true);
|
|
|
|
|
if (destination) return destination;
|
|
|
|
|
return createBlock(target,true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void *cacheManager::writeBlock(vnode *target)
|
|
|
|
|
{
|
|
|
|
|
void *destination=findBlock(target,false);
|
|
|
|
|
if (destination) return destination;
|
|
|
|
|
return createBlock(target,false);
|
|
|
|
|
}
|