* Renamed VMAddressSpace::ResizeArea{Head,Tail}() to ShrinkArea{Head,Tail}()
to clarify that they never enlarge the area.
* Reimplemented VMKernelAddressSpace. It is somewhat inspired by Bonwick's
vmem resource allocator (though we have different requirements):
- We consider the complete address space to be divided into contiguous
ranges of type free, reserved, or area, each range being represented by
a VMKernelAddressRange object.
- The range objects are managed in an AVL tree and a doubly linked list
(the latter only for faster iteration) sorted by address. This provides
O(log(n)) lookup, insertion and removal.
- For each power of two size we maintain a list of free ranges of at least
that size. Thus for the most common case of B_ANY*_ADDRESS area
allocation, we find a free range in constant time (the rest of the
processing being O(log(n))) with a rather good fit. This should also
help avoiding address space fragmentation.
While the new implementation should be faster, particularly with an
increasing number of areas, I couldn't measure any difference in the -j2
haiku build. From a cursory test the -j8 build hasn't tangibly benefitted
either.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34528 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -62,6 +62,8 @@ public:
|
|||||||
|
|
||||||
VMAddressSpace*& HashTableLink() { return fHashTableLink; }
|
VMAddressSpace*& HashTableLink() { return fHashTableLink; }
|
||||||
|
|
||||||
|
virtual status_t InitObject();
|
||||||
|
|
||||||
virtual VMArea* FirstArea() const = 0;
|
virtual VMArea* FirstArea() const = 0;
|
||||||
virtual VMArea* NextArea(VMArea* area) const = 0;
|
virtual VMArea* NextArea(VMArea* area) const = 0;
|
||||||
|
|
||||||
@@ -70,13 +72,15 @@ public:
|
|||||||
uint32 protection) = 0;
|
uint32 protection) = 0;
|
||||||
virtual void DeleteArea(VMArea* area) = 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;
|
size_t size, VMArea* area) = 0;
|
||||||
virtual void RemoveArea(VMArea* area) = 0;
|
virtual void RemoveArea(VMArea* area) = 0;
|
||||||
|
|
||||||
virtual bool CanResizeArea(VMArea* area, size_t newSize) = 0;
|
virtual bool CanResizeArea(VMArea* area, size_t newSize) = 0;
|
||||||
virtual status_t ResizeArea(VMArea* area, size_t newSize) = 0;
|
virtual status_t ResizeArea(VMArea* area, size_t newSize) = 0;
|
||||||
virtual status_t ResizeAreaHead(VMArea* area, size_t size) = 0;
|
virtual status_t ShrinkAreaHead(VMArea* area, size_t newSize)
|
||||||
virtual status_t ResizeAreaTail(VMArea* area, size_t size) = 0;
|
= 0;
|
||||||
|
virtual status_t ShrinkAreaTail(VMArea* area, size_t newSize)
|
||||||
|
= 0;
|
||||||
|
|
||||||
virtual status_t ReserveAddressRange(void** _address,
|
virtual status_t ReserveAddressRange(void** _address,
|
||||||
uint32 addressSpec, size_t size,
|
uint32 addressSpec, size_t size,
|
||||||
|
|||||||
@@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
|
|
||||||
#include <util/OpenHashTable.h>
|
#include <util/OpenHashTable.h>
|
||||||
@@ -181,17 +183,24 @@ VMAddressSpace::RemoveAndPut()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
VMAddressSpace::InitObject()
|
||||||
|
{
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
VMAddressSpace::Dump() const
|
VMAddressSpace::Dump() const
|
||||||
{
|
{
|
||||||
kprintf("dump of address space at %p:\n", this);
|
kprintf("dump of address space at %p:\n", this);
|
||||||
kprintf("id: 0x%lx\n", fID);
|
kprintf("id: %" B_PRId32 "\n", fID);
|
||||||
kprintf("ref_count: %ld\n", fRefCount);
|
kprintf("ref_count: %" B_PRId32 "\n", fRefCount);
|
||||||
kprintf("fault_count: %ld\n", fFaultCount);
|
kprintf("fault_count: %" B_PRId32 "\n", fFaultCount);
|
||||||
kprintf("translation_map: %p\n", &fTranslationMap);
|
kprintf("translation_map: %p\n", &fTranslationMap);
|
||||||
kprintf("base: 0x%lx\n", fBase);
|
kprintf("base: %#" B_PRIxADDR "\n", fBase);
|
||||||
kprintf("end: 0x%lx\n", fEndAddress);
|
kprintf("end: %#" B_PRIxADDR "\n", fEndAddress);
|
||||||
kprintf("change_count: 0x%lx\n", fChangeCount);
|
kprintf("change_count: %" B_PRId32 "\n", fChangeCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -205,11 +214,17 @@ VMAddressSpace::Create(team_id teamID, addr_t base, size_t size, bool kernel,
|
|||||||
if (addressSpace == NULL)
|
if (addressSpace == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
status_t status = addressSpace->InitObject();
|
||||||
|
if (status != B_OK) {
|
||||||
|
delete addressSpace;
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
TRACE(("vm_create_aspace: team %ld (%skernel): %#lx bytes starting at "
|
TRACE(("vm_create_aspace: team %ld (%skernel): %#lx bytes starting at "
|
||||||
"%#lx => %p\n", id, kernel ? "!" : "", size, base, addressSpace));
|
"%#lx => %p\n", id, kernel ? "!" : "", size, base, addressSpace));
|
||||||
|
|
||||||
// initialize the corresponding translation map
|
// initialize the corresponding translation map
|
||||||
status_t status = arch_vm_translation_map_init_map(
|
status = arch_vm_translation_map_init_map(
|
||||||
&addressSpace->fTranslationMap, kernel);
|
&addressSpace->fTranslationMap, kernel);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
delete addressSpace;
|
delete addressSpace;
|
||||||
@@ -321,9 +336,9 @@ VMAddressSpace::_DumpListCommand(int argc, char** argv)
|
|||||||
areaSize += area->Size();
|
areaSize += area->Size();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
kprintf("%p %6ld %#010lx %#10lx %10ld %10lld\n",
|
kprintf("%p %6" B_PRId32 " %#010" B_PRIxADDR " %#10" B_PRIxADDR
|
||||||
space, space->ID(), space->Base(), space->EndAddress(), areaCount,
|
" %10" B_PRId32 " %10" B_PRIdOFF "\n", space, space->ID(),
|
||||||
areaSize);
|
space->Base(), space->EndAddress(), areaCount, areaSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -10,6 +10,8 @@
|
|||||||
|
|
||||||
#include <vm/VMArea.h>
|
#include <vm/VMArea.h>
|
||||||
|
|
||||||
|
#include <new>
|
||||||
|
|
||||||
#include <heap.h>
|
#include <heap.h>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,10 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009, Ingo Weinhold, [email protected].
|
* Copyright 2009, Ingo Weinhold, [email protected].
|
||||||
* Copyright 2002-2008, Axel Dörfler, [email protected]. All rights reserved.
|
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
|
||||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
|
||||||
* Distributed under the terms of the NewOS License.
|
|
||||||
*/
|
*/
|
||||||
#ifndef VM_KERNEL_ADDRESS_SPACE_H
|
#ifndef VM_KERNEL_ADDRESS_SPACE_H
|
||||||
#define VM_KERNEL_ADDRESS_SPACE_H
|
#define VM_KERNEL_ADDRESS_SPACE_H
|
||||||
@@ -21,6 +17,8 @@ public:
|
|||||||
size_t size);
|
size_t size);
|
||||||
virtual ~VMKernelAddressSpace();
|
virtual ~VMKernelAddressSpace();
|
||||||
|
|
||||||
|
virtual status_t InitObject();
|
||||||
|
|
||||||
virtual VMArea* FirstArea() const;
|
virtual VMArea* FirstArea() const;
|
||||||
virtual VMArea* NextArea(VMArea* area) const;
|
virtual VMArea* NextArea(VMArea* area) const;
|
||||||
|
|
||||||
@@ -29,13 +27,13 @@ public:
|
|||||||
uint32 protection);
|
uint32 protection);
|
||||||
virtual void DeleteArea(VMArea* area);
|
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);
|
size_t size, VMArea* area);
|
||||||
virtual void RemoveArea(VMArea* area);
|
virtual void RemoveArea(VMArea* area);
|
||||||
|
|
||||||
virtual bool CanResizeArea(VMArea* area, size_t newSize);
|
virtual bool CanResizeArea(VMArea* area, size_t newSize);
|
||||||
virtual status_t ResizeArea(VMArea* area, size_t newSize);
|
virtual status_t ResizeArea(VMArea* area, size_t newSize);
|
||||||
virtual status_t ResizeAreaHead(VMArea* area, size_t size);
|
virtual status_t ShrinkAreaHead(VMArea* area, size_t newSize);
|
||||||
virtual status_t ResizeAreaTail(VMArea* area, size_t size);
|
virtual status_t ShrinkAreaTail(VMArea* area, size_t newSize);
|
||||||
|
|
||||||
virtual status_t ReserveAddressRange(void** _address,
|
virtual status_t ReserveAddressRange(void** _address,
|
||||||
uint32 addressSpec, size_t size,
|
uint32 addressSpec, size_t size,
|
||||||
@@ -47,15 +45,37 @@ public:
|
|||||||
virtual void Dump() const;
|
virtual void Dump() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
status_t _InsertAreaIntoReservedRegion(addr_t start,
|
typedef VMKernelAddressRange Range;
|
||||||
size_t size, VMKernelArea* area);
|
typedef VMKernelAddressRangeTree RangeTree;
|
||||||
status_t _InsertAreaSlot(addr_t start, addr_t size,
|
typedef DoublyLinkedList<Range,
|
||||||
addr_t end, uint32 addressSpec,
|
DoublyLinkedListMemberGetLink<Range, &Range::listLink> >
|
||||||
VMKernelArea* area);
|
RangeList;
|
||||||
|
typedef DoublyLinkedList<Range, VMKernelAddressRangeGetFreeListLink>
|
||||||
|
RangeFreeList;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VMKernelAreaList fAreas;
|
inline void _FreeListInsertRange(Range* range, size_t size);
|
||||||
mutable VMArea* fAreaHint;
|
inline void _FreeListRemoveRange(Range* range, size_t size);
|
||||||
|
|
||||||
|
void _InsertRange(Range* range);
|
||||||
|
void _RemoveRange(Range* range);
|
||||||
|
|
||||||
|
status_t _AllocateRange(addr_t address,
|
||||||
|
uint32 addressSpec, size_t size,
|
||||||
|
bool allowReservedRange, Range*& _range);
|
||||||
|
Range* _FindFreeRange(addr_t start, size_t size,
|
||||||
|
size_t alignment, uint32 addressSpec,
|
||||||
|
bool allowReservedRange,
|
||||||
|
addr_t& _foundAddress);
|
||||||
|
void _FreeRange(Range* range);
|
||||||
|
|
||||||
|
void _CheckStructures() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
RangeTree fRangeTree;
|
||||||
|
RangeList fRangeList;
|
||||||
|
RangeFreeList* fFreeLists;
|
||||||
|
int fFreeListCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -39,13 +39,3 @@ VMKernelArea::Create(VMAddressSpace* addressSpace, const char* name,
|
|||||||
|
|
||||||
return area;
|
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;
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -6,13 +6,109 @@
|
|||||||
#define VM_KERNEL_AREA_H
|
#define VM_KERNEL_AREA_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <util/AVLTree.h>
|
||||||
|
|
||||||
#include <vm/VMArea.h>
|
#include <vm/VMArea.h>
|
||||||
|
|
||||||
|
|
||||||
struct VMKernelAddressSpace;
|
struct VMKernelAddressSpace;
|
||||||
|
struct VMKernelArea;
|
||||||
|
|
||||||
|
|
||||||
struct VMKernelArea : VMArea {
|
struct VMKernelAddressRange : AVLTreeNode {
|
||||||
|
public:
|
||||||
|
// range types
|
||||||
|
enum {
|
||||||
|
RANGE_FREE,
|
||||||
|
RANGE_RESERVED,
|
||||||
|
RANGE_AREA
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
DoublyLinkedListLink<VMKernelAddressRange> listLink;
|
||||||
|
addr_t base;
|
||||||
|
size_t size;
|
||||||
|
union {
|
||||||
|
VMKernelArea* area;
|
||||||
|
struct {
|
||||||
|
addr_t base;
|
||||||
|
uint32 flags;
|
||||||
|
} reserved;
|
||||||
|
DoublyLinkedListLink<VMKernelAddressRange> freeListLink;
|
||||||
|
};
|
||||||
|
int type;
|
||||||
|
|
||||||
|
public:
|
||||||
|
VMKernelAddressRange(addr_t base, size_t size, int type)
|
||||||
|
:
|
||||||
|
base(base),
|
||||||
|
size(size),
|
||||||
|
type(type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
VMKernelAddressRange(addr_t base, size_t size,
|
||||||
|
const VMKernelAddressRange* other)
|
||||||
|
:
|
||||||
|
base(base),
|
||||||
|
size(size),
|
||||||
|
type(other->type)
|
||||||
|
{
|
||||||
|
if (type == RANGE_RESERVED) {
|
||||||
|
reserved.base = other->reserved.base;
|
||||||
|
reserved.flags = other->reserved.flags;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct VMKernelAddressRangeTreeDefinition {
|
||||||
|
typedef addr_t Key;
|
||||||
|
typedef VMKernelAddressRange Value;
|
||||||
|
|
||||||
|
AVLTreeNode* GetAVLTreeNode(Value* value) const
|
||||||
|
{
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
Value* GetValue(AVLTreeNode* node) const
|
||||||
|
{
|
||||||
|
return static_cast<Value*>(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
int Compare(addr_t a, const Value* _b) const
|
||||||
|
{
|
||||||
|
addr_t b = _b->base;
|
||||||
|
if (a == b)
|
||||||
|
return 0;
|
||||||
|
return a < b ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Compare(const Value* a, const Value* b) const
|
||||||
|
{
|
||||||
|
return Compare(a->base, b);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef AVLTree<VMKernelAddressRangeTreeDefinition> VMKernelAddressRangeTree;
|
||||||
|
|
||||||
|
|
||||||
|
struct VMKernelAddressRangeGetFreeListLink {
|
||||||
|
typedef DoublyLinkedListLink<VMKernelAddressRange> Link;
|
||||||
|
|
||||||
|
inline Link* operator()(VMKernelAddressRange* range) const
|
||||||
|
{
|
||||||
|
return &range->freeListLink;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline const Link* operator()(const VMKernelAddressRange* range) const
|
||||||
|
{
|
||||||
|
return &range->freeListLink;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
struct VMKernelArea : VMArea, AVLTreeNode {
|
||||||
VMKernelArea(VMAddressSpace* addressSpace,
|
VMKernelArea(VMAddressSpace* addressSpace,
|
||||||
uint32 wiring, uint32 protection);
|
uint32 wiring, uint32 protection);
|
||||||
~VMKernelArea();
|
~VMKernelArea();
|
||||||
@@ -20,34 +116,15 @@ struct VMKernelArea : VMArea {
|
|||||||
static VMKernelArea* Create(VMAddressSpace* addressSpace,
|
static VMKernelArea* Create(VMAddressSpace* addressSpace,
|
||||||
const char* name, uint32 wiring,
|
const char* name, uint32 wiring,
|
||||||
uint32 protection);
|
uint32 protection);
|
||||||
static VMKernelArea* CreateReserved(VMAddressSpace* addressSpace,
|
|
||||||
uint32 flags);
|
|
||||||
|
|
||||||
DoublyLinkedListLink<VMKernelArea>& AddressSpaceLink()
|
VMKernelAddressRange* Range() const
|
||||||
{ return fAddressSpaceLink; }
|
{ return fRange; }
|
||||||
const DoublyLinkedListLink<VMKernelArea>& AddressSpaceLink() const
|
void SetRange(VMKernelAddressRange* range)
|
||||||
{ return fAddressSpaceLink; }
|
{ fRange = range; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
DoublyLinkedListLink<VMKernelArea> fAddressSpaceLink;
|
VMKernelAddressRange* fRange;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
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
|
#endif // VM_KERNEL_AREA_H
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ is_valid_spot(addr_t base, addr_t alignedBase, addr_t size, addr_t limit)
|
|||||||
|
|
||||||
VMUserAddressSpace::VMUserAddressSpace(team_id id, addr_t base, size_t size)
|
VMUserAddressSpace::VMUserAddressSpace(team_id id, addr_t base, size_t size)
|
||||||
:
|
:
|
||||||
VMAddressSpace(id, base, size, "kernel address space"),
|
VMAddressSpace(id, base, size, "address space"),
|
||||||
fAreaHint(NULL)
|
fAreaHint(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -118,7 +118,7 @@ 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)
|
size_t size, VMArea* _area)
|
||||||
{
|
{
|
||||||
VMUserArea* area = static_cast<VMUserArea*>(_area);
|
VMUserArea* area = static_cast<VMUserArea*>(_area);
|
||||||
|
|
||||||
@@ -225,22 +225,21 @@ VMUserAddressSpace::ResizeArea(VMArea* _area, size_t newSize)
|
|||||||
addr_t offset = area->Base() + newSize - next->Base();
|
addr_t offset = area->Base() + newSize - next->Base();
|
||||||
if (next->Size() <= offset) {
|
if (next->Size() <= offset) {
|
||||||
RemoveArea(next);
|
RemoveArea(next);
|
||||||
free(next);
|
delete next;
|
||||||
} else {
|
} else {
|
||||||
status_t error = ResizeAreaHead(next, next->Size() - offset);
|
status_t error = ShrinkAreaHead(next, next->Size() - offset);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ResizeAreaTail(area, newSize);
|
area->SetSize(newSize);
|
||||||
// TODO: In case of error we should undo the change to the reserved
|
return B_OK;
|
||||||
// area.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
VMUserAddressSpace::ResizeAreaHead(VMArea* area, size_t size)
|
VMUserAddressSpace::ShrinkAreaHead(VMArea* area, size_t size)
|
||||||
{
|
{
|
||||||
size_t oldSize = area->Size();
|
size_t oldSize = area->Size();
|
||||||
if (size == oldSize)
|
if (size == oldSize)
|
||||||
@@ -254,7 +253,7 @@ VMUserAddressSpace::ResizeAreaHead(VMArea* area, size_t size)
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
VMUserAddressSpace::ResizeAreaTail(VMArea* area, size_t size)
|
VMUserAddressSpace::ShrinkAreaTail(VMArea* area, size_t size)
|
||||||
{
|
{
|
||||||
size_t oldSize = area->Size();
|
size_t oldSize = area->Size();
|
||||||
if (size == oldSize)
|
if (size == oldSize)
|
||||||
@@ -283,7 +282,7 @@ VMUserAddressSpace::ReserveAddressRange(void** _address, uint32 addressSpec,
|
|||||||
|
|
||||||
status_t status = InsertArea(_address, addressSpec, size, area);
|
status_t status = InsertArea(_address, addressSpec, size, area);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
free(area);
|
delete area;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -316,7 +315,7 @@ VMUserAddressSpace::UnreserveAddressRange(addr_t address, size_t size)
|
|||||||
// remove reserved range
|
// remove reserved range
|
||||||
RemoveArea(area);
|
RemoveArea(area);
|
||||||
Put();
|
Put();
|
||||||
free(area);
|
delete area;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,7 +331,7 @@ VMUserAddressSpace::UnreserveAllAddressRanges()
|
|||||||
if (area->id == RESERVED_AREA_ID) {
|
if (area->id == RESERVED_AREA_ID) {
|
||||||
RemoveArea(area);
|
RemoveArea(area);
|
||||||
Put();
|
Put();
|
||||||
free(area);
|
delete area;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -396,7 +395,7 @@ VMUserAddressSpace::_InsertAreaIntoReservedRegion(addr_t start, size_t size,
|
|||||||
// the new area fully covers the reversed range
|
// the new area fully covers the reversed range
|
||||||
fAreas.Remove(next);
|
fAreas.Remove(next);
|
||||||
Put();
|
Put();
|
||||||
free(next);
|
delete next;
|
||||||
} else {
|
} else {
|
||||||
// resize the reserved range behind the area
|
// resize the reserved range behind the area
|
||||||
next->SetBase(next->Base() + size);
|
next->SetBase(next->Base() + size);
|
||||||
@@ -556,7 +555,7 @@ second_chance:
|
|||||||
|
|
||||||
foundSpot = true;
|
foundSpot = true;
|
||||||
area->SetBase(alignedBase);
|
area->SetBase(alignedBase);
|
||||||
free(next);
|
delete next;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
* Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
|
||||||
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
|
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
|
||||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
|
||||||
* Distributed under the terms of the NewOS License.
|
|
||||||
*/
|
*/
|
||||||
#ifndef VM_USER_ADDRESS_SPACE_H
|
#ifndef VM_USER_ADDRESS_SPACE_H
|
||||||
#define VM_USER_ADDRESS_SPACE_H
|
#define VM_USER_ADDRESS_SPACE_H
|
||||||
@@ -29,13 +25,13 @@ public:
|
|||||||
uint32 protection);
|
uint32 protection);
|
||||||
virtual void DeleteArea(VMArea* area);
|
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);
|
size_t size, VMArea* area);
|
||||||
virtual void RemoveArea(VMArea* area);
|
virtual void RemoveArea(VMArea* area);
|
||||||
|
|
||||||
virtual bool CanResizeArea(VMArea* area, size_t newSize);
|
virtual bool CanResizeArea(VMArea* area, size_t newSize);
|
||||||
virtual status_t ResizeArea(VMArea* area, size_t newSize);
|
virtual status_t ResizeArea(VMArea* area, size_t newSize);
|
||||||
virtual status_t ResizeAreaHead(VMArea* area, size_t size);
|
virtual status_t ShrinkAreaHead(VMArea* area, size_t newSize);
|
||||||
virtual status_t ResizeAreaTail(VMArea* area, size_t size);
|
virtual status_t ShrinkAreaTail(VMArea* area, size_t newSize);
|
||||||
|
|
||||||
virtual status_t ReserveAddressRange(void** _address,
|
virtual status_t ReserveAddressRange(void** _address,
|
||||||
uint32 addressSpec, size_t size,
|
uint32 addressSpec, size_t size,
|
||||||
|
|||||||
@@ -45,7 +45,9 @@ VMUserArea::Create(VMAddressSpace* addressSpace, const char* name,
|
|||||||
VMUserArea::CreateReserved(VMAddressSpace* addressSpace, uint32 flags)
|
VMUserArea::CreateReserved(VMAddressSpace* addressSpace, uint32 flags)
|
||||||
{
|
{
|
||||||
VMUserArea* area = new(nogrow) VMUserArea(addressSpace, 0, 0);
|
VMUserArea* area = new(nogrow) VMUserArea(addressSpace, 0, 0);
|
||||||
if (area != NULL)
|
if (area != NULL) {
|
||||||
area->id = RESERVED_AREA_ID;
|
area->id = RESERVED_AREA_ID;
|
||||||
|
area->protection = flags;
|
||||||
|
}
|
||||||
return area;
|
return area;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -338,7 +338,7 @@ cut_area(VMAddressSpace* addressSpace, VMArea* area, addr_t address,
|
|||||||
size_t oldSize = area->Size();
|
size_t oldSize = area->Size();
|
||||||
size_t newSize = address - area->Base();
|
size_t newSize = address - area->Base();
|
||||||
|
|
||||||
status_t error = addressSpace->ResizeAreaTail(area, newSize);
|
status_t error = addressSpace->ShrinkAreaTail(area, newSize);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
@@ -350,7 +350,7 @@ cut_area(VMAddressSpace* addressSpace, VMArea* area, addr_t address,
|
|||||||
&& list_is_empty(&cache->consumers)) {
|
&& list_is_empty(&cache->consumers)) {
|
||||||
error = cache->Resize(cache->virtual_base + newSize);
|
error = cache->Resize(cache->virtual_base + newSize);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
addressSpace->ResizeAreaTail(area, oldSize);
|
addressSpace->ShrinkAreaTail(area, oldSize);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -368,7 +368,7 @@ cut_area(VMAddressSpace* addressSpace, VMArea* area, addr_t address,
|
|||||||
vm_unmap_pages(area, oldBase, newBase - oldBase, false);
|
vm_unmap_pages(area, oldBase, newBase - oldBase, false);
|
||||||
|
|
||||||
// resize the area
|
// resize the area
|
||||||
status_t error = addressSpace->ResizeAreaHead(area, newSize);
|
status_t error = addressSpace->ShrinkAreaHead(area, newSize);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
@@ -392,7 +392,7 @@ cut_area(VMAddressSpace* addressSpace, VMArea* area, addr_t address,
|
|||||||
|
|
||||||
// resize the area
|
// resize the area
|
||||||
addr_t oldSize = area->Size();
|
addr_t oldSize = area->Size();
|
||||||
status_t error = addressSpace->ResizeAreaTail(area, firstNewSize);
|
status_t error = addressSpace->ShrinkAreaTail(area, firstNewSize);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
@@ -408,7 +408,7 @@ cut_area(VMAddressSpace* addressSpace, VMArea* area, addr_t address,
|
|||||||
B_EXACT_ADDRESS, area->wiring, area->protection, REGION_NO_PRIVATE_MAP,
|
B_EXACT_ADDRESS, area->wiring, area->protection, REGION_NO_PRIVATE_MAP,
|
||||||
&secondArea, area->name, false, kernel);
|
&secondArea, area->name, false, kernel);
|
||||||
if (error != B_OK) {
|
if (error != B_OK) {
|
||||||
addressSpace->ResizeAreaTail(area, oldSize);
|
addressSpace->ShrinkAreaTail(area, oldSize);
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user