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
This commit is contained in:
parent
6c657a0ed5
commit
c70c326c96
@ -85,14 +85,14 @@ void area::freeArea(void)
|
|||||||
vpages.dump();
|
vpages.dump();
|
||||||
for (struct node *cur=vpages.rock;cur;)
|
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;
|
vpage *page=(vpage *)cur;
|
||||||
page->flush();
|
page->flush();
|
||||||
printf ("area::freeArea: flushed a page \n");
|
//printf ("area::freeArea: flushed a page \n");
|
||||||
cur=cur->next;
|
cur=cur->next;
|
||||||
delete page; // Probably need to add a destructor
|
delete page; // Probably need to add a destructor
|
||||||
}
|
}
|
||||||
printf ("area::freeArea: unlocking \n");
|
//printf ("area::freeArea: unlocking \n");
|
||||||
manager->unlock();
|
manager->unlock();
|
||||||
printf ("area::freeArea: ending \n");
|
printf ("area::freeArea: ending \n");
|
||||||
}
|
}
|
||||||
|
@ -37,6 +37,7 @@ class area : public node
|
|||||||
status_t setProtection(protectType prot);
|
status_t setProtection(protectType prot);
|
||||||
bool couldAdd(unsigned long start,unsigned long end) { return ((end<start_address) || (start>end_address));}
|
bool couldAdd(unsigned long start,unsigned long end) { return ((end<start_address) || (start>end_address));}
|
||||||
unsigned long getEndAddress(void) {return end_address;}
|
unsigned long getEndAddress(void) {return end_address;}
|
||||||
|
unsigned long getStartAddress(void) {return start_address;}
|
||||||
void pager(int desperation);
|
void pager(int desperation);
|
||||||
void saver(void);
|
void saver(void);
|
||||||
|
|
||||||
|
@ -8,12 +8,14 @@ areaManager::areaManager(void)
|
|||||||
|
|
||||||
unsigned long areaManager::getNextAddress(int pages, unsigned long start)
|
unsigned long areaManager::getNextAddress(int pages, unsigned long start)
|
||||||
{
|
{
|
||||||
|
// areas.dump();
|
||||||
unsigned long end=start+(pages*PAGE_SIZE)-1;
|
unsigned long end=start+(pages*PAGE_SIZE)-1;
|
||||||
for (struct node *cur=areas.rock;cur;cur=cur->next)
|
for (struct node *cur=areas.rock;cur;cur=cur->next)
|
||||||
{
|
{
|
||||||
if (cur)
|
if (cur)
|
||||||
{
|
{
|
||||||
area *myArea=(area *)cur;
|
area *myArea=(area *)cur;
|
||||||
|
// printf ("Looking for %x, %d pages; current = %x\n",start,pages,myArea->getEndAddress());
|
||||||
if (!myArea->couldAdd(start,end))
|
if (!myArea->couldAdd(start,end))
|
||||||
{ // if we don't work, there must be an overlap, so go to the end of this area.
|
{ // if we don't work, there must be an overlap, so go to the end of this area.
|
||||||
start=myArea->getEndAddress();
|
start=myArea->getEndAddress();
|
||||||
@ -40,7 +42,7 @@ area *areaManager::findArea(void *address)
|
|||||||
for (struct node *cur=areas.rock;cur;cur=cur->next)
|
for (struct node *cur=areas.rock;cur;cur=cur->next)
|
||||||
{
|
{
|
||||||
area *myArea=(area *)cur;
|
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))
|
if (myArea->contains(address))
|
||||||
return myArea;
|
return myArea;
|
||||||
}
|
}
|
||||||
|
@ -24,13 +24,22 @@ class list {
|
|||||||
void *next(void) {nodeCount--;node *n=rock;if (rock) rock=rock->next;return n;}
|
void *next(void) {nodeCount--;node *n=rock;if (rock) rock=rock->next;return n;}
|
||||||
void remove(node *toNuke)
|
void remove(node *toNuke)
|
||||||
{
|
{
|
||||||
bool done=false;
|
// printf ("list::remove starting: nuking %x \n",toNuke);
|
||||||
for (struct node *cur=rock;!done && cur->next;cur=cur->next)
|
// list::dump();
|
||||||
if (cur->next==toNuke)
|
if (rock==toNuke)
|
||||||
{
|
rock=rock->next;
|
||||||
cur->next=toNuke->next;
|
else
|
||||||
done=true;
|
{
|
||||||
}
|
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)
|
void dump(void)
|
||||||
{
|
{
|
||||||
|
@ -33,26 +33,26 @@ pageManager::pageManager(int pages)
|
|||||||
page *pageManager::getPage(void)
|
page *pageManager::getPage(void)
|
||||||
{
|
{
|
||||||
page *ret=NULL;
|
page *ret=NULL;
|
||||||
printf ("pageManager::getPage: Checking clean\n");
|
//printf ("pageManager::getPage: Checking clean\n");
|
||||||
printf ("pageManager::getPage:cleanCount = %d\n", clean.nodeCount);
|
printf ("pageManager::getPage:cleanCount = %d\n", clean.nodeCount);
|
||||||
if (clean.count())
|
if (clean.count())
|
||||||
{
|
{
|
||||||
printf ("pageManager::getPage:locking clean\n");
|
//printf ("pageManager::getPage:locking clean\n");
|
||||||
acquire_sem(cleanLock);
|
acquire_sem(cleanLock);
|
||||||
printf ("pageManager::getPage:locked clean\n");
|
//printf ("pageManager::getPage:locked clean\n");
|
||||||
ret=(page *)clean.next();
|
ret=(page *)clean.next();
|
||||||
printf ("pageManager::getPage:got next clean\n");
|
//printf ("pageManager::getPage:got next clean\n");
|
||||||
release_sem(cleanLock);
|
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.
|
} // This could fail if someone swoops in and steal our page.
|
||||||
if (!ret && unused.count())
|
if (!ret && unused.count())
|
||||||
{
|
{
|
||||||
printf ("pageManager::getPage:Checking unused\n");
|
//printf ("pageManager::getPage:Checking unused\n");
|
||||||
acquire_sem(unusedLock);
|
acquire_sem(unusedLock);
|
||||||
ret=(page *)unused.next();
|
ret=(page *)unused.next();
|
||||||
printf ("pageManager::getPage:got next unused\n");
|
//printf ("pageManager::getPage:got next unused\n");
|
||||||
release_sem(unusedLock);
|
release_sem(unusedLock);
|
||||||
printf ("pageManager::getPage:next unused = %x\n",ret);
|
//printf ("pageManager::getPage:next unused = %x\n",ret);
|
||||||
if (ret)
|
if (ret)
|
||||||
ret->zero();
|
ret->zero();
|
||||||
} // This could fail if someone swoops in and steal our page.
|
} // This could fail if someone swoops in and steal our page.
|
||||||
@ -62,6 +62,7 @@ page *pageManager::getPage(void)
|
|||||||
inUse.add(ret);
|
inUse.add(ret);
|
||||||
release_sem(inUseLock);
|
release_sem(inUseLock);
|
||||||
}
|
}
|
||||||
|
printf ("pageManager::getPage:leaving with page = %x\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +90,7 @@ void pageManager::cleaner(void)
|
|||||||
clean.add(first);
|
clean.add(first);
|
||||||
release_sem(cleanLock);
|
release_sem(cleanLock);
|
||||||
release_sem(unusedLock);
|
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);
|
snooze(125000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,44 +1,60 @@
|
|||||||
#include "vmInterface.h"
|
#include "vmInterface.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
unsigned long addr;
|
|
||||||
vmInterface vm(10);
|
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)
|
int createFillAndTest(int pages)
|
||||||
{
|
{
|
||||||
|
unsigned long addr;
|
||||||
int area1;
|
int area1;
|
||||||
area1=vm.createArea("Mine",pages,(void **)(&addr));
|
area1=vm.createArea("Mine",pages,(void **)(&addr));
|
||||||
for (int i=0;i<pages*PAGE_SIZE;i++)
|
for (int i=0;i<pages*PAGE_SIZE;i++)
|
||||||
writeByte(i,i%256);
|
writeByte(addr,i,i%256);
|
||||||
for (int i=0;i<pages*PAGE_SIZE;i++)
|
for (int i=0;i<pages*PAGE_SIZE;i++)
|
||||||
if (i%256!=readByte(i))
|
if (i%256!=readByte(addr,i))
|
||||||
printf ("ERROR! Byte at offset %d does not match: expected: %d, found: %d\n",i,i%256,readByte(i));
|
printf ("ERROR! Byte at offset %d does not match: expected: %d, found: %d\n",i,i%256,readByte(addr,i));
|
||||||
return area1;
|
return area1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct loopTestParameters
|
||||||
|
{
|
||||||
|
char *name;
|
||||||
|
bigtime_t initialSnooze;
|
||||||
|
int areaSize;
|
||||||
|
bigtime_t holdSnooze;
|
||||||
|
bigtime_t loopSnooze;
|
||||||
|
};
|
||||||
|
|
||||||
|
int32 loopTest(void *parameters)
|
||||||
|
{
|
||||||
|
loopTestParameters *params=((loopTestParameters *)parameters);
|
||||||
|
int area1;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
snooze(params->initialSnooze);
|
||||||
|
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 main(int argc,char **argv)
|
||||||
{
|
{
|
||||||
int area1,area2;
|
loopTestParameters area1Params={"area1",1000000,2,100000,100000};
|
||||||
printf ("Creating a new area1\n");
|
loopTestParameters area2Params={"area2",1000000,2,100000,100000};
|
||||||
area1=createFillAndTest(2);
|
|
||||||
snooze(5000000);
|
resume_thread(spawn_thread(loopTest,"area test 1",0,&area1Params));
|
||||||
printf ("Creating a new area2\n");
|
resume_thread(spawn_thread(loopTest,"area test 2",0,&area2Params));
|
||||||
area2=createFillAndTest(2);
|
|
||||||
snooze(500000);
|
snooze(50000000);
|
||||||
printf ("Freeing area1\n");
|
|
||||||
vm.freeArea(area1);
|
|
||||||
snooze(500000);
|
|
||||||
printf ("Freeing area2\n");
|
|
||||||
vm.freeArea(area2);
|
|
||||||
printf ("Done Freeing area2\n");
|
|
||||||
snooze(20000000);
|
|
||||||
|
|
||||||
printf ("Creating a new area\n");
|
|
||||||
area1=createFillAndTest(2);
|
|
||||||
vm.freeArea(area1);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -97,7 +97,10 @@ void vmInterface::freeArea(int Area)
|
|||||||
status_t vmInterface::getAreaInfo(int Area,area_info *dest)
|
status_t vmInterface::getAreaInfo(int Area,area_info *dest)
|
||||||
{
|
{
|
||||||
area *oldArea=getAM()->findArea(Area);
|
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)
|
status_t vmInterface::getNextAreaInfo(int process,int32 *cookie,area_info *dest)
|
||||||
|
@ -55,7 +55,7 @@ void vpage::setProtection(protectType prot)
|
|||||||
|
|
||||||
bool vpage::fault(void *fault_address, bool writeError) // true = OK, false = panic.
|
bool vpage::fault(void *fault_address, bool writeError) // true = OK, false = panic.
|
||||||
{ // This is dispatched by the real interrupt handler, who locates us
|
{ // 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)
|
if (writeError)
|
||||||
{
|
{
|
||||||
dirty=true;
|
dirty=true;
|
||||||
@ -78,7 +78,7 @@ bool vpage::fault(void *fault_address, bool writeError) // true = OK, false = pa
|
|||||||
// 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...
|
||||||
refresh(); // I wonder if these vnode calls are safe during an interrupt...
|
refresh(); // I wonder if these vnode calls are safe during an interrupt...
|
||||||
printf ("vpage::fault: Refreshed\n");
|
//printf ("vpage::fault: Refreshed\n");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user