From a91d0d02023d38dc5902725d097d049cfabdd7e6 Mon Sep 17 00:00:00 2001 From: Roland Conybeare Date: Sun, 23 Nov 2025 11:35:05 -0500 Subject: [PATCH] xo-alloc: bugfix expand: limit_ is soft, hi_ is hard. + docs --- xo-alloc/include/xo/alloc/ArenaAlloc.hpp | 6 ++++-- xo-alloc/src/alloc/ArenaAlloc.cpp | 27 +++++++++++++++++++++++- 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/xo-alloc/include/xo/alloc/ArenaAlloc.hpp b/xo-alloc/include/xo/alloc/ArenaAlloc.hpp index e0bfed2f..302d9c0a 100644 --- a/xo-alloc/include/xo/alloc/ArenaAlloc.hpp +++ b/xo-alloc/include/xo/alloc/ArenaAlloc.hpp @@ -127,7 +127,7 @@ namespace xo { bool debug_flag); /** size of virtual address range reserved for this allocator **/ - std::size_t reserved() const { return this->size(); } + std::size_t reserved() const { return hi_ - lo_; }; std::size_t page_size() const { return page_z_; } std::byte * free_ptr() const { return free_ptr_; } @@ -212,7 +212,9 @@ namespace xo { std::byte * checkpoint_ = nullptr; /** free pointer. memory in range [@ref free_, @ref limit_) available **/ std::byte * free_ptr_ = nullptr; - /** soft limit: end of committed virtual memory **/ + /** soft limit: end of committed virtual memory + * invariant: @ref limit_ = @ref lo_ + @ref committed_z_ + **/ std::byte * limit_ = nullptr; /** hard limit: end of reserved virtual memory **/ std::byte * hi_ = nullptr; diff --git a/xo-alloc/src/alloc/ArenaAlloc.cpp b/xo-alloc/src/alloc/ArenaAlloc.cpp index e5609297..c06b9518 100644 --- a/xo-alloc/src/alloc/ArenaAlloc.cpp +++ b/xo-alloc/src/alloc/ArenaAlloc.cpp @@ -170,15 +170,37 @@ namespace xo { return true; } - if (lo_ + offset_z > limit_) { + if (lo_ + offset_z > hi_) { throw std::runtime_error(tostr("ArenaAlloc::expand: requested size exceeds reserved size", xtag("requested", offset_z), xtag("reserved", reserved()))); } + /* + * pre: + * + * _______________................................... + * ^ ^ ^ + * lo limit hi + * + * < committed_z > + * <----------offset_z-----------> + * > <- z: 0 <= z < hugepage_z + * <---------aligned_offset_z---------> + * <--- add_commit_z --> + * + * post: + * ____________________________________.............. + * ^ ^ ^ + * lo limit hi + * + */ + std::size_t aligned_offset_z = align_lub(offset_z, hugepage_z_); std::byte * commit_start = lo_ + committed_z_; std::size_t add_commit_z = aligned_offset_z - committed_z_; + assert(limit_ == lo_ + committed_z_); + log && log(xtag("aligned_offset_z", aligned_offset_z), xtag("add_commit_z", add_commit_z)); @@ -196,6 +218,9 @@ namespace xo { this->committed_z_ = aligned_offset_z; this->limit_ = this->lo_ + committed_z_; + assert(committed_z_ % hugepage_z_ == 0); + assert(reinterpret_cast(limit_) % hugepage_z_ == 0); + return true; }