* r33037 broke the handling of reserved areas, more specifically, it ignored

the RESERVED_AVOID_BASE flag of those, and introduced a way to fill them
  from the start. This caused #4778.
* Turned IS_VALID_SPOT() macro into an inline function.
* Removed already resolved TODO comment.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33581 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-10-14 07:53:45 +00:00
parent ea95b4d03e
commit d5a396a60b
+21 -18
View File
@@ -1096,11 +1096,16 @@ find_reserved_area(vm_address_space* addressSpace, addr_t start,
} }
// verifies that an area with the given aligned base and size fits into /*! Verifies that an area with the given aligned base and size fits into
// the spot defined by base and limit and does check for overflows the spot defined by base and limit and does check for overflows.
#define IS_VALID_SPOT(base, alignedBase, size, limit) \ */
((alignedBase) >= (base) && (alignedBase) + ((size) - 1) > (alignedBase) \ static inline bool
&& (alignedBase) + ((size) - 1) <= (limit)) is_valid_spot(addr_t base, addr_t alignedBase, addr_t size, addr_t limit)
{
return (alignedBase >= base && alignedBase + (size - 1) > alignedBase
&& alignedBase + (size - 1) <= limit);
}
/*! Must be called with this address space's sem held */ /*! Must be called with this address space's sem held */
static status_t static status_t
@@ -1166,7 +1171,7 @@ second_chance:
if (last == NULL) { if (last == NULL) {
// see if we can build it at the beginning of the virtual map // see if we can build it at the beginning of the virtual map
addr_t alignedBase = ROUNDUP(addressSpace->base, alignment); addr_t alignedBase = ROUNDUP(addressSpace->base, alignment);
if (IS_VALID_SPOT(addressSpace->base, alignedBase, size, if (is_valid_spot(addressSpace->base, alignedBase, size,
next == NULL ? end : next->base)) { next == NULL ? end : next->base)) {
foundSpot = true; foundSpot = true;
area->base = alignedBase; area->base = alignedBase;
@@ -1180,7 +1185,7 @@ second_chance:
// keep walking // keep walking
while (next != NULL) { while (next != NULL) {
addr_t alignedBase = ROUNDUP(last->base + last->size, alignment); addr_t alignedBase = ROUNDUP(last->base + last->size, alignment);
if (IS_VALID_SPOT(last->base + (last->size - 1), alignedBase, if (is_valid_spot(last->base + (last->size - 1), alignedBase,
size, next->base)) { size, next->base)) {
foundSpot = true; foundSpot = true;
area->base = alignedBase; area->base = alignedBase;
@@ -1195,16 +1200,15 @@ second_chance:
break; break;
addr_t alignedBase = ROUNDUP(last->base + last->size, alignment); addr_t alignedBase = ROUNDUP(last->base + last->size, alignment);
if (IS_VALID_SPOT(last->base + (last->size - 1), alignedBase, if (is_valid_spot(last->base + (last->size - 1), alignedBase,
size, end)) { size, end)) {
// got a spot // got a spot
foundSpot = true; foundSpot = true;
area->base = alignedBase; area->base = alignedBase;
break; break;
} else { } else {
// We didn't find a free spot - if there were any reserved areas // We didn't find a free spot - if there are any reserved areas,
// with the RESERVED_AVOID_BASE flag set, we can now test those // we can now test those for free space
// for free space
// TODO: it would make sense to start with the biggest of them // TODO: it would make sense to start with the biggest of them
next = addressSpace->areas; next = addressSpace->areas;
for (last = NULL; next != NULL; for (last = NULL; next != NULL;
@@ -1231,7 +1235,8 @@ second_chance:
break; break;
} }
if (alignedBase == next->base && next->size >= size) { if ((next->protection & RESERVED_AVOID_BASE) == 0
&& alignedBase == next->base && next->size >= size) {
// The new area will be placed at the beginning of the // The new area will be placed at the beginning of the
// reserved area and the reserved area will be offset // reserved area and the reserved area will be offset
// and resized // and resized
@@ -1242,7 +1247,7 @@ second_chance:
break; break;
} }
if (IS_VALID_SPOT(next->base, alignedBase, size, if (is_valid_spot(next->base, alignedBase, size,
next->base + (next->size - 1))) { next->base + (next->size - 1))) {
// The new area will be placed at the end of the // The new area will be placed at the end of the
// reserved area, and the reserved area will be resized // reserved area, and the reserved area will be resized
@@ -1375,11 +1380,8 @@ insert_area(vm_address_space* addressSpace, void** _address,
status = find_and_insert_area_slot(addressSpace, searchBase, size, status = find_and_insert_area_slot(addressSpace, searchBase, size,
searchEnd, addressSpec, area); searchEnd, addressSpec, area);
if (status == B_OK) { if (status == B_OK)
// TODO: do we have to do anything about B_ANY_KERNEL_ADDRESS
// vs. B_ANY_KERNEL_BLOCK_ADDRESS here?
*_address = (void*)area->base; *_address = (void*)area->base;
}
return status; return status;
} }
@@ -6111,7 +6113,8 @@ delete_area(area_id area)
status_t status_t
_user_reserve_address_range(addr_t* userAddress, uint32 addressSpec, addr_t size) _user_reserve_address_range(addr_t* userAddress, uint32 addressSpec,
addr_t size)
{ {
// filter out some unavailable values (for userland) // filter out some unavailable values (for userland)
switch (addressSpec) { switch (addressSpec) {