mirror of
https://review.haiku-os.org/haiku
synced 2025-01-24 07:14:48 +01:00
35d940014e
simplify migration of the area management, but as a side effect, it also makes area deletion O(1) (instead of O(n), n == number of areas in the address space). * Moved more area management functionality from vm.cpp to VMAddressSpace and VMArea structure creation to VMArea. Made the list and list link members itself private. * VMAddressSpace tracks its amount of free space, now. This also replaces the previous mechanism to do that only for the kernel address space. It was broken anyway, since delete_area() subtracted the area size instead of adding it. * vm_free_unused_boot_loader_range(): - lastEnd could be set to a value < start, which could cause memory outside of the given range to be unmapped. Haven't checked whether this could happen in practice -- if so, it would be seriously unhealthy. - The range between the end of the last area in the range and the end of the range would never be freed. - Fixed potential integer overflows when computing addresses. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34459 a95241bf-73f2-0310-859d-f6bbb57e9c96
176 lines
3.9 KiB
C++
176 lines
3.9 KiB
C++
/*
|
|
* 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.
|
|
*
|
|
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
|
* Distributed under the terms of the NewOS License.
|
|
*/
|
|
#ifndef _KERNEL_VM_VM_ADDRESS_SPACE_H
|
|
#define _KERNEL_VM_VM_ADDRESS_SPACE_H
|
|
|
|
|
|
#include <OS.h>
|
|
|
|
#include <vm/vm_translation_map.h>
|
|
#include <vm/VMArea.h>
|
|
|
|
|
|
struct VMAddressSpace {
|
|
public:
|
|
class Iterator;
|
|
|
|
public:
|
|
VMAddressSpace(team_id id, addr_t base,
|
|
size_t size, bool kernel);
|
|
~VMAddressSpace();
|
|
|
|
static status_t Init();
|
|
static status_t InitPostSem();
|
|
|
|
team_id ID() const { return fID; }
|
|
addr_t Base() const { return fBase; }
|
|
size_t Size() const { return fSize; }
|
|
size_t FreeSpace() const { return fFreeSpace; }
|
|
bool IsBeingDeleted() const { return fDeleting; }
|
|
|
|
vm_translation_map& TranslationMap() { return fTranslationMap; }
|
|
|
|
status_t ReadLock()
|
|
{ return rw_lock_read_lock(&fLock); }
|
|
void ReadUnlock()
|
|
{ rw_lock_read_unlock(&fLock); }
|
|
status_t WriteLock()
|
|
{ return rw_lock_write_lock(&fLock); }
|
|
void WriteUnlock()
|
|
{ rw_lock_write_unlock(&fLock); }
|
|
|
|
int32 RefCount() const
|
|
{ return fRefCount; }
|
|
|
|
void Get() { atomic_add(&fRefCount, 1); }
|
|
void Put();
|
|
void RemoveAndPut();
|
|
|
|
void IncrementFaultCount()
|
|
{ atomic_add(&fFaultCount, 1); }
|
|
void IncrementChangeCount()
|
|
{ fChangeCount++; }
|
|
|
|
VMArea* FirstArea() const
|
|
{ return fAreas.Head(); }
|
|
VMArea* NextArea(VMArea* area) const
|
|
{ return fAreas.GetNext(area); }
|
|
|
|
VMArea* LookupArea(addr_t address) const;
|
|
status_t InsertArea(void** _address, uint32 addressSpec,
|
|
addr_t size, VMArea* area);
|
|
void RemoveArea(VMArea* area);
|
|
|
|
inline Iterator GetIterator();
|
|
|
|
static status_t Create(team_id teamID, addr_t base, size_t size,
|
|
bool kernel,
|
|
VMAddressSpace** _addressSpace);
|
|
|
|
static team_id KernelID()
|
|
{ return sKernelAddressSpace->ID(); }
|
|
static VMAddressSpace* Kernel()
|
|
{ return sKernelAddressSpace; }
|
|
static VMAddressSpace* GetKernel();
|
|
|
|
static team_id CurrentID();
|
|
static VMAddressSpace* GetCurrent();
|
|
|
|
static VMAddressSpace* Get(team_id teamID);
|
|
|
|
VMAddressSpace*& HashTableLink() { return fHashTableLink; }
|
|
|
|
void Dump() const;
|
|
|
|
private:
|
|
status_t _InsertAreaIntoReservedRegion(addr_t start,
|
|
size_t size, VMArea* area);
|
|
status_t _InsertAreaSlot(addr_t start, addr_t size,
|
|
addr_t end, uint32 addressSpec,
|
|
VMArea* area);
|
|
|
|
static int _DumpCommand(int argc, char** argv);
|
|
static int _DumpListCommand(int argc, char** argv);
|
|
|
|
private:
|
|
friend class Iterator;
|
|
|
|
struct HashDefinition;
|
|
|
|
private:
|
|
VMAddressSpace* fHashTableLink;
|
|
addr_t fBase;
|
|
size_t fSize;
|
|
size_t fFreeSpace;
|
|
rw_lock fLock;
|
|
team_id fID;
|
|
int32 fRefCount;
|
|
int32 fFaultCount;
|
|
int32 fChangeCount;
|
|
vm_translation_map fTranslationMap;
|
|
VMAddressSpaceAreaList fAreas;
|
|
mutable VMArea* fAreaHint;
|
|
bool fDeleting;
|
|
static VMAddressSpace* sKernelAddressSpace;
|
|
};
|
|
|
|
|
|
class VMAddressSpace::Iterator {
|
|
public:
|
|
Iterator()
|
|
{
|
|
}
|
|
|
|
Iterator(VMAddressSpace* addressSpace)
|
|
:
|
|
fIterator(addressSpace->fAreas.GetIterator())
|
|
{
|
|
}
|
|
|
|
bool HasNext() const
|
|
{
|
|
return fIterator.HasNext();
|
|
}
|
|
|
|
VMArea* Next()
|
|
{
|
|
return fIterator.Next();
|
|
}
|
|
|
|
void Rewind()
|
|
{
|
|
fIterator.Rewind();
|
|
}
|
|
|
|
private:
|
|
VMAddressSpaceAreaList::Iterator fIterator;
|
|
};
|
|
|
|
|
|
inline VMAddressSpace::Iterator
|
|
VMAddressSpace::GetIterator()
|
|
{
|
|
return Iterator(this);
|
|
}
|
|
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
status_t vm_delete_areas(struct VMAddressSpace *aspace);
|
|
#define vm_swap_address_space(from, to) arch_vm_aspace_swap(from, to)
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
|
|
#endif /* _KERNEL_VM_VM_ADDRESS_SPACE_H */
|