kernel/vm: Introduce and use VMAddressSpace::AreaRangeIterator.
It iterates over all areas intersecting a given address range and removes the need for manually skipping uninteresting initial areas. It uses VMAddressSpace::FindClosestArea() to efficiently find the starting area. This speeds up the two iterations in unmap_address_range and one in wait_if_address_range_is_wired and resolves a TODO in the latter hinting at such a solution. Change-Id: Iba1d39942db4e4b27e17706be194496f9d4279ed Reviewed-on: https://review.haiku-os.org/c/haiku/+/2841 Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
a626bdab77
commit
a6926d4287
@@ -23,6 +23,7 @@ struct virtual_address_restrictions;
|
||||
struct VMAddressSpace {
|
||||
public:
|
||||
class AreaIterator;
|
||||
class AreaRangeIterator;
|
||||
|
||||
public:
|
||||
VMAddressSpace(team_id id, addr_t base,
|
||||
@@ -67,6 +68,8 @@ public:
|
||||
{ fRandomizingEnabled = enabled; }
|
||||
|
||||
inline AreaIterator GetAreaIterator();
|
||||
inline AreaRangeIterator GetAreaRangeIterator(addr_t address,
|
||||
addr_t size);
|
||||
|
||||
VMAddressSpace*& HashTableLink() { return fHashTableLink; }
|
||||
|
||||
@@ -202,6 +205,54 @@ private:
|
||||
};
|
||||
|
||||
|
||||
class VMAddressSpace::AreaRangeIterator : public VMAddressSpace::AreaIterator {
|
||||
public:
|
||||
AreaRangeIterator()
|
||||
{
|
||||
}
|
||||
|
||||
AreaRangeIterator(VMAddressSpace* addressSpace, addr_t address, addr_t size)
|
||||
:
|
||||
fAddressSpace(addressSpace),
|
||||
fNext(NULL),
|
||||
fAddress(address),
|
||||
fEndAddress(address + size - 1)
|
||||
{
|
||||
Rewind();
|
||||
}
|
||||
|
||||
bool HasNext() const
|
||||
{
|
||||
return fNext != NULL;
|
||||
}
|
||||
|
||||
VMArea* Next()
|
||||
{
|
||||
VMArea* result = fNext;
|
||||
if (fNext != NULL) {
|
||||
fNext = fAddressSpace->NextArea(fNext);
|
||||
if (fNext != NULL && fNext->Base() > fEndAddress)
|
||||
fNext = NULL;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Rewind()
|
||||
{
|
||||
fNext = fAddressSpace->FindClosestArea(fAddress, true);
|
||||
if (fNext != NULL && !fNext->ContainsAddress(fAddress))
|
||||
Next();
|
||||
}
|
||||
|
||||
private:
|
||||
VMAddressSpace* fAddressSpace;
|
||||
VMArea* fNext;
|
||||
addr_t fAddress;
|
||||
addr_t fEndAddress;
|
||||
};
|
||||
|
||||
|
||||
inline VMAddressSpace::AreaIterator
|
||||
VMAddressSpace::GetAreaIterator()
|
||||
{
|
||||
@@ -209,6 +260,13 @@ VMAddressSpace::GetAreaIterator()
|
||||
}
|
||||
|
||||
|
||||
inline VMAddressSpace::AreaRangeIterator
|
||||
VMAddressSpace::GetAreaRangeIterator(addr_t address, addr_t size)
|
||||
{
|
||||
return AreaRangeIterator(this, address, size);
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user