xo-arena: + src_fn argument in alloc_error + contributaries
This commit is contained in:
parent
c8ba4d42b8
commit
a3e72f33a5
9 changed files with 73 additions and 37 deletions
|
|
@ -48,20 +48,25 @@ namespace xo {
|
|||
uint32_t seq) : error_{err},
|
||||
error_seq_{seq} {}
|
||||
AllocError(error err,
|
||||
const char * src_fn,
|
||||
uint32_t seq,
|
||||
size_type req_z,
|
||||
size_type com_z,
|
||||
size_type rsv_z) : error_{err},
|
||||
error_seq_{seq},
|
||||
request_z_{req_z},
|
||||
committed_z_{com_z},
|
||||
reserved_z_{rsv_z} {}
|
||||
size_type rsv_z) : error_{err},
|
||||
src_fn_{src_fn},
|
||||
error_seq_{seq},
|
||||
request_z_{req_z},
|
||||
committed_z_{com_z},
|
||||
reserved_z_{rsv_z} {}
|
||||
|
||||
static const char * error_description(error x);
|
||||
|
||||
/** error code **/
|
||||
error error_ = error::ok;
|
||||
|
||||
/** source function. Typically injected with __PRETTY_FUNCTION__
|
||||
* somewhere suitable on stack
|
||||
**/
|
||||
const char * src_fn_ = nullptr;
|
||||
/** sequence# of this error.
|
||||
* Each error event within an allocator gets next sequence number
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -203,19 +203,21 @@ namespace xo {
|
|||
|
||||
/** capture error information: advance error count + set last_error **/
|
||||
void capture_error(error err,
|
||||
const char * src_fn,
|
||||
size_type target_z = 0) const;
|
||||
|
||||
/** alloc driver. shared by alloc(), super_alloc(), sub_alloc() **/
|
||||
value_type _alloc(std::size_t req_z,
|
||||
alloc_mode mode,
|
||||
typeseq tseq,
|
||||
uint32_t age);
|
||||
uint32_t age,
|
||||
const char * src_fn);
|
||||
|
||||
/** expand committed space in arena @p d
|
||||
* to size at least @p z
|
||||
* to size at least @p z, on behalf of @p src_fn
|
||||
* In practice will round up to a multiple of @ref page_z_.
|
||||
**/
|
||||
bool expand(size_type z) noexcept;
|
||||
bool expand(size_type z, const char * src_fn) noexcept;
|
||||
|
||||
/** create initial guard **/
|
||||
void establish_initial_guard() noexcept;
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ namespace xo {
|
|||
template <typename T>
|
||||
void
|
||||
DArenaVector<T>::reserve(size_type z) {
|
||||
store_.expand(z * sizeof(T));
|
||||
store_.expand(z * sizeof(T), __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
|
@ -193,7 +193,7 @@ namespace xo {
|
|||
if (z > size_) {
|
||||
// expand arena to accomodate
|
||||
|
||||
if (!store_.expand(req_z))
|
||||
if (!store_.expand(req_z, __PRETTY_FUNCTION__))
|
||||
return false;
|
||||
|
||||
// run ctors
|
||||
|
|
@ -258,7 +258,7 @@ namespace xo {
|
|||
size_type new_z = size_ + 1;
|
||||
size_type req_z = new_z * sizeof(T);
|
||||
|
||||
store_.expand(req_z);
|
||||
store_.expand(req_z, __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
// move elements [i .. z-1] right by one position.
|
||||
|
|
@ -283,7 +283,7 @@ namespace xo {
|
|||
size_type new_z = size_ + 1;
|
||||
size_type req_z = new_z * sizeof(T);
|
||||
|
||||
store_.expand(req_z);
|
||||
store_.expand(req_z, __PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
// move elements [i .. z-1] right by one position.
|
||||
|
|
@ -322,7 +322,7 @@ namespace xo {
|
|||
size_type z = size_ + 1;
|
||||
size_type req_z = z * sizeof(T);
|
||||
|
||||
if (this->store_.expand(req_z)) {
|
||||
if (this->store_.expand(req_z, __PRETTY_FUNCTION__)) {
|
||||
T * addr = this->_address_of(size_);
|
||||
|
||||
new (addr) T{std::move(x)};
|
||||
|
|
@ -336,7 +336,7 @@ namespace xo {
|
|||
DArenaVector<T>::push_back(const T & x) {
|
||||
size_type z = size_ + 1;
|
||||
|
||||
if (this->store_.expand(z * sizeof(T))) {
|
||||
if (this->store_.expand(z * sizeof(T), __PRETTY_FUNCTION__)) {
|
||||
T * addr = this->_address_of(size_);
|
||||
|
||||
new (addr) T{x};
|
||||
|
|
|
|||
|
|
@ -20,12 +20,17 @@ namespace xo {
|
|||
inline std::ostream &
|
||||
operator<<(std::ostream & os, const AllocError & x) {
|
||||
os << "<AllocError"
|
||||
<< xtag("error", x.error_)
|
||||
<< xtag("seq", x.error_seq_)
|
||||
<< xtag("error", x.error_);
|
||||
|
||||
if (x.src_fn_)
|
||||
os << xtag("src_fn", x.src_fn_);
|
||||
|
||||
os << xtag("seq", x.error_seq_)
|
||||
<< xtag("req_z", x.request_z_)
|
||||
<< xtag("commit_z", x.committed_z_)
|
||||
<< xtag("resv_z", x.reserved_z_)
|
||||
<< ">";
|
||||
|
||||
return os;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ set(SELF_SRCS
|
|||
DArena.cpp
|
||||
DArenaIterator.cpp
|
||||
DCircularBuffer.cpp
|
||||
backtrace.cpp
|
||||
)
|
||||
|
||||
xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS})
|
||||
|
|
@ -24,5 +25,7 @@ xo_install_include_tree3(include/xo/arena)
|
|||
|
||||
xo_dependency(${SELF_LIB} xo_reflectutil)
|
||||
xo_dependency(${SELF_LIB} indentlog)
|
||||
xo_external_pkgconfig_dependency(${SELF_LIB} LIBUNWIND libunwind-generic)
|
||||
xo_external_pkgconfig_dependency(${SELF_LIB} LIBDW libdw)
|
||||
|
||||
# end src/CMakeLists.txt
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "DArena.hpp"
|
||||
#include "DArenaIterator.hpp"
|
||||
#include "mmap_util.hpp"
|
||||
#include "backtrace.hpp"
|
||||
#include <xo/arena/padding.hpp>
|
||||
#include <xo/indentlog/scope.hpp>
|
||||
#include <xo/indentlog/print/tag.hpp>
|
||||
|
|
@ -230,7 +231,7 @@ namespace xo {
|
|||
DArena::alloc_info(value_type mem) const noexcept
|
||||
{
|
||||
if (!config_.store_header_flag_) [[unlikely]] {
|
||||
this->capture_error(error::alloc_info_disabled);
|
||||
this->capture_error(error::alloc_info_disabled, __PRETTY_FUNCTION__);
|
||||
|
||||
return AllocInfo::error_not_configured(&config_.header_);
|
||||
}
|
||||
|
|
@ -272,7 +273,7 @@ namespace xo {
|
|||
DArena::begin_header() const noexcept
|
||||
{
|
||||
if (config_.store_header_flag_ == false) {
|
||||
this->capture_error(error::alloc_iterator_not_supported);
|
||||
this->capture_error(error::alloc_iterator_not_supported, __PRETTY_FUNCTION__);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -284,7 +285,7 @@ namespace xo {
|
|||
DArena::end_header() const noexcept
|
||||
{
|
||||
if (config_.store_header_flag_ == false) {
|
||||
this->capture_error(error::alloc_iterator_not_supported);
|
||||
this->capture_error(error::alloc_iterator_not_supported, __PRETTY_FUNCTION__);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -299,7 +300,11 @@ namespace xo {
|
|||
* exactly 1 header per alloc() call.
|
||||
* - store_header_flag follows configuration
|
||||
*/
|
||||
return _alloc(req_z, alloc_mode::standard, t, 0 /*age*/);
|
||||
return _alloc(req_z,
|
||||
alloc_mode::standard,
|
||||
t,
|
||||
0 /*age*/,
|
||||
__PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
std::byte *
|
||||
|
|
@ -316,7 +321,8 @@ namespace xo {
|
|||
return _alloc(req_z,
|
||||
alloc_mode::super,
|
||||
t,
|
||||
0 /*age*/);
|
||||
0 /*age*/,
|
||||
__PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
std::byte *
|
||||
|
|
@ -334,7 +340,8 @@ namespace xo {
|
|||
? alloc_mode::sub_complete
|
||||
: alloc_mode::sub_incomplete),
|
||||
typeseq::sentinel() /*typeseq: ignored*/,
|
||||
0 /*age - ignored */);
|
||||
0 /*age - ignored */,
|
||||
__PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
std::byte *
|
||||
|
|
@ -354,17 +361,20 @@ namespace xo {
|
|||
typeseq tseq = typeseq(src_info.tseq());
|
||||
uint32_t age = src_info.age();
|
||||
|
||||
return _alloc(req_z, alloc_mode::standard, tseq, age + 1);
|
||||
return _alloc(req_z, alloc_mode::standard, tseq, age + 1,
|
||||
__PRETTY_FUNCTION__);
|
||||
}
|
||||
|
||||
void
|
||||
DArena::capture_error(error err,
|
||||
const char * src_fn,
|
||||
size_type target_z) const
|
||||
{
|
||||
DArena * self = const_cast<DArena *>(this);
|
||||
|
||||
++(self->error_count_);
|
||||
self->last_error_ = AllocError(err,
|
||||
src_fn,
|
||||
error_count_,
|
||||
target_z,
|
||||
committed_z_,
|
||||
|
|
@ -375,7 +385,8 @@ namespace xo {
|
|||
DArena::_alloc(std::size_t req_z,
|
||||
alloc_mode mode,
|
||||
typeseq tseq,
|
||||
uint32_t age)
|
||||
uint32_t age,
|
||||
const char * src_fn)
|
||||
{
|
||||
scope log(XO_DEBUG(config_.debug_flag_));
|
||||
|
||||
|
|
@ -444,7 +455,7 @@ namespace xo {
|
|||
hz = sizeof(header);
|
||||
} else {
|
||||
/* req_z doesn't fit in configured header_size_mask bits */
|
||||
capture_error(error::header_size_mask);
|
||||
capture_error(error::header_size_mask, src_fn);
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
@ -453,7 +464,7 @@ namespace xo {
|
|||
|
||||
assert(padding::is_aligned(z1));
|
||||
|
||||
if (!this->expand(this->allocated() + z1)) [[unlikely]] {
|
||||
if (!this->expand(this->allocated() + z1, src_fn)) [[unlikely]] {
|
||||
/* (error state already captured) */
|
||||
return nullptr;
|
||||
}
|
||||
|
|
@ -509,11 +520,12 @@ namespace xo {
|
|||
}
|
||||
|
||||
bool
|
||||
DArena::expand(size_t target_z) noexcept
|
||||
DArena::expand(size_t target_z, const char * src_fn) noexcept
|
||||
{
|
||||
scope log(XO_DEBUG(config_.debug_flag_),
|
||||
xtag("target_z", target_z),
|
||||
xtag("committed_z", committed_z_));
|
||||
xtag("committed_z", committed_z_),
|
||||
xtag("src_fn", src_fn));
|
||||
|
||||
if (target_z <= committed_z_) [[likely]] {
|
||||
log && log("trivial success, offset within committed range",
|
||||
|
|
@ -523,7 +535,12 @@ namespace xo {
|
|||
}
|
||||
|
||||
if (lo_ + target_z > hi_) [[unlikely]] {
|
||||
this->capture_error(error::reserve_exhausted, target_z);
|
||||
this->capture_error(error::reserve_exhausted, src_fn, target_z);
|
||||
|
||||
fprintf(stderr, "DArena::expand: reserve exhausted");
|
||||
print_backtrace_dwarf(true /*demangle_flag*/);
|
||||
std::terminate();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -566,7 +583,11 @@ namespace xo {
|
|||
);
|
||||
}
|
||||
|
||||
capture_error(error::commit_failed, add_commit_z);
|
||||
this->capture_error(error::commit_failed, src_fn, add_commit_z);
|
||||
|
||||
fprintf(stderr, "DArena::expand: mprotect failed (system oom?)");
|
||||
print_backtrace_dwarf(false /*!demangle_flag*/);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -74,7 +74,7 @@ namespace xo {
|
|||
xtag("bounds_flag", bounds_flag));
|
||||
|
||||
if (!contains_flag || !bounds_flag) {
|
||||
arena_->capture_error(error::alloc_iterator_deref);
|
||||
arena_->capture_error(error::alloc_iterator_deref, __PRETTY_FUNCTION__);
|
||||
|
||||
return AllocInfo::error_invalid_iterator(&(arena_->config_.header_));
|
||||
}
|
||||
|
|
@ -122,7 +122,7 @@ namespace xo {
|
|||
xtag("bounds_flag", bounds_flag));
|
||||
|
||||
if (!contains_flag || !bounds_flag) {
|
||||
arena_->capture_error(error::alloc_iterator_next);
|
||||
arena_->capture_error(error::alloc_iterator_next, __PRETTY_FUNCTION__);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ namespace xo {
|
|||
this->color_escape_chars_ = 0;
|
||||
this->color_escape_start_ = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
arena_streambuf::rewind_to(rewind_state s)
|
||||
{
|
||||
|
|
@ -85,7 +85,7 @@ namespace xo {
|
|||
|
||||
/* note: local_ppos_ invariant across expand_to() */
|
||||
|
||||
arena_->expand(new_z);
|
||||
arena_->expand(new_z, __PRETTY_FUNCTION__);
|
||||
|
||||
char * p_base = (char *)(arena_->lo_);
|
||||
char * p_hi = (char *)(arena_->limit_);
|
||||
|
|
@ -207,7 +207,7 @@ namespace xo {
|
|||
|
||||
return this->pptr() - this->pbase();
|
||||
} /*seekoff*/
|
||||
|
||||
|
||||
} /*namespace mm*/
|
||||
} /*namespace xo*/
|
||||
|
||||
|
|
|
|||
|
|
@ -118,7 +118,7 @@ namespace xo {
|
|||
REQUIRE(arena.allocated() == 0);
|
||||
|
||||
size_t z2 = 512;
|
||||
bool ok = arena.expand(z2);
|
||||
bool ok = arena.expand(z2, __PRETTY_FUNCTION__);
|
||||
|
||||
INFO(xtag("last_error", arena.last_error()));
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue