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:
Michael Phipps
2002-08-26 20:14:54 +00:00
parent 3e5d9213bd
commit afea942ffa
15 changed files with 308 additions and 54 deletions
+1 -6
View File
@@ -1,9 +1,4 @@
SubDir OBOS_TOP src kernel vm2 ; SubDir OBOS_TOP src kernel vm2 ;
C++FLAGS += -g ; BinCommand vmTest : area.C areaManager.C cacheManager.C page.C pageManager.C swapFileManager.C test.C vmInterface.C vpage.C : root be ;
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 ;
+7 -7
View File
@@ -1,16 +1,16 @@
1) Need to make the paging daemon load the pages in, using semaphores. 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 2) See how unresolvable page faults and permissions errors are handled - need to properly handle
3) Implment cloneArea 3) Tests are not done.
4) Tests are not done.
Test: Test:
getAreaInfo
getNextAreaInfo getNextAreaInfo
cloneArea cloneArea
resizeArea resizeArea
setAreaProtection setAreaProtection
mmap mmap / munmap
paging paging
disk caching
5) Improve locking (remains to be seen - works ok so far) 4) 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. 5) 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. - 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
View File
@@ -1,8 +1,17 @@
#include "area.h" #include "area.h"
#include "areaManager.h" #include "areaManager.h"
#include "vpage.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; manager=myManager;
} }
@@ -43,11 +52,12 @@ status_t area::createAreaMappingFile(char *inName, int pageCount,void **address,
unsigned long base=mapAddressSpecToAddress(type,requested,pageCount); unsigned long base=mapAddressSpecToAddress(type,requested,pageCount);
for (int i=0;i<pageCount;i++) for (int i=0;i<pageCount;i++)
{ {
vnode *newVnode=new vnode; vnode *newVnode=vnodePool.get();
newVnode->fd=fd; newVnode->fd=fd;
newVnode->offset=offset+PAGE_SIZE*i; newVnode->offset=offset+PAGE_SIZE*i;
newVnode->valid=true; 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); 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);
} }
@@ -76,7 +86,8 @@ status_t area::createArea(char *inName, int pageCount,void **address, addressSpe
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=vpagePool.get();
newPage->setup(base+PAGE_SIZE*i,NULL,NULL,protect,inState);
vpages.add(newPage); vpages.add(newPage);
} }
manager->unlock(); manager->unlock();
@@ -107,7 +118,8 @@ status_t area::cloneArea(area *origArea, char *inName, void **address, addressSp
{ {
vpage *newPage,*page=(vpage *)cur; vpage *newPage,*page=(vpage *)cur;
// Cloned area has the same physical page and backing store... // 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); vpages.add(newPage);
base+=PAGE_SIZE; base+=PAGE_SIZE;
cur=cur->next; cur=cur->next;
@@ -124,23 +136,25 @@ status_t area::cloneArea(area *origArea, char *inName, void **address, addressSp
void area::freeArea(void) void area::freeArea(void)
{ {
//printf ("area::freeArea: starting \n"); //printf ("area::freeArea: starting \n");
manager->lock(); manager->lock();
// vpages.dump(); // vpages.dump();
for (struct node *cur=vpages.rock;cur;) node *cur;
while (cur=vpages.next())
{ {
//printf ("area::freeArea: wasting a page: %x\n",cur); //printf ("area::freeArea: wasting a page: %x\n",cur);
vpage *page=(vpage *)cur; vpage *page=reinterpret_cast<vpage *>(cur);
if (finalWrite) if (finalWrite)
page->flush(); page->flush();
//printf ("area::freeArea: flushed a page \n"); //printf ("area::freeArea: flushed a page \n");
cur=cur->next; page->cleanup();
delete page; // Probably need to add a destructor //page->next=NULL;
vpagePool.put(page);
} }
//printf ("area::freeArea: unlocking \n"); //printf ("area::freeArea: unlocking \n");
manager->unlock(); manager->unlock();
//printf ("area::freeArea: ending \n"); //printf ("area::freeArea: ending \n");
} }
status_t area::getInfo(area_info *dest) status_t area::getInfo(area_info *dest)
@@ -188,7 +202,8 @@ status_t area::resize(size_t newSize)
vpage *newPage; vpage *newPage;
for (int i=0;i<pageCount;i++) 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); vpages.add(newPage);
} }
end_address+=start_address+newSize; 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; for (cur=vpages.rock;cur->next;cur=cur->next); // INTENTIONAL - find the last one;
vpage *oldPage=(vpage *)cur; vpage *oldPage=(vpage *)cur;
delete oldPage; oldPage->cleanup();
vpagePool.put(oldPage);
} }
} }
manager->unlock(); manager->unlock();
+2 -1
View File
@@ -24,7 +24,8 @@ class area : public node
unsigned long end_address; unsigned long end_address;
vpage *findVPage(unsigned long); vpage *findVPage(unsigned long);
public: public:
area(areaManager *myManager); area(void);
void setup(areaManager *myManager);
bool nameMatch(char *matchName) {return (strcmp(matchName,name)==0);} bool nameMatch(char *matchName) {return (strcmp(matchName,name)==0);}
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);
+51
View File
@@ -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);
}
};
+6 -2
View File
@@ -1,6 +1,9 @@
#include <cacheManager.h> #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. 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(); lock();
// Create a vnode here // 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); vpages.add(newPage);
cacheMembers.add(newPage); cacheMembers.add(newPage);
unlock(); unlock();
+55
View File
@@ -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);
}
};
*/
+4 -1
View File
@@ -2,6 +2,9 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <vnodePool.h>
extern poolvnode vnodePool;
swapFileManager::swapFileManager(void) swapFileManager::swapFileManager(void)
{ {
@@ -44,7 +47,7 @@ vnode &swapFileManager::findNode(void)
Unlock(); Unlock();
if (!newNode) if (!newNode)
{ {
newNode=new vnode; newNode=vnodePool.get();
newNode->fd=swapFile; newNode->fd=swapFile;
newNode->offset=maxNode+=PAGE_SIZE; newNode->offset=maxNode+=PAGE_SIZE;
//printf (" New One: %d\n",newNode->offset); //printf (" New One: %d\n",newNode->offset);
+3
View File
@@ -1,3 +1,5 @@
#ifndef _SWAPFILE_MANAGER
#define _SWAPFILE_MANAGER
#include <unistd.h> #include <unistd.h>
#include <fcntl.h> #include <fcntl.h>
#include "vm.h" #include "vm.h"
@@ -19,3 +21,4 @@ class swapFileManager {
void Lock() {acquire_sem(lockFreeList);} void Lock() {acquire_sem(lockFreeList);}
void Unlock() {release_sem(lockFreeList);} void Unlock() {release_sem(lockFreeList);}
}; };
#endif
+2 -2
View File
@@ -94,8 +94,6 @@ int32 getInfoTest(void *parameters)
int32 mmapTest (void *parameters) int32 mmapTest (void *parameters)
{ {
void *map; void *map;
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)
@@ -109,9 +107,11 @@ int32 mmapTest (void *parameters)
printf ("mmap address = %x\n",map); printf ("mmap address = %x\n",map);
for (int i=0;i<size;i++) for (int i=0;i<size;i++)
writeByte((int32)map,i,i%256); writeByte((int32)map,i,i%256);
printf ("mmapTest: writing done\n");
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));
printf ("mmapTest: reading done\n");
snooze(params->loopSnooze); snooze(params->loopSnooze);
vm.munmap(map,size); vm.munmap(map,size);
close(fd); close(fd);
+21 -12
View File
@@ -2,10 +2,16 @@
//#include "areaManager.h" //#include "areaManager.h"
#include "mman.h" #include "mman.h"
#include "area.h" #include "area.h"
#include "areaPool.h"
#include "vpagePool.h"
#include "vnodePool.h"
areaManager am; areaManager am;
swapFileManager swapMan; 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) 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) 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->createArea(AreaName,pageCount,address,addType,state,protect);
newArea->setAreaID(nextAreaID++); // THIS IS NOT THREAD SAFE newArea->setAreaID(nextAreaID++); // THIS IS NOT THREAD SAFE
getAM()->addArea(newArea); getAM()->addArea(newArea);
@@ -93,14 +100,14 @@ void vmInterface::freeArea(int Area)
//printf ("vmInterface::freeArea: found area %x\n",oldArea); //printf ("vmInterface::freeArea: found area %x\n",oldArea);
if (oldArea) if (oldArea)
{ {
//printf ("vmInterface::freeArea: removing area %x from linked list\n",oldArea); // printf ("vmInterface::freeArea: removing area %x from linked list\n",oldArea);
areaManager *foo=getAM(); areaManager *manager=getAM();
//printf ("vmInterface::freeArea: areaManager = %x \n",foo); // printf ("vmInterface::freeArea: areaManager = %x \n",manager);
foo->removeArea(oldArea); manager->removeArea(oldArea);
//printf ("vmInterface::freeArea: deleting area %x \n",oldArea); // printf ("vmInterface::freeArea: deleting area %x \n",oldArea);
oldArea->freeArea(); oldArea->freeArea();
//printf ("vmInterface::freeArea: freeArea complete \n"); // printf ("vmInterface::freeArea: freeArea complete \n");
delete oldArea; areaPool.put(oldArea);
} }
else else
printf ("vmInterface::freeArea: unable to find requested area\n"); 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) 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 *newArea = areaPool.get();
area *oldArea=getAM()->findArea(newAreaID); newArea->setup(getAM());
area *oldArea=getAM()->findArea(newAreaID);
newArea->cloneArea(oldArea,AreaName,address,addType,state,prot); newArea->cloneArea(oldArea,AreaName,address,addType,state,prot);
newArea->setAreaID(nextAreaID++); // THIS IS NOT THREAD SAFE newArea->setAreaID(nextAreaID++); // THIS IS NOT THREAD SAFE
getAM()->addArea(newArea); getAM()->addArea(newArea);
@@ -182,7 +190,8 @@ void *vmInterface::mmap(void *addr, size_t len, int prot, int flags, int fd, off
return addr; return addr;
} }
area *newArea = new area(getAM()); area *newArea = areaPool.get();
newArea->setup(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
+51
View File
@@ -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
View File
@@ -1,7 +1,9 @@
#include "vpage.h" #include "vpage.h"
#include "vnodePool.h"
extern swapFileManager swapMan; extern swapFileManager swapMan;
extern pageManager pageMan; extern pageManager pageMan;
extern poolvnode vnodePool;
void vpage::flush(void) void vpage::flush(void)
{ {
@@ -14,8 +16,12 @@ void vpage::refresh(void)
swapMan.read_block(*backingNode,((void *)(physPage->getAddress())), PAGE_SIZE); swapMan.read_block(*backingNode,((void *)(physPage->getAddress())), PAGE_SIZE);
} }
vpage::vpage(void)
{
}
// 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) 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)); //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;
@@ -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)); //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 if (physPage) // Note that free means release one reference
pageMan.freePage(physPage); pageMan.freePage(physPage);
if (backingNode->fd) if (backingNode)
swapMan.freeVNode(*backingNode); {
if (backingNode->fd)
swapMan.freeVNode(*backingNode);
vnodePool.put(backingNode);
}
} }
void vpage::setProtection(protectType prot) void vpage::setProtection(protectType prot)
@@ -130,7 +140,7 @@ 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); //printf ("vpage::pager start desperation = %d\n",desperation);
if (!swappable) if (!swappable)
return; return;
printf ("vpage::pager swappable\n"); printf ("vpage::pager swappable\n");
+6 -2
View File
@@ -1,3 +1,5 @@
#ifndef VPAGE_H
#define VPAGE_H
#include <vm.h> #include <vm.h>
#include <pageManager.h> #include <pageManager.h>
#include <swapFileManager.h> #include <swapFileManager.h>
@@ -17,8 +19,9 @@ 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(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); 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;}
@@ -43,3 +46,4 @@ class vpage : public node
int getInt(unsigned long offset); // This is for testing only int getInt(unsigned long offset); // This is for testing only
void setInt(unsigned long offset,int value); // This is for testing only void setInt(unsigned long offset,int value); // This is for testing only
}; };
#endif
+52
View File
@@ -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);
}
};