Added reference counting to pages. Cleaned up some bugs.
More testing continues... git-svn-id: file:///srv/svn/repos/haiku/trunk/current@886 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
d1bafb18f2
commit
df6ee31838
@ -29,9 +29,7 @@ unsigned long area::mapAddressSpecToAddress(addressSpec type,unsigned long reque
|
|||||||
break;
|
break;
|
||||||
case CLONE: base=0;break; // Not sure what to do...
|
case CLONE: base=0;break; // Not sure what to do...
|
||||||
}
|
}
|
||||||
printf ("area::mapAddressSpecToAddress, in type: %s, address = %x, size = %d\n",
|
// 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);
|
||||||
((type==EXACT)?"Exact":(type==BASE)?"BASE":(type==ANY)?"ANY":(type==CLONE)?"CLONE":"ANY_KERNEL"),
|
|
||||||
requested,pageCount);
|
|
||||||
return base;
|
return base;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,9 +46,10 @@ status_t area::createAreaMappingFile(char *inName, int pageCount,void **address,
|
|||||||
vnode *newVnode=new vnode;
|
vnode *newVnode=new vnode;
|
||||||
newVnode->fd=fd;
|
newVnode->fd=fd;
|
||||||
newVnode->offset=offset+PAGE_SIZE*i;
|
newVnode->offset=offset+PAGE_SIZE*i;
|
||||||
|
newVnode->valid=true;
|
||||||
newPage = new vpage(base+PAGE_SIZE*i,newVnode,NULL,protect,inState);
|
newPage = new vpage(base+PAGE_SIZE*i,newVnode,NULL,protect,inState);
|
||||||
vpages.add(newPage);
|
vpages.add(newPage);
|
||||||
printf ("New vnode with fd %d, offset = %d\n",fd,newVnode->offset);
|
// printf ("New vnode with fd %d, offset = %d\n",fd,newVnode->offset);
|
||||||
}
|
}
|
||||||
manager->unlock();
|
manager->unlock();
|
||||||
|
|
||||||
@ -58,31 +57,71 @@ status_t area::createAreaMappingFile(char *inName, int pageCount,void **address,
|
|||||||
start_address=base;
|
start_address=base;
|
||||||
end_address=base+pageCount*PAGE_SIZE;
|
end_address=base+pageCount*PAGE_SIZE;
|
||||||
*address=(void *)base;
|
*address=(void *)base;
|
||||||
|
finalWrite=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t area::createArea(char *inName, int pageCount,void **address, addressSpec type,pageState inState,protectType protect)
|
status_t area::createArea(char *inName, int pageCount,void **address, addressSpec type,pageState inState,protectType protect)
|
||||||
{
|
{
|
||||||
|
vpage *newPage;
|
||||||
|
|
||||||
strcpy(name,inName);
|
strcpy(name,inName);
|
||||||
|
state=inState;
|
||||||
|
finalWrite=false;
|
||||||
|
unsigned long requested=(unsigned long)(*address); // Hold onto this to make sure that EXACT works...
|
||||||
|
|
||||||
manager->lock();
|
manager->lock();
|
||||||
//printf ("area::createArea: Locked in createArea\n");
|
//printf ("area::createArea: Locked in createArea\n");
|
||||||
unsigned long requested=(unsigned long)(*address); // Hold onto this to make sure that EXACT works...
|
|
||||||
unsigned long base=mapAddressSpecToAddress(type,requested,pageCount);
|
unsigned long base=mapAddressSpecToAddress(type,requested,pageCount);
|
||||||
//printf ("area::createArea: base address = %d\n",base);
|
//printf ("area::createArea: base address = %d\n",base);
|
||||||
vpage *newPage;
|
|
||||||
for (int i=0;i<pageCount;i++)
|
for (int i=0;i<pageCount;i++)
|
||||||
{
|
{
|
||||||
//printf ("in area::createArea: creating page = %d\n",i);
|
//printf ("in area::createArea: creating page = %d\n",i);
|
||||||
newPage = new vpage(base+PAGE_SIZE*i,NULL,NULL,protect,inState);
|
newPage = new vpage(base+PAGE_SIZE*i,NULL,NULL,protect,inState);
|
||||||
vpages.add(newPage);
|
vpages.add(newPage);
|
||||||
}
|
}
|
||||||
state=inState;
|
manager->unlock();
|
||||||
start_address=base;
|
start_address=base;
|
||||||
end_address=base+pageCount*PAGE_SIZE;
|
end_address=base+pageCount*PAGE_SIZE;
|
||||||
manager->unlock();
|
|
||||||
*address=(void *)base;
|
*address=(void *)base;
|
||||||
//printf ("area::createArea: unlocked in createArea\n");
|
//printf ("area::createArea: unlocked in createArea\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t area::cloneArea(area *origArea, char *inName, void **address, addressSpec type,pageState inState,protectType protect)
|
||||||
|
{
|
||||||
|
// printf ("area::cloneArea: entered\n");
|
||||||
|
strcpy(name,inName);
|
||||||
|
int pageCount = origArea->getPageCount();
|
||||||
|
manager->lock();
|
||||||
|
// printf ("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);
|
||||||
|
start_address=base;
|
||||||
|
// printf ("area::cloneArea: base address = %x\n",base);
|
||||||
|
|
||||||
|
if (origArea->getAreaManager()!=manager) // Else, already locked;
|
||||||
|
{
|
||||||
|
printf ("Holding dual locks! \n");
|
||||||
|
origArea->getAreaManager()->lock();
|
||||||
|
}
|
||||||
|
for (struct node *cur=origArea->vpages.rock;cur;)
|
||||||
|
{
|
||||||
|
vpage *newPage,*page=(vpage *)cur;
|
||||||
|
// Cloned area has the same physical page and backing store...
|
||||||
|
newPage = new vpage(base,page->getBacking(),page->getPhysPage(),protect,inState);
|
||||||
|
vpages.add(newPage);
|
||||||
|
base+=PAGE_SIZE;
|
||||||
|
cur=cur->next;
|
||||||
|
}
|
||||||
|
if (origArea->getAreaManager()!=manager) // Else, already locked;
|
||||||
|
origArea->getAreaManager()->unlock();
|
||||||
|
state=inState;
|
||||||
|
end_address=base+pageCount*PAGE_SIZE;
|
||||||
|
manager->unlock();
|
||||||
|
*address=(void *)start_address;
|
||||||
|
finalWrite=false;
|
||||||
|
// printf ("area::cloneArea: unlocked\n");
|
||||||
|
}
|
||||||
|
|
||||||
void area::freeArea(void)
|
void area::freeArea(void)
|
||||||
{
|
{
|
||||||
//printf ("area::freeArea: starting \n");
|
//printf ("area::freeArea: starting \n");
|
||||||
@ -93,7 +132,8 @@ void area::freeArea(void)
|
|||||||
{
|
{
|
||||||
//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();
|
if (finalWrite)
|
||||||
|
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
|
||||||
@ -257,3 +297,14 @@ void area::saver(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void area::dump(void)
|
||||||
|
{
|
||||||
|
printf ("area::dump: size = %d, lock = %d, address = %x\n",end_address-start_address,state,start_address);
|
||||||
|
for (struct node *cur=vpages.rock;cur;)
|
||||||
|
{
|
||||||
|
vpage *page=(vpage *)cur;
|
||||||
|
page->dump();
|
||||||
|
cur=cur->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ class area : public node
|
|||||||
char name[B_OS_NAME_LENGTH];
|
char name[B_OS_NAME_LENGTH];
|
||||||
pageState state;
|
pageState state;
|
||||||
protectType protection;
|
protectType protection;
|
||||||
|
bool finalWrite;
|
||||||
int areaID;
|
int areaID;
|
||||||
int in_count;
|
int in_count;
|
||||||
int out_count;
|
int out_count;
|
||||||
@ -28,6 +29,7 @@ class area : public node
|
|||||||
unsigned long mapAddressSpecToAddress(addressSpec type,unsigned long requested,int pageCount);
|
unsigned long mapAddressSpecToAddress(addressSpec type,unsigned long requested,int pageCount);
|
||||||
status_t createAreaMappingFile(char *name, int pageCount,void **address, addressSpec type,pageState state,protectType protect,int fd,size_t offset);
|
status_t createAreaMappingFile(char *name, int pageCount,void **address, addressSpec type,pageState state,protectType protect,int fd,size_t offset);
|
||||||
status_t createArea (char *name, int pageCount,void **address, addressSpec type,pageState state,protectType protect);
|
status_t createArea (char *name, int pageCount,void **address, addressSpec type,pageState state,protectType protect);
|
||||||
|
status_t cloneArea(area *area, char *inName, void **address, addressSpec type,pageState inState,protectType protect);
|
||||||
int getAreaID(void) {return areaID;}
|
int getAreaID(void) {return areaID;}
|
||||||
void setAreaID(int id) {areaID=id;}
|
void setAreaID(int id) {areaID=id;}
|
||||||
void freeArea(void);
|
void freeArea(void);
|
||||||
@ -40,7 +42,11 @@ class area : public node
|
|||||||
unsigned long getStartAddress(void) {return start_address;}
|
unsigned long getStartAddress(void) {return start_address;}
|
||||||
void pager(int desperation);
|
void pager(int desperation);
|
||||||
void saver(void);
|
void saver(void);
|
||||||
|
unsigned long getSize(void) {return getEndAddress()-getStartAddress();}
|
||||||
|
unsigned long getPageCount(void) {return (getEndAddress()-getStartAddress())/PAGE_SIZE;}
|
||||||
|
areaManager *getAreaManager(void) {return manager;}
|
||||||
|
|
||||||
|
void dump(void);
|
||||||
bool fault(void *fault_address, bool writeError); // true = OK, false = panic.
|
bool fault(void *fault_address, bool writeError); // true = OK, false = panic.
|
||||||
|
|
||||||
char getByte(unsigned long ); // This is for testing only
|
char getByte(unsigned long ); // This is for testing only
|
||||||
|
@ -43,6 +43,7 @@ area *areaManager::findArea(void *address)
|
|||||||
{
|
{
|
||||||
area *myArea=(area *)cur;
|
area *myArea=(area *)cur;
|
||||||
// printf ("areaManager::findArea: Looking for %x between %x and %x\n",address,myArea->getStartAddress(),myArea->getEndAddress());
|
// printf ("areaManager::findArea: Looking for %x between %x and %x\n",address,myArea->getStartAddress(),myArea->getEndAddress());
|
||||||
|
fflush(NULL);
|
||||||
if (myArea->contains(address))
|
if (myArea->contains(address))
|
||||||
return myArea;
|
return myArea;
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,10 @@ class page : public node {
|
|||||||
void *cpuSpecific;
|
void *cpuSpecific;
|
||||||
void *physicalAddress;
|
void *physicalAddress;
|
||||||
public:
|
public:
|
||||||
page(void *address) : physicalAddress(address) {} ;
|
int count;
|
||||||
|
page(void *address) : physicalAddress(address) {count=0;} ;
|
||||||
void zero(void);
|
void zero(void);
|
||||||
unsigned long getAddress(void) {return (unsigned long)physicalAddress;}
|
unsigned long getAddress(void) {return (unsigned long)physicalAddress;}
|
||||||
|
void dump(void) { printf ("Page %x, physicalAddress = %x\n",this,getAddress()); }
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@ -15,9 +15,11 @@ pageManager::pageManager(int pages)
|
|||||||
printf ("pageManager::pageManager: No memory!\n");
|
printf ("pageManager::pageManager: No memory!\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
printf ("Allocated an area. Address = %x\n",area);
|
||||||
for (int i=0;i<pages;i++)
|
for (int i=0;i<pages;i++)
|
||||||
unused.add(new page(addOffset(area,i*PAGE_SIZE)));
|
unused.add(new page(addOffset(area,i*PAGE_SIZE)));
|
||||||
// unused.add(new page((void *)(i*PAGE_SIZE)));
|
// unused.add(new page((void *)(i*PAGE_SIZE)));
|
||||||
|
|
||||||
cleanLock=create_sem (1,"clean_lock");
|
cleanLock=create_sem (1,"clean_lock");
|
||||||
unusedLock=create_sem (1,"unused_lock");
|
unusedLock=create_sem (1,"unused_lock");
|
||||||
inUseLock=create_sem (1,"inuse_lock");
|
inUseLock=create_sem (1,"inuse_lock");
|
||||||
@ -33,7 +35,7 @@ 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())
|
||||||
{
|
{
|
||||||
@ -44,8 +46,8 @@ page *pageManager::getPage(void)
|
|||||||
//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 swooped in and stole our page.
|
||||||
if (!ret && unused.count())
|
else if (unused.count())
|
||||||
{
|
{
|
||||||
//printf ("pageManager::getPage:Checking unused\n");
|
//printf ("pageManager::getPage:Checking unused\n");
|
||||||
acquire_sem(unusedLock);
|
acquire_sem(unusedLock);
|
||||||
@ -55,25 +57,32 @@ page *pageManager::getPage(void)
|
|||||||
//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 swooped in and stole our page.
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
acquire_sem(inUseLock);
|
acquire_sem(inUseLock);
|
||||||
inUse.add(ret);
|
inUse.add(ret);
|
||||||
release_sem(inUseLock);
|
release_sem(inUseLock);
|
||||||
|
ret->count++;
|
||||||
}
|
}
|
||||||
//printf ("pageManager::getPage:leaving with page = %x\n", ret);
|
// printf ("pageManager::getPage:leaving with page = %x\n", ret->getAddress());
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pageManager::freePage(page *toFree)
|
void pageManager::freePage(page *toFree)
|
||||||
{
|
{
|
||||||
acquire_sem(inUseLock);
|
// printf ("Inside freePage; old value = %d",toFree->count);
|
||||||
inUse.remove(toFree);
|
toFree->count--;
|
||||||
release_sem(inUseLock);
|
// printf (" new value = %d, page = %x\n",toFree->count,toFree->getAddress());
|
||||||
acquire_sem(unusedLock);
|
if (toFree->count==0)
|
||||||
unused.add(toFree);
|
{
|
||||||
release_sem(unusedLock);
|
acquire_sem(inUseLock);
|
||||||
|
inUse.remove(toFree);
|
||||||
|
release_sem(inUseLock);
|
||||||
|
acquire_sem(unusedLock);
|
||||||
|
unused.add(toFree);
|
||||||
|
release_sem(unusedLock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pageManager::cleaner(void)
|
void pageManager::cleaner(void)
|
||||||
@ -98,7 +107,32 @@ void pageManager::cleaner(void)
|
|||||||
|
|
||||||
int pageManager::desperation(void)
|
int pageManager::desperation(void)
|
||||||
{ // Formula to determine how desperate system is to get pages back...
|
{ // Formula to determine how desperate system is to get pages back...
|
||||||
int percentClean=(unused.count()+clean.count())/totalPages;
|
int percentClean=(unused.count()+clean.count())*100/totalPages;
|
||||||
if (percentClean>30) return 1;
|
if (percentClean>30) return 1;
|
||||||
return (35-percentClean)/5;
|
return (35-percentClean)/7;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pageManager::dump(void)
|
||||||
|
{
|
||||||
|
printf ("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");
|
||||||
|
for (struct node *cur=clean.rock;cur;)
|
||||||
|
{
|
||||||
|
page *thisPage=(page *)cur;
|
||||||
|
thisPage->dump();
|
||||||
|
cur=cur->next;
|
||||||
|
}
|
||||||
|
printf ("Dumping the inuse list\n");
|
||||||
|
for (struct node *cur=inUse.rock;cur;)
|
||||||
|
{
|
||||||
|
page *thisPage=(page *)cur;
|
||||||
|
thisPage->dump();
|
||||||
|
cur=cur->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -11,6 +11,7 @@ class pageManager {
|
|||||||
void freePage(page *);
|
void freePage(page *);
|
||||||
void cleaner(void);
|
void cleaner(void);
|
||||||
int desperation(void);
|
int desperation(void);
|
||||||
|
void dump(void);
|
||||||
private:
|
private:
|
||||||
list clean,unused,inUse;
|
list clean,unused,inUse;
|
||||||
sem_id cleanLock,unusedLock,inUseLock;
|
sem_id cleanLock,unusedLock,inUseLock;
|
||||||
|
@ -13,12 +13,13 @@ swapFileManager::swapFileManager(void)
|
|||||||
|
|
||||||
void swapFileManager::write_block(vnode &node,void *loc,unsigned long size)
|
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);
|
//printf ("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))
|
if (-1==lseek(node.fd,node.offset,SEEK_SET))
|
||||||
printf ("seek failed, fd = %d, errno = %d, %s\n",node.fd,errno,strerror(errno));
|
printf ("seek failed, fd = %d, errno = %d, %s\n",node.fd,errno,strerror(errno));
|
||||||
if (-1==write(node.fd,loc,size))
|
if (-1==write(node.fd,loc,size))
|
||||||
printf ("Write failed, fd = %d, errno = %d, %s\n",node.fd,errno,strerror(errno));
|
printf ("Write failed, fd = %d, errno = %d, %s\n",node.fd,errno,strerror(errno));
|
||||||
node.valid=true;
|
node.valid=true;
|
||||||
|
//printf ("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)
|
void swapFileManager::read_block(vnode &node,void *loc,unsigned long size)
|
||||||
@ -26,7 +27,7 @@ void swapFileManager::read_block(vnode &node,void *loc,unsigned long size)
|
|||||||
lseek(node.fd,node.offset,SEEK_SET);
|
lseek(node.fd,node.offset,SEEK_SET);
|
||||||
if (node.valid==false)
|
if (node.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...
|
||||||
//printf ("swapFileManager::read_block: reading, node.fd = %d, node.offset = %d\n",node.fd, node.offset);
|
//printf ("swapFileManager::read_block: reading, node.fd = %d, node.offset = %d into %x\n",node.fd, node.offset,loc);
|
||||||
read(node.fd,loc,size);
|
read(node.fd,loc,size);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -36,30 +37,37 @@ vnode &swapFileManager::findNode(void)
|
|||||||
//swapFileFreeList.dump();
|
//swapFileFreeList.dump();
|
||||||
//printf ("swapFileManager::findNode: Finding a new node for you, Master: ");
|
//printf ("swapFileManager::findNode: Finding a new node for you, Master: ");
|
||||||
vnode *newNode;
|
vnode *newNode;
|
||||||
|
//printf ("locking in sfm\n");
|
||||||
Lock();
|
Lock();
|
||||||
if (newNode=reinterpret_cast<vnode *>(swapFileFreeList.next()))
|
newNode=reinterpret_cast<vnode *>(swapFileFreeList.next());
|
||||||
{
|
//printf ("unlocking in sfm\n");
|
||||||
//printf (" Reused: %d\n",newNode->offset);
|
Unlock();
|
||||||
}
|
if (!newNode)
|
||||||
else
|
|
||||||
{
|
{
|
||||||
newNode=new vnode;
|
newNode=new vnode;
|
||||||
newNode->fd=swapFile;
|
newNode->fd=swapFile;
|
||||||
newNode->offset=maxNode+=PAGE_SIZE;
|
newNode->offset=maxNode+=PAGE_SIZE;
|
||||||
newNode->valid=false;
|
|
||||||
//printf (" New One: %d\n",newNode->offset);
|
//printf (" New One: %d\n",newNode->offset);
|
||||||
}
|
}
|
||||||
Unlock();
|
newNode->valid=false;
|
||||||
|
newNode->count=0;
|
||||||
//printf ("swapFileManager::findNode: swapFileFreeList is now: ");
|
//printf ("swapFileManager::findNode: swapFileFreeList is now: ");
|
||||||
//swapFileFreeList.dump();
|
//swapFileFreeList.dump();
|
||||||
|
newNode->count++;
|
||||||
return *newNode;
|
return *newNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void swapFileManager::freeVNode(vnode &v)
|
void swapFileManager::freeVNode(vnode &v)
|
||||||
{
|
{
|
||||||
Lock();
|
v.count--;
|
||||||
//printf ("swapFileManager::freeNode: Starting Freeing a new node for you, Master: offset:%d\n",v.offset);
|
if (v.count==0)
|
||||||
v.valid=false;
|
{
|
||||||
swapFileFreeList.add(&v);
|
//printf ("locking in sfm\n");
|
||||||
Unlock();
|
Lock();
|
||||||
|
//printf ("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");
|
||||||
|
Unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
vmInterface vm(20);
|
vmInterface vm(30);
|
||||||
|
|
||||||
void writeByte(unsigned long addr,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); }
|
||||||
|
|
||||||
@ -13,15 +13,24 @@ unsigned char readByte(unsigned long addr,unsigned int offset ) { char value=vm.
|
|||||||
|
|
||||||
int createFillAndTest(int pages)
|
int createFillAndTest(int pages)
|
||||||
{
|
{
|
||||||
|
try{
|
||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
int area1;
|
int area1;
|
||||||
area1=vm.createArea("Mine",pages,(void **)(&addr));
|
area1=vm.createArea("Mine",pages,(void **)(&addr));
|
||||||
|
printf ("createFillAndTest: create done\n");
|
||||||
for (int i=0;i<pages*PAGE_SIZE;i++)
|
for (int i=0;i<pages*PAGE_SIZE;i++)
|
||||||
writeByte(addr,i,i%256);
|
writeByte(addr,i,i%256);
|
||||||
|
printf ("createFillAndTest: writing done\n");
|
||||||
for (int i=0;i<pages*PAGE_SIZE;i++)
|
for (int i=0;i<pages*PAGE_SIZE;i++)
|
||||||
if (i%256!=readByte(addr,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(addr,i));
|
printf ("ERROR! Byte at offset %d does not match: expected: %d, found: %d\n",i,i%256,readByte(addr,i));
|
||||||
|
printf ("createFillAndTest: reading done\n");
|
||||||
return area1;
|
return area1;
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
printf ("Exception thrown!\n");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct loopTestParameters
|
struct loopTestParameters
|
||||||
@ -35,16 +44,17 @@ struct loopTestParameters
|
|||||||
|
|
||||||
int32 loopTest(void *parameters)
|
int32 loopTest(void *parameters)
|
||||||
{
|
{
|
||||||
|
printf ("Starting Loop Test!\n");
|
||||||
loopTestParameters *params=((loopTestParameters *)parameters);
|
loopTestParameters *params=((loopTestParameters *)parameters);
|
||||||
int area1;
|
int area1;
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
snooze(params->initialSnooze);
|
snooze(params->initialSnooze);
|
||||||
//printf ("Creating %s area\n",params->name);
|
printf ("Creating %s area\n",params->name);
|
||||||
area1=createFillAndTest(params->areaSize);
|
area1=createFillAndTest(params->areaSize);
|
||||||
snooze(params->holdSnooze);
|
snooze(params->holdSnooze);
|
||||||
//printf ("Freeing %s area\n",params->name);
|
printf ("Freeing %s area\n",params->name);
|
||||||
vm.freeArea(area1);
|
vm.freeArea(area1);
|
||||||
snooze(params->loopSnooze);
|
snooze(params->loopSnooze);
|
||||||
}
|
}
|
||||||
@ -85,13 +95,13 @@ int32 mmapTest (void *parameters)
|
|||||||
{
|
{
|
||||||
void *map;
|
void *map;
|
||||||
|
|
||||||
int fd = open ("OBOS_mmap",O_RDWR|O_CREAT,0x777);
|
|
||||||
printf ("Opened file, fd = %d\n",fd);
|
|
||||||
|
|
||||||
loopTestParameters *params=((loopTestParameters *)parameters);
|
loopTestParameters *params=((loopTestParameters *)parameters);
|
||||||
int size=params->areaSize; // Note that this is in bytes, not in pages
|
int size=params->areaSize; // Note that this is in bytes, not in pages
|
||||||
// while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
int fd = open ("OBOS_mmap",O_RDWR|O_CREAT,0x777);
|
||||||
|
printf ("Opened file, fd = %d\n",fd);
|
||||||
snooze(params->initialSnooze);
|
snooze(params->initialSnooze);
|
||||||
printf ("Creating %s mmap\n",params->name);
|
printf ("Creating %s mmap\n",params->name);
|
||||||
snooze(params->holdSnooze);
|
snooze(params->holdSnooze);
|
||||||
@ -102,12 +112,37 @@ int32 mmapTest (void *parameters)
|
|||||||
for (int i=0;i<size;i++)
|
for (int i=0;i<size;i++)
|
||||||
if (i%256!=readByte((int32)map,i))
|
if (i%256!=readByte((int32)map,i))
|
||||||
printf ("ERROR! Byte at offset %d does not match: expected: %d, found: %d\n",i,i%256,readByte((int32)map,i));
|
printf ("ERROR! Byte at offset %d does not match: expected: %d, found: %d\n",i,i%256,readByte((int32)map,i));
|
||||||
snooze(params->loopSnooze);
|
snooze(params->loopSnooze);
|
||||||
}
|
vm.munmap(map,size);
|
||||||
close(fd);
|
close(fd);
|
||||||
printf ("Closed file, fd = %d\n",fd);
|
printf ("Closed file, fd = %d\n",fd);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 cloneTest (void *parameters)
|
||||||
|
{
|
||||||
|
loopTestParameters *params=((loopTestParameters *)parameters);
|
||||||
|
int area1,area2;
|
||||||
|
void *cloneAddr=NULL;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
snooze(params->initialSnooze);
|
||||||
|
// printf ("Creating %s area, size = %d\n",params->name,params->areaSize);
|
||||||
|
area1=createFillAndTest(params->areaSize);
|
||||||
|
// printf ("cloning, create done \n");
|
||||||
|
area2=vm.cloneArea(area1,"Clone1",&cloneAddr);
|
||||||
|
for (int i=0;i<params->areaSize*PAGE_SIZE;i++)
|
||||||
|
if (i%256!=readByte((int32)cloneAddr,i))
|
||||||
|
printf ("ERROR! Clone Byte at offset %d of %x does not match: expected: %d, found: %d\n",i,cloneAddr,i%256,readByte((int32)cloneAddr,i));
|
||||||
|
// printf ("Snoozing, compare done \n");
|
||||||
|
snooze(params->holdSnooze);
|
||||||
|
// printf ("Freeing %s area\n",params->name);
|
||||||
|
vm.freeArea(area2);
|
||||||
|
vm.freeArea(area1);
|
||||||
|
snooze(params->loopSnooze);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc,char **argv)
|
int main(int argc,char **argv)
|
||||||
{
|
{
|
||||||
@ -116,14 +151,16 @@ int main(int argc,char **argv)
|
|||||||
loopTestParameters area3Params={"area3",1000000,2,300000,200000};
|
loopTestParameters area3Params={"area3",1000000,2,300000,200000};
|
||||||
loopTestParameters info1Params={"info1",500000,2,400000,30000};
|
loopTestParameters info1Params={"info1",500000,2,400000,30000};
|
||||||
loopTestParameters mmap1Params={"mmap",500000,8192,400000,1000000};
|
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 1",0,&area1Params));
|
||||||
//resume_thread(spawn_thread(loopTest,"area test 2",0,&area2Params));
|
//resume_thread(spawn_thread(loopTest,"area test 2",0,&area2Params));
|
||||||
//resume_thread(spawn_thread(loopTest,"area test 3",0,&area3Params));
|
//resume_thread(spawn_thread(loopTest,"area test 3",0,&area3Params));
|
||||||
//resume_thread(spawn_thread(getInfoTest,"info test 1",0,&info1Params));
|
//resume_thread(spawn_thread(getInfoTest,"info test 1",0,&info1Params));
|
||||||
resume_thread(spawn_thread(mmapTest,"mmap test 1",0,&mmap1Params));
|
resume_thread(spawn_thread(mmapTest,"mmap test 1",0,&mmap1Params));
|
||||||
|
//resume_thread(spawn_thread(cloneTest,"clone test 1",0,&clone1Params));
|
||||||
|
|
||||||
snooze(10000000);
|
snooze(1000000000);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,13 @@ struct vnode : public node
|
|||||||
int fd;
|
int fd;
|
||||||
unsigned long offset;
|
unsigned long offset;
|
||||||
bool valid;
|
bool valid;
|
||||||
|
int count;
|
||||||
|
|
||||||
|
vnode (void)
|
||||||
|
{
|
||||||
|
valid=false;
|
||||||
|
count=0;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
typedef unsigned long owningProcess;
|
typedef unsigned long owningProcess;
|
||||||
#define B_OS_NAME_LENGTH 32
|
#define B_OS_NAME_LENGTH 32
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "vmInterface.h"
|
#include "vmInterface.h"
|
||||||
//#include "areaManager.h"
|
//#include "areaManager.h"
|
||||||
#include "mman.h"
|
#include "mman.h"
|
||||||
|
#include "area.h"
|
||||||
|
|
||||||
areaManager am;
|
areaManager am;
|
||||||
swapFileManager swapMan;
|
swapFileManager swapMan;
|
||||||
@ -30,11 +31,22 @@ int32 saverThread(void *areaMan)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 pagerThread(void *areaMan)
|
||||||
|
{
|
||||||
|
areaManager *am=(areaManager *)areaMan;
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
snooze(1000000);
|
||||||
|
am->pager(pageMan.desperation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
vmInterface::vmInterface(int pages)
|
vmInterface::vmInterface(int pages)
|
||||||
{
|
{
|
||||||
nextAreaID=0;
|
nextAreaID=0;
|
||||||
resume_thread(spawn_thread(cleanerThread,"cleanerThread",0,&pageMan));
|
resume_thread(spawn_thread(cleanerThread,"cleanerThread",0,&pageMan));
|
||||||
resume_thread(spawn_thread(saverThread,"saverThread",0,getAM()));
|
resume_thread(spawn_thread(saverThread,"saverThread",0,getAM()));
|
||||||
|
resume_thread(spawn_thread(pagerThread,"pagerThread",0,getAM()));
|
||||||
}
|
}
|
||||||
|
|
||||||
int vmInterface::getAreaByAddress(void *address)
|
int vmInterface::getAreaByAddress(void *address)
|
||||||
@ -104,9 +116,13 @@ status_t vmInterface::getAreaInfo(int Area,area_info *dest)
|
|||||||
}
|
}
|
||||||
|
|
||||||
status_t vmInterface::getNextAreaInfo(int process,int32 *cookie,area_info *dest)
|
status_t vmInterface::getNextAreaInfo(int process,int32 *cookie,area_info *dest)
|
||||||
// Left for later..
|
|
||||||
{
|
{
|
||||||
;
|
area *oldArea=getAM()->findArea(*cookie);
|
||||||
|
area *newArea=(area *)(oldArea->next);
|
||||||
|
if (newArea)
|
||||||
|
return newArea->getInfo(dest);
|
||||||
|
else
|
||||||
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
int vmInterface::getAreaByName(char *name)
|
int vmInterface::getAreaByName(char *name)
|
||||||
@ -114,9 +130,14 @@ int vmInterface::getAreaByName(char *name)
|
|||||||
return getAM()->findArea(name)->getAreaID();
|
return getAM()->findArea(name)->getAreaID();
|
||||||
}
|
}
|
||||||
|
|
||||||
int vmInterface::cloneArea(int area,char *AreaName,void **address, addressSpec addType=ANY, pageState state=NO_LOCK, protectType prot=writable)
|
int vmInterface::cloneArea(int newAreaID,char *AreaName,void **address, addressSpec addType=ANY, pageState state=NO_LOCK, protectType prot=writable)
|
||||||
{
|
{
|
||||||
;
|
area *newArea = new area(getAM());
|
||||||
|
area *oldArea=getAM()->findArea(newAreaID);
|
||||||
|
newArea->cloneArea(oldArea,AreaName,address,addType,state,prot);
|
||||||
|
newArea->setAreaID(nextAreaID++); // THIS IS NOT THREAD SAFE
|
||||||
|
getAM()->addArea(newArea);
|
||||||
|
return newArea->getAreaID();
|
||||||
}
|
}
|
||||||
|
|
||||||
void vmInterface::pager(void)
|
void vmInterface::pager(void)
|
||||||
@ -154,7 +175,7 @@ void *vmInterface::mmap(void *addr, size_t len, int prot, int flags, int fd, off
|
|||||||
addressSpec addType=((flags&MAP_FIXED)?EXACT:ANY);
|
addressSpec addType=((flags&MAP_FIXED)?EXACT:ANY);
|
||||||
protectType protType=(prot&PROT_WRITE)?writable:(prot&PROT_READ)?readable:none;
|
protectType protType=(prot&PROT_WRITE)?writable:(prot&PROT_READ)?readable:none;
|
||||||
// Not doing anything with MAP_SHARED and MAP_COPY - needs to be done
|
// Not doing anything with MAP_SHARED and MAP_COPY - needs to be done
|
||||||
printf ("flags = %x, anon = %x\n",flags,MAP_ANON);
|
//printf ("flags = %x, anon = %x\n",flags,MAP_ANON);
|
||||||
if (flags & MAP_ANON)
|
if (flags & MAP_ANON)
|
||||||
{
|
{
|
||||||
createArea(name,(int)((len+PAGE_SIZE-1)/PAGE_SIZE),&addr, addType ,LAZY,protType);
|
createArea(name,(int)((len+PAGE_SIZE-1)/PAGE_SIZE),&addr, addType ,LAZY,protType);
|
||||||
@ -162,11 +183,20 @@ void *vmInterface::mmap(void *addr, size_t len, int prot, int flags, int fd, off
|
|||||||
}
|
}
|
||||||
|
|
||||||
area *newArea = new area(getAM());
|
area *newArea = new area(getAM());
|
||||||
printf ("area = %x, start = %x\n",newArea, newArea->getStartAddress());
|
//printf ("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->createAreaMappingFile(name,(int)((len+PAGE_SIZE-1)/PAGE_SIZE),&addr,addType,LAZY,protType,fd,offset);
|
||||||
newArea->setAreaID(nextAreaID++); // THIS IS NOT THREAD SAFE
|
newArea->setAreaID(nextAreaID++); // THIS IS NOT THREAD SAFE
|
||||||
getAM()->addArea(newArea);
|
getAM()->addArea(newArea);
|
||||||
newArea->getAreaID();
|
newArea->getAreaID();
|
||||||
|
//pageMan.dump();
|
||||||
|
//newArea->dump();
|
||||||
return addr;
|
return addr;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
status_t vmInterface::munmap(void *addr, size_t len)
|
||||||
|
{
|
||||||
|
// Note that this is broken for any and all munmaps that are not full area in size. This is an all or nothing game...
|
||||||
|
int area=getAreaByAddress(addr);
|
||||||
|
freeArea(area);
|
||||||
|
//pageMan.dump();
|
||||||
|
}
|
||||||
|
@ -24,6 +24,7 @@ class vmInterface // This is the class that "owns" all of the managers.
|
|||||||
status_t resizeArea(int area,size_t size);
|
status_t resizeArea(int area,size_t size);
|
||||||
status_t setAreaProtection(int area,protectType prot);
|
status_t setAreaProtection(int area,protectType prot);
|
||||||
void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
|
void *mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset);
|
||||||
|
status_t munmap(void *addr, size_t len);
|
||||||
void pager(void);
|
void pager(void);
|
||||||
void saver(void);
|
void saver(void);
|
||||||
void cleaner(void);
|
void cleaner(void);
|
||||||
|
@ -11,36 +11,42 @@ void vpage::flush(void)
|
|||||||
|
|
||||||
void vpage::refresh(void)
|
void vpage::refresh(void)
|
||||||
{
|
{
|
||||||
swapMan.read_block(*backingNode,physPage, PAGE_SIZE);
|
swapMan.read_block(*backingNode,((void *)(physPage->getAddress())), PAGE_SIZE);
|
||||||
}
|
|
||||||
|
|
||||||
vpage *vpage::clone(unsigned long address) // The calling method will have to create this...
|
|
||||||
{
|
|
||||||
return new vpage(address,NULL,physPage,(protection==readable)?protection:copyOnWrite,LAZY); // Not sure if LAZY is right or not
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// backing and/or physMem can be NULL/0.
|
// backing and/or physMem can be NULL/0.
|
||||||
vpage::vpage(unsigned long start,vnode *backing, page *physMem,protectType prot,pageState state)
|
vpage::vpage(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));
|
||||||
start_address=start;
|
start_address=start;
|
||||||
end_address=start+PAGE_SIZE-1;
|
end_address=start+PAGE_SIZE-1;
|
||||||
protection=prot;
|
protection=prot;
|
||||||
swappable=(state==NO_LOCK);
|
swappable=(state==NO_LOCK);
|
||||||
|
dirty=true;
|
||||||
|
|
||||||
if (backing)
|
if (backing)
|
||||||
|
{
|
||||||
backingNode=backing;
|
backingNode=backing;
|
||||||
|
backing->count++;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
backingNode=&(swapMan.findNode());
|
backingNode=&(swapMan.findNode());
|
||||||
if (!physPage && (state!=LAZY) && (state!=NO_LOCK))
|
if (!physMem && (state!=LAZY) && (state!=NO_LOCK))
|
||||||
physPage=pageMan.getPage();
|
physPage=pageMan.getPage();
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (physMem)
|
||||||
|
physMem->count++;
|
||||||
physPage=physMem;
|
physPage=physMem;
|
||||||
|
}
|
||||||
|
//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));
|
||||||
}
|
}
|
||||||
|
|
||||||
vpage::~vpage(void)
|
vpage::~vpage(void)
|
||||||
{
|
{
|
||||||
if (physPage) // I doubt that this is always true. Probably need to check for sharing...
|
if (physPage) // Note that free means release one reference
|
||||||
pageMan.freePage(physPage);
|
pageMan.freePage(physPage);
|
||||||
if (backingNode->fd)
|
if (backingNode->fd)
|
||||||
swapMan.freeVNode(*backingNode);
|
swapMan.freeVNode(*backingNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,7 +58,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: virtual address = %x, write = %s\n",(unsigned long) fault_address,((writeError)?"true":"false"));
|
// printf ("vpage::fault: virtual address = %x, write = %s\n",(unsigned long) fault_address,((writeError)?"true":"false"));
|
||||||
if (writeError)
|
if (writeError)
|
||||||
{
|
{
|
||||||
dirty=true;
|
dirty=true;
|
||||||
@ -61,6 +67,8 @@ bool vpage::fault(void *fault_address, bool writeError) // true = OK, false = pa
|
|||||||
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=pageMan.getPage();
|
page *newPhysPage=pageMan.getPage();
|
||||||
|
if (!newPhysPage) // No room at the inn
|
||||||
|
return false;
|
||||||
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;
|
||||||
@ -71,12 +79,17 @@ bool vpage::fault(void *fault_address, bool writeError) // true = OK, false = pa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
physPage=pageMan.getPage();
|
physPage=pageMan.getPage();
|
||||||
printf ("vpage::fault: New page allocated! new physical address = %x\n",physPage->getAddress());
|
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));
|
||||||
// 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();
|
||||||
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");
|
||||||
|
// dump();
|
||||||
|
// printf ("vpage::fault: exiting\n");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
char vpage::getByte(unsigned long address)
|
char vpage::getByte(unsigned long address)
|
||||||
@ -117,8 +130,10 @@ void vpage::setInt(unsigned long address,int value)
|
|||||||
|
|
||||||
void vpage::pager(int desperation)
|
void vpage::pager(int desperation)
|
||||||
{
|
{
|
||||||
|
printf ("vpage::pager start desperation = %d\n",desperation);
|
||||||
if (!swappable)
|
if (!swappable)
|
||||||
return;
|
return;
|
||||||
|
printf ("vpage::pager swappable\n");
|
||||||
switch (desperation)
|
switch (desperation)
|
||||||
{
|
{
|
||||||
case 1: return; break;
|
case 1: return; break;
|
||||||
@ -128,8 +143,11 @@ void vpage::pager(int desperation)
|
|||||||
case 5: if (!physPage) return;break;
|
case 5: if (!physPage) return;break;
|
||||||
default: return;break;
|
default: return;break;
|
||||||
}
|
}
|
||||||
|
printf ("vpage::pager flushing\n");
|
||||||
flush();
|
flush();
|
||||||
|
printf ("vpage::pager freeing\n");
|
||||||
pageMan.freePage(physPage);
|
pageMan.freePage(physPage);
|
||||||
|
printf ("vpage::pager going to NULL\n");
|
||||||
physPage=NULL;
|
physPage=NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,20 +17,27 @@ class vpage : public node
|
|||||||
bool contains(uint32 address) { return ((start_address<=address) && (end_address>=address)); }
|
bool contains(uint32 address) { return ((start_address<=address) && (end_address>=address)); }
|
||||||
void flush(void); // write page to vnode, if necessary
|
void flush(void); // write page to vnode, if necessary
|
||||||
void refresh(void); // Read page back in from vnode
|
void refresh(void); // Read page back in from vnode
|
||||||
vpage *clone(unsigned long); // Make a new vpage that is exactly the same as this one.
|
|
||||||
// If we are read only, it is read only.
|
|
||||||
// If we are read/write, both pages are copy on write
|
|
||||||
vpage(unsigned long start,vnode *backing, page *physMem,protectType prot,pageState state); // backing and/or physMem can be NULL/0.
|
vpage(unsigned long start,vnode *backing, page *physMem,protectType prot,pageState state); // backing and/or physMem can be NULL/0.
|
||||||
~vpage(void);
|
~vpage(void);
|
||||||
void setProtection(protectType prot);
|
void setProtection(protectType prot);
|
||||||
protectType getProtection(void) {return protection;}
|
protectType getProtection(void) {return protection;}
|
||||||
void *getStartAddress(void) {return (void *)start_address;}
|
void *getStartAddress(void) {return (void *)start_address;}
|
||||||
|
page *getPhysPage(void) {return physPage;}
|
||||||
|
vnode *getBacking(void) {return backingNode;}
|
||||||
|
|
||||||
bool fault(void *fault_address, bool writeError); // true = OK, false = panic.
|
bool fault(void *fault_address, bool writeError); // true = OK, false = panic.
|
||||||
|
|
||||||
void pager(int desperation);
|
void pager(int desperation);
|
||||||
void saver(void);
|
void saver(void);
|
||||||
|
|
||||||
|
void dump(void)
|
||||||
|
{
|
||||||
|
printf ("Dumping vpage %x, address = %x, \n\t physPage: ",this,start_address);
|
||||||
|
if (physPage)
|
||||||
|
physPage->dump();
|
||||||
|
else
|
||||||
|
printf ("NULL\n");
|
||||||
|
}
|
||||||
char getByte(unsigned long offset); // This is for testing only
|
char getByte(unsigned long offset); // This is for testing only
|
||||||
void setByte(unsigned long offset,char value); // This is for testing only
|
void setByte(unsigned long offset,char value); // This is for testing only
|
||||||
int getInt(unsigned long offset); // This is for testing only
|
int getInt(unsigned long offset); // This is for testing only
|
||||||
|
Loading…
Reference in New Issue
Block a user