haiku/headers/private/kernel/vm/VMAddressSpace.h
Ingo Weinhold 35d940014e * Changed the address space area list to doubly linked. The reason is to
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
2009-12-03 12:41:11 +00:00

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 */