kernel/vm: Remove linear search from _get_next_area_info.
This introduces VMAddressSpace::FindClosestArea() that can be used to find the closest area to a given address in either direction. This is now trivial and efficient since both kernel and user address spaces use a binary search tree. Using FindClosestArea() getting multiple area infos is sped up dramatically as it removes the need for a linear search from the first area to the one given in the cookie on each successive invocation. Change-Id: I227da87d915f6f3d3ef88bfeb6be5d4c97c3baaa Reviewed-on: https://review.haiku-os.org/c/haiku/+/2840 Reviewed-by: waddlesplash <[email protected]>
This commit is contained in:
committed by
waddlesplash
parent
6d9329be05
commit
a626bdab77
@@ -76,6 +76,8 @@ public:
|
|||||||
virtual VMArea* NextArea(VMArea* area) const = 0;
|
virtual VMArea* NextArea(VMArea* area) const = 0;
|
||||||
|
|
||||||
virtual VMArea* LookupArea(addr_t address) const = 0;
|
virtual VMArea* LookupArea(addr_t address) const = 0;
|
||||||
|
virtual VMArea* FindClosestArea(addr_t address, bool less) const
|
||||||
|
= 0;
|
||||||
virtual VMArea* CreateArea(const char* name, uint32 wiring,
|
virtual VMArea* CreateArea(const char* name, uint32 wiring,
|
||||||
uint32 protection,
|
uint32 protection,
|
||||||
uint32 allocationFlags) = 0;
|
uint32 allocationFlags) = 0;
|
||||||
|
|||||||
@@ -171,6 +171,18 @@ VMKernelAddressSpace::LookupArea(addr_t address) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! You must hold the address space's read lock.
|
||||||
|
VMArea*
|
||||||
|
VMKernelAddressSpace::FindClosestArea(addr_t address, bool less) const
|
||||||
|
{
|
||||||
|
Range* range = fRangeTree.FindClosest(address, less);
|
||||||
|
while (range != NULL && range->type != Range::RANGE_AREA)
|
||||||
|
range = fRangeTree.Next(range);
|
||||||
|
|
||||||
|
return range != NULL ? range->area : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! This inserts the area you pass into the address space.
|
/*! This inserts the area you pass into the address space.
|
||||||
It will also set the "_address" argument to its base address when
|
It will also set the "_address" argument to its base address when
|
||||||
the call succeeds.
|
the call succeeds.
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ public:
|
|||||||
virtual VMArea* NextArea(VMArea* area) const;
|
virtual VMArea* NextArea(VMArea* area) const;
|
||||||
|
|
||||||
virtual VMArea* LookupArea(addr_t address) const;
|
virtual VMArea* LookupArea(addr_t address) const;
|
||||||
|
virtual VMArea* FindClosestArea(addr_t address, bool less)
|
||||||
|
const;
|
||||||
virtual VMArea* CreateArea(const char* name, uint32 wiring,
|
virtual VMArea* CreateArea(const char* name, uint32 wiring,
|
||||||
uint32 protection, uint32 allocationFlags);
|
uint32 protection, uint32 allocationFlags);
|
||||||
virtual void DeleteArea(VMArea* area,
|
virtual void DeleteArea(VMArea* area,
|
||||||
|
|||||||
@@ -142,6 +142,17 @@ VMUserAddressSpace::LookupArea(addr_t address) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! You must hold the address space's read lock.
|
||||||
|
VMArea*
|
||||||
|
VMUserAddressSpace::FindClosestArea(addr_t address, bool less) const
|
||||||
|
{
|
||||||
|
VMUserArea* area = fAreas.FindClosest(address, less);
|
||||||
|
while (area != NULL && area->id == RESERVED_AREA_ID)
|
||||||
|
area = fAreas.Next(area);
|
||||||
|
return area;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*! This inserts the area you pass into the address space.
|
/*! This inserts the area you pass into the address space.
|
||||||
It will also set the "_address" argument to its base address when
|
It will also set the "_address" argument to its base address when
|
||||||
the call succeeds.
|
the call succeeds.
|
||||||
|
|||||||
@@ -21,6 +21,8 @@ public:
|
|||||||
virtual VMArea* NextArea(VMArea* area) const;
|
virtual VMArea* NextArea(VMArea* area) const;
|
||||||
|
|
||||||
virtual VMArea* LookupArea(addr_t address) const;
|
virtual VMArea* LookupArea(addr_t address) const;
|
||||||
|
virtual VMArea* FindClosestArea(addr_t address, bool less)
|
||||||
|
const;
|
||||||
virtual VMArea* CreateArea(const char* name, uint32 wiring,
|
virtual VMArea* CreateArea(const char* name, uint32 wiring,
|
||||||
uint32 protection, uint32 allocationFlags);
|
uint32 protection, uint32 allocationFlags);
|
||||||
virtual void DeleteArea(VMArea* area,
|
virtual void DeleteArea(VMArea* area,
|
||||||
|
|||||||
@@ -6050,21 +6050,14 @@ _get_next_area_info(team_id team, ssize_t* cookie, area_info* info, size_t size)
|
|||||||
if (!locker.IsLocked())
|
if (!locker.IsLocked())
|
||||||
return B_BAD_TEAM_ID;
|
return B_BAD_TEAM_ID;
|
||||||
|
|
||||||
VMArea* area;
|
VMArea* area = locker.AddressSpace()->FindClosestArea(nextBase, false);
|
||||||
for (VMAddressSpace::AreaIterator it
|
|
||||||
= locker.AddressSpace()->GetAreaIterator();
|
|
||||||
(area = it.Next()) != NULL;) {
|
|
||||||
if (area->Base() > nextBase)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (area == NULL) {
|
if (area == NULL) {
|
||||||
nextBase = (addr_t)-1;
|
nextBase = (addr_t)-1;
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
fill_area_info(area, info, size);
|
fill_area_info(area, info, size);
|
||||||
*cookie = (ssize_t)(area->Base());
|
*cookie = (ssize_t)(area->Base() + 1);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user