You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
82 lines
3.3 KiB
82 lines
3.3 KiB
|
|
|
|
#include <map>
|
|
|
|
#include <alloc.h>
|
|
|
|
extern "C" {
|
|
base_allocator::~base_allocator() {}
|
|
}
|
|
|
|
namespace alloc {
|
|
|
|
// Base class for all deallocations that happen within an `anon_raw_secmem` (managed, static, polymorphic, unmanaged, etc.) (TODO: See below, the base should be moved into the header so typed children can be templated...)
|
|
FrozenAllocator::deleter::~deleter() {
|
|
apply_finalizer_group();
|
|
}
|
|
FrozenAllocator::deleter::deleter(std::shared_ptr<anon_raw_secmem>&& p)
|
|
: m_manager_ref(std::move(p))
|
|
, m_gorup_ptr(static_cast<deleter*>(this)) {} //TODO:XXX: Do we actually need finalizer groups now? (see note below about `m_values`.
|
|
|
|
void FrozenAllocator::deleter::apply_finalizer_group(std::initializer_list<void*> ptrs) noexcept {
|
|
if(ptrs.empty()) {
|
|
|
|
//TODO: auto&& fgroup = std::move(m_manager_ref->get_finalizer_group_for(finalizer_group_id())); // The *whole* finalizer group, *moved* from `m_manager_ref`. (which leaves finalizer_group for `this` empty now.)
|
|
//TODO: `bzero_explicit()` the memory from the allocations, then tell `anon_raw_secmem` to mark is as free.
|
|
} else {
|
|
|
|
//TODO: auto& fgroup = m_manager_ref->get_finalizer_group_ref_for(finalizer_group_id()); // The whole finalizer group, *referenced* from `m_manager_ref`. (which leaves finalizer_group for `this` intact, removal of pointers from the group will have to happen below manually.)
|
|
for(void* p : ptrs) {
|
|
//TODO: Do the same as above, but only for pointers registered for finalizing in `ptrs`.
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Instead of acting on pointers in `this`'s finalizer group, immediately get `anon_raw_secmem` to perform the deallocation and map-removal on these `ptrs`.
|
|
void apply_finalizer_now(std::initializer_list<void*> ptrs) noexcept {
|
|
for(void* p : ptrs) {
|
|
//TODO: `m_manager_ref->immediate_dealloc(p)`
|
|
}
|
|
}
|
|
void FrozenAllocator::deleter::apply_delete(void* restrict p, bool add_group) const noexcept {
|
|
// TODO: allow the allocation (the memory corresponding to `p` from `m_manager_ref`) to be mutable (`munlock()` it.)
|
|
// TODO: Then, again through `m_manager_ref`, add to sequence `->register_finalizer_grouped(this, p)`.
|
|
/// TODO: Unless `add_group` is `false`, in which case, `p` is left to dangle.
|
|
|
|
//(XXX: NOTE: `m_values` map removal *causes* this to be invoked, i.e: A value removed from the map calls `deleter::operator()(uniq_p)`, which then calls `apply_delete(uniq_p, true)`
|
|
}
|
|
// This is the *true manager* of the allocation arena, when it is destroyed, the memory is cleared
|
|
struct FrozenAllocator::anon_raw_secmem {
|
|
typedef FrozenAllocator::deleter deleter;
|
|
|
|
~anon_raw_secmem() {
|
|
//TODO: Clear and `munmap()` the used page(s)
|
|
//XXX: Due to how this is managed via `shared_ptr<>`, it is UB for this to be called *before* all actual allocation of the memory are unallocated (via `deleter`, which they must *all* be managed by.
|
|
}
|
|
};
|
|
|
|
struct FrozenAllocator::alloc_info {
|
|
|
|
};
|
|
struct FrozenAllocator::alloc_value {
|
|
|
|
};
|
|
|
|
struct FrozenAllocator::_impl {
|
|
std::shared_ptr<anon_raw_secmem> m_manager;
|
|
std::map<alloc_info, std::unique_ptr<alloc_value, deleter>> m_values;
|
|
};
|
|
|
|
#define $CLASS FrozenAllocator
|
|
$ctor_move(m) noexcept
|
|
: inner_(std::move(m.inner_)) {}
|
|
$assign_move(m) {
|
|
if($LIKELY(this != &m))
|
|
inner_ = std::move(m.inner_);
|
|
return *this;
|
|
}
|
|
$dtor() {}
|
|
#undef $CLASS /* FrozenAllocator */
|
|
|
|
}
|