* 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* 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,
addr_t size, VMArea* area) = 0;
virtual void RemoveArea(VMArea* area) = 0;
+8 -30
View File
@@ -48,50 +48,28 @@ struct VMArea {
{ return address >= fBase
&& address <= fBase + (fSize - 1); }
static VMArea* Create(VMAddressSpace* addressSpace,
const char* name, uint32 wiring,
uint32 protection);
static VMArea* CreateReserved(VMAddressSpace* addressSpace,
uint32 flags);
protected:
VMArea(VMAddressSpace* addressSpace,
uint32 wiring, uint32 protection);
~VMArea();
DoublyLinkedListLink<VMArea>& AddressSpaceLink()
{ return fAddressSpaceLink; }
const DoublyLinkedListLink<VMArea>& AddressSpaceLink() const
{ return fAddressSpaceLink; }
status_t Init(const char* name);
private:
protected:
friend class VMAddressSpace;
friend class VMKernelAddressSpace;
friend class VMUserAddressSpace;
private:
protected:
void SetBase(addr_t base) { fBase = base; }
void SetSize(size_t size) { fSize = size; }
private:
DoublyLinkedListLink<VMArea> fAddressSpaceLink;
protected:
addr_t fBase;
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 {
typedef area_id KeyType;
typedef VMArea ValueType;
+2
View File
@@ -16,8 +16,10 @@ KernelMergeObject kernel_vm.o :
VMCache.cpp
VMDeviceCache.cpp
VMKernelAddressSpace.cpp
VMKernelArea.cpp
VMNullCache.cpp
VMUserAddressSpace.cpp
VMUserArea.cpp
: $(TARGET_KERNEL_PIC_CCFLAGS)
;
+35 -51
View File
@@ -11,7 +11,6 @@
#include <vm/VMArea.h>
#include <heap.h>
#include <vm/vm_priv.h>
#define AREA_HASH_TABLE_SIZE 1024
@@ -24,61 +23,49 @@ static area_id sNextAreaID = 1;
// #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,
uint32 wiring, uint32 protection)
VMArea::~VMArea()
{
free(page_protections);
free(name);
}
status_t
VMArea::Init(const char* name)
{
// restrict the area name to B_OS_NAME_LENGTH
size_t length = strlen(name) + 1;
if (length > B_OS_NAME_LENGTH)
length = B_OS_NAME_LENGTH;
VMArea* area = (VMArea*)malloc_nogrow(sizeof(VMArea));
if (area == NULL)
return NULL;
// clone the name
this->name = (char*)malloc_nogrow(length);
if (this->name == NULL)
return B_NO_MEMORY;
strlcpy(this->name, name, length);
area->name = (char*)malloc_nogrow(length);
if (area->name == NULL) {
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;
id = atomic_add(&sNextAreaID, 1);
return B_OK;
}
@@ -114,9 +101,6 @@ VMAreaHash::Find(const char* name)
for (VMAreaHashTable::Iterator it = sTable.GetIterator();
VMArea* area = it.Next();) {
if (area->id == RESERVED_AREA_ID)
continue;
if (strcmp(area->name, name) == 0) {
id = area->id;
break;
+47 -24
View File
@@ -56,7 +56,7 @@ VMKernelAddressSpace::~VMKernelAddressSpace()
inline VMArea*
VMKernelAddressSpace::FirstArea() const
{
VMArea* area = fAreas.Head();
VMKernelArea* area = fAreas.Head();
while (area != NULL && area->id == RESERVED_AREA_ID)
area = fAreas.GetNext(area);
return area;
@@ -64,8 +64,9 @@ VMKernelAddressSpace::FirstArea() const
inline VMArea*
VMKernelAddressSpace::NextArea(VMArea* area) const
VMKernelAddressSpace::NextArea(VMArea* _area) const
{
VMKernelArea* area = static_cast<VMKernelArea*>(_area);
area = fAreas.GetNext(area);
while (area != NULL && area->id == RESERVED_AREA_ID)
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.
VMArea*
VMKernelAddressSpace::LookupArea(addr_t address) const
@@ -81,8 +97,8 @@ VMKernelAddressSpace::LookupArea(addr_t address) const
if (fAreaHint != NULL && fAreaHint->ContainsAddress(address))
return fAreaHint;
for (VMAddressSpaceAreaList::ConstIterator it = fAreas.GetIterator();
VMArea* area = it.Next();) {
for (VMKernelAreaList::ConstIterator it = fAreas.GetIterator();
VMKernelArea* area = it.Next();) {
if (area->id == RESERVED_AREA_ID)
continue;
@@ -103,8 +119,10 @@ VMKernelAddressSpace::LookupArea(addr_t address) const
*/
status_t
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;
status_t status;
@@ -146,8 +164,10 @@ VMKernelAddressSpace::InsertArea(void** _address, uint32 addressSpec,
//! You must hold the address space's write lock.
void
VMKernelAddressSpace::RemoveArea(VMArea* area)
VMKernelAddressSpace::RemoveArea(VMArea* _area)
{
VMKernelArea* area = static_cast<VMKernelArea*>(_area);
fAreas.Remove(area);
if (area->id != RESERVED_AREA_ID) {
@@ -163,7 +183,7 @@ VMKernelAddressSpace::RemoveArea(VMArea* area)
bool
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);
if (next == NULL) {
if (fEndAddress >= newEnd)
@@ -187,10 +207,12 @@ VMKernelAddressSpace::CanResizeArea(VMArea* area, size_t newSize)
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);
VMArea* next = fAreas.GetNext(area);
VMKernelArea* next = fAreas.GetNext(area);
if (next != NULL && next->Base() <= newEnd) {
if (next->id != RESERVED_AREA_ID
|| next->cache_offset > area->Base()
@@ -256,7 +278,7 @@ VMKernelAddressSpace::ReserveAddressRange(void** _address, uint32 addressSpec,
return B_BAD_TEAM_ID;
}
VMArea* area = VMArea::CreateReserved(this, flags);
VMKernelArea* area = VMKernelArea::CreateReserved(this, flags);
if (area == NULL)
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
addr_t endAddress = address + (size - 1);
for (VMAddressSpaceAreaList::Iterator it = fAreas.GetIterator();
VMArea* area = it.Next();) {
for (VMKernelAreaList::Iterator it = fAreas.GetIterator();
VMKernelArea* area = it.Next();) {
// the area must be completely part of the reserved range
if (area->Base() + (area->Size() - 1) > endAddress)
break;
@@ -306,8 +328,8 @@ VMKernelAddressSpace::UnreserveAddressRange(addr_t address, size_t size)
void
VMKernelAddressSpace::UnreserveAllAddressRanges()
{
for (VMAddressSpaceAreaList::Iterator it = fAreas.GetIterator();
VMArea* area = it.Next();) {
for (VMKernelAreaList::Iterator it = fAreas.GetIterator();
VMKernelArea* area = it.Next();) {
if (area->id == RESERVED_AREA_ID) {
RemoveArea(area);
Put();
@@ -325,8 +347,8 @@ VMKernelAddressSpace::Dump() const
kprintf("area_list:\n");
for (VMAddressSpaceAreaList::ConstIterator it = fAreas.GetIterator();
VMArea* area = it.Next();) {
for (VMKernelAreaList::ConstIterator it = fAreas.GetIterator();
VMKernelArea* area = it.Next();) {
kprintf(" area 0x%lx: ", area->id);
kprintf("base_addr = 0x%lx ", area->Base());
kprintf("size = 0x%lx ", area->Size());
@@ -342,11 +364,11 @@ VMKernelAddressSpace::Dump() const
*/
status_t
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;) {
if (next->Base() <= start
&& next->Base() + (next->Size() - 1) >= start + (size - 1)) {
@@ -390,7 +412,8 @@ VMKernelAddressSpace::_InsertAreaIntoReservedRegion(addr_t start, size_t size,
} else {
// the area splits the reserved range into two separate ones
// 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)
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 */
status_t
VMKernelAddressSpace::_InsertAreaSlot(addr_t start, addr_t size, addr_t end,
uint32 addressSpec, VMArea* area)
uint32 addressSpec, VMKernelArea* area)
{
VMArea* last = NULL;
VMArea* next;
VMKernelArea* last = NULL;
VMKernelArea* next;
bool foundSpot = false;
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
second_chance:
VMAddressSpaceAreaList::Iterator it = fAreas.GetIterator();
VMKernelAreaList::Iterator it = fAreas.GetIterator();
while ((next = it.Next()) != NULL) {
if (next->Base() > start + (size - 1)) {
// we have a winner
+8 -3
View File
@@ -12,6 +12,8 @@
#include <vm/VMAddressSpace.h>
#include "VMKernelArea.h"
struct VMKernelAddressSpace : VMAddressSpace {
public:
@@ -23,6 +25,9 @@ public:
virtual VMArea* NextArea(VMArea* area) 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,
addr_t size, VMArea* area);
virtual void RemoveArea(VMArea* area);
@@ -43,13 +48,13 @@ public:
private:
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,
addr_t end, uint32 addressSpec,
VMArea* area);
VMKernelArea* area);
private:
VMAddressSpaceAreaList fAreas;
VMKernelAreaList fAreas;
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*
VMUserAddressSpace::FirstArea() const
{
VMArea* area = fAreas.Head();
VMUserArea* area = fAreas.Head();
while (area != NULL && area->id == RESERVED_AREA_ID)
area = fAreas.GetNext(area);
return area;
@@ -64,8 +64,9 @@ VMUserAddressSpace::FirstArea() const
inline VMArea*
VMUserAddressSpace::NextArea(VMArea* area) const
VMUserAddressSpace::NextArea(VMArea* _area) const
{
VMUserArea* area = static_cast<VMUserArea*>(_area);
area = fAreas.GetNext(area);
while (area != NULL && area->id == RESERVED_AREA_ID)
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.
VMArea*
VMUserAddressSpace::LookupArea(addr_t address) const
@@ -81,8 +97,8 @@ VMUserAddressSpace::LookupArea(addr_t address) const
if (fAreaHint != NULL && fAreaHint->ContainsAddress(address))
return fAreaHint;
for (VMAddressSpaceAreaList::ConstIterator it = fAreas.GetIterator();
VMArea* area = it.Next();) {
for (VMUserAreaList::ConstIterator it = fAreas.GetIterator();
VMUserArea* area = it.Next();) {
if (area->id == RESERVED_AREA_ID)
continue;
@@ -103,8 +119,10 @@ VMUserAddressSpace::LookupArea(addr_t address) const
*/
status_t
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;
status_t status;
@@ -146,8 +164,10 @@ VMUserAddressSpace::InsertArea(void** _address, uint32 addressSpec,
//! You must hold the address space's write lock.
void
VMUserAddressSpace::RemoveArea(VMArea* area)
VMUserAddressSpace::RemoveArea(VMArea* _area)
{
VMUserArea* area = static_cast<VMUserArea*>(_area);
fAreas.Remove(area);
if (area->id != RESERVED_AREA_ID) {
@@ -163,7 +183,7 @@ VMUserAddressSpace::RemoveArea(VMArea* area)
bool
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);
if (next == NULL) {
if (fEndAddress >= newEnd)
@@ -187,10 +207,12 @@ VMUserAddressSpace::CanResizeArea(VMArea* area, size_t newSize)
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);
VMArea* next = fAreas.GetNext(area);
VMUserArea* next = fAreas.GetNext(area);
if (next != NULL && next->Base() <= newEnd) {
if (next->id != RESERVED_AREA_ID
|| next->cache_offset > area->Base()
@@ -256,7 +278,7 @@ VMUserAddressSpace::ReserveAddressRange(void** _address, uint32 addressSpec,
return B_BAD_TEAM_ID;
}
VMArea* area = VMArea::CreateReserved(this, flags);
VMUserArea* area = VMUserArea::CreateReserved(this, flags);
if (area == NULL)
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
addr_t endAddress = address + (size - 1);
for (VMAddressSpaceAreaList::Iterator it = fAreas.GetIterator();
VMArea* area = it.Next();) {
for (VMUserAreaList::Iterator it = fAreas.GetIterator();
VMUserArea* area = it.Next();) {
// the area must be completely part of the reserved range
if (area->Base() + (area->Size() - 1) > endAddress)
break;
@@ -306,8 +328,8 @@ VMUserAddressSpace::UnreserveAddressRange(addr_t address, size_t size)
void
VMUserAddressSpace::UnreserveAllAddressRanges()
{
for (VMAddressSpaceAreaList::Iterator it = fAreas.GetIterator();
VMArea* area = it.Next();) {
for (VMUserAreaList::Iterator it = fAreas.GetIterator();
VMUserArea* area = it.Next();) {
if (area->id == RESERVED_AREA_ID) {
RemoveArea(area);
Put();
@@ -325,8 +347,8 @@ VMUserAddressSpace::Dump() const
kprintf("area_list:\n");
for (VMAddressSpaceAreaList::ConstIterator it = fAreas.GetIterator();
VMArea* area = it.Next();) {
for (VMUserAreaList::ConstIterator it = fAreas.GetIterator();
VMUserArea* area = it.Next();) {
kprintf(" area 0x%lx: ", area->id);
kprintf("base_addr = 0x%lx ", area->Base());
kprintf("size = 0x%lx ", area->Size());
@@ -342,11 +364,11 @@ VMUserAddressSpace::Dump() const
*/
status_t
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;) {
if (next->Base() <= start
&& next->Base() + (next->Size() - 1) >= start + (size - 1)) {
@@ -390,7 +412,8 @@ VMUserAddressSpace::_InsertAreaIntoReservedRegion(addr_t start, size_t size,
} else {
// the area splits the reserved range into two separate ones
// 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)
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 */
status_t
VMUserAddressSpace::_InsertAreaSlot(addr_t start, addr_t size, addr_t end,
uint32 addressSpec, VMArea* area)
uint32 addressSpec, VMUserArea* area)
{
VMArea* last = NULL;
VMArea* next;
VMUserArea* last = NULL;
VMUserArea* next;
bool foundSpot = false;
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
second_chance:
VMAddressSpaceAreaList::Iterator it = fAreas.GetIterator();
VMUserAreaList::Iterator it = fAreas.GetIterator();
while ((next = it.Next()) != NULL) {
if (next->Base() > start + (size - 1)) {
// we have a winner
+8 -3
View File
@@ -12,6 +12,8 @@
#include <vm/VMAddressSpace.h>
#include "VMUserArea.h"
struct VMUserAddressSpace : VMAddressSpace {
public:
@@ -23,6 +25,9 @@ public:
virtual VMArea* NextArea(VMArea* area) 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,
addr_t size, VMArea* area);
virtual void RemoveArea(VMArea* area);
@@ -43,13 +48,13 @@ public:
private:
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,
addr_t end, uint32 addressSpec,
VMArea* area);
VMUserArea* area);
private:
VMAddressSpaceAreaList fAreas;
VMUserAreaList fAreas;
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 "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, [email protected].
* 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));
cache->AssertLocked();
VMArea* area = VMArea::Create(addressSpace, areaName, wiring, protection);
VMArea* area = addressSpace->CreateArea(areaName, wiring, protection);
if (area == NULL)
return B_NO_MEMORY;
@@ -594,8 +594,7 @@ err2:
sourceCache->Lock();
}
err1:
free(area->name);
free(area);
addressSpace->DeleteArea(area);
return status;
}
@@ -1584,9 +1583,7 @@ delete_area(VMAddressSpace* addressSpace, VMArea* area)
area->cache->RemoveArea(area);
area->cache->ReleaseRef();
free(area->page_protections);
free(area->name);
free(area);
addressSpace->DeleteArea(area);
}