From c70c326c96807b0f4ebdbd64625f96547674328a Mon Sep 17 00:00:00 2001 From: Michael Phipps Date: Mon, 5 Aug 2002 03:41:16 +0000 Subject: [PATCH] Fixed a serious bug in list.h. :-( Improved tests to be multi-threaded. Still needs a lot more testing. Removed the nasty global variable in test.C. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@584 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kernel/vm2/area.C | 6 ++-- src/kernel/vm2/area.h | 1 + src/kernel/vm2/areaManager.C | 4 ++- src/kernel/vm2/list.h | 23 +++++++++---- src/kernel/vm2/pageManager.C | 19 +++++------ src/kernel/vm2/test.C | 62 +++++++++++++++++++++++------------- src/kernel/vm2/vmInterface.C | 5 ++- src/kernel/vm2/vpage.C | 4 +-- 8 files changed, 78 insertions(+), 46 deletions(-) diff --git a/src/kernel/vm2/area.C b/src/kernel/vm2/area.C index 6d74f0ae25..8b2587832e 100644 --- a/src/kernel/vm2/area.C +++ b/src/kernel/vm2/area.C @@ -85,14 +85,14 @@ void area::freeArea(void) vpages.dump(); for (struct node *cur=vpages.rock;cur;) { - printf ("area::freeArea: wasting a page: %x\n",cur); + //printf ("area::freeArea: wasting a page: %x\n",cur); vpage *page=(vpage *)cur; page->flush(); - printf ("area::freeArea: flushed a page \n"); + //printf ("area::freeArea: flushed a page \n"); cur=cur->next; delete page; // Probably need to add a destructor } - printf ("area::freeArea: unlocking \n"); + //printf ("area::freeArea: unlocking \n"); manager->unlock(); printf ("area::freeArea: ending \n"); } diff --git a/src/kernel/vm2/area.h b/src/kernel/vm2/area.h index 975e66f6aa..ed39e627d6 100644 --- a/src/kernel/vm2/area.h +++ b/src/kernel/vm2/area.h @@ -37,6 +37,7 @@ class area : public node status_t setProtection(protectType prot); bool couldAdd(unsigned long start,unsigned long end) { return ((endend_address));} unsigned long getEndAddress(void) {return end_address;} + unsigned long getStartAddress(void) {return start_address;} void pager(int desperation); void saver(void); diff --git a/src/kernel/vm2/areaManager.C b/src/kernel/vm2/areaManager.C index 94bc4ae6ec..d1993e87a6 100644 --- a/src/kernel/vm2/areaManager.C +++ b/src/kernel/vm2/areaManager.C @@ -8,12 +8,14 @@ areaManager::areaManager(void) unsigned long areaManager::getNextAddress(int pages, unsigned long start) { +// areas.dump(); unsigned long end=start+(pages*PAGE_SIZE)-1; for (struct node *cur=areas.rock;cur;cur=cur->next) { if (cur) { area *myArea=(area *)cur; +// printf ("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(); @@ -40,7 +42,7 @@ area *areaManager::findArea(void *address) for (struct node *cur=areas.rock;cur;cur=cur->next) { area *myArea=(area *)cur; - // printf ("areaManager::findArea: Looking for %d\n",address); +// printf ("areaManager::findArea: Looking for %x between %x and %x\n",address,myArea->getStartAddress(),myArea->getEndAddress()); if (myArea->contains(address)) return myArea; } diff --git a/src/kernel/vm2/list.h b/src/kernel/vm2/list.h index 07c00c4139..1e0bd46770 100644 --- a/src/kernel/vm2/list.h +++ b/src/kernel/vm2/list.h @@ -24,13 +24,22 @@ class list { void *next(void) {nodeCount--;node *n=rock;if (rock) rock=rock->next;return n;} void remove(node *toNuke) { - bool done=false; - for (struct node *cur=rock;!done && cur->next;cur=cur->next) - if (cur->next==toNuke) - { - cur->next=toNuke->next; - done=true; - } +// printf ("list::remove starting: nuking %x \n",toNuke); +// list::dump(); + if (rock==toNuke) + rock=rock->next; + else + { + bool done=false; + for (struct node *cur=rock;!done && cur->next;cur=cur->next) + if (cur->next==toNuke) + { + cur->next=toNuke->next; + done=true; + } + } +// printf ("list::remove ending: \n"); +// list::dump(); } void dump(void) { diff --git a/src/kernel/vm2/pageManager.C b/src/kernel/vm2/pageManager.C index c101d67873..e93622f120 100644 --- a/src/kernel/vm2/pageManager.C +++ b/src/kernel/vm2/pageManager.C @@ -33,26 +33,26 @@ pageManager::pageManager(int pages) page *pageManager::getPage(void) { page *ret=NULL; - printf ("pageManager::getPage: Checking clean\n"); + //printf ("pageManager::getPage: Checking clean\n"); printf ("pageManager::getPage:cleanCount = %d\n", clean.nodeCount); if (clean.count()) { - printf ("pageManager::getPage:locking clean\n"); + //printf ("pageManager::getPage:locking clean\n"); acquire_sem(cleanLock); - printf ("pageManager::getPage:locked clean\n"); + //printf ("pageManager::getPage:locked clean\n"); ret=(page *)clean.next(); - printf ("pageManager::getPage:got next clean\n"); + //printf ("pageManager::getPage:got next clean\n"); release_sem(cleanLock); - printf ("pageManager::getPage:unlocked clean\n"); + //printf ("pageManager::getPage:unlocked clean\n"); } // This could fail if someone swoops in and steal our page. if (!ret && unused.count()) { - printf ("pageManager::getPage:Checking unused\n"); + //printf ("pageManager::getPage:Checking unused\n"); acquire_sem(unusedLock); ret=(page *)unused.next(); - printf ("pageManager::getPage:got next unused\n"); + //printf ("pageManager::getPage:got next unused\n"); release_sem(unusedLock); - printf ("pageManager::getPage:next unused = %x\n",ret); + //printf ("pageManager::getPage:next unused = %x\n",ret); if (ret) ret->zero(); } // This could fail if someone swoops in and steal our page. @@ -62,6 +62,7 @@ page *pageManager::getPage(void) inUse.add(ret); release_sem(inUseLock); } + printf ("pageManager::getPage:leaving with page = %x\n", ret); return ret; } @@ -89,7 +90,7 @@ void pageManager::cleaner(void) clean.add(first); release_sem(cleanLock); release_sem(unusedLock); - printf ("pageManager::cleaner: All done with vacuum a page\n"); + //printf ("pageManager::cleaner: All done with vacuum a page\n"); snooze(125000); } } diff --git a/src/kernel/vm2/test.C b/src/kernel/vm2/test.C index f29301ce35..5b9136e2bc 100644 --- a/src/kernel/vm2/test.C +++ b/src/kernel/vm2/test.C @@ -1,44 +1,60 @@ #include "vmInterface.h" #include -unsigned long addr; vmInterface vm(10); -void writeByte(unsigned int offset, char value) { vm.setByte(addr+offset,value); } +void writeByte(unsigned long addr,unsigned int offset, char value) { vm.setByte(addr+offset,value); } -unsigned char readByte(unsigned int offset ) { char value=vm.getByte(addr+offset); return value; } +unsigned char readByte(unsigned long addr,unsigned int offset ) { char value=vm.getByte(addr+offset); return value; } int createFillAndTest(int pages) { + unsigned long addr; int area1; area1=vm.createArea("Mine",pages,(void **)(&addr)); for (int i=0;iinitialSnooze); + printf ("Creating %s area\n",params->name); + area1=createFillAndTest(params->areaSize); + snooze(params->holdSnooze); + printf ("Freeing %s area\n",params->name); + vm.freeArea(area1); + snooze(params->loopSnooze); + } + } + int main(int argc,char **argv) { - int area1,area2; - printf ("Creating a new area1\n"); - area1=createFillAndTest(2); - snooze(5000000); - printf ("Creating a new area2\n"); - area2=createFillAndTest(2); - snooze(500000); - printf ("Freeing area1\n"); - vm.freeArea(area1); - snooze(500000); - printf ("Freeing area2\n"); - vm.freeArea(area2); - printf ("Done Freeing area2\n"); - snooze(20000000); + loopTestParameters area1Params={"area1",1000000,2,100000,100000}; + loopTestParameters area2Params={"area2",1000000,2,100000,100000}; + + resume_thread(spawn_thread(loopTest,"area test 1",0,&area1Params)); + resume_thread(spawn_thread(loopTest,"area test 2",0,&area2Params)); + + snooze(50000000); - printf ("Creating a new area\n"); - area1=createFillAndTest(2); - vm.freeArea(area1); return 0; } diff --git a/src/kernel/vm2/vmInterface.C b/src/kernel/vm2/vmInterface.C index b6eff82db9..94c799e937 100644 --- a/src/kernel/vm2/vmInterface.C +++ b/src/kernel/vm2/vmInterface.C @@ -97,7 +97,10 @@ void vmInterface::freeArea(int Area) status_t vmInterface::getAreaInfo(int Area,area_info *dest) { area *oldArea=getAM()->findArea(Area); - return oldArea->getInfo(dest); + if (oldArea) + return oldArea->getInfo(dest); + else + printf ("vmInterface::getAreaInfo: unable to find requested area\n"); } status_t vmInterface::getNextAreaInfo(int process,int32 *cookie,area_info *dest) diff --git a/src/kernel/vm2/vpage.C b/src/kernel/vm2/vpage.C index cd4b128e54..d78894e06d 100644 --- a/src/kernel/vm2/vpage.C +++ b/src/kernel/vm2/vpage.C @@ -55,7 +55,7 @@ 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: address = %d, write = %s\n",(unsigned long) fault_address,((writeError)?"true":"false")); + //printf ("vpage::fault: address = %d, write = %s\n",(unsigned long) fault_address,((writeError)?"true":"false")); if (writeError) { dirty=true; @@ -78,7 +78,7 @@ bool vpage::fault(void *fault_address, bool writeError) // true = OK, false = pa // Update the architecture specific stuff here... // This refresh is unneeded if the data was never written out... refresh(); // I wonder if these vnode calls are safe during an interrupt... - printf ("vpage::fault: Refreshed\n"); + //printf ("vpage::fault: Refreshed\n"); }