bug fixes found as a resule of testing

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2543 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Michael Phipps 2003-01-24 05:41:40 +00:00
parent cd5053c617
commit 556632b760
8 changed files with 68 additions and 44 deletions

View File

@ -49,7 +49,7 @@ unsigned long area::mapAddressSpecToAddress(addressSpec type,void * req,int page
default: // should never happen default: // should never happen
throw ("Unknown type passed to mapAddressSpecToAddress"); 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; 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); inName,pageCount,address,type,inState,protect,inFinalWrite,fd,offset,originalArea);
vpage *newPage; 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 // Get an address to start this area at
unsigned long base=mapAddressSpecToAddress(type,*address,pageCount); unsigned long base=mapAddressSpecToAddress(type,*address,pageCount);
if (base==0) if (base==0)
@ -96,8 +103,8 @@ status_t area::createAreaGuts( char *inName, int pageCount, void **address, addr
vpages.add(newPage); vpages.add(newPage);
base+=PAGE_SIZE; base+=PAGE_SIZE;
} }
error ("Dumping the area's hashtable"); //error ("Dumping the area's hashtable");
dump(); //dump();
vmBlock->areas.add(this); vmBlock->areas.add(this);
return B_OK; return B_OK;
} }
@ -137,15 +144,15 @@ void area::freeArea(void) {
vpage *page=reinterpret_cast<vpage *>(cur); vpage *page=reinterpret_cast<vpage *>(cur);
if (finalWrite) { if (finalWrite) {
page->flush(); page->flush();
error ("area::freeArea: flushed page %x\n",page); // error ("area::freeArea: flushed page %x\n",page);
} }
page->cleanup(); page->cleanup();
//page->next=NULL; //page->next=NULL;
vmBlock->vpagePool->put(page); vmBlock->vpagePool->put(page);
} }
vpages.~hashTable(); vpages.~hashTable();
error ("area::freeArea ----------------------------------------------------------------\n"); // error ("area::freeArea ----------------------------------------------------------------\n");
vmBlock->vnodeMan->dump(); // vmBlock->vnodeMan->dump();
//error ("area::freeArea: unlocking \n"); //error ("area::freeArea: unlocking \n");
//error ("area::freeArea: ending \n"); //error ("area::freeArea: ending \n");
} }

View File

@ -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 // 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) { 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(); lock();
area *newArea = new (vmBlock->areaPool->get()) area; 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); newArea->setup(this);
//error ("areaManager::createArea - setup complete\n"); error ("areaManager::createArea - setup complete\n");
newArea->createArea(AreaName,pageCount,address,addType,state,protect); int retVal = newArea->createArea(AreaName,pageCount,address,addType,state,protect);
//error ("areaManager::createArea - new area's createArea called\n"); error ("areaManager::createArea - new area's createArea called\n");
atomic_add(&nextAreaID,1); if (retVal==B_OK) {
newArea->setAreaID(nextAreaID); atomic_add(&nextAreaID,1);
//error ("areaManager::createArea - new area's setAreaID called\n"); newArea->setAreaID(nextAreaID);
addArea(newArea); //error ("areaManager::createArea - new area's setAreaID called\n");
//error ("areaManager::createArea - new area added to list\n"); addArea(newArea);
int retVal=newArea->getAreaID(); //error ("areaManager::createArea - new area added to list\n");
retVal=newArea->getAreaID();
//error ("areaManager::createArea - new area id found\n"); //error ("areaManager::createArea - new area id found\n");
}
unlock(); unlock();
//error ("areaManager::createArea - Done Creating an area\n"); //error ("areaManager::createArea - Done Creating an area\n");
return retVal; return retVal;

View File

@ -27,7 +27,7 @@ class hashTable : public list
// Get the block for the page of pointers // Get the block for the page of pointers
page *newPage=vmBlock->pageMan->getPage(); page *newPage=vmBlock->pageMan->getPage();
error ("hashTable::hashTable - Got Page %x\n",newPage); //error ("hashTable::hashTable - Got Page %x\n",newPage);
pageList.add(newPage); pageList.add(newPage);
if (!newPage) { if (!newPage) {
@ -42,7 +42,7 @@ class hashTable : public list
for (int pageCount=0;pageCount<pages;pageCount++) { for (int pageCount=0;pageCount<pages;pageCount++) {
// Allocate a page of lists // Allocate a page of lists
page *newPage=vmBlock->pageMan->getPage(); page *newPage=vmBlock->pageMan->getPage();
error ("hashTable::hashTable - Got Page %x\n",newPage); //error ("hashTable::hashTable - Got Page %x\n",newPage);
if (!newPage) if (!newPage)
throw ("Out of pages to allocate a pool!"); throw ("Out of pages to allocate a pool!");
for (int i=0;i<listsPerPage;i++) for (int i=0;i<listsPerPage;i++)
@ -52,7 +52,7 @@ class hashTable : public list
} }
~hashTable() { ~hashTable() {
while (struct page *cur=reinterpret_cast<page *>(pageList.next())) { while (struct page *cur=reinterpret_cast<page *>(pageList.next())) {
error ("hashTable::~hashTable; freeing page %x\n",cur); //error ("hashTable::~hashTable; freeing page %x\n",cur);
vmBlock->pageMan->freePage(cur); vmBlock->pageMan->freePage(cur);
} }
} }

View File

@ -25,7 +25,7 @@ void pageManager::setup(void *area,int pages) {
unusedLock=create_sem (1,"unused_lock"); unusedLock=create_sem (1,"unused_lock");
inUseLock=create_sem (1,"inuse_lock"); inUseLock=create_sem (1,"inuse_lock");
totalPages=pages; 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. // 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(); ret->zero();
} // This could fail if someone swooped in and stole our page. } // 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); acquire_sem(inUseLock);
inUse.add(ret); inUse.add(ret);
release_sem(inUseLock); release_sem(inUseLock);
@ -58,7 +58,7 @@ page *pageManager::getPage(void) {
// Take page from in use list and put it on the unused list // Take page from in use list and put it on the unused list
void pageManager::freePage(page *toFree) { 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. 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); acquire_sem(inUseLock);
inUse.remove(toFree); inUse.remove(toFree);

View File

@ -16,6 +16,7 @@ class pageManager {
// Accessors // Accessors
int desperation(void); int desperation(void);
int freePageCount(void) {return clean.count()+unused.count();}
// External methods for "server" type calls // External methods for "server" type calls
void cleaner(void); void cleaner(void);

View File

@ -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 vmInterface::createArea(char *AreaName,int pageCount,void **address, addressSpec addType,pageState state,protectType protect)
{ {
int retVal; 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); retVal = getAM()->createArea(AreaName,pageCount,address,addType,state,protect);
//error ("vmInterface::createArea: Done creating an area!\n"); //error ("vmInterface::createArea: Done creating an area!\n");
return retVal; return retVal;

View File

@ -29,7 +29,7 @@ vpage *vnodeManager::findVnode(vnode &target) {
// This method will make a new vnode object // This method will make a new vnode object
vpage *vnodeManager::addVnode(vnode &target,vpage &vp, vnode **newOne) { vpage *vnodeManager::addVnode(vnode &target,vpage &vp, vnode **newOne) {
vpage *retVal; 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<vnode *>(vnodes.find(&target)); vnode *found=reinterpret_cast<vnode *>(vnodes.find(&target));
if (!found) { if (!found) {
found=new (vmBlock->vnodePool->get()) vnode; found=new (vmBlock->vnodePool->get()) vnode;
@ -45,7 +45,7 @@ vpage *vnodeManager::addVnode(vnode &target,vpage &vp, vnode **newOne) {
*newOne=retVal->getBacking(); *newOne=retVal->getBacking();
} }
found->vpages.add(&vp); found->vpages.add(&vp);
error ("vnodeManager::addVnode returning %x, newOne = %x \n"); //error ("vnodeManager::addVnode returning %x, newOne = %x \n");
return retVal; return retVal;
} }
@ -54,7 +54,7 @@ vpage *vnodeManager::addVnode(vnode &target,vpage &vp, vnode **newOne) {
// This method will NOT make a new vnode object // This method will NOT make a new vnode object
vpage *vnodeManager::addVnode(vnode *target,vpage &vp) { vpage *vnodeManager::addVnode(vnode *target,vpage &vp) {
vpage *retVal; 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<vnode *>(vnodes.find(target)); vnode *found=reinterpret_cast<vnode *>(vnodes.find(target));
if (!found) { if (!found) {
found=target; found=target;
@ -64,13 +64,13 @@ vpage *vnodeManager::addVnode(vnode *target,vpage &vp) {
else else
retVal=reinterpret_cast<vpage *>(found->vpages.top()); retVal=reinterpret_cast<vpage *>(found->vpages.top());
found->vpages.add(&vp); found->vpages.add(&vp);
found->vpages.dump(); // found->vpages.dump();
vnodes.dump(); // vnodes.dump();
} }
// Remove a vpage from the manager; return "is this the last one" // Remove a vpage from the manager; return "is this the last one"
bool vnodeManager::remove(vnode &target,vpage &vp) { 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<vnode *>(vnodes.find(&target)); vnode *found=reinterpret_cast<vnode *>(vnodes.find(&target));
if (!found) { if (!found) {
vnodes.dump(); vnodes.dump();

View File

@ -12,7 +12,7 @@ extern vmHeaderBlock *vmBlock;
// Write this vpage out if necessary // Write this vpage out if necessary
void vpage::flush(void) { void vpage::flush(void) {
if (physPage && protection==writable && dirty) { 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)) 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)); 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)) if (-1==write(backingNode->fd,(void *)(physPage->getAddress()),PAGE_SIZE))
@ -25,8 +25,8 @@ void vpage::flush(void) {
// Load this vpage in if necessary // Load this vpage in if necessary
void vpage::refresh(void) { void vpage::refresh(void) {
error ("vpage::refresh: reading into %x\n",physPage->getAddress()); // error ("vpage::refresh: reading into %x\n",physPage->getAddress());
backingNode->dump(); // backingNode->dump();
if (backingNode->valid==false) if (backingNode->valid==false)
return; // Do nothing. This prevents "garbage" data on disk from being read in... return; // Do nothing. This prevents "garbage" data on disk from being read in...
if (-1==lseek(backingNode->fd,backingNode->offset,SEEK_SET)) 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) { void vpage::setup(unsigned long start,vnode *backing, page *physMem,protectType prot,pageState state, mmapSharing share) {
// Basic setup from parameters // Basic setup from parameters
vpage *clonedPage; // This is the page that this page is to be the clone of... 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; physPage=physMem;
backingNode=backing; backingNode=backing;
protection=prot; 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 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)) { if (!physPage && (state!=LAZY) && (state!=NO_LOCK)) {
physPage=vmBlock->pageMan->getPage(); 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. else { // We either don't need it or we already have it.
if (physPage) if (physPage)
atomic_add(&(physPage->count),1); 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. // Destruction.
@ -120,14 +120,14 @@ void vpage::setProtection(protectType prot) {
// This is dispatched by the real interrupt handler, who locates us // This is dispatched by the real interrupt handler, who locates us
// true = OK, false = panic. // true = OK, false = panic.
bool vpage::fault(void *fault_address, bool writeError, int &in_count) { 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) if (writeError && protection != copyOnWrite && protection != writable)
return false; 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 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; dirty=true;
if (protection==copyOnWrite) { // Else, this was just a "let me know when I am dirty"... if (protection==copyOnWrite) { // Else, this was just a "let me know when I am dirty"...
page *newPhysPage=vmBlock->pageMan->getPage(); 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); memcpy((void *)(newPhysPage->getAddress()),(void *)(physPage->getAddress()),PAGE_SIZE);
physPage=newPhysPage; physPage=newPhysPage;
protection=writable; 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. // Guess this is the real deal. Get a physical page.
physPage=vmBlock->pageMan->getPage(); 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 if (!physPage) // No room at the inn
return false; 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... // Update the architecture specific stuff here...
// This refresh is unneeded if the data was never written out... // 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... 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) dirty=writeError; // If the client is writing, we are now dirty (or will be when we get back to user land)
in_count++; in_count++;
//error ("vpage::fault: Refreshed\n"); //error ("vpage::fault: Refreshed\n");
dump(); // //dump();
//error ("vpage::fault: exiting\n"); //error ("vpage::fault: exiting\n");
return true; return true;
} }
@ -191,12 +191,12 @@ void vpage::setByte(unsigned long address,char value,areaManager *manager) {
} }
int vpage::getInt(unsigned long address,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 (!physPage)
if (!manager->fault((void *)(address),false)) if (!manager->fault((void *)(address),false))
throw ("vpage::getInt"); throw ("vpage::getInt");
//error ("vpage::getInt: About to return %d\n", *((char *)(address-start_address+physPage->getAddress()))); //error ("vpage::getInt: About to return %d\n", *((char *)(address-start_address+physPage->getAddress())));
dump(); //dump();
return *((int *)(address-start_address+physPage->getAddress())); return *((int *)(address-start_address+physPage->getAddress()));
} }