Skip to content

Commit

Permalink
[TBD] add global object creation function
Browse files Browse the repository at this point in the history
  • Loading branch information
mutouyun committed Jan 1, 2024
1 parent d995c69 commit fc60c75
Show file tree
Hide file tree
Showing 5 changed files with 143 additions and 16 deletions.
86 changes: 86 additions & 0 deletions include/libpmr/new.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/**
* \file libpmr/new.h
* \author mutouyun (orz@orzz.org)
* \brief Global object creation function.
* \date 2024-01-01
*/
#pragma once

#include <cstddef>

#include "libimp/aligned.h"
#include "libimp/uninitialized.h"

#include "libpmr/def.h"
#include "libpmr/block_pool.h"
#include "libpmr/memory_resource.h"

LIBPMR_NAMESPACE_BEG_

constexpr inline std::size_t regular_level(std::size_t s) noexcept {
if (s <= 128 ) return 0;
if (s <= 1024 ) return 1;
if (s <= 8192 ) return 2;
if (s <= 65536) return 3;
return 4;
}

constexpr inline std::size_t regular_sizeof(std::size_t s) noexcept {
switch (regular_level(s)) {
case 0 : return ::LIBIMP::round_up<std::size_t>(s, 8);
case 1 : return ::LIBIMP::round_up<std::size_t>(s, 128);
case 2 : return ::LIBIMP::round_up<std::size_t>(s, 1024);
case 3 : return ::LIBIMP::round_up<std::size_t>(s, 8192);
default: return 0;
}
}

template <typename T>
constexpr inline std::size_t regular_sizeof() noexcept {
return regular_sizeof(sizeof(T));
}

template <std::size_t BlockSize, std::size_t BlockPoolExpansion>
class block_pool_resource : public block_pool<BlockSize, BlockPoolExpansion> {
public:
static block_pool_resource *get() noexcept {
thread_local block_pool_resource instance;
return &instance;
}
void *allocate(std::size_t /*bytes*/, std::size_t /*alignment*/ = alignof(std::max_align_t)) noexcept {
return block_pool<BlockSize, BlockPoolExpansion>::allocate();
}
void deallocate(void *p, std::size_t /*bytes*/, std::size_t /*alignment*/ = alignof(std::max_align_t)) noexcept {
block_pool<BlockSize, BlockPoolExpansion>::deallocate(p);
}
};

template <std::size_t N, std::size_t L = regular_level(N)>
class regular_resource : public new_delete_resource {};

template <std::size_t N>
class regular_resource<N, 0> : public block_pool_resource<N, 512> {};

template <std::size_t N>
class regular_resource<N, 1> : public block_pool_resource<N, 256> {};

template <std::size_t N>
class regular_resource<N, 2> : public block_pool_resource<N, 128> {};

template <std::size_t N>
class regular_resource<N, 3> : public block_pool_resource<N, 64> {};

template <typename T, typename... A>
T *new_(A &&... args) noexcept {
auto *mem_res = regular_resource<regular_sizeof<T>()>::get();
return ::LIBIMP::construct<T>(mem_res->allocate(sizeof(T), alignof(T)), std::forward<A>(args)...);
}

template <typename T>
void delete_(T *p) noexcept {
if (p == nullptr) return;
auto *mem_res = regular_resource<regular_sizeof<T>()>::get();
mem_res->deallocate(::LIBIMP::destroy(p), sizeof(T), alignof(T));
}

LIBPMR_NAMESPACE_END_
18 changes: 2 additions & 16 deletions src/libpmr/memory_resource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,9 @@

#include "libpmr/memory_resource.h"

LIBPMR_NAMESPACE_BEG_
namespace {

/**
* \brief Check that bytes is not 0 and that the alignment is a power of two.
*/
bool verify_args(std::size_t bytes, std::size_t alignment) noexcept {
if (bytes == 0) {
return false;
}
if ((alignment == 0) || (alignment & (alignment - 1)) != 0) {
return false;
}
return true;
}
#include "verify_args.h"

} // namespace
LIBPMR_NAMESPACE_BEG_

/**
* \brief Returns a pointer to a new_delete_resource.
Expand Down
28 changes: 28 additions & 0 deletions src/libpmr/synchronized_pool_resource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,38 @@
#include "libimp/log.h"

#include "libpmr/synchronized_pool_resource.h"
#include "libpmr/block_pool.h"

#include "verify_args.h"

LIBPMR_NAMESPACE_BEG_
namespace {

} // namespace

synchronized_pool_resource *synchronized_pool_resource::get() noexcept {
static synchronized_pool_resource mem_res;
return &mem_res;
}

void *synchronized_pool_resource::allocate(std::size_t bytes, std::size_t alignment) noexcept {
LIBIMP_LOG_();
if (!verify_args(bytes, alignment) || (alignment > alignof(std::max_align_t))) {
log.error("invalid bytes = ", bytes, ", alignment = ", alignment);
return nullptr;
}
return nullptr;
}

void synchronized_pool_resource::deallocate(void *p, std::size_t bytes, std::size_t alignment) noexcept {
LIBIMP_LOG_();
if (p == nullptr) {
return;
}
if (!verify_args(bytes, alignment) || (alignment > alignof(std::max_align_t))) {
log.error("invalid bytes = ", bytes, ", alignment = ", alignment);
return;
}
}

LIBPMR_NAMESPACE_END_
22 changes: 22 additions & 0 deletions src/libpmr/verify_args.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

#include <cstddef>

#include "libpmr/def.h"

LIBPMR_NAMESPACE_BEG_

/**
* \brief Check that bytes is not 0 and that the alignment is a power of two.
*/
inline bool verify_args(std::size_t bytes, std::size_t alignment) noexcept {
if (bytes == 0) {
return false;
}
if ((alignment == 0) || (alignment & (alignment - 1)) != 0) {
return false;
}
return true;
}

LIBPMR_NAMESPACE_END_
5 changes: 5 additions & 0 deletions test/pmr/test_pmr_new.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@

#include "gtest/gtest.h"

#include "libpmr/new.h"

0 comments on commit fc60c75

Please sign in to comment.