1
Fork 0
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:
Andreas Kling 2021-09-05 23:12:16 +02:00
parent 21f7932ae2
commit f4a9a0d561
9 changed files with 82 additions and 95 deletions

View file

@ -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)