xo-alloc2: DX1CollectorIterator infra [WIP]
This commit is contained in:
parent
59c0311ed7
commit
bf27314688
30 changed files with 1041 additions and 176 deletions
|
|
@ -7,7 +7,6 @@
|
|||
|
||||
namespace xo {
|
||||
namespace mm {
|
||||
|
||||
auto
|
||||
AllocInfo::guard_lo() const noexcept -> span_type
|
||||
{
|
||||
|
|
@ -18,6 +17,18 @@ namespace xo {
|
|||
p_guard_lo_ + p_config_->guard_z_);
|
||||
}
|
||||
|
||||
auto
|
||||
AllocInfo::payload() const noexcept -> span_type
|
||||
{
|
||||
if (!p_header_)
|
||||
return span_type(nullptr, nullptr);
|
||||
|
||||
byte * lo = (byte *)(p_header_ + 1);
|
||||
size_type z = this->size();
|
||||
|
||||
return span_type(lo, lo+z);
|
||||
}
|
||||
|
||||
auto
|
||||
AllocInfo::guard_hi() const noexcept -> span_type
|
||||
{
|
||||
|
|
|
|||
|
|
@ -11,13 +11,17 @@ set(SELF_SRCS
|
|||
IAllocator_DArena.cpp
|
||||
|
||||
IAllocIterator_Any.cpp
|
||||
DArenaIterator.cpp
|
||||
IAllocIterator_DArenaIterator.cpp
|
||||
|
||||
ICollector_Any.cpp
|
||||
IGCObject_Any.cpp
|
||||
IAllocator_DX1Collector.cpp
|
||||
ICollector_DX1Collector.cpp
|
||||
IAllocIterator_DX1CollectorIterator.cpp
|
||||
|
||||
DX1Collector.cpp
|
||||
DX1CollectorIterator.cpp
|
||||
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "alloc/AAllocator.hpp"
|
||||
#include "arena/DArena.hpp"
|
||||
#include "arena/DArenaIterator.hpp"
|
||||
#include "xo/alloc2/padding.hpp"
|
||||
#include "xo/indentlog/print/tag.hpp"
|
||||
#include <cassert>
|
||||
|
|
@ -249,15 +250,10 @@ namespace xo {
|
|||
}
|
||||
|
||||
AllocInfo
|
||||
DArena::alloc_info(value_type mem) noexcept
|
||||
DArena::alloc_info(value_type mem) const noexcept
|
||||
{
|
||||
if (!config_.store_header_flag_) [[unlikely]] {
|
||||
++(error_count_);
|
||||
last_error_ = AllocError(error::alloc_info_disabled,
|
||||
error_count_,
|
||||
0 /*add_commit_z*/,
|
||||
committed_z_,
|
||||
this->reserved());
|
||||
this->capture_error(error::alloc_info_disabled);
|
||||
|
||||
return AllocInfo::error_not_configured(&config_.header_);
|
||||
}
|
||||
|
|
@ -265,12 +261,7 @@ namespace xo {
|
|||
byte * header_mem = mem - sizeof(AllocHeader);
|
||||
|
||||
if (!this->contains(header_mem)) {
|
||||
++(error_count_);
|
||||
last_error_ = AllocError(error::alloc_info_address,
|
||||
error_count_,
|
||||
0 /*add_commit_z*/,
|
||||
committed_z_,
|
||||
this->reserved());
|
||||
this->capture_error(error::alloc_info_address);
|
||||
}
|
||||
|
||||
AllocHeader * header = (AllocHeader *)header_mem;
|
||||
|
|
@ -286,6 +277,32 @@ namespace xo {
|
|||
guard_hi);
|
||||
}
|
||||
|
||||
DArenaIterator
|
||||
DArena::begin() const noexcept
|
||||
{
|
||||
return DArenaIterator::begin(this);
|
||||
}
|
||||
|
||||
DArenaIterator
|
||||
DArena::end() const noexcept
|
||||
{
|
||||
return DArenaIterator::end(this);
|
||||
}
|
||||
|
||||
void
|
||||
DArena::capture_error(error err,
|
||||
size_type target_z) const
|
||||
{
|
||||
DArena * self = const_cast<DArena *>(this);
|
||||
|
||||
++(self->error_count_);
|
||||
self->last_error_ = AllocError(err,
|
||||
error_count_,
|
||||
target_z,
|
||||
committed_z_,
|
||||
reserved());
|
||||
}
|
||||
|
||||
void
|
||||
DArena::clear() noexcept
|
||||
{
|
||||
|
|
|
|||
134
src/alloc2/DArenaIterator.cpp
Normal file
134
src/alloc2/DArenaIterator.cpp
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
/** @file DArenaIterator.cpp
|
||||
*
|
||||
* @author Roland Conybeare, Dec 2025
|
||||
**/
|
||||
|
||||
#include "arena/DArenaIterator.hpp"
|
||||
#include "arena/DArena.hpp"
|
||||
#include <xo/indentlog/scope.hpp>
|
||||
#include <xo/indentlog/print/tag.hpp>
|
||||
#include <cassert>
|
||||
|
||||
namespace xo {
|
||||
using std::byte;
|
||||
|
||||
namespace mm {
|
||||
DArenaIterator
|
||||
DArenaIterator::begin(const DArena * arena)
|
||||
{
|
||||
constexpr bool c_debug_flag = false;
|
||||
scope log(XO_DEBUG(c_debug_flag));
|
||||
|
||||
assert(arena);
|
||||
|
||||
if (arena->config_.store_header_flag_ == false) {
|
||||
arena->capture_error(error::alloc_iterator_not_supported);
|
||||
|
||||
return DArenaIterator::invalid();
|
||||
}
|
||||
|
||||
byte * begin_byte = arena->lo_;
|
||||
AllocHeader * begin_hdr = (AllocHeader *)begin_byte;
|
||||
|
||||
log && log(xtag("begin_hdr", begin_hdr));
|
||||
|
||||
return DArenaIterator(arena, begin_hdr);
|
||||
}
|
||||
|
||||
DArenaIterator
|
||||
DArenaIterator::end(const DArena * arena)
|
||||
{
|
||||
constexpr bool c_debug_flag = false;
|
||||
scope log(XO_DEBUG(c_debug_flag));
|
||||
|
||||
assert(arena);
|
||||
|
||||
if (arena->config_.store_header_flag_ == false) {
|
||||
arena->capture_error(error::alloc_iterator_not_supported);
|
||||
|
||||
return DArenaIterator::invalid();
|
||||
}
|
||||
|
||||
byte * end_byte = arena->free_;
|
||||
AllocHeader * end_hdr = (AllocHeader *)end_byte;
|
||||
|
||||
log && log(xtag("end_hdr", end_hdr));
|
||||
|
||||
return DArenaIterator(arena, end_hdr);
|
||||
}
|
||||
|
||||
AllocInfo
|
||||
DArenaIterator::deref() const noexcept
|
||||
{
|
||||
constexpr bool c_debug_flag = false;
|
||||
scope log(XO_DEBUG(c_debug_flag));
|
||||
|
||||
bool contains_flag = arena_->contains(this->pos_as_byte());
|
||||
bool bounds_flag = (this->pos_as_byte() < arena_->free_);
|
||||
|
||||
log && log(xtag("contains_flag", contains_flag),
|
||||
xtag("bounds_flag", bounds_flag));
|
||||
|
||||
if (!contains_flag || !bounds_flag) {
|
||||
arena_->capture_error(error::alloc_iterator_deref);
|
||||
|
||||
return AllocInfo::error_invalid_iterator(&(arena_->config_.header_));
|
||||
}
|
||||
|
||||
/* iterator points to beginning of header.
|
||||
* memory given to application start immediately followed header
|
||||
*/
|
||||
|
||||
byte * mem = (byte *)(pos_ + 1);
|
||||
|
||||
return arena_->alloc_info(mem);
|
||||
}
|
||||
|
||||
cmpresult
|
||||
DArenaIterator::compare(const DArenaIterator & other_ix) const noexcept
|
||||
{
|
||||
if (is_invalid() || (arena_ != other_ix.arena_))
|
||||
return cmpresult::incomparable();
|
||||
|
||||
if (pos_ < other_ix.pos_) {
|
||||
return cmpresult::lesser();
|
||||
} else if(pos_ == other_ix.pos_) {
|
||||
return cmpresult::equal();
|
||||
} else {
|
||||
return cmpresult::greater();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DArenaIterator::next() noexcept
|
||||
{
|
||||
constexpr bool c_debug_flag = false;
|
||||
scope log(XO_DEBUG(c_debug_flag));
|
||||
|
||||
bool contains_flag = arena_->contains(this->pos_as_byte());
|
||||
bool bounds_flag = (this->pos_as_byte() < arena_->free_);
|
||||
|
||||
log && log(xtag("contains_flag", contains_flag),
|
||||
xtag("bounds_flag", bounds_flag));
|
||||
|
||||
if (!contains_flag || !bounds_flag) {
|
||||
arena_->capture_error(error::alloc_iterator_next);
|
||||
return;
|
||||
}
|
||||
|
||||
size_t mem_z = arena_->config_.header_.size(*pos_);
|
||||
size_t guard_z = arena_->config_.header_.guard_z_;
|
||||
|
||||
byte * next_as_byte = ((byte *)pos_ + sizeof(AllocHeader) + mem_z + guard_z);
|
||||
/* next == ix.arena_free_ --> iterator is at end of allocator */
|
||||
assert(next_as_byte <= arena_->free_);
|
||||
|
||||
AllocHeader * next = (AllocHeader *)next_as_byte;
|
||||
|
||||
this->pos_ = next;
|
||||
}
|
||||
|
||||
} /*namespace mm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end DArenaIterator.cpp */
|
||||
|
|
@ -6,6 +6,7 @@
|
|||
#include "Allocator.hpp"
|
||||
#include "arena/IAllocator_DArena.hpp"
|
||||
#include "gc/DX1Collector.hpp"
|
||||
#include "gc/DX1CollectorIterator.hpp"
|
||||
#include "gc/generation.hpp"
|
||||
#include "gc/object_age.hpp"
|
||||
#include <xo/facet/obj.hpp>
|
||||
|
|
@ -24,23 +25,6 @@ namespace xo {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef OBSOLETE
|
||||
constexpr std::uint64_t
|
||||
CollectorConfig::gen_shift() const {
|
||||
return arena_config_.header_size_bits_;
|
||||
}
|
||||
|
||||
constexpr std::uint64_t
|
||||
CollectorConfig::gen_mask_unshifted() const {
|
||||
return (1ul << gen_bits_) - 1;
|
||||
}
|
||||
|
||||
constexpr std::uint64_t
|
||||
CollectorConfig::gen_mask_shifted() const {
|
||||
return gen_mask_unshifted() << arena_config_.header_size_bits_;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NOT_USING
|
||||
constexpr std::uint64_t
|
||||
CollectorConfig::tseq_mult() const {
|
||||
|
|
@ -48,23 +32,6 @@ namespace xo {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef OBSOLETE
|
||||
constexpr std::uint64_t
|
||||
CollectorConfig::tseq_shift() const {
|
||||
return gen_bits_ + arena_config_.header_size_bits_;
|
||||
}
|
||||
|
||||
constexpr std::uint64_t
|
||||
CollectorConfig::tseq_mask_unshifted() const {
|
||||
return (1ul << tseq_bits_) - 1;
|
||||
}
|
||||
|
||||
constexpr std::uint64_t
|
||||
CollectorConfig::tseq_mask_shifted() const {
|
||||
return tseq_mask_unshifted() << (gen_bits_ + arena_config_.header_size_bits_);
|
||||
}
|
||||
#endif
|
||||
|
||||
// ----- GCRunState -----
|
||||
|
||||
GCRunState::GCRunState(generation gc_upto)
|
||||
|
|
@ -257,6 +224,27 @@ namespace xo {
|
|||
return this->new_space()->alloc_info(mem);
|
||||
}
|
||||
|
||||
DX1CollectorIterator
|
||||
DX1Collector::begin() const noexcept
|
||||
{
|
||||
return DX1CollectorIterator(this,
|
||||
generation{0},
|
||||
generation{config_.n_generation_},
|
||||
DArenaIterator(),
|
||||
DArenaIterator());
|
||||
}
|
||||
|
||||
DX1CollectorIterator
|
||||
DX1Collector::end() const noexcept {
|
||||
generation gen_hi = generation{config_.n_generation_};
|
||||
|
||||
return DX1CollectorIterator(this,
|
||||
gen_hi,
|
||||
gen_hi,
|
||||
DArenaIterator(),
|
||||
DArenaIterator());
|
||||
}
|
||||
|
||||
void
|
||||
DX1Collector::reverse_roles(generation g) noexcept {
|
||||
assert(g < config_.n_generation_);
|
||||
|
|
|
|||
88
src/alloc2/DX1CollectorIterator.cpp
Normal file
88
src/alloc2/DX1CollectorIterator.cpp
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/** @file DX1CollectorIterator.cpp
|
||||
*
|
||||
* @author Roland Conybeare, Dec 2025
|
||||
**/
|
||||
|
||||
#include "gc/DX1CollectorIterator.hpp"
|
||||
#include "gc/DX1Collector.hpp"
|
||||
#include <xo/indentlog/scope.hpp>
|
||||
#include <xo/indentlog/print/tag.hpp>
|
||||
|
||||
namespace xo {
|
||||
namespace mm {
|
||||
DX1CollectorIterator::DX1CollectorIterator(const DX1Collector * gc,
|
||||
generation gen_ix,
|
||||
generation gen_hi,
|
||||
DArenaIterator arena_ix,
|
||||
DArenaIterator arena_hi) : gc_{gc},
|
||||
gen_ix_{gen_ix},
|
||||
gen_hi_{gen_hi},
|
||||
arena_ix_{arena_ix},
|
||||
arena_hi_{arena_hi}
|
||||
{
|
||||
this->normalize();
|
||||
}
|
||||
|
||||
void
|
||||
DX1CollectorIterator::normalize() noexcept
|
||||
{
|
||||
/* normalize: find lowest generation with non-empty to-space */
|
||||
|
||||
for (; gen_ix_ < gen_hi_; ++gen_ix_) {
|
||||
const DArena * arena
|
||||
= gc_->get_space(role::to_space(), gen_ix_);
|
||||
|
||||
arena_ix_ = arena->begin();
|
||||
arena_hi_ = arena->end();
|
||||
|
||||
if (arena_ix_ != arena_hi_) {
|
||||
// normalization achieved!
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
AllocInfo
|
||||
DX1CollectorIterator::deref() const noexcept
|
||||
{
|
||||
return arena_ix_.deref();
|
||||
}
|
||||
|
||||
cmpresult
|
||||
DX1CollectorIterator::compare(const DX1CollectorIterator & other_ix) const noexcept
|
||||
{
|
||||
scope log(XO_DEBUG(true),
|
||||
xtag("is_valid", is_valid()),
|
||||
xtag("other_ix.is_valid", other_ix.is_valid()) );
|
||||
|
||||
if (is_invalid() || (gc_ != other_ix.gc_)) {
|
||||
log && log("incomparable!");
|
||||
return cmpresult::incomparable();
|
||||
}
|
||||
|
||||
if (gen_ix_ != other_ix.gen_ix_) {
|
||||
log && log(xtag("gen", gen_ix_), xtag("other.gen", other_ix.gen_ix_));
|
||||
|
||||
/* same collector, different arenas -> compare based on gen# */
|
||||
|
||||
return cmpresult::from_cmp(gen_ix_, other_ix.gen_ix_);
|
||||
}
|
||||
|
||||
/* both iterators refer to the same arena,
|
||||
* so can compare their arena iterators directly
|
||||
*/
|
||||
return arena_ix_.compare(other_ix.arena_ix_);
|
||||
}
|
||||
|
||||
void
|
||||
DX1CollectorIterator::next() noexcept
|
||||
{
|
||||
if (arena_ix_ != arena_hi_) {
|
||||
++arena_ix_;
|
||||
this->normalize();
|
||||
}
|
||||
}
|
||||
} /*namespace mm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end DX1CollectorIterator.cpp */
|
||||
43
src/alloc2/IAllocIterator_DArenaIterator.cpp
Normal file
43
src/alloc2/IAllocIterator_DArenaIterator.cpp
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
/** @file IAllocIterator_DArenaIterator.cpp
|
||||
*
|
||||
* @author Roland Conybeare, Dec 2025
|
||||
**/
|
||||
|
||||
#include "arena/IAllocIterator_DArenaIterator.hpp"
|
||||
#include "AllocIterator.hpp"
|
||||
#include <cassert>
|
||||
|
||||
namespace xo {
|
||||
using std::byte;
|
||||
|
||||
namespace mm {
|
||||
AllocInfo
|
||||
IAllocIterator_DArenaIterator::deref(const DArenaIterator & ix) noexcept
|
||||
{
|
||||
return ix.deref();
|
||||
}
|
||||
|
||||
cmpresult
|
||||
IAllocIterator_DArenaIterator::compare(const DArenaIterator & ix,
|
||||
const obj<AAllocIterator> & other_arg) noexcept
|
||||
{
|
||||
/* downcast from variant */
|
||||
auto other = obj<AAllocIterator, DArenaIterator>::from(other_arg);
|
||||
|
||||
if (!other)
|
||||
return cmpresult::incomparable();
|
||||
|
||||
DArenaIterator & other_ix = *other;
|
||||
|
||||
return ix.compare(other_ix);
|
||||
}
|
||||
|
||||
void
|
||||
IAllocIterator_DArenaIterator::next(DArenaIterator & ix) noexcept
|
||||
{
|
||||
ix.next();
|
||||
}
|
||||
} /*namespace mm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end IAllocIterator_DArenaIterator.cpp */
|
||||
41
src/alloc2/IAllocIterator_DX1CollectorIterator.cpp
Normal file
41
src/alloc2/IAllocIterator_DX1CollectorIterator.cpp
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
/** @file IAllocIterator_DX1CollectorIterator.cpp
|
||||
*
|
||||
* @author Roland Conybeare, Dec 2025
|
||||
**/
|
||||
|
||||
#include "gc/IAllocIterator_DX1CollectorIterator.hpp"
|
||||
#include "AllocIterator.hpp"
|
||||
//#include <cassert>
|
||||
|
||||
namespace xo {
|
||||
namespace mm {
|
||||
AllocInfo
|
||||
IAllocIterator_DX1CollectorIterator::deref(const DX1CollectorIterator & ix) noexcept
|
||||
{
|
||||
return ix.deref();
|
||||
}
|
||||
|
||||
cmpresult
|
||||
IAllocIterator_DX1CollectorIterator::compare(const DX1CollectorIterator & ix,
|
||||
const obj<AAllocIterator> & other_arg) noexcept
|
||||
{
|
||||
/* downcast from variant */
|
||||
auto other = obj<AAllocIterator, DX1CollectorIterator>::from(other_arg);
|
||||
|
||||
if (!other)
|
||||
return cmpresult::incomparable();
|
||||
|
||||
DX1CollectorIterator & other_ix = *other;
|
||||
|
||||
return ix.compare(other_ix);
|
||||
}
|
||||
|
||||
void
|
||||
IAllocIterator_DX1CollectorIterator::next(DX1CollectorIterator & ix) noexcept
|
||||
{
|
||||
ix.next();
|
||||
}
|
||||
} /*namespace mm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
/* end IAllocIterator_DX1CollectorIterator.cpp */
|
||||
|
|
@ -80,10 +80,7 @@ namespace xo {
|
|||
}
|
||||
|
||||
if (s.lo_ + target_z > s.hi_) [[unlikely]] {
|
||||
++(s.error_count_);
|
||||
s.last_error_ = AllocError(error::reserve_exhausted,
|
||||
s.error_count_,
|
||||
target_z, s.committed_z_, reserved(s));
|
||||
s.capture_error(error::reserve_exhausted, target_z);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -124,15 +121,7 @@ namespace xo {
|
|||
add_commit_z,
|
||||
PROT_READ | PROT_WRITE) != 0) [[unlikely]]
|
||||
{
|
||||
++(s.error_count_);
|
||||
s.last_error_ = AllocError(error::commit_failed,
|
||||
s.error_count_,
|
||||
add_commit_z, s.committed_z_, reserved(s));
|
||||
#ifdef OBSOLETE
|
||||
throw std::runtime_error(tostr("ArenaAlloc::expand: commit failure",
|
||||
xtag("committed_z", s.committed_z_),
|
||||
xtag("add_commit_z", add_commit_z)));
|
||||
#endif
|
||||
s.capture_error(error::commit_failed, add_commit_z);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -198,75 +187,6 @@ namespace xo {
|
|||
? alloc_mode::sub_complete
|
||||
: alloc_mode::sub_incomplete));
|
||||
|
||||
#ifdef OBSOLETE
|
||||
if ((req_z == 0) && complete_flag) [[unlikely]] {
|
||||
/** use zero req_z with complete_flag to clear s.last_header_ **/
|
||||
|
||||
if (s.config_.store_header_flag_) {
|
||||
if (!s.last_header_) [[unlikely]] {
|
||||
++(s.error_count_);
|
||||
s.last_error_ = AllocError(error::orphan_sub_alloc,
|
||||
s.error_count_,
|
||||
0 /*add_commit_z*/, s.committed_z_, reserved(s));
|
||||
} else {
|
||||
s.last_header_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
byte * free0 = s.free_;
|
||||
byte * mem = _alloc(s, req_z,
|
||||
complete_flag ? alloc_mode::sub_complete : alloc_mode::sub,
|
||||
false /*!store_header_flag*/,
|
||||
false /*!remember_header_flag*/);
|
||||
|
||||
if (!mem) [[unlikely]] {
|
||||
/* error already captured */
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
byte * free1 = s.free_;
|
||||
/* used: accounting for padding applied to req_z */
|
||||
size_t z0 = (free1 - free0);
|
||||
|
||||
assert(z0 > 0);
|
||||
|
||||
if (s.config_.store_header_flag_) {
|
||||
if (!s.last_header_) [[unlikely]] {
|
||||
++(s.error_count_);
|
||||
s.last_error_ = AllocError(error::orphan_sub_alloc,
|
||||
s.error_count_,
|
||||
0 /*add_commit_z*/, s.committed_z_, reserved(s));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/* s.last_header_ holds aggregate size of preceding super_alloc
|
||||
* (+ any sub-alloc's).
|
||||
*
|
||||
* Accumulate allocation size
|
||||
*/
|
||||
uint64_t header = *s.last_header_;
|
||||
|
||||
if ((header & s.config_.header_size_mask_ & z0) != z0) [[unlikely]] {
|
||||
/* cumulative alloc size doesn't fit in configured header_size_mask bits */
|
||||
++(s.error_count_);
|
||||
s.last_error_ = AllocError(error::header_size_mask,
|
||||
s.error_count_,
|
||||
0 /*add_commit_z*/, s.committed_z_, reserved(s));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
*s.last_header_ = ((header & ~s.config_.header_size_mask_) | z0);
|
||||
|
||||
if (complete_flag) {
|
||||
s.last_header_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
return mem;
|
||||
#endif
|
||||
}
|
||||
|
||||
byte *
|
||||
|
|
@ -340,12 +260,7 @@ namespace xo {
|
|||
hz = sizeof(header);
|
||||
} else {
|
||||
/* req_z doesn't fit in configured header_size_mask bits */
|
||||
++(s.error_count_);
|
||||
s.last_error_ = AllocError(error::header_size_mask,
|
||||
s.error_count_,
|
||||
0 /*add_commit_z*/,
|
||||
s.committed_z_,
|
||||
reserved(s));
|
||||
s.capture_error(error::header_size_mask);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
@ -391,6 +306,8 @@ namespace xo {
|
|||
xtag("z1", z1),
|
||||
xtag("size", size(s)),
|
||||
xtag("avail", available(s)));
|
||||
log && log(xtag("mem", mem),
|
||||
xtag("free", s.free_));
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue