More changes and bug fixes.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2871 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -180,7 +180,7 @@ status_t area::getInfo(area_info *dest) {
|
|||||||
|
|
||||||
bool area::contains(const void *address) {
|
bool area::contains(const void *address) {
|
||||||
unsigned long base=(unsigned long)(address);
|
unsigned long base=(unsigned long)(address);
|
||||||
error ("area::contains: looking for %d in %d -- %d, value = %d\n",base,start_address,end_address, ((start_address<=base) && (end_address>=base)));
|
// error ("area::contains: looking for %d in %d -- %d, value = %d\n",base,start_address,end_address, ((start_address<=base) && (end_address>=base)));
|
||||||
|
|
||||||
return ((start_address<=base) && (base<=end_address));
|
return ((start_address<=base) && (base<=end_address));
|
||||||
}
|
}
|
||||||
@@ -223,8 +223,10 @@ status_t area::resize(size_t newSize) {
|
|||||||
|
|
||||||
// When the protection for the area changes, the protection for every one of the pages must change
|
// When the protection for the area changes, the protection for every one of the pages must change
|
||||||
status_t area::setProtection(protectType prot) {
|
status_t area::setProtection(protectType prot) {
|
||||||
|
dump();
|
||||||
for (hashIterate hi(vpages);node *cur=hi.get();) {
|
for (hashIterate hi(vpages);node *cur=hi.get();) {
|
||||||
vpage *page=(vpage *)cur;
|
vpage *page=(vpage *)cur;
|
||||||
|
error ("setting protection on %x\n",page);
|
||||||
page->setProtection(prot);
|
page->setProtection(prot);
|
||||||
}
|
}
|
||||||
protection=prot;
|
protection=prot;
|
||||||
|
|||||||
@@ -249,12 +249,13 @@ void areaManager::setByte(unsigned long address,char value) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void areaManager::setInt(unsigned long address,int value) {
|
void areaManager::setInt(unsigned long address,int value) {
|
||||||
error ("areaManager::setInt starting to set on address %lx, value = %d\n",address,value);
|
// error ("areaManager::setInt starting to set on address %lx, value = %d\n",address,value);
|
||||||
area *myArea;
|
area *myArea;
|
||||||
lock();
|
lock();
|
||||||
error ("areaManager::setInt locked\n");
|
// error ("areaManager::setInt locked\n");
|
||||||
myArea=findArea((void *)address);
|
myArea=findArea((void *)address);
|
||||||
error ("areaManager::setInt area %s found\n",((myArea)?"":" not "));
|
// error ("areaManager::setInt area %s found\n",((myArea)?"":" not "));
|
||||||
|
try {
|
||||||
if (myArea)
|
if (myArea)
|
||||||
myArea->setInt(address,value);
|
myArea->setInt(address,value);
|
||||||
else {
|
else {
|
||||||
@@ -263,7 +264,10 @@ void areaManager::setInt(unsigned long address,int value) {
|
|||||||
unlock();
|
unlock();
|
||||||
throw (temp);
|
throw (temp);
|
||||||
}
|
}
|
||||||
error ("areaManager::setInt unlocking\n");
|
}
|
||||||
|
catch (const char *t) { unlock();throw t;}
|
||||||
|
catch (char *t) { unlock();throw t;}
|
||||||
|
// error ("areaManager::setInt unlocking\n");
|
||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,28 +307,29 @@ void *areaManager::mmap(void *addr, size_t len, int prot, int flags, int fd, off
|
|||||||
protType=(prot&PROT_WRITE)?writable:(prot&(PROT_READ|PROT_EXEC))?readable:none;
|
protType=(prot&PROT_WRITE)?writable:(prot&(PROT_READ|PROT_EXEC))?readable:none;
|
||||||
//error ("flags = %x, anon = %x\n",flags,MAP_ANON);
|
//error ("flags = %x, anon = %x\n",flags,MAP_ANON);
|
||||||
lock();
|
lock();
|
||||||
if (flags & MAP_ANON) {
|
if (flags & MAP_ANON)
|
||||||
createArea(name,(int)((len+PAGE_SIZE-1)/PAGE_SIZE),&addr, addType ,LAZY,protType);
|
createArea(name,(int)((len+PAGE_SIZE-1)/PAGE_SIZE),&addr, addType ,LAZY,protType);
|
||||||
return addr;
|
else {
|
||||||
|
int shareCount=0;
|
||||||
|
mmapSharing share;
|
||||||
|
if (flags & MAP_SHARED) { share=SHARED;shareCount++;}
|
||||||
|
if (flags & MAP_PRIVATE) { share=PRIVATE;shareCount++;}
|
||||||
|
if (flags & MAP_COPY){ share=COPY;shareCount++;}
|
||||||
|
if (shareCount!=1)
|
||||||
|
addr=NULL;
|
||||||
|
else {
|
||||||
|
area *newArea = new (vmBlock->areaPool->get()) area;
|
||||||
|
newArea->setup(this);
|
||||||
|
//error ("area = %x, start = %x\n",newArea, newArea->getStartAddress());
|
||||||
|
newArea->createAreaMappingFile(name,(int)((len+PAGE_SIZE-1)/PAGE_SIZE),&addr,addType,LAZY,protType,fd,offset,share);
|
||||||
|
atomic_add(&nextAreaID,1);
|
||||||
|
newArea->setAreaID(nextAreaID);
|
||||||
|
addArea(newArea);
|
||||||
|
newArea->getAreaID();
|
||||||
|
//pageMan.dump();
|
||||||
|
//newArea->dump();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
int shareCount=0;
|
|
||||||
mmapSharing share;
|
|
||||||
if (flags & MAP_SHARED) { share=SHARED;shareCount++;}
|
|
||||||
if (flags & MAP_PRIVATE) { share=PRIVATE;shareCount++;}
|
|
||||||
if (flags & MAP_COPY){ share=COPY;shareCount++;}
|
|
||||||
if (shareCount!=1)
|
|
||||||
return NULL;
|
|
||||||
area *newArea = new (vmBlock->areaPool->get()) area;
|
|
||||||
newArea->setup(this);
|
|
||||||
//error ("area = %x, start = %x\n",newArea, newArea->getStartAddress());
|
|
||||||
newArea->createAreaMappingFile(name,(int)((len+PAGE_SIZE-1)/PAGE_SIZE),&addr,addType,LAZY,protType,fd,offset,share);
|
|
||||||
atomic_add(&nextAreaID,1);
|
|
||||||
newArea->setAreaID(nextAreaID);
|
|
||||||
addArea(newArea);
|
|
||||||
newArea->getAreaID();
|
|
||||||
//pageMan.dump();
|
|
||||||
//newArea->dump();
|
|
||||||
unlock();
|
unlock();
|
||||||
return addr;
|
return addr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,13 +53,16 @@ class areaManager // One of these per process
|
|||||||
area *findAreaLock(area_id id);
|
area *findAreaLock(area_id id);
|
||||||
status_t setProtection(int areaID,protectType prot) {
|
status_t setProtection(int areaID,protectType prot) {
|
||||||
status_t retVal;
|
status_t retVal;
|
||||||
|
error ("area::setProtection about to lock\n");
|
||||||
lock();
|
lock();
|
||||||
|
error ("area::setProtection locked\n");
|
||||||
area *myArea=findArea(areaID);
|
area *myArea=findArea(areaID);
|
||||||
if (myArea)
|
if (myArea)
|
||||||
retVal= myArea->setProtection(prot);
|
retVal= myArea->setProtection(prot);
|
||||||
else
|
else
|
||||||
retVal= B_ERROR;
|
retVal= B_ERROR;
|
||||||
unlock();
|
unlock();
|
||||||
|
error ("area::setProtection unlocked\n");
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
status_t resizeArea(int Area,size_t size) {
|
status_t resizeArea(int Area,size_t size) {
|
||||||
|
|||||||
@@ -46,6 +46,8 @@ class list {
|
|||||||
nodeCount--;
|
nodeCount--;
|
||||||
done=true;
|
done=true;
|
||||||
}
|
}
|
||||||
|
if (!done)
|
||||||
|
throw ("list::remove failed to find node %x\n",toNuke);
|
||||||
}
|
}
|
||||||
//error ("list::remove ending: \n");
|
//error ("list::remove ending: \n");
|
||||||
//dump();
|
//dump();
|
||||||
|
|||||||
+14
-8
@@ -120,14 +120,14 @@ void vpage::setProtection(protectType prot) {
|
|||||||
// This is dispatched by the real interrupt handler, who locates us
|
// This is dispatched by the real interrupt handler, who locates us
|
||||||
// true = OK, false = panic.
|
// true = OK, false = panic.
|
||||||
bool vpage::fault(void *fault_address, bool writeError, int &in_count) {
|
bool vpage::fault(void *fault_address, bool writeError, int &in_count) {
|
||||||
error ("vpage::fault: virtual address = %lx, write = %s\n",(unsigned long) fault_address,((writeError)?"true":"false"));
|
// error ("vpage::fault: virtual address = %lx, write = %s\n",(unsigned long) fault_address,((writeError)?"true":"false"));
|
||||||
if (writeError && protection != copyOnWrite && protection != writable)
|
if (writeError && protection != copyOnWrite && protection != writable)
|
||||||
return false;
|
return false;
|
||||||
if (writeError && physPage) { // If we already have a page and this is a write, it is either a copy on write or a "dirty" notice
|
if (writeError && physPage) { // If we already have a page and this is a write, it is either a copy on write or a "dirty" notice
|
||||||
dirty=true;
|
dirty=true;
|
||||||
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=vmBlock->pageMan->getPage();
|
page *newPhysPage=vmBlock->pageMan->getPage();
|
||||||
error ("vpage::fault - copy on write allocated page %x\n",newPhysPage);
|
// error ("vpage::fault - copy on write allocated page %x\n",newPhysPage);
|
||||||
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;
|
||||||
@@ -140,10 +140,10 @@ bool vpage::fault(void *fault_address, bool writeError, int &in_count) {
|
|||||||
}
|
}
|
||||||
// Guess this is the real deal. Get a physical page.
|
// Guess this is the real deal. Get a physical page.
|
||||||
physPage=vmBlock->pageMan->getPage();
|
physPage=vmBlock->pageMan->getPage();
|
||||||
error ("vpage::fault - regular - allocated page %x\n",physPage);
|
// error ("vpage::fault - regular - allocated page %x\n",physPage);
|
||||||
if (!physPage) // No room at the inn
|
if (!physPage) // No room at the inn
|
||||||
return false;
|
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));
|
// 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));
|
||||||
// Update the architecture specific stuff here...
|
// Update the architecture specific stuff here...
|
||||||
// This refresh is unneeded if the data was never written out...
|
// This refresh is unneeded if the data was never written out...
|
||||||
// dump();
|
// dump();
|
||||||
@@ -186,7 +186,10 @@ void vpage::setByte(unsigned long address,char value,areaManager *manager) {
|
|||||||
if (!physPage)
|
if (!physPage)
|
||||||
if (!manager->fault((void *)(address),true))
|
if (!manager->fault((void *)(address),true))
|
||||||
throw ("vpage::setByte");
|
throw ("vpage::setByte");
|
||||||
*((char *)(address-start_address+physPage->getAddress()))=value;
|
if (protection>=writable)
|
||||||
|
*((char *)(address-start_address+physPage->getAddress()))=value;
|
||||||
|
else
|
||||||
|
throw ("vpage::setByte - no permission to write");
|
||||||
// error ("vpage::setByte: physical address = %d, value = %d\n",physPage->getAddress(), *((char *)(physPage->getAddress())));
|
// error ("vpage::setByte: physical address = %d, value = %d\n",physPage->getAddress(), *((char *)(physPage->getAddress())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -201,12 +204,15 @@ int vpage::getInt(unsigned long address,areaManager *manager) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void vpage::setInt(unsigned long address,int value,areaManager *manager) {
|
void vpage::setInt(unsigned long address,int value,areaManager *manager) {
|
||||||
error ("vpage::setInt: here I am!\n");
|
// error ("vpage::setInt: here I am!\n");
|
||||||
if (!physPage)
|
if (!physPage)
|
||||||
if (!manager->fault((void *)(address),true))
|
if (!manager->fault((void *)(address),true))
|
||||||
throw ("vpage::setInt");
|
throw ("vpage::setInt");
|
||||||
*((int *)(address-start_address+physPage->getAddress()))=value;
|
if (protection>=writable)
|
||||||
error ("vpage::setInt: leaving!\n");
|
*((int *)(address-start_address+physPage->getAddress()))=value;
|
||||||
|
else
|
||||||
|
throw ("vpage::setInt - no permission to write");
|
||||||
|
// error ("vpage::setInt: leaving!\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Swaps pages out where necessary.
|
// Swaps pages out where necessary.
|
||||||
|
|||||||
Reference in New Issue
Block a user