diff --git a/include/xo/arena/ArenaConfig.hpp b/include/xo/arena/ArenaConfig.hpp index 9ca2a38..d1ecbdc 100644 --- a/include/xo/arena/ArenaConfig.hpp +++ b/include/xo/arena/ArenaConfig.hpp @@ -31,6 +31,12 @@ namespace xo { return copy; } + ArenaConfig with_store_header_flag(bool x) const { + ArenaConfig copy(*this); + copy.store_header_flag_ = x; + return copy; + } + /** @defgroup mm-arenaconfig-instance-vars ArenaConfig members **/ ///@{ @@ -44,7 +50,7 @@ namespace xo { std::size_t hugepage_z_ = 2 * 1024 * 1024; /** true to store header (8 bytes) at the beginning of each allocation. * necessary and sufficient to allows iterating over allocs - * present in arena + * present in arena. **/ bool store_header_flag_ = false; /** configuration for per-alloc header **/ diff --git a/include/xo/arena/DArena.hpp b/include/xo/arena/DArena.hpp index 4c12c8c..658d2b1 100644 --- a/include/xo/arena/DArena.hpp +++ b/include/xo/arena/DArena.hpp @@ -205,7 +205,7 @@ namespace xo { void establish_initial_guard() noexcept; /** checkpoint arena state. Revert to the same state with - * @ref rstore + * @ref restore **/ Checkpoint checkpoint() noexcept { return Checkpoint(free_); } diff --git a/include/xo/arena/DArenaHashMap.hpp b/include/xo/arena/DArenaHashMap.hpp index c40f692..c52b989 100644 --- a/include/xo/arena/DArenaHashMap.hpp +++ b/include/xo/arena/DArenaHashMap.hpp @@ -30,8 +30,10 @@ namespace xo { * * Replicates (to the extent feasible) std::unordered_map * - * @tparam K key type. - * @tparam V value type. + * @tparam Key key type. + * @tparam Value value type. + * @tparam Hash hash function for keys + * @tparam Equal equality function for keys **/ template @@ -122,14 +123,16 @@ namespace xo { size_type arena_align_z, DArena::value_type lo, DArena::value_type hi) - : store_{cfg, page_z, arena_align_z, lo, hi} + : store_{cfg, page_z, arena_align_z, lo, hi}, + zero_ckp_{store_.checkpoint()} {} template DArenaVector::DArenaVector(DArenaVector && other) - : size_{other.size_}, store_{std::move(other.store_)} + : size_{other.size_}, store_{std::move(other.store_)}, zero_ckp_{std::move(other.zero_ckp_)} { other.size_ = 0; + other.zero_ckp_ = DArena::Checkpoint(); } template @@ -153,8 +156,10 @@ namespace xo { { this->size_ = other.size_; this->store_ = std::move(other.store_); + this->zero_ckp_ = std::move(other.zero_ckp_); other.size_ = 0; + other.zero_ckp_ = DArena::Checkpoint(); return *this; } @@ -166,6 +171,7 @@ namespace xo { DArenaVector retval; retval.store_ = std::move(DArena::map(cfg)); + retval.zero_ckp_ = retval.store_.checkpoint(); return retval; } @@ -179,9 +185,11 @@ namespace xo { template void DArenaVector::resize(size_type z) { + // new arena size in bytes + size_t req_z = z * sizeof(T); + if (z > size_) { // expand arena to accomodate - size_t req_z = z * sizeof(T); store_.expand(req_z); @@ -208,6 +216,14 @@ namespace xo { } } + // rewind to checkpoint, then reallocate. + // This is for form's sake, so that DArena considers memory + // to be 'allocated'. DArenaVector doesn't care for itself, + // but this preserves expected behavior of visit_pools(). + // + store_.restore(zero_ckp_); + store_.alloc(xo::reflect::typeseq::id(), req_z); + this->size_ = z; } diff --git a/include/xo/arena/hashmap/HashMapStore.hpp b/include/xo/arena/hashmap/HashMapStore.hpp index 3485022..436e88e 100644 --- a/include/xo/arena/hashmap/HashMapStore.hpp +++ b/include/xo/arena/hashmap/HashMapStore.hpp @@ -33,11 +33,13 @@ namespace xo { control_{control_vector_type::map (xo::mm::ArenaConfig{ .name_ = name + "-ctl", - .size_ = control_size(n_slot_)})}, + .size_ = control_size(n_slot_), + .store_header_flag_ = false})}, slots_{slot_vector_type::map (xo::mm::ArenaConfig{ .name_ = name + "-slots", - .size_ = n_slot_ * sizeof(value_type)})} + .size_ = n_slot_ * sizeof(value_type), + .store_header_flag_ = false})} { /* here: arenas have allocated address range, but no committed memory yet */