With this change, all memory except for the areaManager is allocated from the
one area that we allocate. The areaManager should really be created when the process is created, so this is something to wait for HW integration time. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@983 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+4
-1
@@ -1,6 +1,9 @@
|
||||
1) Need to make the paging daemon load the pages in, using semaphores.
|
||||
-- Looks like we *don't* have to do this, based on what is done in NewOS. Need to consult...
|
||||
2) Make the caching and the VM (mmap) work together so that an mmap'ed file and a cached file will not race.
|
||||
3) Change the architecture so that instead of multiple static globals, everything is stored in pages.
|
||||
-- Maybe a vnodeManager or a lookup in a hash table or something so that we can tell if someone is already caching this vnode.
|
||||
This could get a little tricky wrt permissions and all...
|
||||
3) Change the architecture so that instead of multiple threads of tests, we have multiple apps of tests...
|
||||
4) Tests are not done.
|
||||
Test:
|
||||
getNextAreaInfo
|
||||
|
||||
+16
-14
@@ -2,11 +2,12 @@
|
||||
#include "area.h"
|
||||
#include "areaManager.h"
|
||||
#include "vpage.h"
|
||||
#include "vpagePool.h"
|
||||
#include "vnodePool.h"
|
||||
#include "vpagePool.h"
|
||||
|
||||
extern poolvpage vpagePool;
|
||||
extern poolvnode vnodePool;
|
||||
#include "vmHeaderBlock.h"
|
||||
|
||||
extern vmHeaderBlock *vmBlock;
|
||||
|
||||
area::area(void)
|
||||
{
|
||||
@@ -14,6 +15,7 @@ area::area(void)
|
||||
|
||||
void area::setup (areaManager *myManager)
|
||||
{
|
||||
printf ("area::setup setting up new area\n");
|
||||
manager=myManager;
|
||||
}
|
||||
|
||||
@@ -53,11 +55,11 @@ status_t area::createAreaMappingFile(char *inName, int pageCount,void **address,
|
||||
unsigned long base=mapAddressSpecToAddress(type,requested,pageCount);
|
||||
for (int i=0;i<pageCount;i++)
|
||||
{
|
||||
vnode *newVnode=new (vnodePool.get()) vnode;
|
||||
vnode *newVnode=new (vmBlock->vnodePool->get()) vnode;
|
||||
newVnode->fd=fd;
|
||||
newVnode->offset=offset+PAGE_SIZE*i;
|
||||
newVnode->valid=true;
|
||||
newPage=new (vpagePool.get()) vpage;
|
||||
newPage=new (vmBlock->vpagePool->get()) vpage;
|
||||
newPage->setup(base+PAGE_SIZE*i,newVnode,NULL,protect,inState);
|
||||
vpages.add(newPage);
|
||||
// printf ("New vnode with fd %d, offset = %d\n",fd,newVnode->offset);
|
||||
@@ -81,13 +83,13 @@ status_t area::createArea(char *inName, int pageCount,void **address, addressSpe
|
||||
unsigned long requested=(unsigned long)(*address); // Hold onto this to make sure that EXACT works...
|
||||
|
||||
manager->lock();
|
||||
//printf ("area::createArea: Locked in createArea\n");
|
||||
printf ("area::createArea: Locked in createArea\n");
|
||||
unsigned long base=mapAddressSpecToAddress(type,requested,pageCount);
|
||||
//printf ("area::createArea: base address = %d\n",base);
|
||||
printf ("area::createArea: base address = %d\n",base);
|
||||
for (int i=0;i<pageCount;i++)
|
||||
{
|
||||
//printf ("in area::createArea: creating page = %d\n",i);
|
||||
newPage=new (vpagePool.get()) vpage;
|
||||
printf ("in area::createArea: creating page = %d\n",i);
|
||||
newPage=new (vmBlock->vpagePool->get()) vpage;
|
||||
newPage->setup(base+PAGE_SIZE*i,NULL,NULL,protect,inState);
|
||||
vpages.add(newPage);
|
||||
}
|
||||
@@ -95,7 +97,7 @@ status_t area::createArea(char *inName, int pageCount,void **address, addressSpe
|
||||
start_address=base;
|
||||
end_address=base+pageCount*PAGE_SIZE;
|
||||
*address=(void *)base;
|
||||
//printf ("area::createArea: unlocked in createArea\n");
|
||||
printf ("area::createArea: unlocked in createArea\n");
|
||||
}
|
||||
|
||||
status_t area::cloneArea(area *origArea, char *inName, void **address, addressSpec type,pageState inState,protectType protect)
|
||||
@@ -119,7 +121,7 @@ status_t area::cloneArea(area *origArea, char *inName, void **address, addressSp
|
||||
{
|
||||
vpage *newPage,*page=(vpage *)cur;
|
||||
// Cloned area has the same physical page and backing store...
|
||||
newPage=new (vpagePool.get()) vpage;
|
||||
newPage=new (vmBlock->vpagePool->get()) vpage;
|
||||
newPage->setup(base,page->getBacking(),page->getPhysPage(),protect,inState);
|
||||
vpages.add(newPage);
|
||||
base+=PAGE_SIZE;
|
||||
@@ -151,7 +153,7 @@ void area::freeArea(void)
|
||||
//printf ("area::freeArea: flushed a page \n");
|
||||
page->cleanup();
|
||||
//page->next=NULL;
|
||||
vpagePool.put(page);
|
||||
vmBlock->vpagePool->put(page);
|
||||
}
|
||||
//printf ("area::freeArea: unlocking \n");
|
||||
manager->unlock();
|
||||
@@ -203,7 +205,7 @@ status_t area::resize(size_t newSize)
|
||||
vpage *newPage;
|
||||
for (int i=0;i<pageCount;i++)
|
||||
{
|
||||
newPage=new (vpagePool.get()) vpage;
|
||||
newPage=new (vmBlock->vpagePool->get()) vpage;
|
||||
newPage->setup(end_address+PAGE_SIZE*i-1,NULL,NULL,protection,state);
|
||||
vpages.add(newPage);
|
||||
}
|
||||
@@ -220,7 +222,7 @@ status_t area::resize(size_t newSize)
|
||||
for (cur=vpages.rock;cur->next;cur=cur->next); // INTENTIONAL - find the last one;
|
||||
vpage *oldPage=(vpage *)cur;
|
||||
oldPage->cleanup();
|
||||
vpagePool.put(oldPage);
|
||||
vmBlock->vpagePool->put(oldPage);
|
||||
}
|
||||
}
|
||||
manager->unlock();
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
#include "areaPool.h"
|
||||
#include "area.h"
|
||||
#include "page.h"
|
||||
#include "vmHeaderBlock.h"
|
||||
#include "pageManager.h"
|
||||
|
||||
extern vmHeaderBlock *vmBlock;
|
||||
|
||||
area *poolarea::get(void)
|
||||
{
|
||||
area *ret=NULL;
|
||||
if (unused.count())
|
||||
{
|
||||
//printf ("poolarea::get: Getting an unused one!\n");
|
||||
acquire_sem(inUse);
|
||||
ret=(area *)unused.next();
|
||||
release_sem(inUse);
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
//printf ("poolarea::get: Returning address:%x \n",ret);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf ("poolarea::get: Getting a new page!\n");
|
||||
page *newPage=vmBlock->pageMan->getPage();
|
||||
if (!newPage)
|
||||
throw ("Out of pages to allocate a pool!");
|
||||
int newCount=PAGE_SIZE/sizeof(area);
|
||||
acquire_sem(inUse);
|
||||
//printf ("poolarea::get: Adding %d new elements to the pool!\n",newCount);
|
||||
for (int i=0;i<newCount;i++)
|
||||
unused.add(((void *)(newPage->getAddress()+(i*sizeof(area)))));
|
||||
release_sem(inUse);
|
||||
return (get()); // A little cheat - call self again to get the first one from stack...
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
#include "pageManager.h"
|
||||
|
||||
extern pageManager pageMan;
|
||||
#include <OS.h>
|
||||
#include "list.h"
|
||||
class area;
|
||||
class poolarea
|
||||
{
|
||||
private:
|
||||
@@ -11,36 +11,7 @@ class poolarea
|
||||
{
|
||||
inUse = create_sem(1,"areapool");
|
||||
}
|
||||
area *get(void)
|
||||
{
|
||||
area *ret=NULL;
|
||||
if (unused.count())
|
||||
{
|
||||
//printf ("poolarea::get: Getting an unused one!\n");
|
||||
acquire_sem(inUse);
|
||||
ret=(area *)unused.next();
|
||||
release_sem(inUse);
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
//printf ("poolarea::get: Returning address:%x \n",ret);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf ("poolarea::get: Getting a new page!\n");
|
||||
page *newPage=pageMan.getPage();
|
||||
if (!newPage)
|
||||
throw ("Out of pages to allocate a pool!");
|
||||
int newCount=PAGE_SIZE/sizeof(area);
|
||||
acquire_sem(inUse);
|
||||
//printf ("poolarea::get: Adding %d new elements to the pool!\n",newCount);
|
||||
for (int i=0;i<newCount;i++)
|
||||
unused.add(((void *)(newPage->getAddress()+(i*sizeof(area)))));
|
||||
release_sem(inUse);
|
||||
return (get()); // A little cheat - call self again to get the first one from stack...
|
||||
}
|
||||
}
|
||||
area *get(void);
|
||||
void put(area *in)
|
||||
{
|
||||
acquire_sem(inUse);
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
#include <new.h>
|
||||
#include <cacheManager.h>
|
||||
#include <vpagePool.h>
|
||||
#include "vmHeaderBlock.h"
|
||||
|
||||
extern poolvpage vpagePool;
|
||||
extern vmHeaderBlock *vmBlock;
|
||||
// TODO - we need to (somehow) make sure that the same vnodes here are shared with mmap.
|
||||
// Maybe a vnode manager...
|
||||
cacheManager::cacheManager(void) : area ()
|
||||
@@ -38,7 +39,7 @@ void *cacheManager::createBlock(vnode *target,bool readOnly)
|
||||
}
|
||||
lock();
|
||||
// Create a vnode here
|
||||
vpage *newPage = new (vpagePool.get()) vpage;
|
||||
vpage *newPage = new (vmBlock->vpagePool->get()) vpage;
|
||||
newPage->setup(begin,target,NULL,((readOnly)?readable:writable),NO_LOCK);
|
||||
vpages.add(newPage);
|
||||
cacheMembers.add(newPage);
|
||||
|
||||
@@ -7,25 +7,21 @@ void *addOffset(void *base,unsigned long offset)
|
||||
return (void *)(((unsigned long)base+offset));
|
||||
}
|
||||
|
||||
pageManager::pageManager(int pages)
|
||||
pageManager::pageManager(void)
|
||||
{
|
||||
}
|
||||
|
||||
void pageManager::setup(void *area,int pages)
|
||||
{
|
||||
// This is compatability for in BeOS usage only...
|
||||
void *area;
|
||||
if (0>=create_area("vm_test",&area,B_ANY_ADDRESS,B_PAGE_SIZE*pages,B_NO_LOCK,B_READ_AREA|B_WRITE_AREA))
|
||||
{
|
||||
printf ("pageManager::pageManager: No memory!\n");
|
||||
exit(1);
|
||||
}
|
||||
printf ("Allocated an area. Address = %x\n",area);
|
||||
// Calculate the number of pages that we will need to hold the page structures
|
||||
int pageOverhead=((pages*sizeof(page))+(PAGE_SIZE-1))/PAGE_SIZE;
|
||||
for (int i=0;i<pages-pageOverhead;i++)
|
||||
{
|
||||
page *newPage=(page *)(addOffset(area,i*sizeof(page)));
|
||||
newPage->setup(addOffset(area,(i+pageOverhead)*PAGE_SIZE));
|
||||
printf ("newPage = %x, setup = %x\n",newPage,addOffset(area,(i+pageOverhead)*PAGE_SIZE));
|
||||
printf ("i = %d, sizeof(page) = %x, pageOverhead = %d\n",i,sizeof(page),pageOverhead);
|
||||
newPage->dump();
|
||||
//printf ("newPage = %x, setup = %x\n",newPage,addOffset(area,(i+pageOverhead)*PAGE_SIZE));
|
||||
//printf ("i = %d, sizeof(page) = %x, pageOverhead = %d\n",i,sizeof(page),pageOverhead);
|
||||
//newPage->dump();
|
||||
unused.add(addOffset(area,i*sizeof(page)));
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
|
||||
class pageManager {
|
||||
public:
|
||||
pageManager(int);
|
||||
pageManager(void);
|
||||
void setup(void *memory,int pages);
|
||||
page *getPage(void);
|
||||
void freePage(page *);
|
||||
void cleaner(void);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "pageManager.h"
|
||||
|
||||
extern pageManager pageMan;
|
||||
#include "vmHeaderBlock.h"
|
||||
|
||||
extern vmHeaderBlock *vmBlock;
|
||||
/* This is the template
|
||||
* replace TYPE with the type you need a pool for
|
||||
*
|
||||
@@ -32,7 +34,7 @@ class poolTYPE
|
||||
else
|
||||
{
|
||||
printf ("poolTYPE::get: Getting a new page!\n");
|
||||
page *newPage=pageMan.getPage();
|
||||
page *newPage=vmBlock->pageMan->getPage();
|
||||
if (!newPage)
|
||||
throw ("Out of pages to allocate a pool!");
|
||||
int newCount=PAGE_SIZE/sizeof(TYPE);
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
#include <errno.h>
|
||||
#include <new.h>
|
||||
#include <vnodePool.h>
|
||||
#include "vmHeaderBlock.h"
|
||||
|
||||
extern poolvnode vnodePool;
|
||||
extern vmHeaderBlock *vmBlock;
|
||||
|
||||
swapFileManager::swapFileManager(void)
|
||||
{
|
||||
@@ -48,7 +49,7 @@ vnode &swapFileManager::findNode(void)
|
||||
Unlock();
|
||||
if (!newNode)
|
||||
{
|
||||
newNode=new (vnodePool.get()) vnode;
|
||||
newNode=new (vmBlock->vnodePool->get()) vnode;
|
||||
newNode->fd=swapFile;
|
||||
newNode->offset=maxNode+=PAGE_SIZE;
|
||||
//printf (" New One: %d\n",newNode->offset);
|
||||
|
||||
@@ -16,6 +16,7 @@ int createFillAndTest(int pages)
|
||||
try{
|
||||
unsigned long addr;
|
||||
int area1;
|
||||
printf ("createFillAndTest: about to create \n");
|
||||
area1=vm.createArea("Mine",pages,(void **)(&addr));
|
||||
printf ("createFillAndTest: create done\n");
|
||||
for (int i=0;i<pages*PAGE_SIZE;i++)
|
||||
|
||||
@@ -26,14 +26,4 @@ enum addressSpec {EXACT,BASE,ANY,ANY_KERNEL,CLONE};
|
||||
#define CACHE_BEGIN 0x90000000
|
||||
#define CACHE_END 0xe0000000
|
||||
|
||||
struct vmHeaderBlock
|
||||
{
|
||||
poolarea areaPool;
|
||||
poolvpage vpagePool;
|
||||
poolvnode vnodePool;
|
||||
pageManager pageMan(30); // Obviously this hard coded number is a hack...
|
||||
swapFileManager swapMan;
|
||||
cacheManager cacheMan;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
#ifndef _VM_HEADERBLOCK
|
||||
#define _VM_HEADERBLOCK
|
||||
|
||||
|
||||
#ifndef I_AM_VM_INTERFACE
|
||||
class poolarea;
|
||||
class poolvpage;
|
||||
class poolvnode;
|
||||
class pageManager;
|
||||
class swapFileManager;
|
||||
class cacheManager;
|
||||
#endif
|
||||
|
||||
struct vmHeaderBlock
|
||||
{
|
||||
poolarea *areaPool;
|
||||
poolvpage *vpagePool;
|
||||
poolvnode *vnodePool;
|
||||
pageManager *pageMan;
|
||||
swapFileManager *swapMan;
|
||||
cacheManager *cacheMan;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -1,35 +1,46 @@
|
||||
#include "vmInterface.h"
|
||||
//#include "areaManager.h"
|
||||
#include <new.h>
|
||||
#include "mman.h"
|
||||
#include "area.h"
|
||||
#include "areaPool.h"
|
||||
#include "vpagePool.h"
|
||||
#include "vnodePool.h"
|
||||
#include "pageManager.h"
|
||||
#include "swapFileManager.h"
|
||||
#include "cacheManager.h"
|
||||
#define I_AM_VM_INTERFACE
|
||||
#include "vmHeaderBlock.h"
|
||||
#include "vmInterface.h"
|
||||
|
||||
areaManager am;
|
||||
swapFileManager swapMan;
|
||||
poolarea areaPool;
|
||||
poolvpage vpagePool;
|
||||
poolvnode vnodePool;
|
||||
pageManager pageMan(30); // Obviously this hard coded number is a hack...
|
||||
vmHeaderBlock *vmBlock;
|
||||
static areaManager am;
|
||||
|
||||
areaManager *getAM(void)
|
||||
{
|
||||
return &am;
|
||||
}
|
||||
|
||||
void *addToPointer(void *ptr,uint32 offset)
|
||||
{
|
||||
return ((void *)(((unsigned long)ptr)+offset));
|
||||
}
|
||||
|
||||
areaManager *vmInterface::getAM(void)
|
||||
{
|
||||
// Normally, we would go to the current user process to get this. Since there no such thing exists here...
|
||||
|
||||
return &am;
|
||||
}
|
||||
|
||||
int32 cleanerThread(void *pageMan)
|
||||
{
|
||||
pageManager *pm=(pageManager *)pageMan;
|
||||
pageManager *pm=(vmBlock->pageMan);
|
||||
pm->cleaner();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32 saverThread(void *areaMan)
|
||||
{
|
||||
areaManager *am=(areaManager *)areaMan;
|
||||
areaManager *am=getAM();
|
||||
// This should iterate over all processes...
|
||||
while (1)
|
||||
{
|
||||
@@ -40,18 +51,55 @@ int32 saverThread(void *areaMan)
|
||||
|
||||
int32 pagerThread(void *areaMan)
|
||||
{
|
||||
areaManager *am=(areaManager *)areaMan;
|
||||
areaManager *am=getAM();
|
||||
while (1)
|
||||
{
|
||||
snooze(1000000);
|
||||
am->pager(pageMan.desperation());
|
||||
am->pager(vmBlock->pageMan->desperation());
|
||||
}
|
||||
}
|
||||
|
||||
vmInterface::vmInterface(int pages)
|
||||
{
|
||||
char temp[1000];
|
||||
sprintf (temp,"vm_test_clone_%d",getpid());
|
||||
if (clone_area(temp,(void **)(&vmBlock),B_ANY_ADDRESS,B_WRITE_AREA,find_area("vm_test"))<0)
|
||||
{
|
||||
// This is compatability for in BeOS usage only...
|
||||
if (0>=create_area("vm_test",(void **)(&vmBlock),B_ANY_ADDRESS,B_PAGE_SIZE*pages,B_NO_LOCK,B_READ_AREA|B_WRITE_AREA))
|
||||
{
|
||||
printf ("pageManager::pageManager: No memory!\n");
|
||||
exit(1);
|
||||
}
|
||||
//printf ("Allocated an area. Address = %x\n",vmBlock);
|
||||
// Figure out how many pages we need
|
||||
int pageCount = (sizeof(poolarea)+sizeof(poolvpage)+sizeof(poolvnode)+sizeof(pageManager)+sizeof(swapFileManager)+sizeof(cacheManager)+sizeof(vmHeaderBlock)+PAGE_SIZE-1)/PAGE_SIZE;
|
||||
if (pageCount >=pages)
|
||||
{
|
||||
printf ("Hey! Go buy some ram! Trying to create a VM with fewer pages than the setup will take!\n");
|
||||
exit(1);
|
||||
}
|
||||
//printf ("Need %d pages, creation calls for %d\n",pageCount,pages);
|
||||
void *currentAddress = addToPointer(vmBlock,sizeof(struct vmHeaderBlock));
|
||||
vmBlock->areaPool = new (currentAddress) poolarea;
|
||||
currentAddress=addToPointer(currentAddress,sizeof(poolarea));
|
||||
vmBlock->vpagePool = new (currentAddress) poolvpage;
|
||||
currentAddress=addToPointer(currentAddress,sizeof(poolvpage));
|
||||
vmBlock->vnodePool = new (currentAddress) poolvnode;
|
||||
currentAddress=addToPointer(currentAddress,sizeof(poolvnode));
|
||||
vmBlock->pageMan = new (currentAddress) pageManager;
|
||||
currentAddress=addToPointer(currentAddress,sizeof(pageManager));
|
||||
vmBlock->swapMan = new (currentAddress) swapFileManager;
|
||||
currentAddress=addToPointer(currentAddress,sizeof(swapFileManager));
|
||||
vmBlock->cacheMan = new (currentAddress) cacheManager;
|
||||
currentAddress=addToPointer(currentAddress,sizeof(cacheManager));
|
||||
//printf ("Need %d pages, creation calls for %d\n",pageCount,pages);
|
||||
//printf ("vmBlock is at %x, end of structures is at %x, pageMan called with address %x, pages = %d\n",vmBlock,currentAddress,addToPointer(vmBlock,PAGE_SIZE*pageCount),pages-pageCount);
|
||||
vmBlock->pageMan->setup(addToPointer(vmBlock,PAGE_SIZE*pageCount),pages-pageCount);
|
||||
}
|
||||
nextAreaID=0;
|
||||
resume_thread(spawn_thread(cleanerThread,"cleanerThread",0,&pageMan));
|
||||
|
||||
resume_thread(spawn_thread(cleanerThread,"cleanerThread",0,(vmBlock->pageMan)));
|
||||
resume_thread(spawn_thread(saverThread,"saverThread",0,getAM()));
|
||||
resume_thread(spawn_thread(pagerThread,"pagerThread",0,getAM()));
|
||||
}
|
||||
@@ -86,7 +134,10 @@ status_t vmInterface::resizeArea(int Area,size_t size)
|
||||
|
||||
int vmInterface::createArea(char *AreaName,int pageCount,void **address, addressSpec addType,pageState state,protectType protect)
|
||||
{
|
||||
area *newArea = new (areaPool.get()) area;
|
||||
area *newArea = new (vmBlock->areaPool->get()) area;
|
||||
areaManager *foo;
|
||||
printf ("vmInterface::createArea - got a new area (%x) from the areaPool\n",newArea);
|
||||
foo=getAM();
|
||||
newArea->setup(getAM());
|
||||
newArea->createArea(AreaName,pageCount,address,addType,state,protect);
|
||||
newArea->setAreaID(nextAreaID++); // THIS IS NOT THREAD SAFE
|
||||
@@ -108,7 +159,7 @@ void vmInterface::freeArea(int Area)
|
||||
// printf ("vmInterface::freeArea: deleting area %x \n",oldArea);
|
||||
oldArea->freeArea();
|
||||
// printf ("vmInterface::freeArea: freeArea complete \n");
|
||||
areaPool.put(oldArea);
|
||||
vmBlock->areaPool->put(oldArea);
|
||||
}
|
||||
else
|
||||
printf ("vmInterface::freeArea: unable to find requested area\n");
|
||||
@@ -140,7 +191,7 @@ int vmInterface::getAreaByName(char *name)
|
||||
|
||||
int vmInterface::cloneArea(int newAreaID,char *AreaName,void **address, addressSpec addType=ANY, pageState state=NO_LOCK, protectType prot=writable)
|
||||
{
|
||||
area *newArea = new (areaPool.get()) area;
|
||||
area *newArea = new (vmBlock->areaPool->get()) area;
|
||||
newArea->setup(getAM());
|
||||
area *oldArea=getAM()->findArea(newAreaID);
|
||||
newArea->cloneArea(oldArea,AreaName,address,addType,state,prot);
|
||||
@@ -155,7 +206,7 @@ void vmInterface::pager(void)
|
||||
while (1)
|
||||
{
|
||||
snooze(250000);
|
||||
am.pager(pageMan.desperation());
|
||||
getAM()->pager(vmBlock->pageMan->desperation());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,14 +216,14 @@ void vmInterface::saver(void)
|
||||
while (1)
|
||||
{
|
||||
snooze(250000);
|
||||
am.saver();
|
||||
getAM()->saver();
|
||||
}
|
||||
}
|
||||
|
||||
void vmInterface::cleaner(void)
|
||||
{
|
||||
// This loops on its own
|
||||
pageMan.cleaner();
|
||||
vmBlock->pageMan->cleaner();
|
||||
}
|
||||
|
||||
void *vmInterface::mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset)
|
||||
@@ -191,7 +242,7 @@ void *vmInterface::mmap(void *addr, size_t len, int prot, int flags, int fd, off
|
||||
return addr;
|
||||
}
|
||||
|
||||
area *newArea = new (areaPool.get()) area;
|
||||
area *newArea = new (vmBlock->areaPool->get()) area;
|
||||
newArea->setup(getAM());
|
||||
//printf ("area = %x, start = %x\n",newArea, newArea->getStartAddress());
|
||||
newArea->createAreaMappingFile(name,(int)((len+PAGE_SIZE-1)/PAGE_SIZE),&addr,addType,LAZY,protType,fd,offset);
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
#include "vnodePool.h"
|
||||
|
||||
#include "vmHeaderBlock.h"
|
||||
#include "pageManager.h"
|
||||
|
||||
extern vmHeaderBlock *vmBlock;
|
||||
vnode *poolvnode::get(void)
|
||||
{
|
||||
vnode *ret=NULL;
|
||||
if (unused.count())
|
||||
{
|
||||
//printf ("poolvnode::get: Getting an unused one!\n");
|
||||
acquire_sem(inUse);
|
||||
ret=(vnode *)unused.next();
|
||||
release_sem(inUse);
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
//printf ("poolvnode::get: Returning address:%x \n",ret);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf ("poolvnode::get: Getting a new page!\n");
|
||||
page *newPage=vmBlock->pageMan->getPage();
|
||||
if (!newPage)
|
||||
throw ("Out of pages to allocate a pool!");
|
||||
int newCount=PAGE_SIZE/sizeof(vnode);
|
||||
acquire_sem(inUse);
|
||||
//printf ("poolvnode::get: Adding %d new elements to the pool!\n",newCount);
|
||||
for (int i=0;i<newCount;i++)
|
||||
unused.add(((void *)(newPage->getAddress()+(i*sizeof(vnode)))));
|
||||
release_sem(inUse);
|
||||
return (get()); // A little cheat - call self again to get the first one from stack...
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "pageManager.h"
|
||||
|
||||
extern pageManager pageMan;
|
||||
#include <OS.h>
|
||||
#include "list.h"
|
||||
class area;
|
||||
class vnode;
|
||||
class poolvnode
|
||||
{
|
||||
private:
|
||||
@@ -11,36 +12,7 @@ class poolvnode
|
||||
{
|
||||
inUse = create_sem(1,"vnodepool");
|
||||
}
|
||||
vnode *get(void)
|
||||
{
|
||||
vnode *ret=NULL;
|
||||
if (unused.count())
|
||||
{
|
||||
//printf ("poolvnode::get: Getting an unused one!\n");
|
||||
acquire_sem(inUse);
|
||||
ret=(vnode *)unused.next();
|
||||
release_sem(inUse);
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
//printf ("poolvnode::get: Returning address:%x \n",ret);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf ("poolvnode::get: Getting a new page!\n");
|
||||
page *newPage=pageMan.getPage();
|
||||
if (!newPage)
|
||||
throw ("Out of pages to allocate a pool!");
|
||||
int newCount=PAGE_SIZE/sizeof(vnode);
|
||||
acquire_sem(inUse);
|
||||
//printf ("poolvnode::get: Adding %d new elements to the pool!\n",newCount);
|
||||
for (int i=0;i<newCount;i++)
|
||||
unused.add(((void *)(newPage->getAddress()+(i*sizeof(vnode)))));
|
||||
release_sem(inUse);
|
||||
return (get()); // A little cheat - call self again to get the first one from stack...
|
||||
}
|
||||
}
|
||||
vnode *get(void);
|
||||
void put(vnode *in)
|
||||
{
|
||||
acquire_sem(inUse);
|
||||
|
||||
+13
-14
@@ -1,19 +1,18 @@
|
||||
#include "vpage.h"
|
||||
#include "vnodePool.h"
|
||||
#include "vmHeaderBlock.h"
|
||||
|
||||
extern swapFileManager swapMan;
|
||||
extern pageManager pageMan;
|
||||
extern poolvnode vnodePool;
|
||||
extern vmHeaderBlock *vmBlock;
|
||||
|
||||
void vpage::flush(void)
|
||||
{
|
||||
if (protection==writable && dirty)
|
||||
swapMan.write_block(*backingNode,((void *)(physPage->getAddress())), PAGE_SIZE);
|
||||
vmBlock->swapMan->write_block(*backingNode,((void *)(physPage->getAddress())), PAGE_SIZE);
|
||||
}
|
||||
|
||||
void vpage::refresh(void)
|
||||
{
|
||||
swapMan.read_block(*backingNode,((void *)(physPage->getAddress())), PAGE_SIZE);
|
||||
vmBlock->swapMan->read_block(*backingNode,((void *)(physPage->getAddress())), PAGE_SIZE);
|
||||
}
|
||||
|
||||
vpage::vpage(void)
|
||||
@@ -42,9 +41,9 @@ void vpage::setup(unsigned long start,vnode *backing, page *physMem,protectType
|
||||
backing->count++;
|
||||
}
|
||||
else
|
||||
backingNode=&(swapMan.findNode());
|
||||
backingNode=&(vmBlock->swapMan->findNode());
|
||||
if (!physMem && (state!=LAZY) && (state!=NO_LOCK))
|
||||
physPage=pageMan.getPage();
|
||||
physPage=vmBlock->pageMan->getPage();
|
||||
else
|
||||
{
|
||||
if (physMem)
|
||||
@@ -57,12 +56,12 @@ void vpage::setup(unsigned long start,vnode *backing, page *physMem,protectType
|
||||
void vpage::cleanup(void)
|
||||
{
|
||||
if (physPage) // Note that free means release one reference
|
||||
pageMan.freePage(physPage);
|
||||
vmBlock->pageMan->freePage(physPage);
|
||||
if (backingNode)
|
||||
{
|
||||
if (backingNode->fd)
|
||||
swapMan.freeVNode(*backingNode);
|
||||
vnodePool.put(backingNode);
|
||||
vmBlock->swapMan->freeVNode(*backingNode);
|
||||
vmBlock->vnodePool->put(backingNode);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,19 +81,19 @@ bool vpage::fault(void *fault_address, bool writeError) // true = OK, false = pa
|
||||
{
|
||||
if (protection==copyOnWrite) // Else, this was just a "let me know when I am dirty"...
|
||||
{
|
||||
page *newPhysPage=pageMan.getPage();
|
||||
page *newPhysPage=vmBlock->pageMan->getPage();
|
||||
if (!newPhysPage) // No room at the inn
|
||||
return false;
|
||||
memcpy((void *)(newPhysPage->getAddress()),(void *)(physPage->getAddress()),PAGE_SIZE);
|
||||
physPage=newPhysPage;
|
||||
protection=writable;
|
||||
backingNode=&(swapMan.findNode()); // Need new backing store for this node, since it was copied, the original is no good...
|
||||
backingNode=&(vmBlock->swapMan->findNode()); // Need new backing store for this node, since it was copied, the original is no good...
|
||||
// Update the architecture specific stuff here...
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
physPage=pageMan.getPage();
|
||||
physPage=vmBlock->pageMan->getPage();
|
||||
if (!physPage) // No room at the inn
|
||||
return false;
|
||||
// printf ("vpage::fault: New page allocated! new physical address = %x vnode.fd=%d, vnode.offset=%d, \n",physPage->getAddress(),((backingNode)?backingNode->fd:0),((backingNode)?backingNode->offset:0));
|
||||
@@ -162,7 +161,7 @@ void vpage::pager(int desperation)
|
||||
printf ("vpage::pager flushing\n");
|
||||
flush();
|
||||
printf ("vpage::pager freeing\n");
|
||||
pageMan.freePage(physPage);
|
||||
vmBlock->pageMan->freePage(physPage);
|
||||
printf ("vpage::pager going to NULL\n");
|
||||
physPage=NULL;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
#include "vpagePool.h"
|
||||
|
||||
#include "vmHeaderBlock.h"
|
||||
#include "pageManager.h"
|
||||
#include "vpage.h"
|
||||
|
||||
extern vmHeaderBlock *vmBlock;
|
||||
vpage *poolvpage::get(void)
|
||||
{
|
||||
vpage *ret=NULL;
|
||||
if (unused.count())
|
||||
{
|
||||
//printf ("poolvpage::get: Getting an unused one!\n");
|
||||
acquire_sem(inUse);
|
||||
ret=(vpage *)unused.next();
|
||||
release_sem(inUse);
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
//printf ("poolvpage::get: Returning address:%x \n",ret);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf ("poolvpage::get: Getting a new page!\n");
|
||||
page *newPage=vmBlock->pageMan->getPage();
|
||||
if (!newPage)
|
||||
throw ("Out of pages to allocate a pool!");
|
||||
int newCount=PAGE_SIZE/sizeof(vpage);
|
||||
acquire_sem(inUse);
|
||||
//printf ("poolvpage::get: Adding %d new elements to the pool!\n",newCount);
|
||||
for (int i=0;i<newCount;i++)
|
||||
unused.add(((void *)(newPage->getAddress()+(i*sizeof(vpage)))));
|
||||
release_sem(inUse);
|
||||
return (get()); // A little cheat - call self again to get the first one from stack...
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "pageManager.h"
|
||||
#include "vpage.h"
|
||||
|
||||
extern pageManager pageMan;
|
||||
#include <OS.h>
|
||||
#include "list.h"
|
||||
class vpage;
|
||||
class poolvpage
|
||||
{
|
||||
private:
|
||||
@@ -12,36 +11,7 @@ class poolvpage
|
||||
{
|
||||
inUse = create_sem(1,"vpagepool");
|
||||
}
|
||||
vpage *get(void)
|
||||
{
|
||||
vpage *ret=NULL;
|
||||
if (unused.count())
|
||||
{
|
||||
//printf ("poolvpage::get: Getting an unused one!\n");
|
||||
acquire_sem(inUse);
|
||||
ret=(vpage *)unused.next();
|
||||
release_sem(inUse);
|
||||
}
|
||||
if (ret)
|
||||
{
|
||||
//printf ("poolvpage::get: Returning address:%x \n",ret);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf ("poolvpage::get: Getting a new page!\n");
|
||||
page *newPage=pageMan.getPage();
|
||||
if (!newPage)
|
||||
throw ("Out of pages to allocate a pool!");
|
||||
int newCount=PAGE_SIZE/sizeof(vpage);
|
||||
acquire_sem(inUse);
|
||||
//printf ("poolvpage::get: Adding %d new elements to the pool!\n",newCount);
|
||||
for (int i=0;i<newCount;i++)
|
||||
unused.add(((void *)(newPage->getAddress()+(i*sizeof(vpage)))));
|
||||
release_sem(inUse);
|
||||
return (get()); // A little cheat - call self again to get the first one from stack...
|
||||
}
|
||||
}
|
||||
vpage *get(void);
|
||||
void put(vpage *in)
|
||||
{
|
||||
acquire_sem(inUse);
|
||||
|
||||
Reference in New Issue
Block a user