Added pooling, removing new and delete in most cases.
pageManager still needs special treatment. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@890 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,9 +1,4 @@
|
||||
SubDir OBOS_TOP src kernel vm2 ;
|
||||
|
||||
C++FLAGS += -g ;
|
||||
CCFLAGS += -g ;
|
||||
|
||||
Server vmTest : area.C areaManager.C cacheManager.C page.C pageManager.C swapFileManager.C test.C vmInterface.C vpage.C ;
|
||||
|
||||
LinkSharedOSLibs vmTest : root be ;
|
||||
BinCommand vmTest : area.C areaManager.C cacheManager.C page.C pageManager.C swapFileManager.C test.C vmInterface.C vpage.C : root be ;
|
||||
|
||||
|
||||
+7
-7
@@ -1,16 +1,16 @@
|
||||
1) Need to make the paging daemon load the pages in, using semaphores.
|
||||
2) See how unresolvable page faults and permissions errors are handled - need to properly handle
|
||||
3) Implment cloneArea
|
||||
4) Tests are not done.
|
||||
3) Tests are not done.
|
||||
Test:
|
||||
getAreaInfo
|
||||
getNextAreaInfo
|
||||
cloneArea
|
||||
resizeArea
|
||||
setAreaProtection
|
||||
mmap
|
||||
mmap / munmap
|
||||
paging
|
||||
disk caching
|
||||
|
||||
5) Improve locking (remains to be seen - works ok so far)
|
||||
6) I use new and delete. I know that doesn't work in kernel land. Not too tough to change, though.
|
||||
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.
|
||||
4) Improve locking (remains to be seen - works ok so far)
|
||||
5) I use new and delete. I know that doesn't work in kernel land. Not too tough to change, though.
|
||||
- Pooling is now used for everything but pages
|
||||
6) There is no arch-level integration. This is to be tested (to death) in user land first. * == can not be done in user land.
|
||||
|
||||
+32
-16
@@ -1,8 +1,17 @@
|
||||
#include "area.h"
|
||||
#include "areaManager.h"
|
||||
#include "vpage.h"
|
||||
#include "vpagePool.h"
|
||||
#include "vnodePool.h"
|
||||
|
||||
area::area (areaManager *myManager)
|
||||
extern poolvpage vpagePool;
|
||||
extern poolvnode vnodePool;
|
||||
|
||||
area::area(void)
|
||||
{
|
||||
}
|
||||
|
||||
void area::setup (areaManager *myManager)
|
||||
{
|
||||
manager=myManager;
|
||||
}
|
||||
@@ -43,11 +52,12 @@ status_t area::createAreaMappingFile(char *inName, int pageCount,void **address,
|
||||
unsigned long base=mapAddressSpecToAddress(type,requested,pageCount);
|
||||
for (int i=0;i<pageCount;i++)
|
||||
{
|
||||
vnode *newVnode=new vnode;
|
||||
vnode *newVnode=vnodePool.get();
|
||||
newVnode->fd=fd;
|
||||
newVnode->offset=offset+PAGE_SIZE*i;
|
||||
newVnode->valid=true;
|
||||
newPage = new vpage(base+PAGE_SIZE*i,newVnode,NULL,protect,inState);
|
||||
newPage=vpagePool.get();
|
||||
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);
|
||||
}
|
||||
@@ -76,7 +86,8 @@ status_t area::createArea(char *inName, int pageCount,void **address, addressSpe
|
||||
for (int i=0;i<pageCount;i++)
|
||||
{
|
||||
//printf ("in area::createArea: creating page = %d\n",i);
|
||||
newPage = new vpage(base+PAGE_SIZE*i,NULL,NULL,protect,inState);
|
||||
newPage=vpagePool.get();
|
||||
newPage->setup(base+PAGE_SIZE*i,NULL,NULL,protect,inState);
|
||||
vpages.add(newPage);
|
||||
}
|
||||
manager->unlock();
|
||||
@@ -107,7 +118,8 @@ status_t area::cloneArea(area *origArea, char *inName, void **address, addressSp
|
||||
{
|
||||
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);
|
||||
newPage=vpagePool.get();
|
||||
newPage->setup(base,page->getBacking(),page->getPhysPage(),protect,inState);
|
||||
vpages.add(newPage);
|
||||
base+=PAGE_SIZE;
|
||||
cur=cur->next;
|
||||
@@ -124,23 +136,25 @@ status_t area::cloneArea(area *origArea, char *inName, void **address, addressSp
|
||||
|
||||
void area::freeArea(void)
|
||||
{
|
||||
//printf ("area::freeArea: starting \n");
|
||||
//printf ("area::freeArea: starting \n");
|
||||
|
||||
manager->lock();
|
||||
// vpages.dump();
|
||||
for (struct node *cur=vpages.rock;cur;)
|
||||
node *cur;
|
||||
while (cur=vpages.next())
|
||||
{
|
||||
//printf ("area::freeArea: wasting a page: %x\n",cur);
|
||||
vpage *page=(vpage *)cur;
|
||||
//printf ("area::freeArea: wasting a page: %x\n",cur);
|
||||
vpage *page=reinterpret_cast<vpage *>(cur);
|
||||
if (finalWrite)
|
||||
page->flush();
|
||||
//printf ("area::freeArea: flushed a page \n");
|
||||
cur=cur->next;
|
||||
delete page; // Probably need to add a destructor
|
||||
//printf ("area::freeArea: flushed a page \n");
|
||||
page->cleanup();
|
||||
//page->next=NULL;
|
||||
vpagePool.put(page);
|
||||
}
|
||||
//printf ("area::freeArea: unlocking \n");
|
||||
//printf ("area::freeArea: unlocking \n");
|
||||
manager->unlock();
|
||||
//printf ("area::freeArea: ending \n");
|
||||
//printf ("area::freeArea: ending \n");
|
||||
}
|
||||
|
||||
status_t area::getInfo(area_info *dest)
|
||||
@@ -188,7 +202,8 @@ status_t area::resize(size_t newSize)
|
||||
vpage *newPage;
|
||||
for (int i=0;i<pageCount;i++)
|
||||
{
|
||||
newPage = new vpage(end_address+PAGE_SIZE*i-1,NULL,NULL,protection,state);
|
||||
newPage=vpagePool.get();
|
||||
newPage->setup(end_address+PAGE_SIZE*i-1,NULL,NULL,protection,state);
|
||||
vpages.add(newPage);
|
||||
}
|
||||
end_address+=start_address+newSize;
|
||||
@@ -203,7 +218,8 @@ status_t area::resize(size_t newSize)
|
||||
{
|
||||
for (cur=vpages.rock;cur->next;cur=cur->next); // INTENTIONAL - find the last one;
|
||||
vpage *oldPage=(vpage *)cur;
|
||||
delete oldPage;
|
||||
oldPage->cleanup();
|
||||
vpagePool.put(oldPage);
|
||||
}
|
||||
}
|
||||
manager->unlock();
|
||||
|
||||
@@ -24,7 +24,8 @@ class area : public node
|
||||
unsigned long end_address;
|
||||
vpage *findVPage(unsigned long);
|
||||
public:
|
||||
area(areaManager *myManager);
|
||||
area(void);
|
||||
void setup(areaManager *myManager);
|
||||
bool nameMatch(char *matchName) {return (strcmp(matchName,name)==0);}
|
||||
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);
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
#include "pageManager.h"
|
||||
|
||||
extern pageManager pageMan;
|
||||
class poolarea
|
||||
{
|
||||
private:
|
||||
list unused;
|
||||
sem_id inUse;
|
||||
public:
|
||||
poolarea(void)
|
||||
{
|
||||
inUse = create_sem(1,"areapool");
|
||||
}
|
||||
area *get(void)
|
||||
{
|
||||
area *ret=NULL;
|
||||
if (unused.count())
|
||||
{
|
||||
//printf ("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);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf ("poolarea::get: Getting a new page!\n");
|
||||
page *newPage=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);
|
||||
for (int i=0;i<newCount;i++)
|
||||
unused.add(((void *)(newPage->getAddress()+(i*sizeof(area)))));
|
||||
release_sem(inUse);
|
||||
return (get()); // A little cheat - call self again to get the first one from stack...
|
||||
}
|
||||
}
|
||||
void put(area *in)
|
||||
{
|
||||
acquire_sem(inUse);
|
||||
unused.add(in);
|
||||
release_sem(inUse);
|
||||
}
|
||||
|
||||
};
|
||||
@@ -1,6 +1,9 @@
|
||||
#include <cacheManager.h>
|
||||
#include <vpagePool.h>
|
||||
|
||||
cacheManager::cacheManager(void) : area (NULL)
|
||||
extern poolvpage vpagePool;
|
||||
|
||||
cacheManager::cacheManager(void) : area ()
|
||||
{
|
||||
myLock=create_sem(1,"Area Manager Semaphore"); // Should have team name in it.
|
||||
}
|
||||
@@ -33,7 +36,8 @@ void *cacheManager::createBlock(vnode *target,bool readOnly)
|
||||
}
|
||||
lock();
|
||||
// Create a vnode here
|
||||
vpage *newPage = new vpage(begin,target,NULL,((readOnly)?readable:writable),NO_LOCK);
|
||||
vpage *newPage = vpagePool.get();
|
||||
newPage->setup(begin,target,NULL,((readOnly)?readable:writable),NO_LOCK);
|
||||
vpages.add(newPage);
|
||||
cacheMembers.add(newPage);
|
||||
unlock();
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
#include "pageManager.h"
|
||||
|
||||
extern pageManager pageMan;
|
||||
/* This is the template
|
||||
* replace TYPE with the type you need a pool for
|
||||
*
|
||||
class poolTYPE
|
||||
{
|
||||
private:
|
||||
list unused;
|
||||
sem_id inUse;
|
||||
public:
|
||||
poolTYPE(void)
|
||||
{
|
||||
inUse = create_sem(1,"TYPEpool");
|
||||
}
|
||||
TYPE *get(void)
|
||||
{
|
||||
TYPE *ret=NULL;
|
||||
if (unused.count())
|
||||
{
|
||||
printf ("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);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
printf ("poolTYPE::get: Getting a new page!\n");
|
||||
page *newPage=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);
|
||||
for (int i=0;i<newCount;i++)
|
||||
unused.add(((void *)(newPage->getAddress()+(i*sizeof(TYPE)))));
|
||||
release_sem(inUse);
|
||||
return (get()); // A little cheat - call self again to get the first one from stack...
|
||||
}
|
||||
}
|
||||
void put(TYPE *in)
|
||||
{
|
||||
acquire_sem(inUse);
|
||||
unused.add(in);
|
||||
release_sem(inUse);
|
||||
}
|
||||
|
||||
};
|
||||
*/
|
||||
@@ -2,6 +2,9 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <vnodePool.h>
|
||||
|
||||
extern poolvnode vnodePool;
|
||||
|
||||
swapFileManager::swapFileManager(void)
|
||||
{
|
||||
@@ -44,7 +47,7 @@ vnode &swapFileManager::findNode(void)
|
||||
Unlock();
|
||||
if (!newNode)
|
||||
{
|
||||
newNode=new vnode;
|
||||
newNode=vnodePool.get();
|
||||
newNode->fd=swapFile;
|
||||
newNode->offset=maxNode+=PAGE_SIZE;
|
||||
//printf (" New One: %d\n",newNode->offset);
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#ifndef _SWAPFILE_MANAGER
|
||||
#define _SWAPFILE_MANAGER
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include "vm.h"
|
||||
@@ -19,3 +21,4 @@ class swapFileManager {
|
||||
void Lock() {acquire_sem(lockFreeList);}
|
||||
void Unlock() {release_sem(lockFreeList);}
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -94,8 +94,6 @@ int32 getInfoTest(void *parameters)
|
||||
int32 mmapTest (void *parameters)
|
||||
{
|
||||
void *map;
|
||||
|
||||
|
||||
loopTestParameters *params=((loopTestParameters *)parameters);
|
||||
int size=params->areaSize; // Note that this is in bytes, not in pages
|
||||
while (1)
|
||||
@@ -109,9 +107,11 @@ int32 mmapTest (void *parameters)
|
||||
printf ("mmap address = %x\n",map);
|
||||
for (int i=0;i<size;i++)
|
||||
writeByte((int32)map,i,i%256);
|
||||
printf ("mmapTest: writing done\n");
|
||||
for (int i=0;i<size;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 ("mmapTest: reading done\n");
|
||||
snooze(params->loopSnooze);
|
||||
vm.munmap(map,size);
|
||||
close(fd);
|
||||
|
||||
@@ -2,10 +2,16 @@
|
||||
//#include "areaManager.h"
|
||||
#include "mman.h"
|
||||
#include "area.h"
|
||||
#include "areaPool.h"
|
||||
#include "vpagePool.h"
|
||||
#include "vnodePool.h"
|
||||
|
||||
areaManager am;
|
||||
swapFileManager swapMan;
|
||||
pageManager pageMan(10); // Obviously this hard coded number is a hack...
|
||||
poolarea areaPool;
|
||||
poolvpage vpagePool;
|
||||
poolvnode vnodePool;
|
||||
pageManager pageMan(30); // Obviously this hard coded number is a hack...
|
||||
|
||||
areaManager *vmInterface::getAM(void)
|
||||
{
|
||||
@@ -79,7 +85,8 @@ status_t vmInterface::resizeArea(int Area,size_t size)
|
||||
|
||||
int vmInterface::createArea(char *AreaName,int pageCount,void **address, addressSpec addType,pageState state,protectType protect)
|
||||
{
|
||||
area *newArea = new area(getAM());
|
||||
area *newArea = areaPool.get();
|
||||
newArea->setup(getAM());
|
||||
newArea->createArea(AreaName,pageCount,address,addType,state,protect);
|
||||
newArea->setAreaID(nextAreaID++); // THIS IS NOT THREAD SAFE
|
||||
getAM()->addArea(newArea);
|
||||
@@ -93,14 +100,14 @@ void vmInterface::freeArea(int Area)
|
||||
//printf ("vmInterface::freeArea: found area %x\n",oldArea);
|
||||
if (oldArea)
|
||||
{
|
||||
//printf ("vmInterface::freeArea: removing area %x from linked list\n",oldArea);
|
||||
areaManager *foo=getAM();
|
||||
//printf ("vmInterface::freeArea: areaManager = %x \n",foo);
|
||||
foo->removeArea(oldArea);
|
||||
//printf ("vmInterface::freeArea: deleting area %x \n",oldArea);
|
||||
// printf ("vmInterface::freeArea: removing area %x from linked list\n",oldArea);
|
||||
areaManager *manager=getAM();
|
||||
// printf ("vmInterface::freeArea: areaManager = %x \n",manager);
|
||||
manager->removeArea(oldArea);
|
||||
// printf ("vmInterface::freeArea: deleting area %x \n",oldArea);
|
||||
oldArea->freeArea();
|
||||
//printf ("vmInterface::freeArea: freeArea complete \n");
|
||||
delete oldArea;
|
||||
// printf ("vmInterface::freeArea: freeArea complete \n");
|
||||
areaPool.put(oldArea);
|
||||
}
|
||||
else
|
||||
printf ("vmInterface::freeArea: unable to find requested area\n");
|
||||
@@ -132,8 +139,9 @@ int vmInterface::getAreaByName(char *name)
|
||||
|
||||
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);
|
||||
area *newArea = areaPool.get();
|
||||
newArea->setup(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);
|
||||
@@ -182,7 +190,8 @@ void *vmInterface::mmap(void *addr, size_t len, int prot, int flags, int fd, off
|
||||
return addr;
|
||||
}
|
||||
|
||||
area *newArea = new area(getAM());
|
||||
area *newArea = areaPool.get();
|
||||
newArea->setup(getAM());
|
||||
//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->setAreaID(nextAreaID++); // THIS IS NOT THREAD SAFE
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
#include "pageManager.h"
|
||||
|
||||
extern pageManager pageMan;
|
||||
class poolvnode
|
||||
{
|
||||
private:
|
||||
list unused;
|
||||
sem_id inUse;
|
||||
public:
|
||||
poolvnode(void)
|
||||
{
|
||||
inUse = create_sem(1,"vnodepool");
|
||||
}
|
||||
vnode *get(void)
|
||||
{
|
||||
vnode *ret=NULL;
|
||||
if (unused.count())
|
||||
{
|
||||
//printf ("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);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf ("poolvnode::get: Getting a new page!\n");
|
||||
page *newPage=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);
|
||||
for (int i=0;i<newCount;i++)
|
||||
unused.add(((void *)(newPage->getAddress()+(i*sizeof(vnode)))));
|
||||
release_sem(inUse);
|
||||
return (get()); // A little cheat - call self again to get the first one from stack...
|
||||
}
|
||||
}
|
||||
void put(vnode *in)
|
||||
{
|
||||
acquire_sem(inUse);
|
||||
unused.add(in);
|
||||
release_sem(inUse);
|
||||
}
|
||||
|
||||
};
|
||||
+15
-5
@@ -1,7 +1,9 @@
|
||||
#include "vpage.h"
|
||||
#include "vnodePool.h"
|
||||
|
||||
extern swapFileManager swapMan;
|
||||
extern pageManager pageMan;
|
||||
extern poolvnode vnodePool;
|
||||
|
||||
void vpage::flush(void)
|
||||
{
|
||||
@@ -14,8 +16,12 @@ void vpage::refresh(void)
|
||||
swapMan.read_block(*backingNode,((void *)(physPage->getAddress())), PAGE_SIZE);
|
||||
}
|
||||
|
||||
vpage::vpage(void)
|
||||
{
|
||||
}
|
||||
|
||||
// backing and/or physMem can be NULL/0.
|
||||
vpage::vpage(unsigned long start,vnode *backing, page *physMem,protectType prot,pageState state)
|
||||
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));
|
||||
start_address=start;
|
||||
@@ -42,12 +48,16 @@ vpage::vpage(unsigned long start,vnode *backing, page *physMem,protectType prot,
|
||||
//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)
|
||||
void vpage::cleanup(void)
|
||||
{
|
||||
if (physPage) // Note that free means release one reference
|
||||
pageMan.freePage(physPage);
|
||||
if (backingNode->fd)
|
||||
swapMan.freeVNode(*backingNode);
|
||||
if (backingNode)
|
||||
{
|
||||
if (backingNode->fd)
|
||||
swapMan.freeVNode(*backingNode);
|
||||
vnodePool.put(backingNode);
|
||||
}
|
||||
}
|
||||
|
||||
void vpage::setProtection(protectType prot)
|
||||
@@ -130,7 +140,7 @@ void vpage::setInt(unsigned long address,int value)
|
||||
|
||||
void vpage::pager(int desperation)
|
||||
{
|
||||
printf ("vpage::pager start desperation = %d\n",desperation);
|
||||
//printf ("vpage::pager start desperation = %d\n",desperation);
|
||||
if (!swappable)
|
||||
return;
|
||||
printf ("vpage::pager swappable\n");
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
#ifndef VPAGE_H
|
||||
#define VPAGE_H
|
||||
#include <vm.h>
|
||||
#include <pageManager.h>
|
||||
#include <swapFileManager.h>
|
||||
@@ -17,8 +19,9 @@ class vpage : public node
|
||||
bool contains(uint32 address) { return ((start_address<=address) && (end_address>=address)); }
|
||||
void flush(void); // write page to vnode, if necessary
|
||||
void refresh(void); // Read page back in from vnode
|
||||
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 setup(unsigned long start,vnode *backing, page *physMem,protectType prot,pageState state); // backing and/or physMem can be NULL/0.
|
||||
void cleanup(void);
|
||||
void setProtection(protectType prot);
|
||||
protectType getProtection(void) {return protection;}
|
||||
void *getStartAddress(void) {return (void *)start_address;}
|
||||
@@ -43,3 +46,4 @@ class vpage : public node
|
||||
int getInt(unsigned long offset); // This is for testing only
|
||||
void setInt(unsigned long offset,int value); // This is for testing only
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
#include "pageManager.h"
|
||||
#include "vpage.h"
|
||||
|
||||
extern pageManager pageMan;
|
||||
class poolvpage
|
||||
{
|
||||
private:
|
||||
list unused;
|
||||
sem_id inUse;
|
||||
public:
|
||||
poolvpage(void)
|
||||
{
|
||||
inUse = create_sem(1,"vpagepool");
|
||||
}
|
||||
vpage *get(void)
|
||||
{
|
||||
vpage *ret=NULL;
|
||||
if (unused.count())
|
||||
{
|
||||
//printf ("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);
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf ("poolvpage::get: Getting a new page!\n");
|
||||
page *newPage=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);
|
||||
for (int i=0;i<newCount;i++)
|
||||
unused.add(((void *)(newPage->getAddress()+(i*sizeof(vpage)))));
|
||||
release_sem(inUse);
|
||||
return (get()); // A little cheat - call self again to get the first one from stack...
|
||||
}
|
||||
}
|
||||
void put(vpage *in)
|
||||
{
|
||||
acquire_sem(inUse);
|
||||
unused.add(in);
|
||||
release_sem(inUse);
|
||||
}
|
||||
|
||||
};
|
||||
Reference in New Issue
Block a user