Fixed a bug in the vnodeManagement
Added statistics counting. Started down the path of making various tests share one VM space. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@2265 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -2,6 +2,7 @@ SubDir OBOS_TOP src kernel vm2 ;
|
|||||||
|
|
||||||
BinCommand vmTest : error.C area.C areaManager.C cacheManager.C page.C pageManager.C swapFileManager.C vmInterface.C vpage.C areaPool.C vnodePool.C vpagePool.C vnodeManager.C test.C : root be ;
|
BinCommand vmTest : error.C area.C areaManager.C cacheManager.C page.C pageManager.C swapFileManager.C vmInterface.C vpage.C areaPool.C vnodePool.C vpagePool.C vnodeManager.C test.C : root be ;
|
||||||
BinCommand simpleTest : error.C area.C areaManager.C cacheManager.C page.C pageManager.C swapFileManager.C vmInterface.C vpage.C areaPool.C vnodePool.C vpagePool.C vnodeManager.C simpleTest.C : root be ;
|
BinCommand simpleTest : error.C area.C areaManager.C cacheManager.C page.C pageManager.C swapFileManager.C vmInterface.C vpage.C areaPool.C vnodePool.C vpagePool.C vnodeManager.C simpleTest.C : root be ;
|
||||||
|
BinCommand testSetup : error.C area.C areaManager.C cacheManager.C page.C pageManager.C swapFileManager.C vmInterface.C vpage.C areaPool.C vnodePool.C vpagePool.C vnodeManager.C simpleTest.C : root be ;
|
||||||
BinCommand hashTest : error.C area.C areaManager.C cacheManager.C page.C pageManager.C swapFileManager.C vmInterface.C vpage.C areaPool.C vnodePool.C vpagePool.C vnodeManager.C hashTest.C : root be ;
|
BinCommand hashTest : error.C area.C areaManager.C cacheManager.C page.C pageManager.C swapFileManager.C vmInterface.C vpage.C areaPool.C vnodePool.C vpagePool.C vnodeManager.C hashTest.C : root be ;
|
||||||
BinCommand olTest : error.C olTest.C : root be ;
|
BinCommand olTest : error.C olTest.C : root be ;
|
||||||
BinCommand pmTest : error.C pageManager.C pageManTest.C page.C : root be ;
|
BinCommand pmTest : error.C pageManager.C pageManTest.C page.C : root be ;
|
||||||
|
|||||||
+4
-8
@@ -1,6 +1,5 @@
|
|||||||
1) Must lock original area when clone()ing. Sigh. Also must add ability to clone other process' areas. The issue here is that areaManager is finding the areas. Need to keep a global list of areas for this. An area might well work.
|
1) Change the architecture so that instead of multiple threads of tests, we have multiple apps of tests...
|
||||||
2) Add statistics counting for copy in/out
|
2) Tests are not done.
|
||||||
3) Tests are not done.
|
|
||||||
Test:
|
Test:
|
||||||
getNextAreaInfo
|
getNextAreaInfo
|
||||||
cloneArea
|
cloneArea
|
||||||
@@ -9,10 +8,7 @@
|
|||||||
mmap / munmap
|
mmap / munmap
|
||||||
paging
|
paging
|
||||||
disk caching
|
disk caching
|
||||||
4) Change the architecture so that instead of multiple threads of tests, we have multiple apps of tests...
|
|
||||||
|
|
||||||
5) Need to make the paging daemon load the pages in, using semaphores.
|
4) See how unresolvable page faults and permissions errors are handled - need to properly handle *
|
||||||
-- Looks like we *don't* have to do this, based on what is done in NewOS. Need to consult...
|
|
||||||
6) See how unresolvable page faults and permissions errors are handled - need to properly handle
|
|
||||||
- This may have to come at HW integration time, since they will be app signals, etc...
|
- This may have to come at HW integration time, since they will be app signals, etc...
|
||||||
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.
|
5) There is no arch-level integration. This is to be tested (to death) in user land first. * == can not be done in user land.
|
||||||
|
|||||||
@@ -95,6 +95,7 @@ status_t area::createAreaGuts( char *inName, int pageCount, void **address, addr
|
|||||||
base+=PAGE_SIZE;
|
base+=PAGE_SIZE;
|
||||||
}
|
}
|
||||||
dump();
|
dump();
|
||||||
|
vmBlock->areas.add(this);
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,16 +153,13 @@ status_t area::getInfo(area_info *dest) {
|
|||||||
dest->protection=protection;
|
dest->protection=protection;
|
||||||
dest->team=manager->getTeam();
|
dest->team=manager->getTeam();
|
||||||
dest->ram_size=0;
|
dest->ram_size=0;
|
||||||
dest->in_count=0;
|
dest->in_count=in_count;
|
||||||
dest->out_count=0;
|
dest->out_count=out_count;
|
||||||
dest->copy_count=0;
|
dest->copy_count=0;
|
||||||
for (hashIterate hi(vpages);node *cur=hi.get();) {
|
for (hashIterate hi(vpages);node *cur=hi.get();) {
|
||||||
vpage *page=(vpage *)cur;
|
vpage *page=(vpage *)cur;
|
||||||
if (page->isMapped())
|
if (page->isMapped())
|
||||||
dest->ram_size+=PAGE_SIZE;
|
dest->ram_size+=PAGE_SIZE;
|
||||||
dest->in_count+=PAGE_SIZE;
|
|
||||||
dest->out_count+=PAGE_SIZE;
|
|
||||||
dest->copy_count+=PAGE_SIZE;
|
|
||||||
}
|
}
|
||||||
dest->address=(void *)start_address;
|
dest->address=(void *)start_address;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@@ -234,7 +232,7 @@ vpage *area::findVPage(unsigned long address) {
|
|||||||
bool area::fault(void *fault_address, bool writeError) { // true = OK, false = panic.
|
bool area::fault(void *fault_address, bool writeError) { // true = OK, false = panic.
|
||||||
vpage *page=findVPage((unsigned long)fault_address);
|
vpage *page=findVPage((unsigned long)fault_address);
|
||||||
if (page)
|
if (page)
|
||||||
return page->fault(fault_address,writeError);
|
return page->fault(fault_address,writeError,in_count);
|
||||||
else
|
else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -271,7 +269,8 @@ void area::setInt(unsigned long address,int value) { // This is for testing only
|
|||||||
void area::pager(int desperation) {
|
void area::pager(int desperation) {
|
||||||
for (hashIterate hi(vpages);node *cur=hi.get();) {
|
for (hashIterate hi(vpages);node *cur=hi.get();) {
|
||||||
vpage *page=(vpage *)cur;
|
vpage *page=(vpage *)cur;
|
||||||
page->pager(desperation);
|
if (page->pager(desperation))
|
||||||
|
out_count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,14 +5,12 @@
|
|||||||
#include "areaPool.h"
|
#include "areaPool.h"
|
||||||
extern vmHeaderBlock *vmBlock;
|
extern vmHeaderBlock *vmBlock;
|
||||||
|
|
||||||
bool areaIsLessThan(void *a,void *b)
|
bool areaIsLessThan(void *a,void *b) {
|
||||||
{
|
|
||||||
return (((reinterpret_cast<area *>(a))->getStartAddress()) < (reinterpret_cast<area *>(b))->getStartAddress());
|
return (((reinterpret_cast<area *>(a))->getStartAddress()) < (reinterpret_cast<area *>(b))->getStartAddress());
|
||||||
}
|
}
|
||||||
|
|
||||||
// This creates the one true lock for this area
|
// This creates the one true lock for this area
|
||||||
areaManager::areaManager(void)
|
areaManager::areaManager(void) {
|
||||||
{
|
|
||||||
team=0; // should be proc_get_current_proc_id()
|
team=0; // should be proc_get_current_proc_id()
|
||||||
myLock=0;
|
myLock=0;
|
||||||
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.
|
||||||
@@ -20,8 +18,7 @@ areaManager::areaManager(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Loops over every area looking for someplace where we can get the space we need.
|
// Loops over every area looking for someplace where we can get the space we need.
|
||||||
unsigned long areaManager::getNextAddress(int pages, unsigned long start)
|
unsigned long areaManager::getNextAddress(int pages, unsigned long start) {
|
||||||
{
|
|
||||||
// This function needs to deal with the possibility that we run out of address space...
|
// This function needs to deal with the possibility that we run out of address space...
|
||||||
// areas.dump();
|
// areas.dump();
|
||||||
unsigned long end=start+(pages*PAGE_SIZE)-1;
|
unsigned long end=start+(pages*PAGE_SIZE)-1;
|
||||||
@@ -42,8 +39,7 @@ unsigned long areaManager::getNextAddress(int pages, unsigned long start)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Remove the area from our list, put it on the area pool and move on
|
// Remove the area from our list, put it on the area pool and move on
|
||||||
void areaManager::freeArea(area_id areaID)
|
void areaManager::freeArea(area_id areaID) {
|
||||||
{
|
|
||||||
error ("areaManager::freeArea: begin\n");
|
error ("areaManager::freeArea: begin\n");
|
||||||
lock();
|
lock();
|
||||||
area *oldArea=findArea(areaID);
|
area *oldArea=findArea(areaID);
|
||||||
@@ -54,6 +50,7 @@ void areaManager::freeArea(area_id areaID)
|
|||||||
// error ("areaManager::freeArea: areaManager = %x \n",manager);
|
// error ("areaManager::freeArea: areaManager = %x \n",manager);
|
||||||
removeArea(oldArea);
|
removeArea(oldArea);
|
||||||
// error ("areaManager::freeArea: deleting area %x \n",oldArea);
|
// error ("areaManager::freeArea: deleting area %x \n",oldArea);
|
||||||
|
vmBlock->areas.remove(oldArea);
|
||||||
oldArea->freeArea();
|
oldArea->freeArea();
|
||||||
// error ("areaManager::freeArea: freeArea complete \n");
|
// error ("areaManager::freeArea: freeArea complete \n");
|
||||||
vmBlock->areaPool->put(oldArea);
|
vmBlock->areaPool->put(oldArea);
|
||||||
@@ -63,8 +60,7 @@ void areaManager::freeArea(area_id areaID)
|
|||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
area *areaManager::findAreaLock(void *address)
|
area *areaManager::findAreaLock(void *address) {
|
||||||
{
|
|
||||||
lock();
|
lock();
|
||||||
area *retVal=findArea(address);
|
area *retVal=findArea(address);
|
||||||
unlock();
|
unlock();
|
||||||
@@ -72,8 +68,7 @@ area *areaManager::findAreaLock(void *address)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Loops over our areas looking for this one by name
|
// Loops over our areas looking for this one by name
|
||||||
area *areaManager::findArea(char *address)
|
area *areaManager::findArea(char *address) {
|
||||||
{
|
|
||||||
error ("Finding area by string\n");
|
error ("Finding area by string\n");
|
||||||
area *retVal=NULL;
|
area *retVal=NULL;
|
||||||
lock();
|
lock();
|
||||||
@@ -88,8 +83,7 @@ area *areaManager::findArea(char *address)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Loops over our areas looking for the one whose virtual address matches the passed in address
|
// Loops over our areas looking for the one whose virtual address matches the passed in address
|
||||||
area *areaManager::findArea(void *address)
|
area *areaManager::findArea(void *address) {
|
||||||
{
|
|
||||||
// THIS DOES NOT HAVE LOCKING - all callers must lock.
|
// THIS DOES NOT HAVE LOCKING - all callers must lock.
|
||||||
// error ("Finding area by void * address\n");
|
// error ("Finding area by void * address\n");
|
||||||
for (struct node *cur=areas.rock;cur;cur=cur->next)
|
for (struct node *cur=areas.rock;cur;cur=cur->next)
|
||||||
@@ -103,8 +97,7 @@ area *areaManager::findArea(void *address)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
area *areaManager::findAreaLock(area_id id)
|
area *areaManager::findAreaLock(area_id id) {
|
||||||
{
|
|
||||||
error ("Finding area by areaID \n");
|
error ("Finding area by areaID \n");
|
||||||
lock();
|
lock();
|
||||||
area *retVal=findArea(id);
|
area *retVal=findArea(id);
|
||||||
@@ -113,8 +106,7 @@ area *areaManager::findAreaLock(area_id id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Loops over our areas looking for the one whose ID was passed in
|
// Loops over our areas looking for the one whose ID was passed in
|
||||||
area *areaManager::findArea(area_id id)
|
area *areaManager::findArea(area_id id) {
|
||||||
{
|
|
||||||
//error ("Finding area by area_id\n");
|
//error ("Finding area by area_id\n");
|
||||||
area *retVal=NULL;
|
area *retVal=NULL;
|
||||||
for (struct node *cur=areas.rock;cur && !retVal;cur=cur->next)
|
for (struct node *cur=areas.rock;cur && !retVal;cur=cur->next)
|
||||||
@@ -127,8 +119,7 @@ area *areaManager::findArea(area_id id)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find the area whose address matches this page fault and dispatch the fault to it.
|
// Find the area whose address matches this page fault and dispatch the fault to it.
|
||||||
bool areaManager::fault(void *fault_address, bool writeError) // true = OK, false = panic.
|
bool areaManager::fault(void *fault_address, bool writeError) { // true = OK, false = panic.
|
||||||
{
|
|
||||||
area *myArea;
|
area *myArea;
|
||||||
bool retVal;
|
bool retVal;
|
||||||
error ("Faulting \n");
|
error ("Faulting \n");
|
||||||
@@ -145,8 +136,7 @@ bool areaManager::fault(void *fault_address, bool writeError) // true = OK, fals
|
|||||||
long areaManager::nextAreaID=0;
|
long areaManager::nextAreaID=0;
|
||||||
|
|
||||||
// Create an area; get a new structure, call setup, create the guts, set its ID, add it to our list
|
// Create an area; get a new structure, call setup, create the guts, set its ID, add it to our list
|
||||||
int areaManager::createArea(char *AreaName,int pageCount,void **address, addressSpec addType,pageState state,protectType protect)
|
int areaManager::createArea(char *AreaName,int pageCount,void **address, addressSpec addType,pageState state,protectType protect) {
|
||||||
{
|
|
||||||
error ("areaManager::createArea - Creating an area\n");
|
error ("areaManager::createArea - Creating an area\n");
|
||||||
lock();
|
lock();
|
||||||
area *newArea = new (vmBlock->areaPool->get()) area;
|
area *newArea = new (vmBlock->areaPool->get()) area;
|
||||||
@@ -167,14 +157,24 @@ int areaManager::createArea(char *AreaName,int pageCount,void **address, address
|
|||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
area *findAreaGlobal(int areaID) {
|
||||||
|
for (struct node *cur=vmBlock->areas.rock;cur;cur=cur->next) {
|
||||||
|
area *myArea=(area *)cur;
|
||||||
|
if (((area *)(cur))->getAreaID()==areaID)
|
||||||
|
return myArea;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
// FIX: THIS IS WRONG! It will only clone areas in our areaManager.
|
// FIX: THIS IS WRONG! It will only clone areas in our areaManager.
|
||||||
// Should: find the specified area, create a new area to be its clone, and set it up
|
// Should: find the specified area, create a new area to be its clone, and set it up
|
||||||
int areaManager::cloneArea(int newAreaID,char *AreaName,void **address, addressSpec addType,pageState state,protectType protect)
|
int areaManager::cloneArea(int newAreaID,char *AreaName,void **address, addressSpec addType,pageState state,protectType protect) {
|
||||||
{
|
|
||||||
int retVal;
|
int retVal;
|
||||||
error ("Cloning an area\n");
|
error ("Cloning an area\n");
|
||||||
lock();
|
lock();
|
||||||
area *oldArea=findArea(newAreaID);
|
area *oldArea=findArea(newAreaID);
|
||||||
|
if (!oldArea)
|
||||||
|
oldArea=findAreaGlobal(newAreaID);
|
||||||
if (oldArea)
|
if (oldArea)
|
||||||
{
|
{
|
||||||
area *newArea = new (vmBlock->areaPool->get()) area;
|
area *newArea = new (vmBlock->areaPool->get()) area;
|
||||||
@@ -191,8 +191,7 @@ int areaManager::cloneArea(int newAreaID,char *AreaName,void **address, addressS
|
|||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
char areaManager::getByte(unsigned long address)
|
char areaManager::getByte(unsigned long address) {
|
||||||
{
|
|
||||||
area *myArea;
|
area *myArea;
|
||||||
// error ("areaManager::getByte : starting\n");
|
// error ("areaManager::getByte : starting\n");
|
||||||
int retVal;
|
int retVal;
|
||||||
@@ -210,8 +209,7 @@ char areaManager::getByte(unsigned long address)
|
|||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
int areaManager::getInt(unsigned long address)
|
int areaManager::getInt(unsigned long address) {
|
||||||
{
|
|
||||||
area *myArea;
|
area *myArea;
|
||||||
int retVal;
|
int retVal;
|
||||||
lock();
|
lock();
|
||||||
@@ -228,8 +226,7 @@ int areaManager::getInt(unsigned long address)
|
|||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
void areaManager::setByte(unsigned long address,char value)
|
void areaManager::setByte(unsigned long address,char value) {
|
||||||
{
|
|
||||||
// error ("areaManager::setByte : starting\n");
|
// error ("areaManager::setByte : starting\n");
|
||||||
area *myArea;
|
area *myArea;
|
||||||
lock();
|
lock();
|
||||||
@@ -245,15 +242,13 @@ void areaManager::setByte(unsigned long address,char value)
|
|||||||
unlock();
|
unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void areaManager::setInt(unsigned long address,int value)
|
void areaManager::setInt(unsigned long address,int value) {
|
||||||
{
|
|
||||||
area *myArea;
|
area *myArea;
|
||||||
lock();
|
lock();
|
||||||
myArea=findArea((void *)address);
|
myArea=findArea((void *)address);
|
||||||
if (myArea)
|
if (myArea)
|
||||||
myArea->setInt(address,value);
|
myArea->setInt(address,value);
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
char temp[1000];
|
char temp[1000];
|
||||||
sprintf (temp,"Unable to find an area for address %d\n",address);
|
sprintf (temp,"Unable to find an area for address %d\n",address);
|
||||||
throw (temp);
|
throw (temp);
|
||||||
@@ -262,11 +257,9 @@ void areaManager::setInt(unsigned long address,int value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call pager for each of our areas
|
// Call pager for each of our areas
|
||||||
void areaManager::pager(int desperation)
|
void areaManager::pager(int desperation) {
|
||||||
{
|
|
||||||
lock();
|
lock();
|
||||||
for (struct node *cur=areas.rock;cur;cur=cur->next)
|
for (struct node *cur=areas.rock;cur;cur=cur->next) {
|
||||||
{
|
|
||||||
area *myArea=(area *)cur;
|
area *myArea=(area *)cur;
|
||||||
//error ("areaManager::pager; area = \n");
|
//error ("areaManager::pager; area = \n");
|
||||||
//myArea->dump();
|
//myArea->dump();
|
||||||
@@ -276,11 +269,9 @@ void areaManager::pager(int desperation)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Call saver for each of our areas
|
// Call saver for each of our areas
|
||||||
void areaManager::saver(void)
|
void areaManager::saver(void) {
|
||||||
{
|
|
||||||
lock();
|
lock();
|
||||||
for (struct node *cur=areas.rock;cur;cur=cur->next)
|
for (struct node *cur=areas.rock;cur;cur=cur->next) {
|
||||||
{
|
|
||||||
area *myArea=(area *)cur;
|
area *myArea=(area *)cur;
|
||||||
myArea->saver();
|
myArea->saver();
|
||||||
}
|
}
|
||||||
@@ -288,8 +279,7 @@ void areaManager::saver(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// mmap is basically map POSIX values to ours and call createAreaMappingFile...
|
// mmap is basically map POSIX values to ours and call createAreaMappingFile...
|
||||||
void *areaManager::mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset)
|
void *areaManager::mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset) {
|
||||||
{
|
|
||||||
char name[MAXPATHLEN];
|
char name[MAXPATHLEN];
|
||||||
// Get the filename from fd...
|
// Get the filename from fd...
|
||||||
strcpy( name,"mmap - need to include fileName");
|
strcpy( name,"mmap - need to include fileName");
|
||||||
@@ -299,8 +289,7 @@ void *areaManager::mmap(void *addr, size_t len, int prot, int flags, int fd, off
|
|||||||
// Not doing anything with MAP_SHARED and MAP_COPY - needs to be done
|
// Not doing anything with MAP_SHARED and MAP_COPY - needs to be done
|
||||||
//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;
|
return addr;
|
||||||
}
|
}
|
||||||
@@ -326,14 +315,12 @@ status_t areaManager::munmap(void *addr,size_t len)
|
|||||||
status_t retVal=B_OK;
|
status_t retVal=B_OK;
|
||||||
lock();
|
lock();
|
||||||
area *myArea=findArea(addr);
|
area *myArea=findArea(addr);
|
||||||
if (myArea)
|
if (myArea) {
|
||||||
{
|
|
||||||
removeArea(myArea);
|
removeArea(myArea);
|
||||||
myArea->freeArea();
|
myArea->freeArea();
|
||||||
vmBlock->areaPool->put(myArea);
|
vmBlock->areaPool->put(myArea);
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
{
|
|
||||||
error ("areaManager::munmap: unable to find requested area\n");
|
error ("areaManager::munmap: unable to find requested area\n");
|
||||||
retVal=B_ERROR;
|
retVal=B_ERROR;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
#include "vmInterface.h"
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <mman.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
vmInterface *vm;
|
||||||
|
|
||||||
|
int main(int argc,char **argv)
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
vm = new vmInterface (30);
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
snooze(1000000);
|
||||||
|
}
|
||||||
|
catch (const char *t)
|
||||||
|
{
|
||||||
|
error ("Exception thrown! %s\n",t);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
catch (...)
|
||||||
|
{
|
||||||
|
error ("Unknown Exception thrown!\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
+1
-1
@@ -18,7 +18,7 @@ struct vnode : public node
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
#define B_OS_NAME_LENGTH 32
|
#define B_OS_NAME_LENGTH 32
|
||||||
enum protectType {none=0,readable, writable,copyOnWrite,symCopyOnWrite};
|
enum protectType {none=0,readable, writable,copyOnWrite};
|
||||||
//B_EXACT_ADDRESS You want the value of *addr to be taken literally and strictly.
|
//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.
|
// 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_BASE_ADDRESS The area can start at a location equal to or greater than *addr.
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ class pageManager;
|
|||||||
class swapFileManager;
|
class swapFileManager;
|
||||||
class cacheManager;
|
class cacheManager;
|
||||||
class vnodeManager;
|
class vnodeManager;
|
||||||
|
class list;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct vmHeaderBlock
|
struct vmHeaderBlock
|
||||||
@@ -21,6 +22,7 @@ struct vmHeaderBlock
|
|||||||
swapFileManager *swapMan;
|
swapFileManager *swapMan;
|
||||||
cacheManager *cacheMan;
|
cacheManager *cacheMan;
|
||||||
vnodeManager *vnodeMan;
|
vnodeManager *vnodeMan;
|
||||||
|
list areas;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+15
-10
@@ -102,7 +102,7 @@ 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) {
|
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 && 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;
|
||||||
@@ -112,7 +112,9 @@ bool vpage::fault(void *fault_address, bool writeError) {
|
|||||||
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;
|
||||||
|
vmBlock->vnodeMan->remove(*backingNode,*this);
|
||||||
backingNode=&(vmBlock->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...
|
||||||
|
vmBlock->vnodeMan->addVnode(backingNode,*this);
|
||||||
// Update the architecture specific stuff here...
|
// Update the architecture specific stuff here...
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -128,6 +130,7 @@ bool vpage::fault(void *fault_address, bool writeError) {
|
|||||||
dump();
|
dump();
|
||||||
refresh(); // I wonder if these vnode calls are safe during an interrupt...
|
refresh(); // I wonder if these vnode calls are safe during an interrupt...
|
||||||
dirty=false;
|
dirty=false;
|
||||||
|
in_count++;
|
||||||
error ("vpage::fault: Refreshed\n");
|
error ("vpage::fault: Refreshed\n");
|
||||||
dump();
|
dump();
|
||||||
error ("vpage::fault: exiting\n");
|
error ("vpage::fault: exiting\n");
|
||||||
@@ -170,18 +173,18 @@ void vpage::setInt(unsigned long address,int value,areaManager *manager) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Swaps pages out where necessary.
|
// Swaps pages out where necessary.
|
||||||
void vpage::pager(int desperation) {
|
bool vpage::pager(int desperation) {
|
||||||
//error ("vpage::pager start desperation = %d\n",desperation);
|
//error ("vpage::pager start desperation = %d\n",desperation);
|
||||||
if (!swappable)
|
if (!swappable)
|
||||||
return;
|
return false;
|
||||||
error ("vpage::pager swappable\n");
|
error ("vpage::pager swappable\n");
|
||||||
switch (desperation) {
|
switch (desperation) {
|
||||||
case 1: return; break;
|
case 1: return false; break;
|
||||||
case 2: if (!physPage || protection!=readable) return;break;
|
case 2: if (!physPage || protection!=readable) return false;break;
|
||||||
case 3: if (!physPage || dirty) return;break;
|
case 3: if (!physPage || dirty) return false;break;
|
||||||
case 4: if (!physPage) return;break;
|
case 4: if (!physPage) return false;break;
|
||||||
case 5: if (!physPage) return;break;
|
case 5: if (!physPage) return false;break;
|
||||||
default: return;break;
|
default: return false;break;
|
||||||
}
|
}
|
||||||
error ("vpage::pager flushing\n");
|
error ("vpage::pager flushing\n");
|
||||||
flush();
|
flush();
|
||||||
@@ -189,11 +192,13 @@ void vpage::pager(int desperation) {
|
|||||||
vmBlock->pageMan->freePage(physPage);
|
vmBlock->pageMan->freePage(physPage);
|
||||||
error ("vpage::pager going to NULL\n");
|
error ("vpage::pager going to NULL\n");
|
||||||
physPage=NULL;
|
physPage=NULL;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Saves dirty pages
|
// Saves dirty pages
|
||||||
void vpage::saver(void) {
|
void vpage::saver(void) {
|
||||||
if (dirty)
|
if (dirty) {
|
||||||
flush();
|
flush();
|
||||||
dirty=false;
|
dirty=false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ 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)); }
|
||||||
|
|
||||||
// External methods for "server" type calls
|
// External methods for "server" type calls
|
||||||
bool fault(void *fault_address, bool writeError); // true = OK, false = panic.
|
bool fault(void *fault_address, bool writeError, int &in_count); // true = OK, false = panic.
|
||||||
void pager(int desperation);
|
bool pager(int desperation);
|
||||||
void saver(void);
|
void saver(void);
|
||||||
|
|
||||||
// Debugging
|
// Debugging
|
||||||
|
|||||||
Reference in New Issue
Block a user