+ LinearAlloc + utest
This commit is contained in:
parent
b5e7d91883
commit
8970f51dbd
12 changed files with 495 additions and 0 deletions
20
include/xo/alloc/GCAlloc.hpp
Normal file
20
include/xo/alloc/GCAlloc.hpp
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/* file GCAlloc.hpp
|
||||
*
|
||||
* author: Roland Conybeare, Jul 2025
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace xo {
|
||||
namespace gc {
|
||||
class GC : public IAlloc {
|
||||
enum class Space { A, B, N_Space };
|
||||
enum class Gen { Nursery, Tenured };
|
||||
|
||||
};
|
||||
|
||||
} /*namespace mem */
|
||||
} /*namespace xo*/
|
||||
|
||||
|
||||
/* end GCAlloc.hpp */
|
||||
57
include/xo/alloc/IAlloc.hpp
Normal file
57
include/xo/alloc/IAlloc.hpp
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/* file IAlloc.hpp
|
||||
*
|
||||
* author: Roland Conybeare, Jul 2025
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
|
||||
namespace xo {
|
||||
template <typename T>
|
||||
using up = std::unique_ptr<T>;
|
||||
|
||||
namespace gc {
|
||||
/** @class IAllocator
|
||||
* @brief memory allocation interface with limited garbaga collector support
|
||||
**/
|
||||
class IAlloc {
|
||||
public:
|
||||
virtual ~IAlloc() {}
|
||||
|
||||
/** allocator size in bytes (up to soft limit).
|
||||
* Includes unallocated mmeory
|
||||
**/
|
||||
virtual std::size_t size() const = 0;
|
||||
/** number of unallocated bytes available (up to soft limit)
|
||||
* from this allocator
|
||||
**/
|
||||
virtual std::size_t available() const = 0;
|
||||
/** number of bytes allocated from this allocator **/
|
||||
virtual std::size_t allocated() const = 0;
|
||||
/** true iff object at address @p x was allocated by this allocator,
|
||||
* and before checkpoint
|
||||
**/
|
||||
virtual bool is_before_checkpoint(const std::uint8_t * x) const = 0;
|
||||
/** number of bytes allocated before @ref checkpoint **/
|
||||
virtual std::size_t before_checkpoint() const = 0;
|
||||
/** number of bytes allocated since @ref checkpoint **/
|
||||
virtual std::size_t after_checkpoint() const = 0;
|
||||
|
||||
/** reset allocator to empty state. **/
|
||||
virtual void clear() = 0;
|
||||
/** remember allocator state. All currently-allocated addresses x
|
||||
* will satisfy is_before_checkpoint(x). Subsequent allocations x
|
||||
* will fail is_before_checkpoint(x), until checkpoint superseded
|
||||
* by @ref clear or another call to @ref checkpoint
|
||||
**/
|
||||
virtual void checkpoint() = 0;
|
||||
/** allocate @p z bytes of memory. returns pointer to first address **/
|
||||
virtual std::uint8_t * alloc(std::size_t z) = 0;
|
||||
};
|
||||
} /*namespace gc*/
|
||||
} /*namespace xo*/
|
||||
|
||||
|
||||
/* end IAlloc.hpp */
|
||||
90
include/xo/alloc/LinearAlloc.hpp
Normal file
90
include/xo/alloc/LinearAlloc.hpp
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
/* file LinearAlloc.hpp
|
||||
*
|
||||
* author: Roland Conybeare, Jul 2025
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "IAlloc.hpp"
|
||||
|
||||
namespace xo {
|
||||
namespace gc {
|
||||
/** @class LinearAlloc
|
||||
* @brief Bump allocator with fixed capacity
|
||||
*
|
||||
* @text
|
||||
*
|
||||
* before @ref release_redline_memory
|
||||
*
|
||||
* <-----allocated----> <-free-> <-reserved->
|
||||
* XXXXXXXXXXXXXXXXXXXX______________________
|
||||
* ^ ^ ^ ^
|
||||
* lo free redline hi
|
||||
* limit
|
||||
*
|
||||
* after @ref release_redline_memory
|
||||
*
|
||||
* <-----allocated----> <--------free------->
|
||||
* XXXXXXXXXXXXXXXXXXXX______________________
|
||||
* ^ ^ ^
|
||||
* lo free hi
|
||||
* limit
|
||||
* @endtext
|
||||
*
|
||||
* TODO: rename to ArenaAlloc
|
||||
**/
|
||||
class LinearAlloc : public IAlloc {
|
||||
public:
|
||||
~LinearAlloc();
|
||||
|
||||
/** create allocator with capacity @p z,
|
||||
* with reserved capacity @p redline_z.
|
||||
**/
|
||||
static up<LinearAlloc> make(std::size_t redline_z, std::size_t z);
|
||||
|
||||
std::uint8_t * free_ptr() const { return free_ptr_; }
|
||||
void set_free_ptr(std::uint8_t * x);
|
||||
|
||||
// inherited from IAlloc...
|
||||
|
||||
virtual std::size_t size() const override;
|
||||
virtual std::size_t available() const override;
|
||||
virtual std::size_t allocated() const override;
|
||||
virtual bool is_before_checkpoint(const std::uint8_t * x) const override;
|
||||
virtual std::size_t before_checkpoint() const override;
|
||||
virtual std::size_t after_checkpoint() const override;
|
||||
|
||||
virtual void clear() override;
|
||||
virtual void checkpoint() override;
|
||||
virtual std::uint8_t * alloc(std::size_t z) override;
|
||||
|
||||
|
||||
private:
|
||||
LinearAlloc(std::size_t rz, std::size_t z);
|
||||
|
||||
private:
|
||||
/**
|
||||
* Invariants:
|
||||
* - @ref free_ always a multiple of word size (assumed to be sizeof(void*))
|
||||
**/
|
||||
|
||||
/** allocator owns memory in range [@ref lo_, @ref hi_) **/
|
||||
std::uint8_t * lo_ = nullptr;
|
||||
/** checkpoint (for GC support); divides objects into
|
||||
* older (addresses below checkpoint)
|
||||
* and younger (addresses above checkpoint)
|
||||
**/
|
||||
std::uint8_t * checkpoint_;
|
||||
/** free pointer. memory in range [@ref free_, @ref limit_) available **/
|
||||
std::uint8_t * free_ptr_ = nullptr;
|
||||
/** soft limit: end of released memory **/
|
||||
std::uint8_t * limit_ = nullptr;
|
||||
/** hard limit: end of allocated memory **/
|
||||
std::uint8_t * hi_ = nullptr;
|
||||
};
|
||||
|
||||
} /*namespace gc*/
|
||||
} /*namespace xo*/
|
||||
|
||||
|
||||
/* end LinearAlloc.hpp */
|
||||
47
include/xo/alloc/ListAlloc.hpp
Normal file
47
include/xo/alloc/ListAlloc.hpp
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/* file ListAlloc.hpp
|
||||
*
|
||||
* author: Roland Conybeare, Jul 2025
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "IAlloc.hpp"
|
||||
#include <memory>
|
||||
#include <cstdint>
|
||||
|
||||
namespace xo {
|
||||
namespace gc {
|
||||
/** GC-compatible allocator using a linked list of buckets.
|
||||
*
|
||||
* GC Support:
|
||||
* - reserved memory, released after call to @ref release_redline_memory.
|
||||
*
|
||||
* TODO: reserve address space using mmap,
|
||||
* but don't commit until alloc requires it.
|
||||
**/
|
||||
class ListAlloc : public IAlloc {
|
||||
public:
|
||||
ListAlloc(LinearAlloc* hd,
|
||||
std::size_t cz, std::size_t nz; std::size_tz,
|
||||
LinearAlloc* marked, bool use_redline,
|
||||
bool redlined_flag, OnEmptyFn on_overflow);
|
||||
~ListAlloc();
|
||||
|
||||
static up<ListAlloc> make(std::size_t cz, std::size_t nz,
|
||||
OnEmptyFn on_overflow);
|
||||
|
||||
private:
|
||||
std::size_t start_z_ = 0;
|
||||
LinearAlloc* hd_ = nullptr;
|
||||
std::size_t current_z_ = 0;;
|
||||
std::size_t next_z_ = 0;;
|
||||
std::size_t total_z_ = 0;
|
||||
bool use_redline_ = false;
|
||||
bool redlined_flag_ = false;
|
||||
|
||||
};
|
||||
} /*namespace gc*/
|
||||
} /*namespace xo*/
|
||||
|
||||
|
||||
/* end ListAlloc.hpp */
|
||||
Loading…
Add table
Add a link
Reference in a new issue