Fixed some bugs. Yet another checkpoint.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2074 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
08d612b66b
commit
cc22bcb449
@ -50,7 +50,7 @@ unsigned long area::mapAddressSpecToAddress(addressSpec type,void * req,int page
|
||||
}
|
||||
|
||||
status_t area::createAreaGuts( char *inName, int pageCount, void **address, addressSpec type, pageState inState, protectType protect, bool inFinalWrite, int fd, size_t offset, area *originalArea=NULL /* For clone only*/) {
|
||||
error ("area::createAreaGuts : name = %s, pageCount = %d, address = %ld, addressSpec = %d, pageState = %d, protection = %d, inFinalWrite = %d, fd = %d, offset = %d,originalArea=%ld\n",
|
||||
error ("area::createAreaGuts : name = %s, pageCount = %d, address = %lx, addressSpec = %d, pageState = %d, protection = %d, inFinalWrite = %d, fd = %d, offset = %d,originalArea=%ld\n",
|
||||
inName,pageCount,address,type,inState,protect,inFinalWrite,fd,offset,originalArea);
|
||||
strcpy(name,inName);
|
||||
vpage *newPage;
|
||||
|
@ -139,7 +139,7 @@ long areaManager::nextAreaID=0;
|
||||
|
||||
int areaManager::createArea(char *AreaName,int pageCount,void **address, addressSpec addType,pageState state,protectType protect)
|
||||
{
|
||||
error ("Creating an area\n");
|
||||
error ("areaManager::createArea - Creating an area\n");
|
||||
lock();
|
||||
area *newArea = new (vmBlock->areaPool->get()) area;
|
||||
error ("areaManager::createArea - got a new area (%p) from the areaPool\n",newArea);
|
||||
@ -155,7 +155,7 @@ int areaManager::createArea(char *AreaName,int pageCount,void **address, address
|
||||
int retVal=newArea->getAreaID();
|
||||
error ("areaManager::createArea - new area id found\n");
|
||||
unlock();
|
||||
error ("Done Creating an area\n");
|
||||
error ("areaManager::createArea - Done Creating an area\n");
|
||||
return retVal;
|
||||
}
|
||||
|
||||
|
@ -23,8 +23,8 @@ area *poolarea::get(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
//error ("poolarea::get: Getting a new page!\n");
|
||||
page *newPage=vmBlock->pageMan->getPage();
|
||||
error ("poolarea::get: Getting new page %lx!\n",newPage->getAddress());
|
||||
if (!newPage)
|
||||
throw ("Out of pages to allocate a pool!");
|
||||
int newCount=PAGE_SIZE/sizeof(area);
|
||||
|
@ -20,22 +20,28 @@ class hashTable : public list
|
||||
nodeCount=0;
|
||||
numRocks=size;
|
||||
|
||||
error ("Starting to initalize hash table\n");
|
||||
//error ("Starting to initalize hash table\n");
|
||||
if (size*sizeof (list *)>PAGE_SIZE)
|
||||
throw ("Hash table too big!");
|
||||
error ("Getting Page\n");
|
||||
//error ("Getting Page\n");
|
||||
|
||||
// Get the block for the page of pointers
|
||||
page *newPage=vmBlock->pageMan->getPage();
|
||||
error ("Got Page\n");
|
||||
if (!newPage)
|
||||
error ("hashTable::hashTable - Got Page %x\n",newPage);
|
||||
if (!newPage) {
|
||||
error ("Out of pages to allocate a pool! newPage = %x\n",newPage);
|
||||
throw ("Out of pages to allocate a pool!");
|
||||
}
|
||||
rocks=(list **)(newPage->getAddress());
|
||||
error ("Got rocks\n");
|
||||
//error ("Got rocks\n");
|
||||
|
||||
int listsPerPage=PAGE_SIZE/sizeof(list);
|
||||
int pages=(size+(listsPerPage-1))/listsPerPage;
|
||||
for (int pageCount=0;pageCount<pages;pageCount++)
|
||||
{
|
||||
// Allocate a page of lists
|
||||
page *newPage=vmBlock->pageMan->getPage();
|
||||
error ("hashTable::hashTable - Got Page %x\n",newPage);
|
||||
if (!newPage)
|
||||
throw ("Out of pages to allocate a pool!");
|
||||
for (int i=0;i<listsPerPage;i++)
|
||||
|
@ -23,6 +23,7 @@ void pageManager::setup(void *area,int pages) {
|
||||
unusedLock=create_sem (1,"unused_lock");
|
||||
inUseLock=create_sem (1,"inuse_lock");
|
||||
totalPages=pages;
|
||||
error ("pageManager::setup - %d pages ready to rock and roll\n",unused.count());
|
||||
}
|
||||
|
||||
page *pageManager::getPage(void) {
|
||||
@ -42,10 +43,13 @@ page *pageManager::getPage(void) {
|
||||
ret->zero();
|
||||
} // This could fail if someone swooped in and stole our page.
|
||||
}
|
||||
error ("pageManager::getPage - returning page %x, clean = %d, unused = %d, inuse = %x\n",ret,clean.count(),unused.count(),inUse.count());
|
||||
acquire_sem(inUseLock);
|
||||
inUse.add(ret);
|
||||
release_sem(inUseLock);
|
||||
ret->count++;
|
||||
if (!ret)
|
||||
throw ("Out of physical pages!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -79,12 +83,16 @@ bool pageManager::getContiguousPages(int pages,page **location) {
|
||||
}
|
||||
|
||||
void pageManager::freePage(page *toFree) {
|
||||
error ("pageManager::freePage; count = %d, address = %p\n",toFree->count,toFree);
|
||||
if (atomic_add(&(toFree->count),-1)==1) { // atomic_add returns the *PREVIOUS* value. So we need to check to see if the one we are wasting was the last one.
|
||||
acquire_sem(inUseLock);
|
||||
inUse.remove(toFree);
|
||||
inUse.dump();
|
||||
release_sem(inUseLock);
|
||||
|
||||
acquire_sem(unusedLock);
|
||||
unused.add(toFree);
|
||||
unused.dump();
|
||||
release_sem(unusedLock);
|
||||
}
|
||||
}
|
||||
|
@ -5,18 +5,17 @@
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
vmInterface vm(30);
|
||||
vmInterface *vm;
|
||||
|
||||
void writeByte(unsigned long addr,unsigned int offset, char value) { vm.setByte(addr+offset,value); }
|
||||
unsigned char readByte(unsigned long addr,unsigned int offset ) { char value=vm.getByte(addr+offset); return value; }
|
||||
void writeByte(unsigned long addr,unsigned int offset, char value) { vm->setByte(addr+offset,value); }
|
||||
unsigned char readByte(unsigned long addr,unsigned int offset ) { char value=vm->getByte(addr+offset); return value; }
|
||||
|
||||
int createFillAndTest(int pages,char *name)
|
||||
{
|
||||
try{
|
||||
unsigned long addr;
|
||||
int area1;
|
||||
error ("%s: createFillAndTest: about to create \n",name);
|
||||
area1=vm.createArea(name,pages,(void **)(&addr));
|
||||
area1=vm->createArea(name,pages,(void **)(&addr));
|
||||
error ("%s: createFillAndTest: create done\n",name);
|
||||
for (int i=0;i<pages*PAGE_SIZE;i++)
|
||||
{
|
||||
@ -34,6 +33,16 @@ int createFillAndTest(int pages,char *name)
|
||||
}
|
||||
error ("%s: createFillAndTest: reading done\n",name);
|
||||
return area1;
|
||||
}
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
try {
|
||||
vm = new vmInterface (30);
|
||||
error ("Starting Threads!\n");
|
||||
|
||||
for (int i=0;i<20;i++)
|
||||
createFillAndTest(1,"myTest");
|
||||
}
|
||||
catch (const char *t)
|
||||
{
|
||||
@ -42,16 +51,9 @@ int createFillAndTest(int pages,char *name)
|
||||
}
|
||||
catch (...)
|
||||
{
|
||||
error ("Exception thrown!\n");
|
||||
error ("Unknown Exception thrown!\n");
|
||||
exit(1);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main(int argc,char **argv)
|
||||
{
|
||||
error ("Starting Threads!\n");
|
||||
createFillAndTest(1,"myTest");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -20,8 +20,26 @@ struct vnode : public node
|
||||
};
|
||||
#define B_OS_NAME_LENGTH 32
|
||||
enum protectType {none=0,readable, writable,copyOnWrite,symCopyOnWrite};
|
||||
enum pageState {FULL,CONTIGUOUS,LAZY,NO_LOCK,LOMEM};
|
||||
//B_EXACT_ADDRESS You want the value of *addr to be taken literally and strictly.
|
||||
// If the area can't be allocated at that location, the function fails.
|
||||
//B_BASE_ADDRESS The area can start at a location equal to or greater than *addr.
|
||||
//B_ANY_ADDRESS The starting address is determined by the system.
|
||||
// In this case, the value that's pointed to by addr is ignored (going into the function).
|
||||
//B_ANY_KERNEL_ADDRESS The starting address is determined by the system, and the new area will belong to the kernel's team;
|
||||
// it won't be deleted when the application quits. In this case, the value that's pointed to by addr is
|
||||
// ignored (going into the function)
|
||||
//B_CLONE_ADDRESS This is only meaningful to the clone_area() function.
|
||||
enum addressSpec {EXACT,BASE,ANY,ANY_KERNEL,CLONE};
|
||||
|
||||
//B_FULL_LOCK The area's memory is locked into RAM when the area is created, and won't be swapped out.
|
||||
//B_CONTIGUOUS Not only is the area's memory locked into RAM, it's also guaranteed to be contiguous. This is particularly -
|
||||
// and perhaps exclusively - useful to designers of certain types of device drivers.
|
||||
//B_LAZY_LOCK Allows individual pages of memory to be brought into RAM through the natural order of things and then locks them.
|
||||
//B_NO_LOCK Pages are never locked, they're swapped in and out as needed.
|
||||
//B_LOMEM This is a special constant that's used for for areas that need to be locked, contiguous, and that fit within the
|
||||
// first 16MB of physical memory. The folks that need this constant know who they are.
|
||||
|
||||
enum pageState {FULL,CONTIGUOUS,LAZY,NO_LOCK,LOMEM};
|
||||
#define USER_BASE 0x10000000
|
||||
#define KERNEL_BASE 0x80000000
|
||||
#define CACHE_BEGIN 0x90000000
|
||||
|
@ -21,8 +21,8 @@ vnode *poolvnode::get(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
//error ("poolvnode::get: Getting a new page!\n");
|
||||
page *newPage=vmBlock->pageMan->getPage();
|
||||
error ("poolvnode::get: Getting new page %lx!\n",newPage->getAddress());
|
||||
if (!newPage)
|
||||
throw ("Out of pages to allocate a pool!");
|
||||
int newCount=PAGE_SIZE/sizeof(vnode);
|
||||
|
@ -48,8 +48,10 @@ void vpage::setup(unsigned long start,vnode *backing, page *physMem,protectType
|
||||
}
|
||||
else
|
||||
backingNode=&(vmBlock->swapMan->findNode());
|
||||
if (!physMem && (state!=LAZY) && (state!=NO_LOCK))
|
||||
if (!physMem && (state!=LAZY) && (state!=NO_LOCK)) {
|
||||
physPage=vmBlock->pageMan->getPage();
|
||||
error ("vpage::setup, state = %d, allocated page %x\n",state,physPage);
|
||||
}
|
||||
else {
|
||||
if (physMem)
|
||||
atomic_add(&(physMem->count),1);
|
||||
@ -60,8 +62,10 @@ void vpage::setup(unsigned long start,vnode *backing, page *physMem,protectType
|
||||
}
|
||||
|
||||
void vpage::cleanup(void) {
|
||||
if (physPage) // Note that free means release one reference
|
||||
if (physPage) { // Note that free means release one reference
|
||||
error ("vpage::cleanup, freeing physcal page %x\n",physPage);
|
||||
vmBlock->pageMan->freePage(physPage);
|
||||
}
|
||||
if (backingNode) {
|
||||
if (backingNode->fd)
|
||||
if (backingNode->fd==vmBlock->swapMan->getFD())
|
||||
@ -85,8 +89,7 @@ bool vpage::fault(void *fault_address, bool writeError) {
|
||||
dirty=true;
|
||||
if (protection==copyOnWrite) { // Else, this was just a "let me know when I am dirty"...
|
||||
page *newPhysPage=vmBlock->pageMan->getPage();
|
||||
if (!newPhysPage) // No room at the inn
|
||||
return false;
|
||||
error ("vpage::fault - copy on write allocated page %x\n",newPhysPage);
|
||||
memcpy((void *)(newPhysPage->getAddress()),(void *)(physPage->getAddress()),PAGE_SIZE);
|
||||
physPage=newPhysPage;
|
||||
protection=writable;
|
||||
@ -96,6 +99,7 @@ bool vpage::fault(void *fault_address, bool writeError) {
|
||||
return true;
|
||||
}
|
||||
physPage=vmBlock->pageMan->getPage();
|
||||
error ("vpage::fault - regular - allocated page %x\n",physPage);
|
||||
if (!physPage) // No room at the inn
|
||||
return false;
|
||||
error ("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));
|
||||
|
@ -22,8 +22,8 @@ vpage *poolvpage::get(void)
|
||||
}
|
||||
else
|
||||
{
|
||||
//error ("poolvpage::get: Getting a new page!\n");
|
||||
page *newPage=vmBlock->pageMan->getPage();
|
||||
error ("poolvpage::get: Getting new page %lx!\n",newPage->getAddress());
|
||||
if (!newPage)
|
||||
throw ("Out of pages to allocate a pool!");
|
||||
int newCount=PAGE_SIZE/sizeof(vpage);
|
||||
|
Loading…
Reference in New Issue
Block a user