diff --git a/src/kernel/vm2/TODO b/src/kernel/vm2/TODO index 47e493fd0c..a0d36acf72 100644 --- a/src/kernel/vm2/TODO +++ b/src/kernel/vm2/TODO @@ -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 diff --git a/src/kernel/vm2/area.C b/src/kernel/vm2/area.C index a06e465f7d..6602d142b3 100644 --- a/src/kernel/vm2/area.C +++ b/src/kernel/vm2/area.C @@ -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;ivnodePool->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;ivpagePool->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;ivpagePool->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(); diff --git a/src/kernel/vm2/areaPool.C b/src/kernel/vm2/areaPool.C new file mode 100644 index 0000000000..b3e63180ff --- /dev/null +++ b/src/kernel/vm2/areaPool.C @@ -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;igetAddress()+(i*sizeof(area))))); + release_sem(inUse); + return (get()); // A little cheat - call self again to get the first one from stack... + } + } diff --git a/src/kernel/vm2/areaPool.h b/src/kernel/vm2/areaPool.h index 4e8eeb6ea8..aeb4bc3824 100644 --- a/src/kernel/vm2/areaPool.h +++ b/src/kernel/vm2/areaPool.h @@ -1,6 +1,6 @@ -#include "pageManager.h" - -extern pageManager pageMan; +#include +#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;igetAddress()+(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); diff --git a/src/kernel/vm2/cacheManager.C b/src/kernel/vm2/cacheManager.C index 8ddc9fa930..e356425130 100644 --- a/src/kernel/vm2/cacheManager.C +++ b/src/kernel/vm2/cacheManager.C @@ -1,8 +1,9 @@ #include #include #include +#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); diff --git a/src/kernel/vm2/pageManager.C b/src/kernel/vm2/pageManager.C index e1f46fbd1c..a7866a8407 100644 --- a/src/kernel/vm2/pageManager.C +++ b/src/kernel/vm2/pageManager.C @@ -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;isetup(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))); } diff --git a/src/kernel/vm2/pageManager.h b/src/kernel/vm2/pageManager.h index 6e7d2a1014..d5125f734b 100644 --- a/src/kernel/vm2/pageManager.h +++ b/src/kernel/vm2/pageManager.h @@ -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); diff --git a/src/kernel/vm2/pools.h b/src/kernel/vm2/pools.h index b9b38b83ab..874d1155bb 100644 --- a/src/kernel/vm2/pools.h +++ b/src/kernel/vm2/pools.h @@ -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); diff --git a/src/kernel/vm2/swapFileManager.C b/src/kernel/vm2/swapFileManager.C index 5bbeba4e59..ff155ba8f6 100644 --- a/src/kernel/vm2/swapFileManager.C +++ b/src/kernel/vm2/swapFileManager.C @@ -4,8 +4,9 @@ #include #include #include +#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); diff --git a/src/kernel/vm2/test.C b/src/kernel/vm2/test.C index 829d8731ac..04bc34f962 100644 --- a/src/kernel/vm2/test.C +++ b/src/kernel/vm2/test.C @@ -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 #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); diff --git a/src/kernel/vm2/vnodePool.C b/src/kernel/vm2/vnodePool.C new file mode 100644 index 0000000000..c65a317070 --- /dev/null +++ b/src/kernel/vm2/vnodePool.C @@ -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;igetAddress()+(i*sizeof(vnode))))); + release_sem(inUse); + return (get()); // A little cheat - call self again to get the first one from stack... + } + } diff --git a/src/kernel/vm2/vnodePool.h b/src/kernel/vm2/vnodePool.h index 51c02a11e0..6ad7d73b86 100644 --- a/src/kernel/vm2/vnodePool.h +++ b/src/kernel/vm2/vnodePool.h @@ -1,6 +1,7 @@ -#include "pageManager.h" - -extern pageManager pageMan; +#include +#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;igetAddress()+(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); diff --git a/src/kernel/vm2/vpage.C b/src/kernel/vm2/vpage.C index fc90542afb..c676395cea 100644 --- a/src/kernel/vm2/vpage.C +++ b/src/kernel/vm2/vpage.C @@ -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; } diff --git a/src/kernel/vm2/vpagePool.C b/src/kernel/vm2/vpagePool.C new file mode 100644 index 0000000000..ea126c7e1e --- /dev/null +++ b/src/kernel/vm2/vpagePool.C @@ -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;igetAddress()+(i*sizeof(vpage))))); + release_sem(inUse); + return (get()); // A little cheat - call self again to get the first one from stack... + } + } diff --git a/src/kernel/vm2/vpagePool.h b/src/kernel/vm2/vpagePool.h index cd3aa21325..9e7bed176a 100644 --- a/src/kernel/vm2/vpagePool.h +++ b/src/kernel/vm2/vpagePool.h @@ -1,7 +1,6 @@ -#include "pageManager.h" -#include "vpage.h" - -extern pageManager pageMan; +#include +#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;igetAddress()+(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);