From 8aabdd2043571fc07f6e1b2da7b03df5b0def0f8 Mon Sep 17 00:00:00 2001 From: Michael Phipps Date: Mon, 16 Sep 2002 03:14:44 +0000 Subject: [PATCH] More improvements. Does not run all tests, though - still have some locking issues around clone area, I think. Still, much improved... git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1048 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kernel/vm2/Jamfile | 4 +- src/kernel/vm2/TODO | 3 +- src/kernel/vm2/area.C | 40 ++++++------ src/kernel/vm2/area.h | 5 +- src/kernel/vm2/areaManager.C | 84 +++++++++++++------------ src/kernel/vm2/areaManager.h | 8 +-- src/kernel/vm2/areaPool.C | 8 +-- src/kernel/vm2/error.C | 19 ++++++ src/kernel/vm2/error.h | 1 + src/kernel/vm2/list.h | 9 +-- src/kernel/vm2/olTest.C | 2 +- src/kernel/vm2/olist.h | 12 ++-- src/kernel/vm2/page.C | 6 +- src/kernel/vm2/page.h | 2 +- src/kernel/vm2/pageManager.C | 82 ++++++++++++------------ src/kernel/vm2/pools.h | 8 +-- src/kernel/vm2/swapFileManager.C | 33 +++++----- src/kernel/vm2/test.C | 103 ++++++++++++++++++------------- src/kernel/vm2/vm.h | 2 +- src/kernel/vm2/vmInterface.C | 25 +++++--- src/kernel/vm2/vmInterface.h | 4 +- src/kernel/vm2/vnodePool.C | 8 +-- src/kernel/vm2/vpage.C | 45 +++++++------- src/kernel/vm2/vpage.h | 4 +- src/kernel/vm2/vpagePool.C | 8 +-- 25 files changed, 293 insertions(+), 232 deletions(-) create mode 100644 src/kernel/vm2/error.C create mode 100644 src/kernel/vm2/error.h diff --git a/src/kernel/vm2/Jamfile b/src/kernel/vm2/Jamfile index 6428bd539f..6da6705b06 100644 --- a/src/kernel/vm2/Jamfile +++ b/src/kernel/vm2/Jamfile @@ -1,4 +1,6 @@ SubDir OBOS_TOP src kernel vm2 ; -BinCommand vmTest : area.C areaManager.C cacheManager.C page.C pageManager.C swapFileManager.C test.C vmInterface.C vpage.C : root be ; +BinCommand vmTest : error.C area.C areaManager.C cacheManager.C page.C pageManager.C swapFileManager.C test.C vmInterface.C vpage.C areaPool.C vnodePool.C vpagePool.C : root be ; +BinCommand olTest : error.C olTest.C : root be ; + diff --git a/src/kernel/vm2/TODO b/src/kernel/vm2/TODO index a0d36acf72..6fd9fd2bfb 100644 --- a/src/kernel/vm2/TODO +++ b/src/kernel/vm2/TODO @@ -14,7 +14,8 @@ paging disk caching -5) Improve locking (remains to be seen - works ok so far) 6) See how unresolvable page faults and permissions errors are handled - need to properly handle - This may have to come at HW integration time, since they will be app signals, etc... 7) There is no arch-level integration. This is to be tested (to death) in user land first. * == can not be done in user land. +8) Add statistics counting for copy in/out +9) Must lock original area when clone()ing. Sigh. diff --git a/src/kernel/vm2/area.C b/src/kernel/vm2/area.C index c3d563954b..03ae8841cd 100644 --- a/src/kernel/vm2/area.C +++ b/src/kernel/vm2/area.C @@ -15,9 +15,9 @@ area::area(void) void area::setup (areaManager *myManager) { - //printf ("area::setup setting up new area\n"); + //error ("area::setup setting up new area\n"); manager=myManager; - //printf ("area::setup done setting up new area\n"); + //error ("area::setup done setting up new area\n"); } unsigned long area::mapAddressSpecToAddress(addressSpec type,unsigned long requested,int pageCount) @@ -44,7 +44,7 @@ unsigned long area::mapAddressSpecToAddress(addressSpec type,unsigned long reque default: // should never happen throw ("Unknown type passed to mapAddressSpecToAddress"); } -// printf ("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; } @@ -66,7 +66,7 @@ status_t area::createAreaMappingFile(char *inName, int pageCount,void **address, 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); +// error ("New vnode with fd %d, offset = %d\n",fd,newVnode->offset); } state=inState; @@ -86,14 +86,14 @@ status_t area::createArea(char *inName, int pageCount,void **address, addressSpe finalWrite=false; unsigned long requested=(unsigned long)(*address); // Hold onto this to make sure that EXACT works... -// printf ("area::createArea: Locked in createArea\n"); + error ("area::createArea: Locked in createArea\n"); unsigned long base=mapAddressSpecToAddress(type,requested,pageCount); if (base==0) return B_ERROR; -// printf ("area::createArea: base address = %ld\n",base); + error ("area::createArea: base address = %ld\n",base); for (int i=0;ivpagePool->get()) vpage; newPage->setup(base+PAGE_SIZE*i,NULL,NULL,protect,inState); vpages.add(newPage); @@ -101,22 +101,22 @@ status_t area::createArea(char *inName, int pageCount,void **address, addressSpe start_address=base; end_address=base+(pageCount*PAGE_SIZE)-1; *address=(void *)base; -// printf ("area::createArea: unlocked in createArea\n"); + error ("area::createArea: unlocked in createArea\n"); return B_OK; } status_t area::cloneArea(area *origArea, char *inName, void **address, addressSpec type,pageState inState,protectType protect) { -// printf ("area::cloneArea: entered\n"); +// error ("area::cloneArea: entered\n"); strcpy(name,inName); int pageCount = origArea->getPageCount(); -// printf ("area::cloneArea: locked\n"); +// error ("area::cloneArea: locked\n"); unsigned long requested=(unsigned long)(*address); // Hold onto this to make sure that EXACT works... unsigned long base=mapAddressSpecToAddress(type,requested,pageCount); if (base==0) return B_ERROR; start_address=base; -// printf ("area::cloneArea: base address = %x\n",base); +// error ("area::cloneArea: base address = %x\n",base); for (struct node *cur=origArea->vpages.rock;cur;) { @@ -132,29 +132,29 @@ status_t area::cloneArea(area *origArea, char *inName, void **address, addressSp end_address=base+(pageCount*PAGE_SIZE)-1; *address=(void *)start_address; finalWrite=false; -// printf ("area::cloneArea: unlocked\n"); +// error ("area::cloneArea: unlocked\n"); return B_OK; } void area::freeArea(void) { -//printf ("area::freeArea: starting \n"); +//error ("area::freeArea: starting \n"); // vpages.dump(); node *cur; while ((cur=vpages.next())!=NULL) { -//printf ("area::freeArea: wasting a page: %x\n",cur); +//error ("area::freeArea: wasting a page: %x\n",cur); vpage *page=reinterpret_cast(cur); if (finalWrite) page->flush(); -//printf ("area::freeArea: flushed a page \n"); +//error ("area::freeArea: flushed a page \n"); page->cleanup(); //page->next=NULL; vmBlock->vpagePool->put(page); } -//printf ("area::freeArea: unlocking \n"); -//printf ("area::freeArea: ending \n"); +//error ("area::freeArea: unlocking \n"); +//error ("area::freeArea: ending \n"); } status_t area::getInfo(area_info *dest) @@ -186,7 +186,7 @@ bool area::contains(void *address) { // no need to lock here... unsigned long base=(unsigned long)(address); -// printf ("area::contains: looking for %d in %d -- %d, value = %d\n",base,start_address,end_address, ((start_address<=base) && (end_address>=base))); +// error ("area::contains: looking for %d in %d -- %d, value = %d\n",base,start_address,end_address, ((start_address<=base) && (end_address>=base))); return ((start_address<=base) && (base<=end_address)); } @@ -242,7 +242,7 @@ vpage *area::findVPage(unsigned long address) for (struct node *cur=vpages.rock;cur;cur=cur->next) { vpage *page=(vpage *)cur; - //printf ("Examining following vpage, looking for address %lx\n",address); + //error ("Examining following vpage, looking for address %lx\n",address); //page->dump(); if (page->contains(address)) return page; @@ -318,7 +318,7 @@ void area::saver(void) void area::dump(void) { - printf ("area::dump: size = %ld, lock = %d, address = %lx\n",end_address-start_address,state,start_address); + error ("area::dump: size = %ld, lock = %d, address = %lx\n",end_address-start_address,state,start_address); for (struct node *cur=vpages.rock;cur;) { vpage *page=(vpage *)cur; diff --git a/src/kernel/vm2/area.h b/src/kernel/vm2/area.h index ad143b711c..a7922e4b42 100644 --- a/src/kernel/vm2/area.h +++ b/src/kernel/vm2/area.h @@ -3,6 +3,7 @@ #include "OS.h" #include "vm.h" #include "list.h" +#include "olist.h" class areaManager; class vpage; @@ -10,12 +11,12 @@ class vpage; class area : public node { protected: - list vpages; + orderedList vpages; char name[B_OS_NAME_LENGTH]; pageState state; protectType protection; bool finalWrite; - int areaID; + area_id areaID; int in_count; int out_count; int copy_count; diff --git a/src/kernel/vm2/areaManager.C b/src/kernel/vm2/areaManager.C index b3e6f57337..3833a64827 100644 --- a/src/kernel/vm2/areaManager.C +++ b/src/kernel/vm2/areaManager.C @@ -28,7 +28,7 @@ unsigned long areaManager::getNextAddress(int pages, unsigned long start) if (cur) { area *myArea=(area *)cur; -// printf ("Looking for %x, %d pages; current = %x\n",start,pages,myArea->getEndAddress()); +// error ("Looking for %x, %d pages; current = %x\n",start,pages,myArea->getEndAddress()); if (!myArea->couldAdd(start,end)) { // if we don't work, there must be an overlap, so go to the end of this area. start=myArea->getEndAddress(); @@ -39,24 +39,24 @@ unsigned long areaManager::getNextAddress(int pages, unsigned long start) return start; } -void areaManager::freeArea(int areaID) +void areaManager::freeArea(area_id areaID) { - printf ("areaManager::freeArea: begin\n"); + error ("areaManager::freeArea: begin\n"); lock(); area *oldArea=findArea(areaID); - //printf ("areaManager::freeArea: found area %x\n",oldArea); + //error ("areaManager::freeArea: found area %x\n",oldArea); if (oldArea) { -// printf ("areaManager::freeArea: removing area %x from linked list\n",oldArea); -// printf ("areaManager::freeArea: areaManager = %x \n",manager); +// error ("areaManager::freeArea: removing area %x from linked list\n",oldArea); +// error ("areaManager::freeArea: areaManager = %x \n",manager); removeArea(oldArea); -// printf ("areaManager::freeArea: deleting area %x \n",oldArea); +// error ("areaManager::freeArea: deleting area %x \n",oldArea); oldArea->freeArea(); -// printf ("areaManager::freeArea: freeArea complete \n"); +// error ("areaManager::freeArea: freeArea complete \n"); vmBlock->areaPool->put(oldArea); } else - printf ("areaManager::freeArea: unable to find requested area\n"); + error ("areaManager::freeArea: unable to find requested area\n"); unlock(); } @@ -70,7 +70,7 @@ area *areaManager::findAreaLock(void *address) area *areaManager::findArea(char *address) { - printf ("Finding area by string\n"); + error ("Finding area by string\n"); lock(); area *retVal=NULL; for (struct node *cur=areas.rock;cur && !retVal;cur=cur->next) @@ -86,22 +86,21 @@ area *areaManager::findArea(char *address) area *areaManager::findArea(void *address) { // THIS DOES NOT HAVE LOCKING - all callers must lock. - //printf ("Finding area by void * address\n"); + //error ("Finding area by void * address\n"); for (struct node *cur=areas.rock;cur;cur=cur->next) { area *myArea=(area *)cur; -// printf ("areaManager::findArea: Looking for %x between %x and %x\n",address,myArea->getStartAddress(),myArea->getEndAddress()); - fflush(NULL); +// error ("areaManager::findArea: Looking for %x between %x and %x\n",address,myArea->getStartAddress(),myArea->getEndAddress()); if (myArea->contains(address)) return myArea; } - printf ("areaManager::findArea is giving up\n"); + error ("areaManager::findArea is giving up\n"); return NULL; } area *areaManager::findAreaLock(area_id id) { - printf ("Finding area by areaID \n"); + error ("Finding area by areaID \n"); lock(); area *retVal=findArea(id); unlock(); @@ -110,7 +109,7 @@ area *areaManager::findAreaLock(area_id id) area *areaManager::findArea(area_id id) { - //printf ("Finding area by area_id\n"); + //error ("Finding area by area_id\n"); area *retVal=NULL; for (struct node *cur=areas.rock;cur && !retVal;cur=cur->next) { @@ -125,7 +124,7 @@ bool areaManager::fault(void *fault_address, bool writeError) // true = OK, fals { area *myArea; bool retVal; - printf ("Faulting \n"); + error ("Faulting \n"); lock(); myArea=findArea(fault_address); if (myArea) @@ -136,40 +135,48 @@ bool areaManager::fault(void *fault_address, bool writeError) // true = OK, fals return retVal; } -int areaManager::nextAreaID=0; +long areaManager::nextAreaID=0; int areaManager::createArea(char *AreaName,int pageCount,void **address, addressSpec addType,pageState state,protectType protect) { - printf ("Creating an area\n"); + error ("Creating an area\n"); lock(); area *newArea = new (vmBlock->areaPool->get()) area; - // printf ("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); - // printf ("areaManager::createArea - setup complete\n"); + // error ("areaManager::createArea - setup complete\n"); newArea->createArea(AreaName,pageCount,address,addType,state,protect); - // printf ("areaManager::createArea - new area's createArea called\n"); - newArea->setAreaID(nextAreaID++); // THIS IS NOT THREAD SAFE - // printf ("areaManager::createArea - new area's setAreaID called\n"); + // 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); - // printf ("areaManager::createArea - new area added to list\n"); + // error ("areaManager::createArea - new area added to list\n"); int retVal=newArea->getAreaID(); - // printf ("areaManager::createArea - new area id found\n"); + // error ("areaManager::createArea - new area id found\n"); unlock(); - //printf ("Done Creating an area\n"); + //error ("Done Creating an area\n"); return retVal; } int areaManager::cloneArea(int newAreaID,char *AreaName,void **address, addressSpec addType,pageState state,protectType protect) { - printf ("Cloning an area\n"); + int retVal; + error ("Cloning an area\n"); lock(); - area *newArea = new (vmBlock->areaPool->get()) area; - newArea->setup(this); area *oldArea=findArea(newAreaID); - newArea->cloneArea(oldArea,AreaName,address,addType,state,protect); - newArea->setAreaID(nextAreaID++); // THIS IS NOT THREAD SAFE - addArea(newArea); - int retVal=newArea->getAreaID(); + if (oldArea) + { + area *newArea = new (vmBlock->areaPool->get()) area; + newArea->setup(this); + newArea->cloneArea(oldArea,AreaName,address,addType,state,protect); + atomic_add(&nextAreaID,1); + newArea->setAreaID(nextAreaID); + addArea(newArea); + retVal=newArea->getAreaID(); + } + else + retVal=B_ERROR; unlock(); return retVal; } @@ -220,7 +227,7 @@ void areaManager::pager(int desperation) for (struct node *cur=areas.rock;cur;cur=cur->next) { area *myArea=(area *)cur; - //printf ("areaManager::pager; area = \n"); + //error ("areaManager::pager; area = \n"); //myArea->dump(); myArea->pager(desperation); } @@ -247,7 +254,7 @@ void *areaManager::mmap(void *addr, size_t len, int prot, int flags, int fd, off addressSpec addType=((flags&MAP_FIXED)?EXACT:ANY); protectType protType=(prot&PROT_WRITE)?writable:(prot&PROT_READ)?readable:none; // Not doing anything with MAP_SHARED and MAP_COPY - needs to be done - //printf ("flags = %x, anon = %x\n",flags,MAP_ANON); + //error ("flags = %x, anon = %x\n",flags,MAP_ANON); lock(); if (flags & MAP_ANON) { @@ -257,9 +264,10 @@ void *areaManager::mmap(void *addr, size_t len, int prot, int flags, int fd, off area *newArea = new (vmBlock->areaPool->get()) area; newArea->setup(this); - //printf ("area = %x, start = %x\n",newArea, newArea->getStartAddress()); + //error ("area = %x, start = %x\n",newArea, newArea->getStartAddress()); newArea->createAreaMappingFile(name,(int)((len+PAGE_SIZE-1)/PAGE_SIZE),&addr,addType,LAZY,protType,fd,offset); - newArea->setAreaID(nextAreaID++); // THIS IS NOT THREAD SAFE + atomic_add(&nextAreaID,1); + newArea->setAreaID(nextAreaID); addArea(newArea); newArea->getAreaID(); //pageMan.dump(); diff --git a/src/kernel/vm2/areaManager.h b/src/kernel/vm2/areaManager.h index a8ff798a77..349ece06ba 100644 --- a/src/kernel/vm2/areaManager.h +++ b/src/kernel/vm2/areaManager.h @@ -7,12 +7,12 @@ class areaManager // One of these per process orderedList areas; team_id team; sem_id myLock; - static int nextAreaID; + static long nextAreaID; public: areaManager (); void addArea(area *newArea) {areas.add(newArea);} void removeArea(area *oldArea) {areas.remove(oldArea); } - void freeArea(int area); + void freeArea(area_id area); team_id getTeam(void) {return team;} unsigned long getNextAddress(int pages,unsigned long minimum=USER_BASE); area *findArea(void *address); @@ -91,10 +91,10 @@ class areaManager // One of these per process { static long lockCount=0; if (!((lockCount++)%200)) - printf ("locking\n"); + error ("locking\n"); acquire_sem(myLock); } - void unlock() {/*printf ("unlocking\n");*/release_sem(myLock);} + void unlock() {/*error ("unlocking\n");*/release_sem(myLock);} void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset); status_t munmap(void *addr,size_t len) { diff --git a/src/kernel/vm2/areaPool.C b/src/kernel/vm2/areaPool.C index 538e0220bb..baae449062 100644 --- a/src/kernel/vm2/areaPool.C +++ b/src/kernel/vm2/areaPool.C @@ -11,25 +11,25 @@ area *poolarea::get(void) area *ret=NULL; if (unused.count()) { - //printf ("poolarea::get: Getting an unused one!\n"); + //error ("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); + //error ("poolarea::get: Returning address:%x \n",ret); return ret; } else { - //printf ("poolarea::get: Getting a new page!\n"); + //error ("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); + //error ("poolarea::get: Adding %d new elements to the pool!\n",newCount); for (int i=0;igetAddress()+(i*sizeof(area))))); release_sem(inUse); diff --git a/src/kernel/vm2/error.C b/src/kernel/vm2/error.C new file mode 100644 index 0000000000..315f45a4c3 --- /dev/null +++ b/src/kernel/vm2/error.C @@ -0,0 +1,19 @@ +#include +#include +#include + +static sem_id errorPrinting=0; + +void error(char *fmt, ...) +{ + if (errorPrinting==0) + errorPrinting=create_sem(1,"error_printing"); + acquire_sem(errorPrinting); + va_list argp; + char tmp[1000]; + sprintf(tmp, "[%lld] error: %s",real_time_clock_usecs(),fmt); + va_start(argp, tmp); + vfprintf(stderr,tmp,argp); + va_end(argp); + release_sem(errorPrinting); +} diff --git a/src/kernel/vm2/error.h b/src/kernel/vm2/error.h new file mode 100644 index 0000000000..e862ac80fc --- /dev/null +++ b/src/kernel/vm2/error.h @@ -0,0 +1 @@ +void error(char *fmt, ...); diff --git a/src/kernel/vm2/list.h b/src/kernel/vm2/list.h index 3d3d9bf2f0..56b8a1249d 100644 --- a/src/kernel/vm2/list.h +++ b/src/kernel/vm2/list.h @@ -3,6 +3,7 @@ // Simple linked list #include #include +#include "error.h" struct node { @@ -18,7 +19,7 @@ class list { rock=newNode; nodeCount++; } - //int count(void) {printf ("list::count: About to return %d\n",nodeCount);return nodeCount;} + //int count(void) {error ("list::count: About to return %d\n",nodeCount);return nodeCount;} int count(void) {return nodeCount;} node *next(void) { @@ -34,7 +35,7 @@ class list { } void remove(node *toNuke) { - //printf ("list::remove starting: nuking %x \n",toNuke); + //error ("list::remove starting: nuking %x \n",toNuke); //dump(); if (rock==toNuke) { @@ -52,14 +53,14 @@ class list { done=true; } } - //printf ("list::remove ending: \n"); + //error ("list::remove ending: \n"); //dump(); } void dump(void) { for (struct node *cur=rock;cur;cur=cur->next) { - printf ("list::dump: At %p, next = %p\n",cur,cur->next); + error ("list::dump: At %p, next = %p\n",cur,cur->next); } } struct node *rock; diff --git a/src/kernel/vm2/olTest.C b/src/kernel/vm2/olTest.C index fd346a8696..dc255cf833 100644 --- a/src/kernel/vm2/olTest.C +++ b/src/kernel/vm2/olTest.C @@ -32,7 +32,7 @@ int main(int argc,char **argv) catch (const char *badness) { if (strcmp(badness,"Attempting to use an ordered list without setting up a 'toLessThan' function")) - printf ("Failure on adding with no isLessThan, error = %s\n", badness); + printf ("Failure on adding with no isLessThan, printf = %s\n", badness); printf ("Success on adding with no isLessThan, \n" ); } catch(...) diff --git a/src/kernel/vm2/olist.h b/src/kernel/vm2/olist.h index a2bda57512..58dd075ac2 100644 --- a/src/kernel/vm2/olist.h +++ b/src/kernel/vm2/olist.h @@ -17,27 +17,27 @@ class orderedList : public list void add(node *in) { nodeCount++; - //printf ("orderedList::add starting\n"); + //error ("orderedList::add starting\n"); if (!rock || isLessThan(in,rock)) { // special case - this will be the first one - //printf ("orderedList::specialCase starting\n"); + //error ("orderedList::specialCase starting\n"); in->next=rock; rock=in; } else { - //printf ("orderedList::Normal Case starting\n"); + //error ("orderedList::Normal Case starting\n"); bool done=false; for (struct node *cur=rock;cur && !done;cur=cur->next) if (!(cur->next) || isLessThan(in,cur->next)) { // If we have found our niche, *OR* this is the last element, insert here. - //printf ("orderedList::Normal Case Adding Start\n"); + //error ("orderedList::Normal Case Adding Start\n"); in->next=cur->next; cur->next=in; done=true; - //printf ("orderedList::Normal Case Adding END\n"); + //error ("orderedList::Normal Case Adding END\n"); } - //printf ("orderedList::Normal Case ending\n"); + //error ("orderedList::Normal Case ending\n"); } } diff --git a/src/kernel/vm2/page.C b/src/kernel/vm2/page.C index c7959525b8..7e1ec36596 100644 --- a/src/kernel/vm2/page.C +++ b/src/kernel/vm2/page.C @@ -1,7 +1,9 @@ #include "page.h" +#include "string.h" void page::zero(void) { - for (int i=0;i<(PAGE_SIZE/4);i++) - ((long *)physicalAddress)[i]=0; + memset(physicalAddress,'0',PAGE_SIZE); +// for (int i=0;i<(PAGE_SIZE/4);i++) +// ((long *)physicalAddress)[i]=0; } diff --git a/src/kernel/vm2/page.h b/src/kernel/vm2/page.h index 8fe87fb348..1ba523d017 100644 --- a/src/kernel/vm2/page.h +++ b/src/kernel/vm2/page.h @@ -12,6 +12,6 @@ class page : public node { void setup (void *address) {count=0;physicalAddress=address;}; void zero(void); unsigned long getAddress(void) {return (unsigned long)physicalAddress;} - void dump(void) { printf ("Page %p, physicalAddress = %lx\n",this,getAddress()); } + void dump(void) { error ("page::dump: Page %p, physicalAddress = %lx\n",this,getAddress()); } }; #endif diff --git a/src/kernel/vm2/pageManager.C b/src/kernel/vm2/pageManager.C index 7af4de61d4..9f10090254 100644 --- a/src/kernel/vm2/pageManager.C +++ b/src/kernel/vm2/pageManager.C @@ -19,8 +19,8 @@ void pageManager::setup(void *area,int pages) { 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); + //error ("newPage = %x, setup = %x\n",newPage,addOffset(area,(i+pageOverhead)*PAGE_SIZE)); + //error ("i = %d, sizeof(page) = %x, pageOverhead = %d\n",i,sizeof(page),pageOverhead); //newPage->dump(); unused.add(newPage); } @@ -30,9 +30,9 @@ void pageManager::setup(void *area,int pages) inUseLock=create_sem (1,"inuse_lock"); totalPages=pages; /* - printf ("pageManager::pageManager: About to dump the clean pages (should be 0):\n\n"); + error ("pageManager::pageManager: About to dump the clean pages (should be 0):\n\n"); clean.dump(); - printf ("pageManager::pageManager: About to dump the unused pages (should not be 0):\n\n"); + error ("pageManager::pageManager: About to dump the unused pages (should not be 0):\n\n"); unused.dump(); */ } @@ -40,44 +40,44 @@ void pageManager::setup(void *area,int pages) page *pageManager::getPage(void) { page *ret=NULL; -// printf ("pageManager::getPage: Checking clean\n"); - //printf ("pageManager::getPage:cleanCount = %d\n", clean.nodeCount); - if (clean.count()) +// error ("pageManager::getPage: Checking clean\n"); + //error ("pageManager::getPage:cleanCount = %d\n", clean.nodeCount); + while (!ret) { - //printf ("pageManager::getPage:locking clean\n"); - acquire_sem(cleanLock); - //printf ("pageManager::getPage:locked clean\n"); - ret=(page *)clean.next(); - //printf ("pageManager::getPage:got next clean\n"); - release_sem(cleanLock); - //printf ("pageManager::getPage:unlocked clean\n"); - } // This could fail if someone swooped in and stole our page. - else if (unused.count()) - { - //printf ("pageManager::getPage:Checking unused\n"); - acquire_sem(unusedLock); - ret=(page *)unused.next(); - //printf ("pageManager::getPage:got next unused\n"); - release_sem(unusedLock); - //printf ("pageManager::getPage:next unused = %x\n",ret); - if (ret) - ret->zero(); - } // This could fail if someone swooped in and stole our page. - if (ret) - { - acquire_sem(inUseLock); - inUse.add(ret); - release_sem(inUseLock); - ret->count++; + if (clean.count()) + { + //error ("pageManager::getPage:locking clean\n"); + acquire_sem(cleanLock); + //error ("pageManager::getPage:locked clean\n"); + ret=(page *)clean.next(); + //error ("pageManager::getPage:got next clean\n"); + release_sem(cleanLock); + //error ("pageManager::getPage:unlocked clean\n"); + } // This could fail if someone swooped in and stole our page. + else if (unused.count()) + { + //error ("pageManager::getPage:Checking unused\n"); + acquire_sem(unusedLock); + ret=(page *)unused.next(); + //error ("pageManager::getPage:got next unused\n"); + release_sem(unusedLock); + //error ("pageManager::getPage:next unused = %x\n",ret); + if (ret) + ret->zero(); + } // This could fail if someone swooped in and stole our page. } -// printf ("pageManager::getPage:leaving with page = %x\n", ret->getAddress()); + acquire_sem(inUseLock); + inUse.add(ret); + release_sem(inUseLock); + ret->count++; +// error ("pageManager::getPage:leaving with page = %x\n", ret->getAddress()); return ret; } void pageManager::freePage(page *toFree) { -// printf ("Inside freePage; old value = %d",toFree->count); - if (atomic_add(&(toFree->count),-1)==0) + error ("Inside freePage; old value = %d",toFree->count); + 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); @@ -86,7 +86,7 @@ void pageManager::freePage(page *toFree) unused.add(toFree); release_sem(unusedLock); } -// printf (" new value = %d, page = %x\n",toFree->count,toFree->getAddress()); + error (" new value = %d, page = %x\n",toFree->count,toFree->getAddress()); } void pageManager::cleaner(void) @@ -95,7 +95,7 @@ void pageManager::cleaner(void) { if (unused.count()) { - //printf ("pageManager::cleaner: About to vacuum a page\n"); + //error ("pageManager::cleaner: About to vacuum a page\n"); acquire_sem(unusedLock); page *first=(page *)unused.next(); release_sem(unusedLock); @@ -103,7 +103,7 @@ void pageManager::cleaner(void) acquire_sem(cleanLock); clean.add(first); release_sem(cleanLock); - //printf ("pageManager::cleaner: All done with vacuum a page\n"); + //error ("pageManager::cleaner: All done with vacuum a page\n"); snooze(125000); } } @@ -118,21 +118,21 @@ int pageManager::desperation(void) void pageManager::dump(void) { - printf ("Dumping the unused list\n"); + error ("Dumping the unused list\n"); for (struct node *cur=unused.rock;cur;) { page *thisPage=(page *)cur; thisPage->dump(); cur=cur->next; } - printf ("Dumping the clean list\n"); + error ("Dumping the clean list\n"); for (struct node *cur=clean.rock;cur;) { page *thisPage=(page *)cur; thisPage->dump(); cur=cur->next; } - printf ("Dumping the inuse list\n"); + error ("Dumping the inuse list\n"); for (struct node *cur=inUse.rock;cur;) { page *thisPage=(page *)cur; diff --git a/src/kernel/vm2/pools.h b/src/kernel/vm2/pools.h index 874d1155bb..dd8d4ed847 100644 --- a/src/kernel/vm2/pools.h +++ b/src/kernel/vm2/pools.h @@ -21,25 +21,25 @@ class poolTYPE TYPE *ret=NULL; if (unused.count()) { - printf ("poolTYPE::get: Getting an unused one!\n"); + error ("poolTYPE::get: Getting an unused one!\n"); acquire_sem(inUse); ret=(TYPE *)unused.next(); release_sem(inUse); } if (ret) { - printf ("poolTYPE::get: Returning address:%x \n",ret); + error ("poolTYPE::get: Returning address:%x \n",ret); return ret; } else { - printf ("poolTYPE::get: Getting a new page!\n"); + error ("poolTYPE::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(TYPE); acquire_sem(inUse); - printf ("poolTYPE::get: Adding %d new elements to the pool!\n",newCount); + error ("poolTYPE::get: Adding %d new elements to the pool!\n",newCount); for (int i=0;igetAddress()+(i*sizeof(TYPE))))); release_sem(inUse); diff --git a/src/kernel/vm2/swapFileManager.C b/src/kernel/vm2/swapFileManager.C index 82e6f2a014..09b6bffa9a 100644 --- a/src/kernel/vm2/swapFileManager.C +++ b/src/kernel/vm2/swapFileManager.C @@ -12,53 +12,52 @@ swapFileManager::swapFileManager(void) { swapFile = open("/boot/var/tmp/OBOS_swap",O_RDWR|O_CREAT,0x777 ); if (swapFile==-1) - printf ("swapfileManager::swapFileManger: swapfile not opened, errno = %ul, %s\n",errno,strerror(errno)); + error ("swapfileManager::swapFileManger: swapfile not opened, errno = %ul, %s\n",errno,strerror(errno)); lockFreeList=create_sem(1,"SwapFile Free List Semaphore"); // Should have team name in it. } void swapFileManager::write_block(vnode &node,void *loc,unsigned long size) { - //printf ("swapFileManager::write_block: writing, node.fd = %d, node.offset = %d, address = %x\n",node.fd, node.offset,loc); + //error ("swapFileManager::write_block: writing, node.fd = %d, node.offset = %d, address = %x\n",node.fd, node.offset,loc); if (-1==lseek(node.fd,node.offset,SEEK_SET)) - printf ("seek failed, fd = %d, errno = %d, %s\n",node.fd,errno,strerror(errno)); + error ("seek failed, fd = %d, errno = %d, %s\n",node.fd,errno,strerror(errno)); if (-1==write(node.fd,loc,size)) - printf ("Write failed, fd = %d, errno = %d, %s\n",node.fd,errno,strerror(errno)); + error ("Write failed, fd = %d, errno = %d, %s\n",node.fd,errno,strerror(errno)); node.valid=true; - //printf ("swapFileManager::write_block: done, node.fd = %d, node.offset = %d, address = %x\n",node.fd, node.offset,loc); + //error ("swapFileManager::write_block: done, node.fd = %d, node.offset = %d, address = %x\n",node.fd, node.offset,loc); } void swapFileManager::read_block(vnode &node,void *loc,unsigned long size) { if (node.valid==false) return; // Do nothing. This prevents "garbage" data on disk from being read in... - //printf ("swapFileManager::read_block: reading, node.fd = %d, node.offset = %d into %x\n",node.fd, node.offset,loc); + //error ("swapFileManager::read_block: reading, node.fd = %d, node.offset = %d into %x\n",node.fd, node.offset,loc); lseek(node.fd,node.offset,SEEK_SET); read(node.fd,loc,size); } vnode &swapFileManager::findNode(void) { - //printf ("swapFileManager::findNode: Entering findNode \n"); + //error ("swapFileManager::findNode: Entering findNode \n"); //swapFileFreeList.dump(); - //printf ("swapFileManager::findNode: Finding a new node for you, Master: "); + //error ("swapFileManager::findNode: Finding a new node for you, Master: "); vnode *newNode; - //printf ("locking in sfm\n"); + //error ("locking in sfm\n"); Lock(); newNode=reinterpret_cast(swapFileFreeList.next()); - //printf ("unlocking in sfm\n"); + //error ("unlocking in sfm\n"); Unlock(); if (!newNode) { newNode=new (vmBlock->vnodePool->get()) vnode; newNode->fd=swapFile; newNode->offset=maxNode+=PAGE_SIZE; - //printf (" New One: %d\n",newNode->offset); + //error (" New One: %d\n",newNode->offset); } newNode->valid=false; - newNode->count=0; - //printf ("swapFileManager::findNode: swapFileFreeList is now: "); + newNode->count=1; + //error ("swapFileManager::findNode: swapFileFreeList is now: "); //swapFileFreeList.dump(); - newNode->count++; return *newNode; } @@ -67,12 +66,12 @@ void swapFileManager::freeVNode(vnode &v) v.count--; if (v.count==0) { - //printf ("locking in sfm\n"); + //error ("locking in sfm\n"); Lock(); - //printf ("swapFileManager::freeNode: Starting Freeing a new node for you, Master: offset:%d\n",v.offset); + //error ("swapFileManager::freeNode: Starting Freeing a new node for you, Master: offset:%d\n",v.offset); v.valid=false; swapFileFreeList.add(&v); - //printf ("unlocking in sfm\n"); + //error ("unlocking in sfm\n"); Unlock(); } } diff --git a/src/kernel/vm2/test.C b/src/kernel/vm2/test.C index 51cba16efd..d45d25d8a0 100644 --- a/src/kernel/vm2/test.C +++ b/src/kernel/vm2/test.C @@ -6,6 +6,7 @@ #include vmInterface vm(30); +thread_id loop1,loop2,loop3,info1,mmap1,clone1; void writeByte(unsigned long addr,unsigned int offset, char value) { vm.setByte(addr+offset,value); } @@ -16,29 +17,45 @@ int createFillAndTest(int pages,char *name) try{ unsigned long addr; int area1; - printf ("%s: createFillAndTest: about to create \n",name); + error ("%s: createFillAndTest: about to create \n",name); area1=vm.createArea("Mine",pages,(void **)(&addr)); - printf ("%s: createFillAndTest: create done\n",name); + error ("%s: createFillAndTest: create done\n",name); for (int i=0;iinitialSnooze); - printf ("Creating %s area\n",params->name); + error ("Creating %s area\n",params->name); area1=createFillAndTest(params->areaSize,params->name); snooze(params->holdSnooze); - printf ("Freeing %s area\n",params->name); + error ("Freeing %s area\n",params->name); vm.freeArea(area1); snooze(params->loopSnooze); } @@ -79,23 +96,23 @@ int32 getInfoTest(void *parameters) while (1) { snooze(params->initialSnooze); - //printf ("Creating %s area\n",params->name); + //error ("Creating %s area\n",params->name); area1=createFillAndTest(params->areaSize,params->name); snooze(params->holdSnooze); vm.getAreaInfo(area1,&ai); - printf ("Area info : \n"); - printf ("name : %s\n",ai.name); - printf ("size : %ld\n",ai.size); - printf ("lock : %ld\n",ai.lock); - printf ("team : %ld\n",ai.team); - printf ("ram_size : %ld\n",ai.ram_size); - printf ("in_count : %ld\n",ai.in_count); - printf ("out_count : %ld\n",ai.out_count); - printf ("copy_count : %ld\n",ai.copy_count); - printf ("address : %p\n",ai.address); + error ("Area info : \n"); + error ("name : %s\n",ai.name); + error ("size : %ld\n",ai.size); + error ("lock : %ld\n",ai.lock); + error ("team : %ld\n",ai.team); + error ("ram_size : %ld\n",ai.ram_size); + error ("in_count : %ld\n",ai.in_count); + error ("out_count : %ld\n",ai.out_count); + error ("copy_count : %ld\n",ai.copy_count); + error ("address : %p\n",ai.address); - printf ("Freeing %s area\n",params->name); + error ("Freeing %s area\n",params->name); vm.freeArea(area1); snooze(params->loopSnooze); } @@ -109,23 +126,23 @@ int32 mmapTest (void *parameters) while (1) { int fd = open ("OBOS_mmap",O_RDWR|O_CREAT,0x777); - printf ("Opened file, fd = %d\n",fd); + error ("Opened file, fd = %d\n",fd); snooze(params->initialSnooze); - printf ("Creating %s mmap\n",params->name); + error ("Creating %s mmap\n",params->name); snooze(params->holdSnooze); map=vm.mmap(NULL,size,PROT_WRITE|PROT_READ,MAP_SHARED,fd,0); - printf ("mmap address = %p\n",map); + error ("mmap address = %p\n",map); for (int i=0;iloopSnooze); vm.munmap(map,size); close(fd); - printf ("Closed file, fd = %d\n",fd); + error ("Closed file, fd = %d\n",fd); } } @@ -138,16 +155,16 @@ int32 cloneTest (void *parameters) while (1) { snooze(params->initialSnooze); - // printf ("Creating %s area, size = %d\n",params->name,params->areaSize); + // error ("Creating %s area, size = %d\n",params->name,params->areaSize); area1=createFillAndTest(params->areaSize,params->name); - // printf ("cloning, create done \n"); + // error ("cloning, create done \n"); area2=vm.cloneArea(area1,"Clone1",&cloneAddr); for (int i=0;iareaSize*PAGE_SIZE;i++) if (i%256!=readByte((int32)cloneAddr,i)) - printf ("ERROR! Clone Byte at offset %d of %p does not match: expected: %d, found: %d\n",i,cloneAddr,i%256,readByte((int32)cloneAddr,i)); - // printf ("Snoozing, compare done \n"); + error ("ERROR! Clone Byte at offset %d of %p does not match: expected: %d, found: %d\n",i,cloneAddr,i%256,readByte((int32)cloneAddr,i)); + // error ("Snoozing, compare done \n"); snooze(params->holdSnooze); - // printf ("Freeing %s area\n",params->name); + // error ("Freeing %s area\n",params->name); vm.freeArea(area2); vm.freeArea(area1); snooze(params->loopSnooze); @@ -163,12 +180,12 @@ int main(int argc,char **argv) loopTestParameters mmap1Params={"mmap",500000,8192,400000,1000000}; loopTestParameters clone1Params={"clone1",200000,2,300000,400000}; - resume_thread(spawn_thread(loopTest,"area test 1",0,&area1Params)); - resume_thread(spawn_thread(loopTest,"area test 2",0,&area2Params)); - resume_thread(spawn_thread(loopTest,"area test 3",0,&area3Params)); - //resume_thread(spawn_thread(getInfoTest,"info test 1",0,&info1Params)); - //resume_thread(spawn_thread(mmapTest,"mmap test 1",0,&mmap1Params)); - //resume_thread(spawn_thread(cloneTest,"clone test 1",0,&clone1Params)); + resume_thread(loop1=spawn_thread(loopTest,"area test 1",0,&area1Params)); + resume_thread(loop2=spawn_thread(loopTest,"area test 2",0,&area2Params)); + resume_thread(loop3=spawn_thread(loopTest,"area test 3",0,&area3Params)); + resume_thread(info1=spawn_thread(getInfoTest,"info test 1",0,&info1Params)); + resume_thread(mmap1=spawn_thread(mmapTest,"mmap test 1",0,&mmap1Params)); + resume_thread(clone1=spawn_thread(cloneTest,"clone test 1",0,&clone1Params)); snooze(1000000000); diff --git a/src/kernel/vm2/vm.h b/src/kernel/vm2/vm.h index 8c8554e477..5613ad783b 100644 --- a/src/kernel/vm2/vm.h +++ b/src/kernel/vm2/vm.h @@ -8,7 +8,7 @@ struct vnode : public node int fd; unsigned long offset; bool valid; - int count; + long count; vnode (void) { diff --git a/src/kernel/vm2/vmInterface.C b/src/kernel/vm2/vmInterface.C index 586013ee59..01546f438e 100644 --- a/src/kernel/vm2/vmInterface.C +++ b/src/kernel/vm2/vmInterface.C @@ -70,18 +70,18 @@ vmInterface::vmInterface(int pages) // 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"); + error ("pageManager::pageManager: No memory!\n"); exit(1); } - //printf ("Allocated an area. Address = %x\n",vmBlock); + //error ("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"); + error ("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); + //error ("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)); @@ -95,14 +95,14 @@ vmInterface::vmInterface(int pages) 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); + //error ("Need %d pages, creation calls for %d\n",pageCount,pages); + //error ("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); } - 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())); + resume_thread(tid_cleaner=spawn_thread(cleanerThread,"cleanerThread",0,(vmBlock->pageMan))); + resume_thread(tid_saver=spawn_thread(saverThread,"saverThread",0,getAM())); + resume_thread(tid_pager=spawn_thread(pagerThread,"pagerThread",0,getAM())); } int vmInterface::getAreaByAddress(void *address) @@ -210,3 +210,10 @@ status_t vmInterface::munmap(void *addr, size_t len) retVal = getAM()->munmap(addr,len); return retVal; } + +void vmInterface::suspendAll(void) +{ + suspend_thread(tid_cleaner); + suspend_thread(tid_saver); + suspend_thread(tid_pager); +} diff --git a/src/kernel/vm2/vmInterface.h b/src/kernel/vm2/vmInterface.h index f2c6511171..ce61801b30 100644 --- a/src/kernel/vm2/vmInterface.h +++ b/src/kernel/vm2/vmInterface.h @@ -33,4 +33,6 @@ class vmInterface // This is the class that "owns" all of the managers. void setByte(unsigned long offset,char value) {getAM()->setByte(offset,value);} // This is for testing only int getInt(unsigned long offset) {return getAM()->getInt(offset);} // This is for testing only void setInt(unsigned long offset,int value) {getAM()->setByte(offset,value);} // This is for testing only -}; + void suspendAll(void); + thread_id tid_cleaner,tid_saver,tid_pager; +}; diff --git a/src/kernel/vm2/vnodePool.C b/src/kernel/vm2/vnodePool.C index c9d3bf679c..f42bdd8983 100644 --- a/src/kernel/vm2/vnodePool.C +++ b/src/kernel/vm2/vnodePool.C @@ -9,25 +9,25 @@ vnode *poolvnode::get(void) vnode *ret=NULL; if (unused.count()) { - //printf ("poolvnode::get: Getting an unused one!\n"); + //error ("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); + //error ("poolvnode::get: Returning address:%x \n",ret); return ret; } else { - //printf ("poolvnode::get: Getting a new page!\n"); + //error ("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); + //error ("poolvnode::get: Adding %d new elements to the pool!\n",newCount); for (int i=0;igetAddress()+(i*sizeof(vnode))))); release_sem(inUse); diff --git a/src/kernel/vm2/vpage.C b/src/kernel/vm2/vpage.C index 21b4cf5c50..1c16b82ef0 100644 --- a/src/kernel/vm2/vpage.C +++ b/src/kernel/vm2/vpage.C @@ -29,7 +29,7 @@ vpage::vpage(void) // backing and/or physMem can be NULL/0. void vpage::setup(unsigned long start,vnode *backing, page *physMem,protectType prot,pageState state) { - //printf ("vpage::vpage: 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::vpage: start = %x, vnode.fd=%d, vnode.offset=%d, physMem = %x\n",start,((backing)?backing->fd:0),((backing)?backing->offset:0), ((physMem)?(physMem->getAddress()):0)); start_address=start; end_address=start+PAGE_SIZE-1; protection=prot; @@ -38,7 +38,7 @@ void vpage::setup(unsigned long start,vnode *backing, page *physMem,protectType if (backing) { backingNode=backing; - backing->count++; + atomic_add(&(backing->count),1); } else backingNode=&(vmBlock->swapMan->findNode()); @@ -47,11 +47,11 @@ void vpage::setup(unsigned long start,vnode *backing, page *physMem,protectType else { if (physMem) - physMem->count++; + atomic_add(&(physMem->count),1); physPage=physMem; } dirty=(physPage!=NULL); - //printf ("vpage::vpage: 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::vpage: 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)); } void vpage::cleanup(void) @@ -74,12 +74,12 @@ void vpage::setProtection(protectType prot) bool vpage::fault(void *fault_address, bool writeError) // true = OK, false = panic. { // This is dispatched by the real interrupt handler, who locates us - printf ("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) { - dirty=true; if (physPage) { + dirty=true; if (protection==copyOnWrite) // Else, this was just a "let me know when I am dirty"... { page *newPhysPage=vmBlock->pageMan->getPage(); @@ -97,44 +97,45 @@ bool vpage::fault(void *fault_address, bool writeError) // true = OK, false = pa 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)); + 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... -// printf ("vpage::fault: Refreshed\n"); -// dump(); -// printf ("vpage::fault: exiting\n"); + dirty=true; + error ("vpage::fault: Refreshed\n"); + dump(); + error ("vpage::fault: exiting\n"); return true; } char vpage::getByte(unsigned long address,areaManager *manager) { - //printf ("vpage::getByte: address = %ld\n",address ); + //error ("vpage::getByte: address = %ld\n",address ); if (!physPage) if (!manager->fault((void *)(address),false)) throw ("vpage::getByte"); - //printf ("vpage::getByte: About to return %d\n", *((char *)(address-start_address+physPage->getAddress()))); + //error ("vpage::getByte: About to return %d\n", *((char *)(address-start_address+physPage->getAddress()))); return *((char *)(address-start_address+physPage->getAddress())); } void vpage::setByte(unsigned long address,char value,areaManager *manager) { -// printf ("vpage::setByte: address = %d, value = %d\n",address, value); +// error ("vpage::setByte: address = %d, value = %d\n",address, value); if (!physPage) if (!manager->fault((void *)(address),true)) throw ("vpage::setByte"); *((char *)(address-start_address+physPage->getAddress()))=value; -// printf ("vpage::setByte: physical address = %d, value = %d\n",physPage->getAddress(), *((char *)(physPage->getAddress()))); +// error ("vpage::setByte: physical address = %d, value = %d\n",physPage->getAddress(), *((char *)(physPage->getAddress()))); } int vpage::getInt(unsigned long address,areaManager *manager) { - printf ("vpage::getInt: address = %ld\n",address ); + error ("vpage::getInt: address = %ld\n",address ); if (!physPage) if (!manager->fault((void *)(address),false)) throw ("vpage::getInt"); - printf ("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(); return *((int *)(address-start_address+physPage->getAddress())); } @@ -149,10 +150,10 @@ void vpage::setInt(unsigned long address,int value,areaManager *manager) void vpage::pager(int desperation) { - //printf ("vpage::pager start desperation = %d\n",desperation); + //error ("vpage::pager start desperation = %d\n",desperation); if (!swappable) return; - printf ("vpage::pager swappable\n"); + error ("vpage::pager swappable\n"); switch (desperation) { case 1: return; break; @@ -162,11 +163,11 @@ void vpage::pager(int desperation) case 5: if (!physPage) return;break; default: return;break; } - printf ("vpage::pager flushing\n"); + error ("vpage::pager flushing\n"); flush(); - printf ("vpage::pager freeing\n"); + error ("vpage::pager freeing\n"); vmBlock->pageMan->freePage(physPage); - printf ("vpage::pager going to NULL\n"); + error ("vpage::pager going to NULL\n"); physPage=NULL; } diff --git a/src/kernel/vm2/vpage.h b/src/kernel/vm2/vpage.h index 9dfc9081d2..4e1e6a89bc 100644 --- a/src/kernel/vm2/vpage.h +++ b/src/kernel/vm2/vpage.h @@ -36,11 +36,11 @@ class vpage : public node void dump(void) { - printf ("Dumping vpage %p, address = %lx, \n\t physPage: ",this,start_address); + error ("Dumping vpage %p, address = %lx, physPage: \n",this,start_address); if (physPage) physPage->dump(); else - printf ("NULL\n"); + error ("NULL\n"); } char getByte(unsigned long offset,areaManager *manager); // This is for testing only void setByte(unsigned long offset,char value,areaManager *manager); // This is for testing only diff --git a/src/kernel/vm2/vpagePool.C b/src/kernel/vm2/vpagePool.C index fb9d842708..15b58f8f3f 100644 --- a/src/kernel/vm2/vpagePool.C +++ b/src/kernel/vm2/vpagePool.C @@ -10,25 +10,25 @@ vpage *poolvpage::get(void) vpage *ret=NULL; if (unused.count()) { - //printf ("poolvpage::get: Getting an unused one!\n"); + //error ("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); + //error ("poolvpage::get: Returning address:%x \n",ret); return ret; } else { - //printf ("poolvpage::get: Getting a new page!\n"); + //error ("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); + //error ("poolvpage::get: Adding %d new elements to the pool!\n",newCount); for (int i=0;igetAddress()+(i*sizeof(vpage))))); release_sem(inUse);