AK: Make Bitmap construction OOM-fallible

This commit is contained in:
Idan Horowitz 2022-02-10 18:53:26 +02:00
parent 1667a80ade
commit 871a53db76
Notes: sideshowbarker 2024-07-18 02:13:10 +09:00
6 changed files with 44 additions and 32 deletions

View file

@ -7,10 +7,12 @@
#pragma once
#include <AK/BitmapView.h>
#include <AK/Error.h>
#include <AK/Noncopyable.h>
#include <AK/Optional.h>
#include <AK/Platform.h>
#include <AK/StdLibExtras.h>
#include <AK/Try.h>
#include <AK/Types.h>
#include <AK/kmalloc.h>
@ -20,16 +22,26 @@ class Bitmap : public BitmapView {
AK_MAKE_NONCOPYABLE(Bitmap);
public:
Bitmap() = default;
Bitmap(size_t size, bool default_value)
: BitmapView(static_cast<u8*>(kmalloc(ceil_div(size, static_cast<size_t>(8)))), size)
, m_is_owning(true)
static ErrorOr<Bitmap> try_create(size_t size, bool default_value)
{
VERIFY(size != 0);
fill(default_value);
auto* data = kmalloc(ceil_div(size, static_cast<size_t>(8)));
if (!data)
return Error::from_errno(ENOMEM);
auto bitmap = Bitmap { (u8*)data, size, true };
bitmap.fill(default_value);
return bitmap;
}
static Bitmap must_create(size_t size, bool default_value)
{
return MUST(try_create(size, default_value));
}
Bitmap() = default;
Bitmap(u8* data, size_t size, bool is_owning = false)
: BitmapView(data, size)
, m_is_owning(is_owning)

View file

@ -19,7 +19,7 @@ NonnullOwnPtr<HostBridge> HostBridge::must_create_with_io_access()
HostBridge::HostBridge(PCI::Domain const& domain)
: HostController(domain)
, m_enumerated_buses(256, false)
, m_enumerated_buses(Bitmap::try_create(256, false).release_value_but_fixme_should_propagate_errors())
{
}

View file

@ -253,7 +253,7 @@ NonnullRefPtr<PhysicalPage> AnonymousVMObject::allocate_committed_page(Badge<Reg
Bitmap& AnonymousVMObject::ensure_cow_map()
{
if (m_cow_map.is_null())
m_cow_map = Bitmap { page_count(), true };
m_cow_map = Bitmap::try_create(page_count(), true).release_value_but_fixme_should_propagate_errors();
return m_cow_map;
}

View file

@ -12,14 +12,14 @@ namespace Kernel::Memory {
InodeVMObject::InodeVMObject(Inode& inode, FixedArray<RefPtr<PhysicalPage>>&& new_physical_pages)
: VMObject(move(new_physical_pages))
, m_inode(inode)
, m_dirty_pages(page_count(), false)
, m_dirty_pages(Bitmap::try_create(page_count(), false).release_value_but_fixme_should_propagate_errors())
{
}
InodeVMObject::InodeVMObject(InodeVMObject const& other, FixedArray<RefPtr<PhysicalPage>>&& new_physical_pages)
: VMObject(move(new_physical_pages))
, m_inode(other.m_inode)
, m_dirty_pages(page_count(), false)
, m_dirty_pages(Bitmap::try_create(page_count(), false).release_value_but_fixme_should_propagate_errors())
{
for (size_t i = 0; i < page_count(); ++i)
m_dirty_pages.set(i, other.m_dirty_pages.get(i));

View file

@ -16,14 +16,14 @@ TEST_CASE(construct_empty)
TEST_CASE(find_first_set)
{
Bitmap bitmap(128, false);
auto bitmap = Bitmap::must_create(128, false);
bitmap.set(69, true);
EXPECT_EQ(bitmap.find_first_set().value(), 69u);
}
TEST_CASE(find_first_unset)
{
Bitmap bitmap(128, true);
auto bitmap = Bitmap::must_create(128, true);
bitmap.set(51, false);
EXPECT_EQ(bitmap.find_first_unset().value(), 51u);
}
@ -31,7 +31,7 @@ TEST_CASE(find_first_unset)
TEST_CASE(find_one_anywhere_set)
{
{
Bitmap bitmap(168, false);
auto bitmap = Bitmap::must_create(168, false);
bitmap.set(34, true);
bitmap.set(97, true);
EXPECT_EQ(bitmap.find_one_anywhere_set(0).value(), 34u);
@ -48,7 +48,7 @@ TEST_CASE(find_one_anywhere_set)
EXPECT_EQ(bitmap.find_one_anywhere_set(128).value(), 34u);
}
{
Bitmap bitmap(128 + 24, false);
auto bitmap = Bitmap::must_create(128 + 24, false);
bitmap.set(34, true);
bitmap.set(126, true);
EXPECT_EQ(bitmap.find_one_anywhere_set(0).value(), 34u);
@ -56,7 +56,7 @@ TEST_CASE(find_one_anywhere_set)
EXPECT_EQ(bitmap.find_one_anywhere_set(64).value(), 126u);
}
{
Bitmap bitmap(32, false);
auto bitmap = Bitmap::must_create(32, false);
bitmap.set(12, true);
bitmap.set(24, true);
auto got = bitmap.find_one_anywhere_set(0).value();
@ -67,7 +67,7 @@ TEST_CASE(find_one_anywhere_set)
TEST_CASE(find_one_anywhere_unset)
{
{
Bitmap bitmap(168, true);
auto bitmap = Bitmap::must_create(168, true);
bitmap.set(34, false);
bitmap.set(97, false);
EXPECT_EQ(bitmap.find_one_anywhere_unset(0).value(), 34u);
@ -84,7 +84,7 @@ TEST_CASE(find_one_anywhere_unset)
EXPECT_EQ(bitmap.find_one_anywhere_unset(128).value(), 34u);
}
{
Bitmap bitmap(128 + 24, true);
auto bitmap = Bitmap::must_create(128 + 24, true);
bitmap.set(34, false);
bitmap.set(126, false);
EXPECT_EQ(bitmap.find_one_anywhere_unset(0).value(), 34u);
@ -92,7 +92,7 @@ TEST_CASE(find_one_anywhere_unset)
EXPECT_EQ(bitmap.find_one_anywhere_unset(64).value(), 126u);
}
{
Bitmap bitmap(32, true);
auto bitmap = Bitmap::must_create(32, true);
bitmap.set(12, false);
bitmap.set(24, false);
auto got = bitmap.find_one_anywhere_unset(0).value();
@ -102,7 +102,7 @@ TEST_CASE(find_one_anywhere_unset)
TEST_CASE(find_first_range)
{
Bitmap bitmap(128, true);
auto bitmap = Bitmap::must_create(128, true);
bitmap.set(47, false);
bitmap.set(48, false);
bitmap.set(49, false);
@ -118,7 +118,7 @@ TEST_CASE(find_first_range)
TEST_CASE(set_range)
{
{
Bitmap bitmap(128, false);
auto bitmap = Bitmap::must_create(128, false);
bitmap.set_range(41, 10, true);
EXPECT_EQ(bitmap.get(40), false);
EXPECT_EQ(bitmap.get(41), true);
@ -134,7 +134,7 @@ TEST_CASE(set_range)
EXPECT_EQ(bitmap.get(51), false);
}
{
Bitmap bitmap(288, false);
auto bitmap = Bitmap::must_create(288, false);
bitmap.set_range(48, 32, true);
bitmap.set_range(94, 39, true);
bitmap.set_range(190, 71, true);
@ -152,12 +152,12 @@ TEST_CASE(set_range)
TEST_CASE(find_first_fit)
{
{
Bitmap bitmap(32, true);
auto bitmap = Bitmap::must_create(32, true);
auto fit = bitmap.find_first_fit(1);
EXPECT_EQ(fit.has_value(), false);
}
{
Bitmap bitmap(32, true);
auto bitmap = Bitmap::must_create(32, true);
bitmap.set(31, false);
auto fit = bitmap.find_first_fit(1);
EXPECT_EQ(fit.has_value(), true);
@ -165,7 +165,7 @@ TEST_CASE(find_first_fit)
}
for (size_t i = 0; i < 128; ++i) {
Bitmap bitmap(128, true);
auto bitmap = Bitmap::must_create(128, true);
bitmap.set(i, false);
auto fit = bitmap.find_first_fit(1);
EXPECT_EQ(fit.has_value(), true);
@ -173,7 +173,7 @@ TEST_CASE(find_first_fit)
}
for (size_t i = 0; i < 127; ++i) {
Bitmap bitmap(128, true);
auto bitmap = Bitmap::must_create(128, true);
bitmap.set(i, false);
bitmap.set(i + 1, false);
auto fit = bitmap.find_first_fit(2);
@ -184,7 +184,7 @@ TEST_CASE(find_first_fit)
size_t bitmap_size = 1024;
for (size_t chunk_size = 1; chunk_size < 64; ++chunk_size) {
for (size_t i = 0; i < bitmap_size - chunk_size; ++i) {
Bitmap bitmap(bitmap_size, true);
auto bitmap = Bitmap::must_create(bitmap_size, true);
for (size_t c = 0; c < chunk_size; ++c)
bitmap.set(i + c, false);
auto fit = bitmap.find_first_fit(chunk_size);
@ -196,7 +196,7 @@ TEST_CASE(find_first_fit)
TEST_CASE(find_longest_range_of_unset_bits_edge)
{
Bitmap bitmap(36, true);
auto bitmap = Bitmap::must_create(36, true);
bitmap.set_range(32, 4, false);
size_t found_range_size = 0;
auto result = bitmap.find_longest_range_of_unset_bits(1, found_range_size);
@ -206,7 +206,7 @@ TEST_CASE(find_longest_range_of_unset_bits_edge)
TEST_CASE(count_in_range)
{
Bitmap bitmap(256, false);
auto bitmap = Bitmap::must_create(256, false);
bitmap.set(14, true);
bitmap.set(17, true);
bitmap.set(19, true);
@ -252,14 +252,14 @@ TEST_CASE(count_in_range)
TEST_CASE(byte_aligned_access)
{
{
Bitmap bitmap(16, true);
auto bitmap = Bitmap::must_create(16, true);
EXPECT_EQ(bitmap.count_in_range(0, 16, true), 16u);
EXPECT_EQ(bitmap.count_in_range(8, 8, true), 8u);
EXPECT_EQ(bitmap.count_in_range(0, 8, true), 8u);
EXPECT_EQ(bitmap.count_in_range(4, 8, true), 8u);
}
{
Bitmap bitmap(16, false);
auto bitmap = Bitmap::must_create(16, false);
bitmap.set_range(4, 8, true);
EXPECT_EQ(bitmap.count_in_range(0, 16, true), 8u);
EXPECT_EQ(bitmap.count_in_range(8, 8, true), 4u);
@ -267,7 +267,7 @@ TEST_CASE(byte_aligned_access)
EXPECT_EQ(bitmap.count_in_range(4, 8, true), 8u);
}
{
Bitmap bitmap(8, false);
auto bitmap = Bitmap::must_create(8, false);
bitmap.set(2, true);
bitmap.set(4, true);
EXPECT_EQ(bitmap.count_in_range(0, 2, true), 0u);

View file

@ -47,7 +47,7 @@ public:
void will_track_seen_events(size_t profile_event_count)
{
if (m_seen_events.size() != profile_event_count)
m_seen_events = Bitmap { profile_event_count, false };
m_seen_events = Bitmap::must_create(profile_event_count, false);
}
bool has_seen_event(size_t event_index) const { return m_seen_events.get(event_index); }
void did_see_event(size_t event_index) { m_seen_events.set(event_index, true); }