+ LinearAlloc + utest

This commit is contained in:
Roland Conybeare 2025-07-29 07:17:35 -05:00
commit 8970f51dbd
12 changed files with 495 additions and 0 deletions

11
src/alloc/CMakeLists.txt Normal file
View file

@ -0,0 +1,11 @@
# alloc/CMakeLists.txt
set(SELF_LIB xo_alloc)
set(SELF_SRCS
LinearAlloc.cpp
)
xo_add_shared_library4(${SELF_LIB} ${PROJECT_NAME}Targets ${PROJECT_VERSION} 1 ${SELF_SRCS})
xo_dependency(${SELF_LIB} indentlog)
#end CMakeLists.txt

135
src/alloc/LinearAlloc.cpp Normal file
View file

@ -0,0 +1,135 @@
/* file LinearAlloc.cpp
*
* author: Roland Conybeare
*/
#include "LinearAlloc.hpp"
#include "xo/indentlog/print/tag.hpp"
#include <cassert>
namespace xo {
namespace gc {
LinearAlloc::LinearAlloc(std::size_t rz, std::size_t z)
{
this->lo_ = (new std::uint8_t [rz + z]);
this->checkpoint_ = lo_;
this->free_ptr_ = lo_;
this->limit_ = lo_ + z;
this->hi_ = limit_ + rz;
if (!lo_) {
throw std::runtime_error(tostr("LinearAlloc: allocation failed",
xtag("size", rz + z)));
}
}
LinearAlloc::~LinearAlloc()
{
delete [] this->lo_;
// hygiene..
this->lo_ = nullptr;
this->checkpoint_ = nullptr;
this->free_ptr_ = nullptr;
this->limit_ = nullptr;
this->hi_ = nullptr;
}
up<LinearAlloc>
LinearAlloc::make(std::size_t rz, std::size_t z)
{
return up<LinearAlloc>(new LinearAlloc(rz, z));
}
void
LinearAlloc::set_free_ptr(std::uint8_t * x)
{
assert(lo_ <= x);
assert(x < limit_);
if (lo_ <= x && x < limit_) {
this->free_ptr_ = x;
} else {
throw std::runtime_error(tostr("LinearAllog::set_free_ptr(x): expected lo <= x < limit",
xtag("lo", lo_), xtag("x", x), xtag("limit", limit_)));
}
}
std::size_t
LinearAlloc::size() const {
return limit_ - lo_;
}
std::size_t
LinearAlloc::available() const {
return limit_ - free_ptr_;
}
std::size_t
LinearAlloc::allocated() const {
return free_ptr_ - lo_;
}
bool
LinearAlloc::is_before_checkpoint(const std::uint8_t * x) const {
return (lo_ <= x) && (x < checkpoint_);
}
std::size_t
LinearAlloc::before_checkpoint() const
{
return checkpoint_ - lo_;
}
std::size_t
LinearAlloc::after_checkpoint() const
{
return free_ptr_ - checkpoint_;
}
void
LinearAlloc::clear()
{
this->checkpoint_ = lo_;
this->free_ptr_ = lo_;
this->limit_ = lo_;
}
void
LinearAlloc::checkpoint()
{
this->checkpoint_ = this->free_ptr_;
}
std::uint8_t *
LinearAlloc::alloc(std::size_t z)
{
/* word size for alignment */
constexpr uint32_t c_bpw = sizeof(void*);
std::uintptr_t free_u64 = reinterpret_cast<std::uintptr_t>(free_ptr_);
assert(free_u64 % c_bpw == 0ul);
/* round up to multiple of c_bpw */
std::uint32_t dz = (c_bpw - (z % c_bpw));
z += dz;
assert(z % c_bpw == 0ul);
std::uint8_t * retval = this->free_ptr_;
this->free_ptr_ += z;
if (free_ptr_ > limit_) {
return nullptr;
}
return retval;
}
} /*namespace gc*/
} /*namespace xo*/
/* end LinearAlloc.cpp */