* Added VMArea subclasses VM{Kernel,User}Area and moved the address space list
link to them.
* VM{Kernel,User}AddressSpace manage the respective VMArea subclass now, and
VMAddressSpace has grown factory methods {Create,Delete}Area.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34493 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -66,6 +66,9 @@ public:
|
|||||||
virtual VMArea* NextArea(VMArea* area) const = 0;
|
virtual VMArea* NextArea(VMArea* area) const = 0;
|
||||||
|
|
||||||
virtual VMArea* LookupArea(addr_t address) const = 0;
|
virtual VMArea* LookupArea(addr_t address) const = 0;
|
||||||
|
virtual VMArea* CreateArea(const char* name, uint32 wiring,
|
||||||
|
uint32 protection) = 0;
|
||||||
|
virtual void DeleteArea(VMArea* area) = 0;
|
||||||
virtual status_t InsertArea(void** _address, uint32 addressSpec,
|
virtual status_t InsertArea(void** _address, uint32 addressSpec,
|
||||||
addr_t size, VMArea* area) = 0;
|
addr_t size, VMArea* area) = 0;
|
||||||
virtual void RemoveArea(VMArea* area) = 0;
|
virtual void RemoveArea(VMArea* area) = 0;
|
||||||
|
|||||||
@@ -48,50 +48,28 @@ struct VMArea {
|
|||||||
{ return address >= fBase
|
{ return address >= fBase
|
||||||
&& address <= fBase + (fSize - 1); }
|
&& address <= fBase + (fSize - 1); }
|
||||||
|
|
||||||
static VMArea* Create(VMAddressSpace* addressSpace,
|
protected:
|
||||||
const char* name, uint32 wiring,
|
VMArea(VMAddressSpace* addressSpace,
|
||||||
uint32 protection);
|
uint32 wiring, uint32 protection);
|
||||||
static VMArea* CreateReserved(VMAddressSpace* addressSpace,
|
~VMArea();
|
||||||
uint32 flags);
|
|
||||||
|
|
||||||
DoublyLinkedListLink<VMArea>& AddressSpaceLink()
|
status_t Init(const char* name);
|
||||||
{ return fAddressSpaceLink; }
|
|
||||||
const DoublyLinkedListLink<VMArea>& AddressSpaceLink() const
|
|
||||||
{ return fAddressSpaceLink; }
|
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
friend class VMAddressSpace;
|
friend class VMAddressSpace;
|
||||||
friend class VMKernelAddressSpace;
|
friend class VMKernelAddressSpace;
|
||||||
friend class VMUserAddressSpace;
|
friend class VMUserAddressSpace;
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
void SetBase(addr_t base) { fBase = base; }
|
void SetBase(addr_t base) { fBase = base; }
|
||||||
void SetSize(size_t size) { fSize = size; }
|
void SetSize(size_t size) { fSize = size; }
|
||||||
|
|
||||||
private:
|
protected:
|
||||||
DoublyLinkedListLink<VMArea> fAddressSpaceLink;
|
|
||||||
addr_t fBase;
|
addr_t fBase;
|
||||||
size_t fSize;
|
size_t fSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct VMAddressSpaceAreaGetLink {
|
|
||||||
inline DoublyLinkedListLink<VMArea>* operator()(VMArea* area) const
|
|
||||||
{
|
|
||||||
return &area->AddressSpaceLink();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline const DoublyLinkedListLink<VMArea>* operator()(
|
|
||||||
const VMArea* area) const
|
|
||||||
{
|
|
||||||
return &area->AddressSpaceLink();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef DoublyLinkedList<VMArea, VMAddressSpaceAreaGetLink>
|
|
||||||
VMAddressSpaceAreaList;
|
|
||||||
|
|
||||||
|
|
||||||
struct VMAreaHashDefinition {
|
struct VMAreaHashDefinition {
|
||||||
typedef area_id KeyType;
|
typedef area_id KeyType;
|
||||||
typedef VMArea ValueType;
|
typedef VMArea ValueType;
|
||||||
|
|||||||
@@ -16,8 +16,10 @@ KernelMergeObject kernel_vm.o :
|
|||||||
VMCache.cpp
|
VMCache.cpp
|
||||||
VMDeviceCache.cpp
|
VMDeviceCache.cpp
|
||||||
VMKernelAddressSpace.cpp
|
VMKernelAddressSpace.cpp
|
||||||
|
VMKernelArea.cpp
|
||||||
VMNullCache.cpp
|
VMNullCache.cpp
|
||||||
VMUserAddressSpace.cpp
|
VMUserAddressSpace.cpp
|
||||||
|
VMUserArea.cpp
|
||||||
|
|
||||||
: $(TARGET_KERNEL_PIC_CCFLAGS)
|
: $(TARGET_KERNEL_PIC_CCFLAGS)
|
||||||
;
|
;
|
||||||
|
|||||||
@@ -11,7 +11,6 @@
|
|||||||
#include <vm/VMArea.h>
|
#include <vm/VMArea.h>
|
||||||
|
|
||||||
#include <heap.h>
|
#include <heap.h>
|
||||||
#include <vm/vm_priv.h>
|
|
||||||
|
|
||||||
|
|
||||||
#define AREA_HASH_TABLE_SIZE 1024
|
#define AREA_HASH_TABLE_SIZE 1024
|
||||||
@@ -24,61 +23,49 @@ static area_id sNextAreaID = 1;
|
|||||||
|
|
||||||
// #pragma mark - VMArea
|
// #pragma mark - VMArea
|
||||||
|
|
||||||
|
VMArea::VMArea(VMAddressSpace* addressSpace, uint32 wiring, uint32 protection)
|
||||||
|
:
|
||||||
|
name(NULL),
|
||||||
|
protection(protection),
|
||||||
|
wiring(wiring),
|
||||||
|
memory_type(0),
|
||||||
|
cache(NULL),
|
||||||
|
no_cache_change(0),
|
||||||
|
cache_offset(0),
|
||||||
|
cache_type(0),
|
||||||
|
page_protections(NULL),
|
||||||
|
address_space(addressSpace),
|
||||||
|
cache_next(NULL),
|
||||||
|
cache_prev(NULL),
|
||||||
|
hash_next(NULL)
|
||||||
|
{
|
||||||
|
new (&mappings) VMAreaMappings;
|
||||||
|
}
|
||||||
|
|
||||||
/*static*/ VMArea*
|
|
||||||
VMArea::Create(VMAddressSpace* addressSpace, const char* name,
|
VMArea::~VMArea()
|
||||||
uint32 wiring, uint32 protection)
|
{
|
||||||
|
free(page_protections);
|
||||||
|
free(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
VMArea::Init(const char* name)
|
||||||
{
|
{
|
||||||
// restrict the area name to B_OS_NAME_LENGTH
|
// restrict the area name to B_OS_NAME_LENGTH
|
||||||
size_t length = strlen(name) + 1;
|
size_t length = strlen(name) + 1;
|
||||||
if (length > B_OS_NAME_LENGTH)
|
if (length > B_OS_NAME_LENGTH)
|
||||||
length = B_OS_NAME_LENGTH;
|
length = B_OS_NAME_LENGTH;
|
||||||
|
|
||||||
VMArea* area = (VMArea*)malloc_nogrow(sizeof(VMArea));
|
// clone the name
|
||||||
if (area == NULL)
|
this->name = (char*)malloc_nogrow(length);
|
||||||
return NULL;
|
if (this->name == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
strlcpy(this->name, name, length);
|
||||||
|
|
||||||
area->name = (char*)malloc_nogrow(length);
|
id = atomic_add(&sNextAreaID, 1);
|
||||||
if (area->name == NULL) {
|
return B_OK;
|
||||||
free(area);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
strlcpy(area->name, name, length);
|
|
||||||
|
|
||||||
area->id = atomic_add(&sNextAreaID, 1);
|
|
||||||
area->fBase = 0;
|
|
||||||
area->fSize = 0;
|
|
||||||
area->protection = protection;
|
|
||||||
area->wiring = wiring;
|
|
||||||
area->memory_type = 0;
|
|
||||||
|
|
||||||
area->cache = NULL;
|
|
||||||
area->cache_offset = 0;
|
|
||||||
|
|
||||||
area->address_space = addressSpace;
|
|
||||||
area->cache_next = area->cache_prev = NULL;
|
|
||||||
area->hash_next = NULL;
|
|
||||||
new (&area->mappings) VMAreaMappings;
|
|
||||||
area->page_protections = NULL;
|
|
||||||
|
|
||||||
return area;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*static*/ VMArea*
|
|
||||||
VMArea::CreateReserved(VMAddressSpace* addressSpace, uint32 flags)
|
|
||||||
{
|
|
||||||
VMArea* reserved = (VMArea*)malloc_nogrow(sizeof(VMArea));
|
|
||||||
if (reserved == NULL)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
memset(reserved, 0, sizeof(VMArea));
|
|
||||||
reserved->id = RESERVED_AREA_ID;
|
|
||||||
// this marks it as reserved space
|
|
||||||
reserved->protection = flags;
|
|
||||||
reserved->address_space = addressSpace;
|
|
||||||
|
|
||||||
return reserved;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -114,9 +101,6 @@ VMAreaHash::Find(const char* name)
|
|||||||
|
|
||||||
for (VMAreaHashTable::Iterator it = sTable.GetIterator();
|
for (VMAreaHashTable::Iterator it = sTable.GetIterator();
|
||||||
VMArea* area = it.Next();) {
|
VMArea* area = it.Next();) {
|
||||||
if (area->id == RESERVED_AREA_ID)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (strcmp(area->name, name) == 0) {
|
if (strcmp(area->name, name) == 0) {
|
||||||
id = area->id;
|
id = area->id;
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ VMKernelAddressSpace::~VMKernelAddressSpace()
|
|||||||
inline VMArea*
|
inline VMArea*
|
||||||
VMKernelAddressSpace::FirstArea() const
|
VMKernelAddressSpace::FirstArea() const
|
||||||
{
|
{
|
||||||
VMArea* area = fAreas.Head();
|
VMKernelArea* area = fAreas.Head();
|
||||||
while (area != NULL && area->id == RESERVED_AREA_ID)
|
while (area != NULL && area->id == RESERVED_AREA_ID)
|
||||||
area = fAreas.GetNext(area);
|
area = fAreas.GetNext(area);
|
||||||
return area;
|
return area;
|
||||||
@@ -64,8 +64,9 @@ VMKernelAddressSpace::FirstArea() const
|
|||||||
|
|
||||||
|
|
||||||
inline VMArea*
|
inline VMArea*
|
||||||
VMKernelAddressSpace::NextArea(VMArea* area) const
|
VMKernelAddressSpace::NextArea(VMArea* _area) const
|
||||||
{
|
{
|
||||||
|
VMKernelArea* area = static_cast<VMKernelArea*>(_area);
|
||||||
area = fAreas.GetNext(area);
|
area = fAreas.GetNext(area);
|
||||||
while (area != NULL && area->id == RESERVED_AREA_ID)
|
while (area != NULL && area->id == RESERVED_AREA_ID)
|
||||||
area = fAreas.GetNext(area);
|
area = fAreas.GetNext(area);
|
||||||
@@ -73,6 +74,21 @@ VMKernelAddressSpace::NextArea(VMArea* area) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VMArea*
|
||||||
|
VMKernelAddressSpace::CreateArea(const char* name, uint32 wiring,
|
||||||
|
uint32 protection)
|
||||||
|
{
|
||||||
|
return VMKernelArea::Create(this, name, wiring, protection);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
VMKernelAddressSpace::DeleteArea(VMArea* area)
|
||||||
|
{
|
||||||
|
delete static_cast<VMKernelArea*>(area);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//! You must hold the address space's read lock.
|
//! You must hold the address space's read lock.
|
||||||
VMArea*
|
VMArea*
|
||||||
VMKernelAddressSpace::LookupArea(addr_t address) const
|
VMKernelAddressSpace::LookupArea(addr_t address) const
|
||||||
@@ -81,8 +97,8 @@ VMKernelAddressSpace::LookupArea(addr_t address) const
|
|||||||
if (fAreaHint != NULL && fAreaHint->ContainsAddress(address))
|
if (fAreaHint != NULL && fAreaHint->ContainsAddress(address))
|
||||||
return fAreaHint;
|
return fAreaHint;
|
||||||
|
|
||||||
for (VMAddressSpaceAreaList::ConstIterator it = fAreas.GetIterator();
|
for (VMKernelAreaList::ConstIterator it = fAreas.GetIterator();
|
||||||
VMArea* area = it.Next();) {
|
VMKernelArea* area = it.Next();) {
|
||||||
if (area->id == RESERVED_AREA_ID)
|
if (area->id == RESERVED_AREA_ID)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -103,8 +119,10 @@ VMKernelAddressSpace::LookupArea(addr_t address) const
|
|||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
VMKernelAddressSpace::InsertArea(void** _address, uint32 addressSpec,
|
VMKernelAddressSpace::InsertArea(void** _address, uint32 addressSpec,
|
||||||
addr_t size, VMArea* area)
|
addr_t size, VMArea* _area)
|
||||||
{
|
{
|
||||||
|
VMKernelArea* area = static_cast<VMKernelArea*>(_area);
|
||||||
|
|
||||||
addr_t searchBase, searchEnd;
|
addr_t searchBase, searchEnd;
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
@@ -146,8 +164,10 @@ VMKernelAddressSpace::InsertArea(void** _address, uint32 addressSpec,
|
|||||||
|
|
||||||
//! You must hold the address space's write lock.
|
//! You must hold the address space's write lock.
|
||||||
void
|
void
|
||||||
VMKernelAddressSpace::RemoveArea(VMArea* area)
|
VMKernelAddressSpace::RemoveArea(VMArea* _area)
|
||||||
{
|
{
|
||||||
|
VMKernelArea* area = static_cast<VMKernelArea*>(_area);
|
||||||
|
|
||||||
fAreas.Remove(area);
|
fAreas.Remove(area);
|
||||||
|
|
||||||
if (area->id != RESERVED_AREA_ID) {
|
if (area->id != RESERVED_AREA_ID) {
|
||||||
@@ -163,7 +183,7 @@ VMKernelAddressSpace::RemoveArea(VMArea* area)
|
|||||||
bool
|
bool
|
||||||
VMKernelAddressSpace::CanResizeArea(VMArea* area, size_t newSize)
|
VMKernelAddressSpace::CanResizeArea(VMArea* area, size_t newSize)
|
||||||
{
|
{
|
||||||
VMArea* next = fAreas.GetNext(area);
|
VMKernelArea* next = fAreas.GetNext(static_cast<VMKernelArea*>(area));
|
||||||
addr_t newEnd = area->Base() + (newSize - 1);
|
addr_t newEnd = area->Base() + (newSize - 1);
|
||||||
if (next == NULL) {
|
if (next == NULL) {
|
||||||
if (fEndAddress >= newEnd)
|
if (fEndAddress >= newEnd)
|
||||||
@@ -187,10 +207,12 @@ VMKernelAddressSpace::CanResizeArea(VMArea* area, size_t newSize)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
VMKernelAddressSpace::ResizeArea(VMArea* area, size_t newSize)
|
VMKernelAddressSpace::ResizeArea(VMArea* _area, size_t newSize)
|
||||||
{
|
{
|
||||||
|
VMKernelArea* area = static_cast<VMKernelArea*>(_area);
|
||||||
|
|
||||||
addr_t newEnd = area->Base() + (newSize - 1);
|
addr_t newEnd = area->Base() + (newSize - 1);
|
||||||
VMArea* next = fAreas.GetNext(area);
|
VMKernelArea* next = fAreas.GetNext(area);
|
||||||
if (next != NULL && next->Base() <= newEnd) {
|
if (next != NULL && next->Base() <= newEnd) {
|
||||||
if (next->id != RESERVED_AREA_ID
|
if (next->id != RESERVED_AREA_ID
|
||||||
|| next->cache_offset > area->Base()
|
|| next->cache_offset > area->Base()
|
||||||
@@ -256,7 +278,7 @@ VMKernelAddressSpace::ReserveAddressRange(void** _address, uint32 addressSpec,
|
|||||||
return B_BAD_TEAM_ID;
|
return B_BAD_TEAM_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
VMArea* area = VMArea::CreateReserved(this, flags);
|
VMKernelArea* area = VMKernelArea::CreateReserved(this, flags);
|
||||||
if (area == NULL)
|
if (area == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
@@ -286,8 +308,8 @@ VMKernelAddressSpace::UnreserveAddressRange(addr_t address, size_t size)
|
|||||||
|
|
||||||
// search area list and remove any matching reserved ranges
|
// search area list and remove any matching reserved ranges
|
||||||
addr_t endAddress = address + (size - 1);
|
addr_t endAddress = address + (size - 1);
|
||||||
for (VMAddressSpaceAreaList::Iterator it = fAreas.GetIterator();
|
for (VMKernelAreaList::Iterator it = fAreas.GetIterator();
|
||||||
VMArea* area = it.Next();) {
|
VMKernelArea* area = it.Next();) {
|
||||||
// the area must be completely part of the reserved range
|
// the area must be completely part of the reserved range
|
||||||
if (area->Base() + (area->Size() - 1) > endAddress)
|
if (area->Base() + (area->Size() - 1) > endAddress)
|
||||||
break;
|
break;
|
||||||
@@ -306,8 +328,8 @@ VMKernelAddressSpace::UnreserveAddressRange(addr_t address, size_t size)
|
|||||||
void
|
void
|
||||||
VMKernelAddressSpace::UnreserveAllAddressRanges()
|
VMKernelAddressSpace::UnreserveAllAddressRanges()
|
||||||
{
|
{
|
||||||
for (VMAddressSpaceAreaList::Iterator it = fAreas.GetIterator();
|
for (VMKernelAreaList::Iterator it = fAreas.GetIterator();
|
||||||
VMArea* area = it.Next();) {
|
VMKernelArea* area = it.Next();) {
|
||||||
if (area->id == RESERVED_AREA_ID) {
|
if (area->id == RESERVED_AREA_ID) {
|
||||||
RemoveArea(area);
|
RemoveArea(area);
|
||||||
Put();
|
Put();
|
||||||
@@ -325,8 +347,8 @@ VMKernelAddressSpace::Dump() const
|
|||||||
|
|
||||||
kprintf("area_list:\n");
|
kprintf("area_list:\n");
|
||||||
|
|
||||||
for (VMAddressSpaceAreaList::ConstIterator it = fAreas.GetIterator();
|
for (VMKernelAreaList::ConstIterator it = fAreas.GetIterator();
|
||||||
VMArea* area = it.Next();) {
|
VMKernelArea* area = it.Next();) {
|
||||||
kprintf(" area 0x%lx: ", area->id);
|
kprintf(" area 0x%lx: ", area->id);
|
||||||
kprintf("base_addr = 0x%lx ", area->Base());
|
kprintf("base_addr = 0x%lx ", area->Base());
|
||||||
kprintf("size = 0x%lx ", area->Size());
|
kprintf("size = 0x%lx ", area->Size());
|
||||||
@@ -342,11 +364,11 @@ VMKernelAddressSpace::Dump() const
|
|||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
VMKernelAddressSpace::_InsertAreaIntoReservedRegion(addr_t start, size_t size,
|
VMKernelAddressSpace::_InsertAreaIntoReservedRegion(addr_t start, size_t size,
|
||||||
VMArea* area)
|
VMKernelArea* area)
|
||||||
{
|
{
|
||||||
VMArea* next;
|
VMKernelArea* next;
|
||||||
|
|
||||||
for (VMAddressSpaceAreaList::Iterator it = fAreas.GetIterator();
|
for (VMKernelAreaList::Iterator it = fAreas.GetIterator();
|
||||||
(next = it.Next()) != NULL;) {
|
(next = it.Next()) != NULL;) {
|
||||||
if (next->Base() <= start
|
if (next->Base() <= start
|
||||||
&& next->Base() + (next->Size() - 1) >= start + (size - 1)) {
|
&& next->Base() + (next->Size() - 1) >= start + (size - 1)) {
|
||||||
@@ -390,7 +412,8 @@ VMKernelAddressSpace::_InsertAreaIntoReservedRegion(addr_t start, size_t size,
|
|||||||
} else {
|
} else {
|
||||||
// the area splits the reserved range into two separate ones
|
// the area splits the reserved range into two separate ones
|
||||||
// we need a new reserved area to cover this space
|
// we need a new reserved area to cover this space
|
||||||
VMArea* reserved = VMArea::CreateReserved(this, next->protection);
|
VMKernelArea* reserved = VMKernelArea::CreateReserved(this,
|
||||||
|
next->protection);
|
||||||
if (reserved == NULL)
|
if (reserved == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
@@ -416,10 +439,10 @@ VMKernelAddressSpace::_InsertAreaIntoReservedRegion(addr_t start, size_t size,
|
|||||||
/*! Must be called with this address space's write lock held */
|
/*! Must be called with this address space's write lock held */
|
||||||
status_t
|
status_t
|
||||||
VMKernelAddressSpace::_InsertAreaSlot(addr_t start, addr_t size, addr_t end,
|
VMKernelAddressSpace::_InsertAreaSlot(addr_t start, addr_t size, addr_t end,
|
||||||
uint32 addressSpec, VMArea* area)
|
uint32 addressSpec, VMKernelArea* area)
|
||||||
{
|
{
|
||||||
VMArea* last = NULL;
|
VMKernelArea* last = NULL;
|
||||||
VMArea* next;
|
VMKernelArea* next;
|
||||||
bool foundSpot = false;
|
bool foundSpot = false;
|
||||||
|
|
||||||
TRACE(("VMKernelAddressSpace::_InsertAreaSlot: address space %p, start "
|
TRACE(("VMKernelAddressSpace::_InsertAreaSlot: address space %p, start "
|
||||||
@@ -453,7 +476,7 @@ VMKernelAddressSpace::_InsertAreaSlot(addr_t start, addr_t size, addr_t end,
|
|||||||
|
|
||||||
// walk up to the spot where we should start searching
|
// walk up to the spot where we should start searching
|
||||||
second_chance:
|
second_chance:
|
||||||
VMAddressSpaceAreaList::Iterator it = fAreas.GetIterator();
|
VMKernelAreaList::Iterator it = fAreas.GetIterator();
|
||||||
while ((next = it.Next()) != NULL) {
|
while ((next = it.Next()) != NULL) {
|
||||||
if (next->Base() > start + (size - 1)) {
|
if (next->Base() > start + (size - 1)) {
|
||||||
// we have a winner
|
// we have a winner
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
#include <vm/VMAddressSpace.h>
|
#include <vm/VMAddressSpace.h>
|
||||||
|
|
||||||
|
#include "VMKernelArea.h"
|
||||||
|
|
||||||
|
|
||||||
struct VMKernelAddressSpace : VMAddressSpace {
|
struct VMKernelAddressSpace : VMAddressSpace {
|
||||||
public:
|
public:
|
||||||
@@ -23,6 +25,9 @@ public:
|
|||||||
virtual VMArea* NextArea(VMArea* area) const;
|
virtual VMArea* NextArea(VMArea* area) const;
|
||||||
|
|
||||||
virtual VMArea* LookupArea(addr_t address) const;
|
virtual VMArea* LookupArea(addr_t address) const;
|
||||||
|
virtual VMArea* CreateArea(const char* name, uint32 wiring,
|
||||||
|
uint32 protection);
|
||||||
|
virtual void DeleteArea(VMArea* area);
|
||||||
virtual status_t InsertArea(void** _address, uint32 addressSpec,
|
virtual status_t InsertArea(void** _address, uint32 addressSpec,
|
||||||
addr_t size, VMArea* area);
|
addr_t size, VMArea* area);
|
||||||
virtual void RemoveArea(VMArea* area);
|
virtual void RemoveArea(VMArea* area);
|
||||||
@@ -43,13 +48,13 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
status_t _InsertAreaIntoReservedRegion(addr_t start,
|
status_t _InsertAreaIntoReservedRegion(addr_t start,
|
||||||
size_t size, VMArea* area);
|
size_t size, VMKernelArea* area);
|
||||||
status_t _InsertAreaSlot(addr_t start, addr_t size,
|
status_t _InsertAreaSlot(addr_t start, addr_t size,
|
||||||
addr_t end, uint32 addressSpec,
|
addr_t end, uint32 addressSpec,
|
||||||
VMArea* area);
|
VMKernelArea* area);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VMAddressSpaceAreaList fAreas;
|
VMKernelAreaList fAreas;
|
||||||
mutable VMArea* fAreaHint;
|
mutable VMArea* fAreaHint;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the NewOS License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "VMKernelArea.h"
|
||||||
|
|
||||||
|
#include <heap.h>
|
||||||
|
#include <vm/vm_priv.h>
|
||||||
|
|
||||||
|
|
||||||
|
VMKernelArea::VMKernelArea(VMAddressSpace* addressSpace, uint32 wiring,
|
||||||
|
uint32 protection)
|
||||||
|
:
|
||||||
|
VMArea(addressSpace, wiring, protection)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VMKernelArea::~VMKernelArea()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ VMKernelArea*
|
||||||
|
VMKernelArea::Create(VMAddressSpace* addressSpace, const char* name,
|
||||||
|
uint32 wiring, uint32 protection)
|
||||||
|
{
|
||||||
|
VMKernelArea* area = new(nogrow) VMKernelArea(addressSpace, wiring,
|
||||||
|
protection);
|
||||||
|
if (area == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (area->Init(name) != B_OK) {
|
||||||
|
delete area;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return area;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ VMKernelArea*
|
||||||
|
VMKernelArea::CreateReserved(VMAddressSpace* addressSpace, uint32 flags)
|
||||||
|
{
|
||||||
|
VMKernelArea* area = new(nogrow) VMKernelArea(addressSpace, 0, 0);
|
||||||
|
if (area != NULL)
|
||||||
|
area->id = RESERVED_AREA_ID;
|
||||||
|
return area;
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
|
* Distributed under the terms of the NewOS License.
|
||||||
|
*/
|
||||||
|
#ifndef VM_KERNEL_AREA_H
|
||||||
|
#define VM_KERNEL_AREA_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <vm/VMArea.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct VMKernelAddressSpace;
|
||||||
|
|
||||||
|
|
||||||
|
struct VMKernelArea : VMArea {
|
||||||
|
VMKernelArea(VMAddressSpace* addressSpace,
|
||||||
|
uint32 wiring, uint32 protection);
|
||||||
|
~VMKernelArea();
|
||||||
|
|
||||||
|
static VMKernelArea* Create(VMAddressSpace* addressSpace,
|
||||||
|
const char* name, uint32 wiring,
|
||||||
|
uint32 protection);
|
||||||
|
static VMKernelArea* CreateReserved(VMAddressSpace* addressSpace,
|
||||||
|
uint32 flags);
|
||||||
|
|
||||||
|
DoublyLinkedListLink<VMKernelArea>& AddressSpaceLink()
|
||||||
|
{ return fAddressSpaceLink; }
|
||||||
|
const DoublyLinkedListLink<VMKernelArea>& AddressSpaceLink() const
|
||||||
|
{ return fAddressSpaceLink; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
DoublyLinkedListLink<VMKernelArea> fAddressSpaceLink;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct VMKernelAreaGetLink {
|
||||||
|
inline DoublyLinkedListLink<VMKernelArea>* operator()(
|
||||||
|
VMKernelArea* area) const
|
||||||
|
{
|
||||||
|
return &area->AddressSpaceLink();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const DoublyLinkedListLink<VMKernelArea>* operator()(
|
||||||
|
const VMKernelArea* area) const
|
||||||
|
{
|
||||||
|
return &area->AddressSpaceLink();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef DoublyLinkedList<VMKernelArea, VMKernelAreaGetLink> VMKernelAreaList;
|
||||||
|
|
||||||
|
|
||||||
|
#endif // VM_KERNEL_AREA_H
|
||||||
@@ -56,7 +56,7 @@ VMUserAddressSpace::~VMUserAddressSpace()
|
|||||||
inline VMArea*
|
inline VMArea*
|
||||||
VMUserAddressSpace::FirstArea() const
|
VMUserAddressSpace::FirstArea() const
|
||||||
{
|
{
|
||||||
VMArea* area = fAreas.Head();
|
VMUserArea* area = fAreas.Head();
|
||||||
while (area != NULL && area->id == RESERVED_AREA_ID)
|
while (area != NULL && area->id == RESERVED_AREA_ID)
|
||||||
area = fAreas.GetNext(area);
|
area = fAreas.GetNext(area);
|
||||||
return area;
|
return area;
|
||||||
@@ -64,8 +64,9 @@ VMUserAddressSpace::FirstArea() const
|
|||||||
|
|
||||||
|
|
||||||
inline VMArea*
|
inline VMArea*
|
||||||
VMUserAddressSpace::NextArea(VMArea* area) const
|
VMUserAddressSpace::NextArea(VMArea* _area) const
|
||||||
{
|
{
|
||||||
|
VMUserArea* area = static_cast<VMUserArea*>(_area);
|
||||||
area = fAreas.GetNext(area);
|
area = fAreas.GetNext(area);
|
||||||
while (area != NULL && area->id == RESERVED_AREA_ID)
|
while (area != NULL && area->id == RESERVED_AREA_ID)
|
||||||
area = fAreas.GetNext(area);
|
area = fAreas.GetNext(area);
|
||||||
@@ -73,6 +74,21 @@ VMUserAddressSpace::NextArea(VMArea* area) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VMArea*
|
||||||
|
VMUserAddressSpace::CreateArea(const char* name, uint32 wiring,
|
||||||
|
uint32 protection)
|
||||||
|
{
|
||||||
|
return VMUserArea::Create(this, name, wiring, protection);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
VMUserAddressSpace::DeleteArea(VMArea* area)
|
||||||
|
{
|
||||||
|
delete static_cast<VMUserArea*>(area);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//! You must hold the address space's read lock.
|
//! You must hold the address space's read lock.
|
||||||
VMArea*
|
VMArea*
|
||||||
VMUserAddressSpace::LookupArea(addr_t address) const
|
VMUserAddressSpace::LookupArea(addr_t address) const
|
||||||
@@ -81,8 +97,8 @@ VMUserAddressSpace::LookupArea(addr_t address) const
|
|||||||
if (fAreaHint != NULL && fAreaHint->ContainsAddress(address))
|
if (fAreaHint != NULL && fAreaHint->ContainsAddress(address))
|
||||||
return fAreaHint;
|
return fAreaHint;
|
||||||
|
|
||||||
for (VMAddressSpaceAreaList::ConstIterator it = fAreas.GetIterator();
|
for (VMUserAreaList::ConstIterator it = fAreas.GetIterator();
|
||||||
VMArea* area = it.Next();) {
|
VMUserArea* area = it.Next();) {
|
||||||
if (area->id == RESERVED_AREA_ID)
|
if (area->id == RESERVED_AREA_ID)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -103,8 +119,10 @@ VMUserAddressSpace::LookupArea(addr_t address) const
|
|||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
VMUserAddressSpace::InsertArea(void** _address, uint32 addressSpec,
|
VMUserAddressSpace::InsertArea(void** _address, uint32 addressSpec,
|
||||||
addr_t size, VMArea* area)
|
addr_t size, VMArea* _area)
|
||||||
{
|
{
|
||||||
|
VMUserArea* area = static_cast<VMUserArea*>(_area);
|
||||||
|
|
||||||
addr_t searchBase, searchEnd;
|
addr_t searchBase, searchEnd;
|
||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
@@ -146,8 +164,10 @@ VMUserAddressSpace::InsertArea(void** _address, uint32 addressSpec,
|
|||||||
|
|
||||||
//! You must hold the address space's write lock.
|
//! You must hold the address space's write lock.
|
||||||
void
|
void
|
||||||
VMUserAddressSpace::RemoveArea(VMArea* area)
|
VMUserAddressSpace::RemoveArea(VMArea* _area)
|
||||||
{
|
{
|
||||||
|
VMUserArea* area = static_cast<VMUserArea*>(_area);
|
||||||
|
|
||||||
fAreas.Remove(area);
|
fAreas.Remove(area);
|
||||||
|
|
||||||
if (area->id != RESERVED_AREA_ID) {
|
if (area->id != RESERVED_AREA_ID) {
|
||||||
@@ -163,7 +183,7 @@ VMUserAddressSpace::RemoveArea(VMArea* area)
|
|||||||
bool
|
bool
|
||||||
VMUserAddressSpace::CanResizeArea(VMArea* area, size_t newSize)
|
VMUserAddressSpace::CanResizeArea(VMArea* area, size_t newSize)
|
||||||
{
|
{
|
||||||
VMArea* next = fAreas.GetNext(area);
|
VMUserArea* next = fAreas.GetNext(static_cast<VMUserArea*>(area));
|
||||||
addr_t newEnd = area->Base() + (newSize - 1);
|
addr_t newEnd = area->Base() + (newSize - 1);
|
||||||
if (next == NULL) {
|
if (next == NULL) {
|
||||||
if (fEndAddress >= newEnd)
|
if (fEndAddress >= newEnd)
|
||||||
@@ -187,10 +207,12 @@ VMUserAddressSpace::CanResizeArea(VMArea* area, size_t newSize)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
VMUserAddressSpace::ResizeArea(VMArea* area, size_t newSize)
|
VMUserAddressSpace::ResizeArea(VMArea* _area, size_t newSize)
|
||||||
{
|
{
|
||||||
|
VMUserArea* area = static_cast<VMUserArea*>(_area);
|
||||||
|
|
||||||
addr_t newEnd = area->Base() + (newSize - 1);
|
addr_t newEnd = area->Base() + (newSize - 1);
|
||||||
VMArea* next = fAreas.GetNext(area);
|
VMUserArea* next = fAreas.GetNext(area);
|
||||||
if (next != NULL && next->Base() <= newEnd) {
|
if (next != NULL && next->Base() <= newEnd) {
|
||||||
if (next->id != RESERVED_AREA_ID
|
if (next->id != RESERVED_AREA_ID
|
||||||
|| next->cache_offset > area->Base()
|
|| next->cache_offset > area->Base()
|
||||||
@@ -256,7 +278,7 @@ VMUserAddressSpace::ReserveAddressRange(void** _address, uint32 addressSpec,
|
|||||||
return B_BAD_TEAM_ID;
|
return B_BAD_TEAM_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
VMArea* area = VMArea::CreateReserved(this, flags);
|
VMUserArea* area = VMUserArea::CreateReserved(this, flags);
|
||||||
if (area == NULL)
|
if (area == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
@@ -286,8 +308,8 @@ VMUserAddressSpace::UnreserveAddressRange(addr_t address, size_t size)
|
|||||||
|
|
||||||
// search area list and remove any matching reserved ranges
|
// search area list and remove any matching reserved ranges
|
||||||
addr_t endAddress = address + (size - 1);
|
addr_t endAddress = address + (size - 1);
|
||||||
for (VMAddressSpaceAreaList::Iterator it = fAreas.GetIterator();
|
for (VMUserAreaList::Iterator it = fAreas.GetIterator();
|
||||||
VMArea* area = it.Next();) {
|
VMUserArea* area = it.Next();) {
|
||||||
// the area must be completely part of the reserved range
|
// the area must be completely part of the reserved range
|
||||||
if (area->Base() + (area->Size() - 1) > endAddress)
|
if (area->Base() + (area->Size() - 1) > endAddress)
|
||||||
break;
|
break;
|
||||||
@@ -306,8 +328,8 @@ VMUserAddressSpace::UnreserveAddressRange(addr_t address, size_t size)
|
|||||||
void
|
void
|
||||||
VMUserAddressSpace::UnreserveAllAddressRanges()
|
VMUserAddressSpace::UnreserveAllAddressRanges()
|
||||||
{
|
{
|
||||||
for (VMAddressSpaceAreaList::Iterator it = fAreas.GetIterator();
|
for (VMUserAreaList::Iterator it = fAreas.GetIterator();
|
||||||
VMArea* area = it.Next();) {
|
VMUserArea* area = it.Next();) {
|
||||||
if (area->id == RESERVED_AREA_ID) {
|
if (area->id == RESERVED_AREA_ID) {
|
||||||
RemoveArea(area);
|
RemoveArea(area);
|
||||||
Put();
|
Put();
|
||||||
@@ -325,8 +347,8 @@ VMUserAddressSpace::Dump() const
|
|||||||
|
|
||||||
kprintf("area_list:\n");
|
kprintf("area_list:\n");
|
||||||
|
|
||||||
for (VMAddressSpaceAreaList::ConstIterator it = fAreas.GetIterator();
|
for (VMUserAreaList::ConstIterator it = fAreas.GetIterator();
|
||||||
VMArea* area = it.Next();) {
|
VMUserArea* area = it.Next();) {
|
||||||
kprintf(" area 0x%lx: ", area->id);
|
kprintf(" area 0x%lx: ", area->id);
|
||||||
kprintf("base_addr = 0x%lx ", area->Base());
|
kprintf("base_addr = 0x%lx ", area->Base());
|
||||||
kprintf("size = 0x%lx ", area->Size());
|
kprintf("size = 0x%lx ", area->Size());
|
||||||
@@ -342,11 +364,11 @@ VMUserAddressSpace::Dump() const
|
|||||||
*/
|
*/
|
||||||
status_t
|
status_t
|
||||||
VMUserAddressSpace::_InsertAreaIntoReservedRegion(addr_t start, size_t size,
|
VMUserAddressSpace::_InsertAreaIntoReservedRegion(addr_t start, size_t size,
|
||||||
VMArea* area)
|
VMUserArea* area)
|
||||||
{
|
{
|
||||||
VMArea* next;
|
VMUserArea* next;
|
||||||
|
|
||||||
for (VMAddressSpaceAreaList::Iterator it = fAreas.GetIterator();
|
for (VMUserAreaList::Iterator it = fAreas.GetIterator();
|
||||||
(next = it.Next()) != NULL;) {
|
(next = it.Next()) != NULL;) {
|
||||||
if (next->Base() <= start
|
if (next->Base() <= start
|
||||||
&& next->Base() + (next->Size() - 1) >= start + (size - 1)) {
|
&& next->Base() + (next->Size() - 1) >= start + (size - 1)) {
|
||||||
@@ -390,7 +412,8 @@ VMUserAddressSpace::_InsertAreaIntoReservedRegion(addr_t start, size_t size,
|
|||||||
} else {
|
} else {
|
||||||
// the area splits the reserved range into two separate ones
|
// the area splits the reserved range into two separate ones
|
||||||
// we need a new reserved area to cover this space
|
// we need a new reserved area to cover this space
|
||||||
VMArea* reserved = VMArea::CreateReserved(this, next->protection);
|
VMUserArea* reserved = VMUserArea::CreateReserved(this,
|
||||||
|
next->protection);
|
||||||
if (reserved == NULL)
|
if (reserved == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
@@ -416,10 +439,10 @@ VMUserAddressSpace::_InsertAreaIntoReservedRegion(addr_t start, size_t size,
|
|||||||
/*! Must be called with this address space's write lock held */
|
/*! Must be called with this address space's write lock held */
|
||||||
status_t
|
status_t
|
||||||
VMUserAddressSpace::_InsertAreaSlot(addr_t start, addr_t size, addr_t end,
|
VMUserAddressSpace::_InsertAreaSlot(addr_t start, addr_t size, addr_t end,
|
||||||
uint32 addressSpec, VMArea* area)
|
uint32 addressSpec, VMUserArea* area)
|
||||||
{
|
{
|
||||||
VMArea* last = NULL;
|
VMUserArea* last = NULL;
|
||||||
VMArea* next;
|
VMUserArea* next;
|
||||||
bool foundSpot = false;
|
bool foundSpot = false;
|
||||||
|
|
||||||
TRACE(("VMUserAddressSpace::_InsertAreaSlot: address space %p, start "
|
TRACE(("VMUserAddressSpace::_InsertAreaSlot: address space %p, start "
|
||||||
@@ -453,7 +476,7 @@ VMUserAddressSpace::_InsertAreaSlot(addr_t start, addr_t size, addr_t end,
|
|||||||
|
|
||||||
// walk up to the spot where we should start searching
|
// walk up to the spot where we should start searching
|
||||||
second_chance:
|
second_chance:
|
||||||
VMAddressSpaceAreaList::Iterator it = fAreas.GetIterator();
|
VMUserAreaList::Iterator it = fAreas.GetIterator();
|
||||||
while ((next = it.Next()) != NULL) {
|
while ((next = it.Next()) != NULL) {
|
||||||
if (next->Base() > start + (size - 1)) {
|
if (next->Base() > start + (size - 1)) {
|
||||||
// we have a winner
|
// we have a winner
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
#include <vm/VMAddressSpace.h>
|
#include <vm/VMAddressSpace.h>
|
||||||
|
|
||||||
|
#include "VMUserArea.h"
|
||||||
|
|
||||||
|
|
||||||
struct VMUserAddressSpace : VMAddressSpace {
|
struct VMUserAddressSpace : VMAddressSpace {
|
||||||
public:
|
public:
|
||||||
@@ -23,6 +25,9 @@ public:
|
|||||||
virtual VMArea* NextArea(VMArea* area) const;
|
virtual VMArea* NextArea(VMArea* area) const;
|
||||||
|
|
||||||
virtual VMArea* LookupArea(addr_t address) const;
|
virtual VMArea* LookupArea(addr_t address) const;
|
||||||
|
virtual VMArea* CreateArea(const char* name, uint32 wiring,
|
||||||
|
uint32 protection);
|
||||||
|
virtual void DeleteArea(VMArea* area);
|
||||||
virtual status_t InsertArea(void** _address, uint32 addressSpec,
|
virtual status_t InsertArea(void** _address, uint32 addressSpec,
|
||||||
addr_t size, VMArea* area);
|
addr_t size, VMArea* area);
|
||||||
virtual void RemoveArea(VMArea* area);
|
virtual void RemoveArea(VMArea* area);
|
||||||
@@ -43,13 +48,13 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
status_t _InsertAreaIntoReservedRegion(addr_t start,
|
status_t _InsertAreaIntoReservedRegion(addr_t start,
|
||||||
size_t size, VMArea* area);
|
size_t size, VMUserArea* area);
|
||||||
status_t _InsertAreaSlot(addr_t start, addr_t size,
|
status_t _InsertAreaSlot(addr_t start, addr_t size,
|
||||||
addr_t end, uint32 addressSpec,
|
addr_t end, uint32 addressSpec,
|
||||||
VMArea* area);
|
VMUserArea* area);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VMAddressSpaceAreaList fAreas;
|
VMUserAreaList fAreas;
|
||||||
mutable VMArea* fAreaHint;
|
mutable VMArea* fAreaHint;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
|
* Distributed under the terms of the NewOS License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include "VMUserArea.h"
|
||||||
|
|
||||||
|
#include <heap.h>
|
||||||
|
#include <vm/vm_priv.h>
|
||||||
|
|
||||||
|
|
||||||
|
VMUserArea::VMUserArea(VMAddressSpace* addressSpace, uint32 wiring,
|
||||||
|
uint32 protection)
|
||||||
|
:
|
||||||
|
VMArea(addressSpace, wiring, protection)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
VMUserArea::~VMUserArea()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ VMUserArea*
|
||||||
|
VMUserArea::Create(VMAddressSpace* addressSpace, const char* name,
|
||||||
|
uint32 wiring, uint32 protection)
|
||||||
|
{
|
||||||
|
VMUserArea* area = new(nogrow) VMUserArea(addressSpace, wiring,
|
||||||
|
protection);
|
||||||
|
if (area == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (area->Init(name) != B_OK) {
|
||||||
|
delete area;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return area;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*static*/ VMUserArea*
|
||||||
|
VMUserArea::CreateReserved(VMAddressSpace* addressSpace, uint32 flags)
|
||||||
|
{
|
||||||
|
VMUserArea* area = new(nogrow) VMUserArea(addressSpace, 0, 0);
|
||||||
|
if (area != NULL)
|
||||||
|
area->id = RESERVED_AREA_ID;
|
||||||
|
return area;
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
|
* Distributed under the terms of the NewOS License.
|
||||||
|
*/
|
||||||
|
#ifndef VM_USER_AREA_H
|
||||||
|
#define VM_USER_AREA_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <vm/VMArea.h>
|
||||||
|
|
||||||
|
|
||||||
|
struct VMUserAddressSpace;
|
||||||
|
|
||||||
|
|
||||||
|
struct VMUserArea : VMArea {
|
||||||
|
VMUserArea(VMAddressSpace* addressSpace,
|
||||||
|
uint32 wiring, uint32 protection);
|
||||||
|
~VMUserArea();
|
||||||
|
|
||||||
|
static VMUserArea* Create(VMAddressSpace* addressSpace,
|
||||||
|
const char* name, uint32 wiring,
|
||||||
|
uint32 protection);
|
||||||
|
static VMUserArea* CreateReserved(VMAddressSpace* addressSpace,
|
||||||
|
uint32 flags);
|
||||||
|
|
||||||
|
DoublyLinkedListLink<VMUserArea>& AddressSpaceLink()
|
||||||
|
{ return fAddressSpaceLink; }
|
||||||
|
const DoublyLinkedListLink<VMUserArea>& AddressSpaceLink() const
|
||||||
|
{ return fAddressSpaceLink; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
DoublyLinkedListLink<VMUserArea> fAddressSpaceLink;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct VMUserAreaGetLink {
|
||||||
|
inline DoublyLinkedListLink<VMUserArea>* operator()(
|
||||||
|
VMUserArea* area) const
|
||||||
|
{
|
||||||
|
return &area->AddressSpaceLink();
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const DoublyLinkedListLink<VMUserArea>* operator()(
|
||||||
|
const VMUserArea* area) const
|
||||||
|
{
|
||||||
|
return &area->AddressSpaceLink();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef DoublyLinkedList<VMUserArea, VMUserAreaGetLink> VMUserAreaList;
|
||||||
|
|
||||||
|
|
||||||
|
#endif // VM_USER_AREA_H
|
||||||
@@ -503,7 +503,7 @@ map_backing_store(VMAddressSpace* addressSpace, VMCache* cache,
|
|||||||
addressSpec, wiring, protection, _area, areaName));
|
addressSpec, wiring, protection, _area, areaName));
|
||||||
cache->AssertLocked();
|
cache->AssertLocked();
|
||||||
|
|
||||||
VMArea* area = VMArea::Create(addressSpace, areaName, wiring, protection);
|
VMArea* area = addressSpace->CreateArea(areaName, wiring, protection);
|
||||||
if (area == NULL)
|
if (area == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
@@ -594,8 +594,7 @@ err2:
|
|||||||
sourceCache->Lock();
|
sourceCache->Lock();
|
||||||
}
|
}
|
||||||
err1:
|
err1:
|
||||||
free(area->name);
|
addressSpace->DeleteArea(area);
|
||||||
free(area);
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1584,9 +1583,7 @@ delete_area(VMAddressSpace* addressSpace, VMArea* area)
|
|||||||
area->cache->RemoveArea(area);
|
area->cache->RemoveArea(area);
|
||||||
area->cache->ReleaseRef();
|
area->cache->ReleaseRef();
|
||||||
|
|
||||||
free(area->page_protections);
|
addressSpace->DeleteArea(area);
|
||||||
free(area->name);
|
|
||||||
free(area);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user