* 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:
Ingo Weinhold
2009-12-04 17:07:16 +00:00
parent e2518ddbb1
commit 2c1886aeae
13 changed files with 369 additions and 141 deletions
@@ -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;
+8 -30
View File
@@ -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;
+2
View File
@@ -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)
; ;
+35 -51
View File
@@ -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;
+47 -24
View File
@@ -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
+8 -3
View File
@@ -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;
}; };
+51
View File
@@ -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;
}
+53
View File
@@ -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
+47 -24
View File
@@ -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
+8 -3
View File
@@ -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;
}; };
+51
View File
@@ -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;
}
+53
View File
@@ -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
+3 -6
View File
@@ -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);
} }