linux-user: Use page_find_range_empty for mmap_find_vma_reserved
Use the interval tree to find empty space, rather than probing each page in turn. Signed-off-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <20230707204054.8792-19-richard.henderson@linaro.org>
This commit is contained in:
parent
f12294b5bd
commit
4c13048e02
@ -318,55 +318,15 @@ unsigned long last_brk;
|
|||||||
static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size,
|
static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size,
|
||||||
abi_ulong align)
|
abi_ulong align)
|
||||||
{
|
{
|
||||||
abi_ulong addr, end_addr, incr = qemu_host_page_size;
|
target_ulong ret;
|
||||||
int prot;
|
|
||||||
bool looped = false;
|
|
||||||
|
|
||||||
if (size > reserved_va) {
|
ret = page_find_range_empty(start, reserved_va, size, align);
|
||||||
return (abi_ulong)-1;
|
if (ret == -1 && start > mmap_min_addr) {
|
||||||
|
/* Restart at the beginning of the address space. */
|
||||||
|
ret = page_find_range_empty(mmap_min_addr, start - 1, size, align);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note that start and size have already been aligned by mmap_find_vma. */
|
return ret;
|
||||||
|
|
||||||
end_addr = start + size;
|
|
||||||
/*
|
|
||||||
* Start at the top of the address space, ignoring the last page.
|
|
||||||
* If reserved_va == UINT32_MAX, then end_addr wraps to 0,
|
|
||||||
* throwing the rest of the calculations off.
|
|
||||||
* TODO: rewrite using last_addr instead.
|
|
||||||
* TODO: use the interval tree instead of probing every page.
|
|
||||||
*/
|
|
||||||
if (start > reserved_va - size) {
|
|
||||||
end_addr = ((reserved_va - size) & -align) + size;
|
|
||||||
looped = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Search downward from END_ADDR, checking to see if a page is in use. */
|
|
||||||
addr = end_addr;
|
|
||||||
while (1) {
|
|
||||||
addr -= incr;
|
|
||||||
if (addr > end_addr) {
|
|
||||||
if (looped) {
|
|
||||||
/* Failure. The entire address space has been searched. */
|
|
||||||
return (abi_ulong)-1;
|
|
||||||
}
|
|
||||||
/* Re-start at the top of the address space (see above). */
|
|
||||||
addr = end_addr = ((reserved_va - size) & -align) + size;
|
|
||||||
looped = true;
|
|
||||||
} else {
|
|
||||||
prot = page_get_flags(addr);
|
|
||||||
if (prot) {
|
|
||||||
/* Page in use. Restart below this page. */
|
|
||||||
addr = end_addr = ((addr - size) & -align) + size;
|
|
||||||
} else if (addr && addr + size == end_addr) {
|
|
||||||
/* Success! All pages between ADDR and END_ADDR are free. */
|
|
||||||
if (start == mmap_next_start) {
|
|
||||||
mmap_next_start = addr;
|
|
||||||
}
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Loading…
x
Reference in New Issue
Block a user