mirror of
https://github.com/RGBCube/serenity
synced 2025-05-31 11:48:10 +00:00
Kernel: Make VirtualRangeAllocator return KResultOr<VirtualRange>
This achieves two things: - The allocator can report more specific errors - Callers can (and now do) use TRY() :^)
This commit is contained in:
parent
21f7932ae2
commit
f4a9a0d561
9 changed files with 82 additions and 95 deletions
|
@ -56,10 +56,10 @@ void VirtualRangeAllocator::carve_at_iterator(auto& it, VirtualRange const& rang
|
|||
}
|
||||
}
|
||||
|
||||
Optional<VirtualRange> VirtualRangeAllocator::allocate_randomized(size_t size, size_t alignment)
|
||||
KResultOr<VirtualRange> VirtualRangeAllocator::try_allocate_randomized(size_t size, size_t alignment)
|
||||
{
|
||||
if (!size)
|
||||
return {};
|
||||
return EINVAL;
|
||||
|
||||
VERIFY((size % PAGE_SIZE) == 0);
|
||||
VERIFY((alignment % PAGE_SIZE) == 0);
|
||||
|
@ -72,18 +72,18 @@ Optional<VirtualRange> VirtualRangeAllocator::allocate_randomized(size_t size, s
|
|||
if (!m_total_range.contains(random_address, size))
|
||||
continue;
|
||||
|
||||
auto range = allocate_specific(random_address, size);
|
||||
if (range.has_value())
|
||||
return range;
|
||||
auto range_or_error = try_allocate_specific(random_address, size);
|
||||
if (!range_or_error.is_error())
|
||||
return range_or_error.release_value();
|
||||
}
|
||||
|
||||
return allocate_anywhere(size, alignment);
|
||||
return try_allocate_anywhere(size, alignment);
|
||||
}
|
||||
|
||||
Optional<VirtualRange> VirtualRangeAllocator::allocate_anywhere(size_t size, size_t alignment)
|
||||
KResultOr<VirtualRange> VirtualRangeAllocator::try_allocate_anywhere(size_t size, size_t alignment)
|
||||
{
|
||||
if (!size)
|
||||
return {};
|
||||
return EINVAL;
|
||||
|
||||
VERIFY((size % PAGE_SIZE) == 0);
|
||||
VERIFY((alignment % PAGE_SIZE) == 0);
|
||||
|
@ -91,7 +91,7 @@ Optional<VirtualRange> VirtualRangeAllocator::allocate_anywhere(size_t size, siz
|
|||
#ifdef VM_GUARD_PAGES
|
||||
// NOTE: We pad VM allocations with a guard page on each side.
|
||||
if (Checked<size_t>::addition_would_overflow(size, PAGE_SIZE * 2))
|
||||
return {};
|
||||
return EOVERFLOW;
|
||||
|
||||
size_t effective_size = size + PAGE_SIZE * 2;
|
||||
size_t offset_from_effective_base = PAGE_SIZE;
|
||||
|
@ -101,7 +101,7 @@ Optional<VirtualRange> VirtualRangeAllocator::allocate_anywhere(size_t size, siz
|
|||
#endif
|
||||
|
||||
if (Checked<size_t>::addition_would_overflow(effective_size, alignment))
|
||||
return {};
|
||||
return EOVERFLOW;
|
||||
|
||||
SpinlockLocker lock(m_lock);
|
||||
|
||||
|
@ -126,21 +126,20 @@ Optional<VirtualRange> VirtualRangeAllocator::allocate_anywhere(size_t size, siz
|
|||
return allocated_range;
|
||||
}
|
||||
dmesgln("VirtualRangeAllocator: Failed to allocate anywhere: size={}, alignment={}", size, alignment);
|
||||
return {};
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
Optional<VirtualRange> VirtualRangeAllocator::allocate_specific(VirtualAddress base, size_t size)
|
||||
KResultOr<VirtualRange> VirtualRangeAllocator::try_allocate_specific(VirtualAddress base, size_t size)
|
||||
{
|
||||
if (!size)
|
||||
return {};
|
||||
return EINVAL;
|
||||
|
||||
VERIFY(base.is_page_aligned());
|
||||
VERIFY((size % PAGE_SIZE) == 0);
|
||||
|
||||
VirtualRange const allocated_range(base, size);
|
||||
if (!m_total_range.contains(allocated_range)) {
|
||||
return {};
|
||||
}
|
||||
if (!m_total_range.contains(allocated_range))
|
||||
return ENOMEM;
|
||||
|
||||
SpinlockLocker lock(m_lock);
|
||||
for (auto it = m_available_ranges.begin(); !it.is_end(); ++it) {
|
||||
|
@ -154,7 +153,7 @@ Optional<VirtualRange> VirtualRangeAllocator::allocate_specific(VirtualAddress b
|
|||
carve_at_iterator(it, allocated_range);
|
||||
return allocated_range;
|
||||
}
|
||||
return {};
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
void VirtualRangeAllocator::deallocate(VirtualRange const& range)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue