From f89acd8e065538fa780798862b5aadfc77d4d5ae Mon Sep 17 00:00:00 2001 From: Michael Phipps Date: Thu, 5 Sep 2002 03:26:02 +0000 Subject: [PATCH] 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 --- src/kernel/vm2/TODO | 5 +- src/kernel/vm2/area.C | 30 ++++++----- src/kernel/vm2/areaPool.C | 38 +++++++++++++ src/kernel/vm2/areaPool.h | 37 ++----------- src/kernel/vm2/cacheManager.C | 5 +- src/kernel/vm2/pageManager.C | 20 +++---- src/kernel/vm2/pageManager.h | 3 +- src/kernel/vm2/pools.h | 6 ++- src/kernel/vm2/swapFileManager.C | 5 +- src/kernel/vm2/test.C | 1 + src/kernel/vm2/vm.h | 10 ---- src/kernel/vm2/vmHeaderBlock.h | 24 +++++++++ src/kernel/vm2/vmInterface.C | 91 +++++++++++++++++++++++++------- src/kernel/vm2/vnodePool.C | 36 +++++++++++++ src/kernel/vm2/vnodePool.h | 38 ++----------- src/kernel/vm2/vpage.C | 27 +++++----- src/kernel/vm2/vpagePool.C | 37 +++++++++++++ src/kernel/vm2/vpagePool.h | 38 ++----------- 18 files changed, 273 insertions(+), 178 deletions(-) create mode 100644 src/kernel/vm2/areaPool.C create mode 100644 src/kernel/vm2/vmHeaderBlock.h create mode 100644 src/kernel/vm2/vnodePool.C create mode 100644 src/kernel/vm2/vpagePool.C 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);