diff --git a/src/kernel/vm2/area.C b/src/kernel/vm2/area.C index 125ae0bc18..9bae4b5f93 100644 --- a/src/kernel/vm2/area.C +++ b/src/kernel/vm2/area.C @@ -49,7 +49,7 @@ unsigned long area::mapAddressSpecToAddress(addressSpec type,void * req,int page default: // should never happen throw ("Unknown type passed to mapAddressSpecToAddress"); } -// error ("area::mapAddressSpecToAddress, in type: %s, address = %x, size = %d\n", ((type==EXACT)?"Exact":(type==BASE)?"BASE":(type==ANY)?"ANY":(type==CLONE)?"CLONE":"ANY_KERNEL"), requested,pageCount); + error ("area::mapAddressSpecToAddress, in type: %s, address = %x, size = %d\n", ((type==EXACT)?"Exact":(type==BASE)?"BASE":(type==ANY)?"ANY":(type==CLONE)?"CLONE":"ANY_KERNEL"), requested,pageCount); return base; } @@ -59,6 +59,13 @@ status_t area::createAreaGuts( char *inName, int pageCount, void **address, addr inName,pageCount,address,type,inState,protect,inFinalWrite,fd,offset,originalArea); vpage *newPage; + // We need RAM - let's fail if we don't have enough... This is Be's way. I probably would do this differently... + if (!originalArea && (inState!=LAZY) && (inState!=NO_LOCK) && (pageCount>(vmBlock->pageMan->freePageCount()))) + return B_NO_MEMORY; +// else +// error ("origArea = %d, instate = %d, LAZY = %d, NO_LOCK = %d, pageCountIn = %d, free pages = %d\n", +// originalArea, inState,LAZY ,NO_LOCK,pageCount,(vmBlock->pageMan->freePageCount())); + // Get an address to start this area at unsigned long base=mapAddressSpecToAddress(type,*address,pageCount); if (base==0) @@ -96,8 +103,8 @@ status_t area::createAreaGuts( char *inName, int pageCount, void **address, addr vpages.add(newPage); base+=PAGE_SIZE; } - error ("Dumping the area's hashtable"); - dump(); + //error ("Dumping the area's hashtable"); + //dump(); vmBlock->areas.add(this); return B_OK; } @@ -137,15 +144,15 @@ void area::freeArea(void) { vpage *page=reinterpret_cast(cur); if (finalWrite) { page->flush(); - error ("area::freeArea: flushed page %x\n",page); +// error ("area::freeArea: flushed page %x\n",page); } page->cleanup(); //page->next=NULL; vmBlock->vpagePool->put(page); } vpages.~hashTable(); - error ("area::freeArea ----------------------------------------------------------------\n"); - vmBlock->vnodeMan->dump(); +// error ("area::freeArea ----------------------------------------------------------------\n"); +// vmBlock->vnodeMan->dump(); //error ("area::freeArea: unlocking \n"); //error ("area::freeArea: ending \n"); } diff --git a/src/kernel/vm2/areaManager.C b/src/kernel/vm2/areaManager.C index f883318a4d..fa7f888dc5 100644 --- a/src/kernel/vm2/areaManager.C +++ b/src/kernel/vm2/areaManager.C @@ -137,21 +137,23 @@ long areaManager::nextAreaID=0; // Create an area; get a new structure, call setup, create the guts, set its ID, add it to our list int areaManager::createArea(char *AreaName,int pageCount,void **address, addressSpec addType,pageState state,protectType protect) { - //error ("areaManager::createArea - Creating an area\n"); + error ("areaManager::createArea - Creating an area\n"); lock(); area *newArea = new (vmBlock->areaPool->get()) area; - //error ("areaManager::createArea - got a new area (%p) from the areaPool\n",newArea); + error ("areaManager::createArea - got a new area (%p) from the areaPool\n",newArea); newArea->setup(this); - //error ("areaManager::createArea - setup complete\n"); - newArea->createArea(AreaName,pageCount,address,addType,state,protect); - //error ("areaManager::createArea - new area's createArea called\n"); - atomic_add(&nextAreaID,1); - newArea->setAreaID(nextAreaID); - //error ("areaManager::createArea - new area's setAreaID called\n"); - addArea(newArea); - //error ("areaManager::createArea - new area added to list\n"); - int retVal=newArea->getAreaID(); + error ("areaManager::createArea - setup complete\n"); + int retVal = newArea->createArea(AreaName,pageCount,address,addType,state,protect); + error ("areaManager::createArea - new area's createArea called\n"); + if (retVal==B_OK) { + atomic_add(&nextAreaID,1); + newArea->setAreaID(nextAreaID); + //error ("areaManager::createArea - new area's setAreaID called\n"); + addArea(newArea); + //error ("areaManager::createArea - new area added to list\n"); + retVal=newArea->getAreaID(); //error ("areaManager::createArea - new area id found\n"); + } unlock(); //error ("areaManager::createArea - Done Creating an area\n"); return retVal; diff --git a/src/kernel/vm2/hashTable.h b/src/kernel/vm2/hashTable.h index 40fbf987b3..8dcb6527f4 100644 --- a/src/kernel/vm2/hashTable.h +++ b/src/kernel/vm2/hashTable.h @@ -27,7 +27,7 @@ class hashTable : public list // Get the block for the page of pointers page *newPage=vmBlock->pageMan->getPage(); - error ("hashTable::hashTable - Got Page %x\n",newPage); + //error ("hashTable::hashTable - Got Page %x\n",newPage); pageList.add(newPage); if (!newPage) { @@ -42,7 +42,7 @@ class hashTable : public list for (int pageCount=0;pageCountpageMan->getPage(); - error ("hashTable::hashTable - Got Page %x\n",newPage); + //error ("hashTable::hashTable - Got Page %x\n",newPage); if (!newPage) throw ("Out of pages to allocate a pool!"); for (int i=0;i(pageList.next())) { - error ("hashTable::~hashTable; freeing page %x\n",cur); + //error ("hashTable::~hashTable; freeing page %x\n",cur); vmBlock->pageMan->freePage(cur); } } diff --git a/src/kernel/vm2/pageManager.C b/src/kernel/vm2/pageManager.C index 96250d4ea5..945d65d30f 100644 --- a/src/kernel/vm2/pageManager.C +++ b/src/kernel/vm2/pageManager.C @@ -25,7 +25,7 @@ void pageManager::setup(void *area,int pages) { unusedLock=create_sem (1,"unused_lock"); inUseLock=create_sem (1,"inuse_lock"); totalPages=pages; - error ("pageManager::setup - %d pages ready to rock and roll\n",unused.count()); + //error ("pageManager::setup - %d pages ready to rock and roll\n",unused.count()); } // Try to get a clean page first. If that fails, get a dirty one and clean it. Loop on this. @@ -46,7 +46,7 @@ page *pageManager::getPage(void) { ret->zero(); } // This could fail if someone swooped in and stole our page. } - error ("pageManager::getPage - returning page %x, clean = %d, unused = %d, inuse = %x\n",ret,clean.count(),unused.count(),inUse.count()); + //error ("pageManager::getPage - returning page %x, clean = %d, unused = %d, inuse = %x\n",ret,clean.count(),unused.count(),inUse.count()); acquire_sem(inUseLock); inUse.add(ret); release_sem(inUseLock); @@ -58,7 +58,7 @@ page *pageManager::getPage(void) { // Take page from in use list and put it on the unused list void pageManager::freePage(page *toFree) { - error ("pageManager::freePage; count = %d, address = %p\n",toFree->count,toFree); + //error ("pageManager::freePage; count = %d, address = %p\n",toFree->count,toFree); if (atomic_add(&(toFree->count),-1)==1) { // atomic_add returns the *PREVIOUS* value. So we need to check to see if the one we are wasting was the last one. acquire_sem(inUseLock); inUse.remove(toFree); diff --git a/src/kernel/vm2/pageManager.h b/src/kernel/vm2/pageManager.h index d56584a12e..f76507e60c 100644 --- a/src/kernel/vm2/pageManager.h +++ b/src/kernel/vm2/pageManager.h @@ -16,6 +16,7 @@ class pageManager { // Accessors int desperation(void); + int freePageCount(void) {return clean.count()+unused.count();} // External methods for "server" type calls void cleaner(void); diff --git a/src/kernel/vm2/vmInterface.C b/src/kernel/vm2/vmInterface.C index 4c67fa31fd..0a6d812820 100644 --- a/src/kernel/vm2/vmInterface.C +++ b/src/kernel/vm2/vmInterface.C @@ -145,7 +145,21 @@ status_t vmInterface::resizeArea(int Area,size_t size) int vmInterface::createArea(char *AreaName,int pageCount,void **address, addressSpec addType,pageState state,protectType protect) { int retVal; - //error ("vmInterface::createArea: Creating an area!\n"); + error ("vmInterface::createArea: Creating an area!\n"); + if (!AreaName) + return B_BAD_ADDRESS; + if (!address) + return B_BAD_ADDRESS; + if (strlen(AreaName)>=B_OS_NAME_LENGTH) + return B_BAD_VALUE; + if (pageCount<=0) + return B_BAD_VALUE; + if (addType>=CLONE || addType < EXACT) + return B_BAD_VALUE; + if (state>LOMEM || state < FULL) + return B_BAD_VALUE; + if (protect>copyOnWrite || protect < none) + return B_BAD_VALUE; retVal = getAM()->createArea(AreaName,pageCount,address,addType,state,protect); //error ("vmInterface::createArea: Done creating an area!\n"); return retVal; diff --git a/src/kernel/vm2/vnodeManager.C b/src/kernel/vm2/vnodeManager.C index c8b20b3944..711e9f4933 100644 --- a/src/kernel/vm2/vnodeManager.C +++ b/src/kernel/vm2/vnodeManager.C @@ -29,7 +29,7 @@ vpage *vnodeManager::findVnode(vnode &target) { // This method will make a new vnode object vpage *vnodeManager::addVnode(vnode &target,vpage &vp, vnode **newOne) { vpage *retVal; - error ("vnodeManager::addVnode : Adding by reference node %x, fd = %d, offset = %d\n",&target,target.fd,target.offset); + //error ("vnodeManager::addVnode : Adding by reference node %x, fd = %d, offset = %d\n",&target,target.fd,target.offset); vnode *found=reinterpret_cast(vnodes.find(&target)); if (!found) { found=new (vmBlock->vnodePool->get()) vnode; @@ -45,7 +45,7 @@ vpage *vnodeManager::addVnode(vnode &target,vpage &vp, vnode **newOne) { *newOne=retVal->getBacking(); } found->vpages.add(&vp); - error ("vnodeManager::addVnode returning %x, newOne = %x \n"); + //error ("vnodeManager::addVnode returning %x, newOne = %x \n"); return retVal; } @@ -54,7 +54,7 @@ vpage *vnodeManager::addVnode(vnode &target,vpage &vp, vnode **newOne) { // This method will NOT make a new vnode object vpage *vnodeManager::addVnode(vnode *target,vpage &vp) { vpage *retVal; - error ("vnodeManager::addVnode : Adding by pointer node %x, fd = %d, offset = %d\n",target,target->fd,target->offset); + //error ("vnodeManager::addVnode : Adding by pointer node %x, fd = %d, offset = %d\n",target,target->fd,target->offset); vnode *found=reinterpret_cast(vnodes.find(target)); if (!found) { found=target; @@ -64,13 +64,13 @@ vpage *vnodeManager::addVnode(vnode *target,vpage &vp) { else retVal=reinterpret_cast(found->vpages.top()); found->vpages.add(&vp); - found->vpages.dump(); - vnodes.dump(); +// found->vpages.dump(); +// vnodes.dump(); } // Remove a vpage from the manager; return "is this the last one" bool vnodeManager::remove(vnode &target,vpage &vp) { - error ("vnodeManager::remove : Removing by reference node %x, fd = %d, offset = %d\n",&target,target.fd,target.offset); + //error ("vnodeManager::remove : Removing by reference node %x, fd = %d, offset = %d\n",&target,target.fd,target.offset); vnode *found=reinterpret_cast(vnodes.find(&target)); if (!found) { vnodes.dump(); diff --git a/src/kernel/vm2/vpage.C b/src/kernel/vm2/vpage.C index ff1d34e2ad..d0adf7a195 100644 --- a/src/kernel/vm2/vpage.C +++ b/src/kernel/vm2/vpage.C @@ -12,7 +12,7 @@ extern vmHeaderBlock *vmBlock; // Write this vpage out if necessary void vpage::flush(void) { if (physPage && protection==writable && dirty) { - error ("vpage::write_block: writing, backingNode->fd = %d, backingNode->offset = %d, address = %x\n",backingNode->fd, backingNode->offset,physPage->getAddress()); +// error ("vpage::write_block: writing, backingNode->fd = %d, backingNode->offset = %d, address = %x\n",backingNode->fd, backingNode->offset,physPage->getAddress()); if (-1==lseek(backingNode->fd,backingNode->offset,SEEK_SET)) error ("vpage::flush:seek failed, fd = %d, errno = %d, %s\n",backingNode->fd,errno,strerror(errno)); if (-1==write(backingNode->fd,(void *)(physPage->getAddress()),PAGE_SIZE)) @@ -25,8 +25,8 @@ void vpage::flush(void) { // Load this vpage in if necessary void vpage::refresh(void) { - error ("vpage::refresh: reading into %x\n",physPage->getAddress()); - backingNode->dump(); +// error ("vpage::refresh: reading into %x\n",physPage->getAddress()); +// backingNode->dump(); if (backingNode->valid==false) return; // Do nothing. This prevents "garbage" data on disk from being read in... if (-1==lseek(backingNode->fd,backingNode->offset,SEEK_SET)) @@ -45,7 +45,7 @@ vpage::vpage(void) : physPage(NULL),backingNode(NULL),protection(none),dirty(fal void vpage::setup(unsigned long start,vnode *backing, page *physMem,protectType prot,pageState state, mmapSharing share) { // Basic setup from parameters vpage *clonedPage; // This is the page that this page is to be the clone of... - error ("vpage::setup: start = %x, vnode.fd=%d, vnode.offset=%d, physMem = %x\n",start,((backing)?backing->fd:0),((backing)?backing->offset:0), ((physMem)?(physMem->getAddress()):0)); +// error ("vpage::setup: start = %x, vnode.fd=%d, vnode.offset=%d, physMem = %x\n",start,((backing)?backing->fd:0),((backing)?backing->offset:0), ((physMem)?(physMem->getAddress()):0)); physPage=physMem; backingNode=backing; protection=prot; @@ -86,14 +86,14 @@ void vpage::setup(unsigned long start,vnode *backing, page *physMem,protectType // If there is no physical page already and we can't wait to get one, then get one now if (!physPage && (state!=LAZY) && (state!=NO_LOCK)) { physPage=vmBlock->pageMan->getPage(); - //error ("vpage::setup, state = %d, allocated page %x\n",state,physPage); + error ("vpage::setup, state = %d, allocated page %x\n",state,physPage); } else { // We either don't need it or we already have it. if (physPage) atomic_add(&(physPage->count),1); } - error ("vpage::setup: ended : start = %x, vnode.fd=%d, vnode.offset=%d, physMem = %x\n",start,((backing)?backing->fd:0),((backing)?backing->offset:0), ((physMem)?(physMem->getAddress()):0)); +// error ("vpage::setup: ended : start = %x, vnode.fd=%d, vnode.offset=%d, physMem = %x\n",start,((backing)?backing->fd:0),((backing)?backing->offset:0), ((physMem)?(physMem->getAddress()):0)); } // Destruction. @@ -120,14 +120,14 @@ void vpage::setProtection(protectType prot) { // This is dispatched by the real interrupt handler, who locates us // true = OK, false = panic. bool vpage::fault(void *fault_address, bool writeError, int &in_count) { - error ("vpage::fault: virtual address = %lx, write = %s\n",(unsigned long) fault_address,((writeError)?"true":"false")); +// error ("vpage::fault: virtual address = %lx, write = %s\n",(unsigned long) fault_address,((writeError)?"true":"false")); if (writeError && protection != copyOnWrite && protection != writable) return false; if (writeError && physPage) { // If we already have a page and this is a write, it is either a copy on write or a "dirty" notice dirty=true; if (protection==copyOnWrite) { // Else, this was just a "let me know when I am dirty"... page *newPhysPage=vmBlock->pageMan->getPage(); - error ("vpage::fault - copy on write allocated page %x\n",newPhysPage); +// error ("vpage::fault - copy on write allocated page %x\n",newPhysPage); memcpy((void *)(newPhysPage->getAddress()),(void *)(physPage->getAddress()),PAGE_SIZE); physPage=newPhysPage; protection=writable; @@ -140,18 +140,18 @@ bool vpage::fault(void *fault_address, bool writeError, int &in_count) { } // Guess this is the real deal. Get a physical page. physPage=vmBlock->pageMan->getPage(); - error ("vpage::fault - regular - allocated page %x\n",physPage); +// error ("vpage::fault - regular - allocated page %x\n",physPage); if (!physPage) // No room at the inn return false; - error ("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)); +// error ("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)); // Update the architecture specific stuff here... // This refresh is unneeded if the data was never written out... - dump(); +// dump(); refresh(); // I wonder if these vnode calls are safe during an interrupt... dirty=writeError; // If the client is writing, we are now dirty (or will be when we get back to user land) in_count++; //error ("vpage::fault: Refreshed\n"); - dump(); +// //dump(); //error ("vpage::fault: exiting\n"); return true; } @@ -191,12 +191,12 @@ void vpage::setByte(unsigned long address,char value,areaManager *manager) { } int vpage::getInt(unsigned long address,areaManager *manager) { - error ("vpage::getInt: address = %ld\n",address ); +// error ("vpage::getInt: address = %ld\n",address ); if (!physPage) if (!manager->fault((void *)(address),false)) throw ("vpage::getInt"); //error ("vpage::getInt: About to return %d\n", *((char *)(address-start_address+physPage->getAddress()))); - dump(); + //dump(); return *((int *)(address-start_address+physPage->getAddress())); }