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:
Michael Phipps
2002-09-05 03:26:02 +00:00
parent e4676f539b
commit f89acd8e06
18 changed files with 273 additions and 178 deletions
+4 -1
View File
@@ -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
View File
@@ -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();
+38
View File
@@ -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...
}
}
+4 -33
View File
@@ -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);
+3 -2
View File
@@ -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);
+8 -12
View File
@@ -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)));
}
+2 -1
View File
@@ -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);
+4 -2
View File
@@ -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);
+3 -2
View File
@@ -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);
+1
View File
@@ -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++)
-10
View File
@@ -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
+24
View File
@@ -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
+71 -20
View File
@@ -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);
+36
View File
@@ -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...
}
}
+5 -33
View File
@@ -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
View File
@@ -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;
}
+37
View File
@@ -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...
}
}
+4 -34
View File
@@ -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);