With this change, all memory except for the areaManager is allocated from the
one area that we allocate. The areaManager should really be created when the process is created, so this is something to wait for HW integration time. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@983 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
+4
-1
@@ -1,6 +1,9 @@
|
|||||||
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.
|
||||||
|
-- Looks like we *don't* have to do this, based on what is done in NewOS. Need to consult...
|
||||||
2) Make the caching and the VM (mmap) work together so that an mmap'ed file and a cached file will not race.
|
2) Make the caching and the VM (mmap) work together so that an mmap'ed file and a cached file will not race.
|
||||||
3) Change the architecture so that instead of multiple static globals, everything is stored in pages.
|
-- Maybe a vnodeManager or a lookup in a hash table or something so that we can tell if someone is already caching this vnode.
|
||||||
|
This could get a little tricky wrt permissions and all...
|
||||||
|
3) Change the architecture so that instead of multiple threads of tests, we have multiple apps of tests...
|
||||||
4) Tests are not done.
|
4) Tests are not done.
|
||||||
Test:
|
Test:
|
||||||
getNextAreaInfo
|
getNextAreaInfo
|
||||||
|
|||||||
+16
-14
@@ -2,11 +2,12 @@
|
|||||||
#include "area.h"
|
#include "area.h"
|
||||||
#include "areaManager.h"
|
#include "areaManager.h"
|
||||||
#include "vpage.h"
|
#include "vpage.h"
|
||||||
#include "vpagePool.h"
|
|
||||||
#include "vnodePool.h"
|
#include "vnodePool.h"
|
||||||
|
#include "vpagePool.h"
|
||||||
|
|
||||||
extern poolvpage vpagePool;
|
#include "vmHeaderBlock.h"
|
||||||
extern poolvnode vnodePool;
|
|
||||||
|
extern vmHeaderBlock *vmBlock;
|
||||||
|
|
||||||
area::area(void)
|
area::area(void)
|
||||||
{
|
{
|
||||||
@@ -14,6 +15,7 @@ area::area(void)
|
|||||||
|
|
||||||
void area::setup (areaManager *myManager)
|
void area::setup (areaManager *myManager)
|
||||||
{
|
{
|
||||||
|
printf ("area::setup setting up new area\n");
|
||||||
manager=myManager;
|
manager=myManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,11 +55,11 @@ 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 (vnodePool.get()) vnode;
|
vnode *newVnode=new (vmBlock->vnodePool->get()) vnode;
|
||||||
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 (vpagePool.get()) vpage;
|
newPage=new (vmBlock->vpagePool->get()) vpage;
|
||||||
newPage->setup(base+PAGE_SIZE*i,newVnode,NULL,protect,inState);
|
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);
|
||||||
@@ -81,13 +83,13 @@ status_t area::createArea(char *inName, int pageCount,void **address, addressSpe
|
|||||||
unsigned long requested=(unsigned long)(*address); // Hold onto this to make sure that EXACT works...
|
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 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);
|
||||||
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 (vpagePool.get()) vpage;
|
newPage=new (vmBlock->vpagePool->get()) vpage;
|
||||||
newPage->setup(base+PAGE_SIZE*i,NULL,NULL,protect,inState);
|
newPage->setup(base+PAGE_SIZE*i,NULL,NULL,protect,inState);
|
||||||
vpages.add(newPage);
|
vpages.add(newPage);
|
||||||
}
|
}
|
||||||
@@ -95,7 +97,7 @@ status_t area::createArea(char *inName, int pageCount,void **address, addressSpe
|
|||||||
start_address=base;
|
start_address=base;
|
||||||
end_address=base+pageCount*PAGE_SIZE;
|
end_address=base+pageCount*PAGE_SIZE;
|
||||||
*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)
|
status_t area::cloneArea(area *origArea, char *inName, void **address, addressSpec type,pageState inState,protectType protect)
|
||||||
@@ -119,7 +121,7 @@ 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 (vpagePool.get()) vpage;
|
newPage=new (vmBlock->vpagePool->get()) vpage;
|
||||||
newPage->setup(base,page->getBacking(),page->getPhysPage(),protect,inState);
|
newPage->setup(base,page->getBacking(),page->getPhysPage(),protect,inState);
|
||||||
vpages.add(newPage);
|
vpages.add(newPage);
|
||||||
base+=PAGE_SIZE;
|
base+=PAGE_SIZE;
|
||||||
@@ -151,7 +153,7 @@ void area::freeArea(void)
|
|||||||
//printf ("area::freeArea: flushed a page \n");
|
//printf ("area::freeArea: flushed a page \n");
|
||||||
page->cleanup();
|
page->cleanup();
|
||||||
//page->next=NULL;
|
//page->next=NULL;
|
||||||
vpagePool.put(page);
|
vmBlock->vpagePool->put(page);
|
||||||
}
|
}
|
||||||
//printf ("area::freeArea: unlocking \n");
|
//printf ("area::freeArea: unlocking \n");
|
||||||
manager->unlock();
|
manager->unlock();
|
||||||
@@ -203,7 +205,7 @@ 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 (vpagePool.get()) vpage;
|
newPage=new (vmBlock->vpagePool->get()) vpage;
|
||||||
newPage->setup(end_address+PAGE_SIZE*i-1,NULL,NULL,protection,state);
|
newPage->setup(end_address+PAGE_SIZE*i-1,NULL,NULL,protection,state);
|
||||||
vpages.add(newPage);
|
vpages.add(newPage);
|
||||||
}
|
}
|
||||||
@@ -220,7 +222,7 @@ 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;
|
||||||
oldPage->cleanup();
|
oldPage->cleanup();
|
||||||
vpagePool.put(oldPage);
|
vmBlock->vpagePool->put(oldPage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
manager->unlock();
|
manager->unlock();
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
#include "areaPool.h"
|
||||||
|
#include "area.h"
|
||||||
|
#include "page.h"
|
||||||
|
#include "vmHeaderBlock.h"
|
||||||
|
#include "pageManager.h"
|
||||||
|
|
||||||
|
extern vmHeaderBlock *vmBlock;
|
||||||
|
|
||||||
|
area *poolarea::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=vmBlock->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...
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
#include "pageManager.h"
|
#include <OS.h>
|
||||||
|
#include "list.h"
|
||||||
extern pageManager pageMan;
|
class area;
|
||||||
class poolarea
|
class poolarea
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@@ -11,36 +11,7 @@ class poolarea
|
|||||||
{
|
{
|
||||||
inUse = create_sem(1,"areapool");
|
inUse = create_sem(1,"areapool");
|
||||||
}
|
}
|
||||||
area *get(void)
|
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)
|
void put(area *in)
|
||||||
{
|
{
|
||||||
acquire_sem(inUse);
|
acquire_sem(inUse);
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
#include <new.h>
|
#include <new.h>
|
||||||
#include <cacheManager.h>
|
#include <cacheManager.h>
|
||||||
#include <vpagePool.h>
|
#include <vpagePool.h>
|
||||||
|
#include "vmHeaderBlock.h"
|
||||||
|
|
||||||
extern poolvpage vpagePool;
|
extern vmHeaderBlock *vmBlock;
|
||||||
// TODO - we need to (somehow) make sure that the same vnodes here are shared with mmap.
|
// TODO - we need to (somehow) make sure that the same vnodes here are shared with mmap.
|
||||||
// Maybe a vnode manager...
|
// Maybe a vnode manager...
|
||||||
cacheManager::cacheManager(void) : area ()
|
cacheManager::cacheManager(void) : area ()
|
||||||
@@ -38,7 +39,7 @@ void *cacheManager::createBlock(vnode *target,bool readOnly)
|
|||||||
}
|
}
|
||||||
lock();
|
lock();
|
||||||
// Create a vnode here
|
// Create a vnode here
|
||||||
vpage *newPage = new (vpagePool.get()) vpage;
|
vpage *newPage = new (vmBlock->vpagePool->get()) vpage;
|
||||||
newPage->setup(begin,target,NULL,((readOnly)?readable:writable),NO_LOCK);
|
newPage->setup(begin,target,NULL,((readOnly)?readable:writable),NO_LOCK);
|
||||||
vpages.add(newPage);
|
vpages.add(newPage);
|
||||||
cacheMembers.add(newPage);
|
cacheMembers.add(newPage);
|
||||||
|
|||||||
@@ -7,25 +7,21 @@ void *addOffset(void *base,unsigned long offset)
|
|||||||
return (void *)(((unsigned long)base+offset));
|
return (void *)(((unsigned long)base+offset));
|
||||||
}
|
}
|
||||||
|
|
||||||
pageManager::pageManager(int pages)
|
pageManager::pageManager(void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void pageManager::setup(void *area,int pages)
|
||||||
{
|
{
|
||||||
// This is compatability for in BeOS usage only...
|
|
||||||
void *area;
|
|
||||||
if (0>=create_area("vm_test",&area,B_ANY_ADDRESS,B_PAGE_SIZE*pages,B_NO_LOCK,B_READ_AREA|B_WRITE_AREA))
|
|
||||||
{
|
|
||||||
printf ("pageManager::pageManager: No memory!\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
printf ("Allocated an area. Address = %x\n",area);
|
|
||||||
// Calculate the number of pages that we will need to hold the page structures
|
// Calculate the number of pages that we will need to hold the page structures
|
||||||
int pageOverhead=((pages*sizeof(page))+(PAGE_SIZE-1))/PAGE_SIZE;
|
int pageOverhead=((pages*sizeof(page))+(PAGE_SIZE-1))/PAGE_SIZE;
|
||||||
for (int i=0;i<pages-pageOverhead;i++)
|
for (int i=0;i<pages-pageOverhead;i++)
|
||||||
{
|
{
|
||||||
page *newPage=(page *)(addOffset(area,i*sizeof(page)));
|
page *newPage=(page *)(addOffset(area,i*sizeof(page)));
|
||||||
newPage->setup(addOffset(area,(i+pageOverhead)*PAGE_SIZE));
|
newPage->setup(addOffset(area,(i+pageOverhead)*PAGE_SIZE));
|
||||||
printf ("newPage = %x, setup = %x\n",newPage,addOffset(area,(i+pageOverhead)*PAGE_SIZE));
|
//printf ("newPage = %x, setup = %x\n",newPage,addOffset(area,(i+pageOverhead)*PAGE_SIZE));
|
||||||
printf ("i = %d, sizeof(page) = %x, pageOverhead = %d\n",i,sizeof(page),pageOverhead);
|
//printf ("i = %d, sizeof(page) = %x, pageOverhead = %d\n",i,sizeof(page),pageOverhead);
|
||||||
newPage->dump();
|
//newPage->dump();
|
||||||
unused.add(addOffset(area,i*sizeof(page)));
|
unused.add(addOffset(area,i*sizeof(page)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
|
|
||||||
class pageManager {
|
class pageManager {
|
||||||
public:
|
public:
|
||||||
pageManager(int);
|
pageManager(void);
|
||||||
|
void setup(void *memory,int pages);
|
||||||
page *getPage(void);
|
page *getPage(void);
|
||||||
void freePage(page *);
|
void freePage(page *);
|
||||||
void cleaner(void);
|
void cleaner(void);
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#include "pageManager.h"
|
#include "pageManager.h"
|
||||||
|
|
||||||
extern pageManager pageMan;
|
#include "vmHeaderBlock.h"
|
||||||
|
|
||||||
|
extern vmHeaderBlock *vmBlock;
|
||||||
/* This is the template
|
/* This is the template
|
||||||
* replace TYPE with the type you need a pool for
|
* replace TYPE with the type you need a pool for
|
||||||
*
|
*
|
||||||
@@ -32,7 +34,7 @@ class poolTYPE
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf ("poolTYPE::get: Getting a new page!\n");
|
printf ("poolTYPE::get: Getting a new page!\n");
|
||||||
page *newPage=pageMan.getPage();
|
page *newPage=vmBlock->pageMan->getPage();
|
||||||
if (!newPage)
|
if (!newPage)
|
||||||
throw ("Out of pages to allocate a pool!");
|
throw ("Out of pages to allocate a pool!");
|
||||||
int newCount=PAGE_SIZE/sizeof(TYPE);
|
int newCount=PAGE_SIZE/sizeof(TYPE);
|
||||||
|
|||||||
@@ -4,8 +4,9 @@
|
|||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <new.h>
|
#include <new.h>
|
||||||
#include <vnodePool.h>
|
#include <vnodePool.h>
|
||||||
|
#include "vmHeaderBlock.h"
|
||||||
|
|
||||||
extern poolvnode vnodePool;
|
extern vmHeaderBlock *vmBlock;
|
||||||
|
|
||||||
swapFileManager::swapFileManager(void)
|
swapFileManager::swapFileManager(void)
|
||||||
{
|
{
|
||||||
@@ -48,7 +49,7 @@ vnode &swapFileManager::findNode(void)
|
|||||||
Unlock();
|
Unlock();
|
||||||
if (!newNode)
|
if (!newNode)
|
||||||
{
|
{
|
||||||
newNode=new (vnodePool.get()) vnode;
|
newNode=new (vmBlock->vnodePool->get()) vnode;
|
||||||
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);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ int createFillAndTest(int pages)
|
|||||||
try{
|
try{
|
||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
int area1;
|
int area1;
|
||||||
|
printf ("createFillAndTest: about to create \n");
|
||||||
area1=vm.createArea("Mine",pages,(void **)(&addr));
|
area1=vm.createArea("Mine",pages,(void **)(&addr));
|
||||||
printf ("createFillAndTest: create done\n");
|
printf ("createFillAndTest: create done\n");
|
||||||
for (int i=0;i<pages*PAGE_SIZE;i++)
|
for (int i=0;i<pages*PAGE_SIZE;i++)
|
||||||
|
|||||||
@@ -26,14 +26,4 @@ enum addressSpec {EXACT,BASE,ANY,ANY_KERNEL,CLONE};
|
|||||||
#define CACHE_BEGIN 0x90000000
|
#define CACHE_BEGIN 0x90000000
|
||||||
#define CACHE_END 0xe0000000
|
#define CACHE_END 0xe0000000
|
||||||
|
|
||||||
struct vmHeaderBlock
|
|
||||||
{
|
|
||||||
poolarea areaPool;
|
|
||||||
poolvpage vpagePool;
|
|
||||||
poolvnode vnodePool;
|
|
||||||
pageManager pageMan(30); // Obviously this hard coded number is a hack...
|
|
||||||
swapFileManager swapMan;
|
|
||||||
cacheManager cacheMan;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
#ifndef _VM_HEADERBLOCK
|
||||||
|
#define _VM_HEADERBLOCK
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef I_AM_VM_INTERFACE
|
||||||
|
class poolarea;
|
||||||
|
class poolvpage;
|
||||||
|
class poolvnode;
|
||||||
|
class pageManager;
|
||||||
|
class swapFileManager;
|
||||||
|
class cacheManager;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct vmHeaderBlock
|
||||||
|
{
|
||||||
|
poolarea *areaPool;
|
||||||
|
poolvpage *vpagePool;
|
||||||
|
poolvnode *vnodePool;
|
||||||
|
pageManager *pageMan;
|
||||||
|
swapFileManager *swapMan;
|
||||||
|
cacheManager *cacheMan;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,35 +1,46 @@
|
|||||||
#include "vmInterface.h"
|
|
||||||
//#include "areaManager.h"
|
|
||||||
#include <new.h>
|
#include <new.h>
|
||||||
#include "mman.h"
|
#include "mman.h"
|
||||||
#include "area.h"
|
#include "area.h"
|
||||||
#include "areaPool.h"
|
#include "areaPool.h"
|
||||||
#include "vpagePool.h"
|
#include "vpagePool.h"
|
||||||
#include "vnodePool.h"
|
#include "vnodePool.h"
|
||||||
|
#include "pageManager.h"
|
||||||
|
#include "swapFileManager.h"
|
||||||
|
#include "cacheManager.h"
|
||||||
|
#define I_AM_VM_INTERFACE
|
||||||
|
#include "vmHeaderBlock.h"
|
||||||
|
#include "vmInterface.h"
|
||||||
|
|
||||||
areaManager am;
|
vmHeaderBlock *vmBlock;
|
||||||
swapFileManager swapMan;
|
static areaManager am;
|
||||||
poolarea areaPool;
|
|
||||||
poolvpage vpagePool;
|
areaManager *getAM(void)
|
||||||
poolvnode vnodePool;
|
{
|
||||||
pageManager pageMan(30); // Obviously this hard coded number is a hack...
|
return &am;
|
||||||
|
}
|
||||||
|
|
||||||
|
void *addToPointer(void *ptr,uint32 offset)
|
||||||
|
{
|
||||||
|
return ((void *)(((unsigned long)ptr)+offset));
|
||||||
|
}
|
||||||
|
|
||||||
areaManager *vmInterface::getAM(void)
|
areaManager *vmInterface::getAM(void)
|
||||||
{
|
{
|
||||||
// Normally, we would go to the current user process to get this. Since there no such thing exists here...
|
// Normally, we would go to the current user process to get this. Since there no such thing exists here...
|
||||||
|
|
||||||
return &am;
|
return &am;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 cleanerThread(void *pageMan)
|
int32 cleanerThread(void *pageMan)
|
||||||
{
|
{
|
||||||
pageManager *pm=(pageManager *)pageMan;
|
pageManager *pm=(vmBlock->pageMan);
|
||||||
pm->cleaner();
|
pm->cleaner();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int32 saverThread(void *areaMan)
|
int32 saverThread(void *areaMan)
|
||||||
{
|
{
|
||||||
areaManager *am=(areaManager *)areaMan;
|
areaManager *am=getAM();
|
||||||
// This should iterate over all processes...
|
// This should iterate over all processes...
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
@@ -40,18 +51,55 @@ int32 saverThread(void *areaMan)
|
|||||||
|
|
||||||
int32 pagerThread(void *areaMan)
|
int32 pagerThread(void *areaMan)
|
||||||
{
|
{
|
||||||
areaManager *am=(areaManager *)areaMan;
|
areaManager *am=getAM();
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
snooze(1000000);
|
snooze(1000000);
|
||||||
am->pager(pageMan.desperation());
|
am->pager(vmBlock->pageMan->desperation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vmInterface::vmInterface(int pages)
|
vmInterface::vmInterface(int pages)
|
||||||
{
|
{
|
||||||
|
char temp[1000];
|
||||||
|
sprintf (temp,"vm_test_clone_%d",getpid());
|
||||||
|
if (clone_area(temp,(void **)(&vmBlock),B_ANY_ADDRESS,B_WRITE_AREA,find_area("vm_test"))<0)
|
||||||
|
{
|
||||||
|
// This is compatability for in BeOS usage only...
|
||||||
|
if (0>=create_area("vm_test",(void **)(&vmBlock),B_ANY_ADDRESS,B_PAGE_SIZE*pages,B_NO_LOCK,B_READ_AREA|B_WRITE_AREA))
|
||||||
|
{
|
||||||
|
printf ("pageManager::pageManager: No memory!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
//printf ("Allocated an area. Address = %x\n",vmBlock);
|
||||||
|
// Figure out how many pages we need
|
||||||
|
int pageCount = (sizeof(poolarea)+sizeof(poolvpage)+sizeof(poolvnode)+sizeof(pageManager)+sizeof(swapFileManager)+sizeof(cacheManager)+sizeof(vmHeaderBlock)+PAGE_SIZE-1)/PAGE_SIZE;
|
||||||
|
if (pageCount >=pages)
|
||||||
|
{
|
||||||
|
printf ("Hey! Go buy some ram! Trying to create a VM with fewer pages than the setup will take!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
//printf ("Need %d pages, creation calls for %d\n",pageCount,pages);
|
||||||
|
void *currentAddress = addToPointer(vmBlock,sizeof(struct vmHeaderBlock));
|
||||||
|
vmBlock->areaPool = new (currentAddress) poolarea;
|
||||||
|
currentAddress=addToPointer(currentAddress,sizeof(poolarea));
|
||||||
|
vmBlock->vpagePool = new (currentAddress) poolvpage;
|
||||||
|
currentAddress=addToPointer(currentAddress,sizeof(poolvpage));
|
||||||
|
vmBlock->vnodePool = new (currentAddress) poolvnode;
|
||||||
|
currentAddress=addToPointer(currentAddress,sizeof(poolvnode));
|
||||||
|
vmBlock->pageMan = new (currentAddress) pageManager;
|
||||||
|
currentAddress=addToPointer(currentAddress,sizeof(pageManager));
|
||||||
|
vmBlock->swapMan = new (currentAddress) swapFileManager;
|
||||||
|
currentAddress=addToPointer(currentAddress,sizeof(swapFileManager));
|
||||||
|
vmBlock->cacheMan = new (currentAddress) cacheManager;
|
||||||
|
currentAddress=addToPointer(currentAddress,sizeof(cacheManager));
|
||||||
|
//printf ("Need %d pages, creation calls for %d\n",pageCount,pages);
|
||||||
|
//printf ("vmBlock is at %x, end of structures is at %x, pageMan called with address %x, pages = %d\n",vmBlock,currentAddress,addToPointer(vmBlock,PAGE_SIZE*pageCount),pages-pageCount);
|
||||||
|
vmBlock->pageMan->setup(addToPointer(vmBlock,PAGE_SIZE*pageCount),pages-pageCount);
|
||||||
|
}
|
||||||
nextAreaID=0;
|
nextAreaID=0;
|
||||||
resume_thread(spawn_thread(cleanerThread,"cleanerThread",0,&pageMan));
|
|
||||||
|
resume_thread(spawn_thread(cleanerThread,"cleanerThread",0,(vmBlock->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()));
|
resume_thread(spawn_thread(pagerThread,"pagerThread",0,getAM()));
|
||||||
}
|
}
|
||||||
@@ -86,7 +134,10 @@ 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 (areaPool.get()) area;
|
area *newArea = new (vmBlock->areaPool->get()) area;
|
||||||
|
areaManager *foo;
|
||||||
|
printf ("vmInterface::createArea - got a new area (%x) from the areaPool\n",newArea);
|
||||||
|
foo=getAM();
|
||||||
newArea->setup(getAM());
|
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
|
||||||
@@ -108,7 +159,7 @@ void vmInterface::freeArea(int Area)
|
|||||||
// 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");
|
||||||
areaPool.put(oldArea);
|
vmBlock->areaPool->put(oldArea);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
printf ("vmInterface::freeArea: unable to find requested area\n");
|
printf ("vmInterface::freeArea: unable to find requested area\n");
|
||||||
@@ -140,7 +191,7 @@ 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 (areaPool.get()) area;
|
area *newArea = new (vmBlock->areaPool->get()) area;
|
||||||
newArea->setup(getAM());
|
newArea->setup(getAM());
|
||||||
area *oldArea=getAM()->findArea(newAreaID);
|
area *oldArea=getAM()->findArea(newAreaID);
|
||||||
newArea->cloneArea(oldArea,AreaName,address,addType,state,prot);
|
newArea->cloneArea(oldArea,AreaName,address,addType,state,prot);
|
||||||
@@ -155,7 +206,7 @@ void vmInterface::pager(void)
|
|||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
snooze(250000);
|
snooze(250000);
|
||||||
am.pager(pageMan.desperation());
|
getAM()->pager(vmBlock->pageMan->desperation());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,14 +216,14 @@ void vmInterface::saver(void)
|
|||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
snooze(250000);
|
snooze(250000);
|
||||||
am.saver();
|
getAM()->saver();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void vmInterface::cleaner(void)
|
void vmInterface::cleaner(void)
|
||||||
{
|
{
|
||||||
// This loops on its own
|
// This loops on its own
|
||||||
pageMan.cleaner();
|
vmBlock->pageMan->cleaner();
|
||||||
}
|
}
|
||||||
|
|
||||||
void *vmInterface::mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset)
|
void *vmInterface::mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset)
|
||||||
@@ -191,7 +242,7 @@ void *vmInterface::mmap(void *addr, size_t len, int prot, int flags, int fd, off
|
|||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
area *newArea = new (areaPool.get()) area;
|
area *newArea = new (vmBlock->areaPool->get()) area;
|
||||||
newArea->setup(getAM());
|
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);
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
#include "vnodePool.h"
|
||||||
|
|
||||||
|
#include "vmHeaderBlock.h"
|
||||||
|
#include "pageManager.h"
|
||||||
|
|
||||||
|
extern vmHeaderBlock *vmBlock;
|
||||||
|
vnode *poolvnode::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=vmBlock->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...
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
#include "pageManager.h"
|
#include <OS.h>
|
||||||
|
#include "list.h"
|
||||||
extern pageManager pageMan;
|
class area;
|
||||||
|
class vnode;
|
||||||
class poolvnode
|
class poolvnode
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@@ -11,36 +12,7 @@ class poolvnode
|
|||||||
{
|
{
|
||||||
inUse = create_sem(1,"vnodepool");
|
inUse = create_sem(1,"vnodepool");
|
||||||
}
|
}
|
||||||
vnode *get(void)
|
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)
|
void put(vnode *in)
|
||||||
{
|
{
|
||||||
acquire_sem(inUse);
|
acquire_sem(inUse);
|
||||||
|
|||||||
+13
-14
@@ -1,19 +1,18 @@
|
|||||||
#include "vpage.h"
|
#include "vpage.h"
|
||||||
#include "vnodePool.h"
|
#include "vnodePool.h"
|
||||||
|
#include "vmHeaderBlock.h"
|
||||||
|
|
||||||
extern swapFileManager swapMan;
|
extern vmHeaderBlock *vmBlock;
|
||||||
extern pageManager pageMan;
|
|
||||||
extern poolvnode vnodePool;
|
|
||||||
|
|
||||||
void vpage::flush(void)
|
void vpage::flush(void)
|
||||||
{
|
{
|
||||||
if (protection==writable && dirty)
|
if (protection==writable && dirty)
|
||||||
swapMan.write_block(*backingNode,((void *)(physPage->getAddress())), PAGE_SIZE);
|
vmBlock->swapMan->write_block(*backingNode,((void *)(physPage->getAddress())), PAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void vpage::refresh(void)
|
void vpage::refresh(void)
|
||||||
{
|
{
|
||||||
swapMan.read_block(*backingNode,((void *)(physPage->getAddress())), PAGE_SIZE);
|
vmBlock->swapMan->read_block(*backingNode,((void *)(physPage->getAddress())), PAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
vpage::vpage(void)
|
vpage::vpage(void)
|
||||||
@@ -42,9 +41,9 @@ void vpage::setup(unsigned long start,vnode *backing, page *physMem,protectType
|
|||||||
backing->count++;
|
backing->count++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
backingNode=&(swapMan.findNode());
|
backingNode=&(vmBlock->swapMan->findNode());
|
||||||
if (!physMem && (state!=LAZY) && (state!=NO_LOCK))
|
if (!physMem && (state!=LAZY) && (state!=NO_LOCK))
|
||||||
physPage=pageMan.getPage();
|
physPage=vmBlock->pageMan->getPage();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (physMem)
|
if (physMem)
|
||||||
@@ -57,12 +56,12 @@ void vpage::setup(unsigned long start,vnode *backing, page *physMem,protectType
|
|||||||
void vpage::cleanup(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);
|
vmBlock->pageMan->freePage(physPage);
|
||||||
if (backingNode)
|
if (backingNode)
|
||||||
{
|
{
|
||||||
if (backingNode->fd)
|
if (backingNode->fd)
|
||||||
swapMan.freeVNode(*backingNode);
|
vmBlock->swapMan->freeVNode(*backingNode);
|
||||||
vnodePool.put(backingNode);
|
vmBlock->vnodePool->put(backingNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,19 +81,19 @@ 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=vmBlock->pageMan->getPage();
|
||||||
if (!newPhysPage) // No room at the inn
|
if (!newPhysPage) // No room at the inn
|
||||||
return false;
|
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;
|
||||||
backingNode=&(swapMan.findNode()); // Need new backing store for this node, since it was copied, the original is no good...
|
backingNode=&(vmBlock->swapMan->findNode()); // Need new backing store for this node, since it was copied, the original is no good...
|
||||||
// Update the architecture specific stuff here...
|
// Update the architecture specific stuff here...
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
physPage=pageMan.getPage();
|
physPage=vmBlock->pageMan->getPage();
|
||||||
if (!physPage) // No room at the inn
|
if (!physPage) // No room at the inn
|
||||||
return false;
|
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));
|
// 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));
|
||||||
@@ -162,7 +161,7 @@ void vpage::pager(int desperation)
|
|||||||
printf ("vpage::pager flushing\n");
|
printf ("vpage::pager flushing\n");
|
||||||
flush();
|
flush();
|
||||||
printf ("vpage::pager freeing\n");
|
printf ("vpage::pager freeing\n");
|
||||||
pageMan.freePage(physPage);
|
vmBlock->pageMan->freePage(physPage);
|
||||||
printf ("vpage::pager going to NULL\n");
|
printf ("vpage::pager going to NULL\n");
|
||||||
physPage=NULL;
|
physPage=NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#include "vpagePool.h"
|
||||||
|
|
||||||
|
#include "vmHeaderBlock.h"
|
||||||
|
#include "pageManager.h"
|
||||||
|
#include "vpage.h"
|
||||||
|
|
||||||
|
extern vmHeaderBlock *vmBlock;
|
||||||
|
vpage *poolvpage::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=vmBlock->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...
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
#include "pageManager.h"
|
#include <OS.h>
|
||||||
#include "vpage.h"
|
#include "list.h"
|
||||||
|
class vpage;
|
||||||
extern pageManager pageMan;
|
|
||||||
class poolvpage
|
class poolvpage
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
@@ -12,36 +11,7 @@ class poolvpage
|
|||||||
{
|
{
|
||||||
inUse = create_sem(1,"vpagepool");
|
inUse = create_sem(1,"vpagepool");
|
||||||
}
|
}
|
||||||
vpage *get(void)
|
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)
|
void put(vpage *in)
|
||||||
{
|
{
|
||||||
acquire_sem(inUse);
|
acquire_sem(inUse);
|
||||||
|
|||||||
Reference in New Issue
Block a user