Throw bad_alloc exception in MiMemoryResource if the allocation fails
This commit is contained in:
parent
770fe0fe47
commit
b197e2c78e
|
@ -339,6 +339,7 @@ DashTable<_Key, _Value, Policy>::DashTable(size_t capacity_log, const Policy& po
|
||||||
segment_.resize(unique_segments_);
|
segment_.resize(unique_segments_);
|
||||||
std::pmr::polymorphic_allocator<SegmentType> pa(mr);
|
std::pmr::polymorphic_allocator<SegmentType> pa(mr);
|
||||||
|
|
||||||
|
// I assume we have enough memory to create the initial table and do not check allocations.
|
||||||
for (auto& ptr : segment_) {
|
for (auto& ptr : segment_) {
|
||||||
ptr = pa.allocate(1);
|
ptr = pa.allocate(1);
|
||||||
pa.construct(ptr, global_depth_); // new SegmentType(global_depth_);
|
pa.construct(ptr, global_depth_); // new SegmentType(global_depth_);
|
||||||
|
|
|
@ -71,6 +71,39 @@ struct UInt64Policy : public BasicDashPolicy {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class CappedResource final : public std::pmr::memory_resource {
|
||||||
|
public:
|
||||||
|
explicit CappedResource(size_t cap) : cap_(cap) {
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t used() const {
|
||||||
|
return used_;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void* do_allocate(std::size_t size, std::size_t align) {
|
||||||
|
if (used_ + size > cap_)
|
||||||
|
throw std::bad_alloc{};
|
||||||
|
|
||||||
|
void* res = pmr::get_default_resource()->allocate(size, align);
|
||||||
|
used_ += size;
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
void do_deallocate(void* ptr, std::size_t size, std::size_t align) {
|
||||||
|
used_ -= size;
|
||||||
|
pmr::get_default_resource()->deallocate(ptr, size, align);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool do_is_equal(const std::pmr::memory_resource& o) const noexcept {
|
||||||
|
return this == &o;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t cap_;
|
||||||
|
size_t used_ = 0;
|
||||||
|
};
|
||||||
|
|
||||||
using Segment = detail::Segment<uint64_t, Buf24>;
|
using Segment = detail::Segment<uint64_t, Buf24>;
|
||||||
using Dash64 = DashTable<uint64_t, uint64_t, UInt64Policy>;
|
using Dash64 = DashTable<uint64_t, uint64_t, UInt64Policy>;
|
||||||
|
|
||||||
|
@ -296,6 +329,19 @@ TEST_F(DashTest, Insert2) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST_F(DashTest, InsertOOM) {
|
||||||
|
CappedResource resource(1 << 15);
|
||||||
|
Dash64 dt{1, UInt64Policy{}, &resource};
|
||||||
|
|
||||||
|
ASSERT_THROW(
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < (1 << 14); ++i) {
|
||||||
|
dt.Insert(i, 0);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
std::bad_alloc);
|
||||||
|
}
|
||||||
|
|
||||||
struct Item {
|
struct Item {
|
||||||
char buf[24];
|
char buf[24];
|
||||||
};
|
};
|
||||||
|
|
|
@ -22,7 +22,9 @@ class MiMemoryResource final : public std::pmr::memory_resource {
|
||||||
private:
|
private:
|
||||||
void* do_allocate(std::size_t size, std::size_t align) {
|
void* do_allocate(std::size_t size, std::size_t align) {
|
||||||
void* res = mi_heap_malloc_aligned(heap_, size, align);
|
void* res = mi_heap_malloc_aligned(heap_, size, align);
|
||||||
if (res)
|
|
||||||
|
if (!res)
|
||||||
|
throw std::bad_alloc{};
|
||||||
used_ += mi_good_size(size);
|
used_ += mi_good_size(size);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue