Skip to content

Commit fc60c75

Browse files
committed
[TBD] add global object creation function
1 parent d995c69 commit fc60c75

File tree

5 files changed

+143
-16
lines changed

5 files changed

+143
-16
lines changed

include/libpmr/new.h

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/**
2+
* \file libpmr/new.h
3+
* \author mutouyun ([email protected])
4+
* \brief Global object creation function.
5+
* \date 2024-01-01
6+
*/
7+
#pragma once
8+
9+
#include <cstddef>
10+
11+
#include "libimp/aligned.h"
12+
#include "libimp/uninitialized.h"
13+
14+
#include "libpmr/def.h"
15+
#include "libpmr/block_pool.h"
16+
#include "libpmr/memory_resource.h"
17+
18+
LIBPMR_NAMESPACE_BEG_
19+
20+
constexpr inline std::size_t regular_level(std::size_t s) noexcept {
21+
if (s <= 128 ) return 0;
22+
if (s <= 1024 ) return 1;
23+
if (s <= 8192 ) return 2;
24+
if (s <= 65536) return 3;
25+
return 4;
26+
}
27+
28+
constexpr inline std::size_t regular_sizeof(std::size_t s) noexcept {
29+
switch (regular_level(s)) {
30+
case 0 : return ::LIBIMP::round_up<std::size_t>(s, 8);
31+
case 1 : return ::LIBIMP::round_up<std::size_t>(s, 128);
32+
case 2 : return ::LIBIMP::round_up<std::size_t>(s, 1024);
33+
case 3 : return ::LIBIMP::round_up<std::size_t>(s, 8192);
34+
default: return 0;
35+
}
36+
}
37+
38+
template <typename T>
39+
constexpr inline std::size_t regular_sizeof() noexcept {
40+
return regular_sizeof(sizeof(T));
41+
}
42+
43+
template <std::size_t BlockSize, std::size_t BlockPoolExpansion>
44+
class block_pool_resource : public block_pool<BlockSize, BlockPoolExpansion> {
45+
public:
46+
static block_pool_resource *get() noexcept {
47+
thread_local block_pool_resource instance;
48+
return &instance;
49+
}
50+
void *allocate(std::size_t /*bytes*/, std::size_t /*alignment*/ = alignof(std::max_align_t)) noexcept {
51+
return block_pool<BlockSize, BlockPoolExpansion>::allocate();
52+
}
53+
void deallocate(void *p, std::size_t /*bytes*/, std::size_t /*alignment*/ = alignof(std::max_align_t)) noexcept {
54+
block_pool<BlockSize, BlockPoolExpansion>::deallocate(p);
55+
}
56+
};
57+
58+
template <std::size_t N, std::size_t L = regular_level(N)>
59+
class regular_resource : public new_delete_resource {};
60+
61+
template <std::size_t N>
62+
class regular_resource<N, 0> : public block_pool_resource<N, 512> {};
63+
64+
template <std::size_t N>
65+
class regular_resource<N, 1> : public block_pool_resource<N, 256> {};
66+
67+
template <std::size_t N>
68+
class regular_resource<N, 2> : public block_pool_resource<N, 128> {};
69+
70+
template <std::size_t N>
71+
class regular_resource<N, 3> : public block_pool_resource<N, 64> {};
72+
73+
template <typename T, typename... A>
74+
T *new_(A &&... args) noexcept {
75+
auto *mem_res = regular_resource<regular_sizeof<T>()>::get();
76+
return ::LIBIMP::construct<T>(mem_res->allocate(sizeof(T), alignof(T)), std::forward<A>(args)...);
77+
}
78+
79+
template <typename T>
80+
void delete_(T *p) noexcept {
81+
if (p == nullptr) return;
82+
auto *mem_res = regular_resource<regular_sizeof<T>()>::get();
83+
mem_res->deallocate(::LIBIMP::destroy(p), sizeof(T), alignof(T));
84+
}
85+
86+
LIBPMR_NAMESPACE_END_

src/libpmr/memory_resource.cpp

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,9 @@
88

99
#include "libpmr/memory_resource.h"
1010

11-
LIBPMR_NAMESPACE_BEG_
12-
namespace {
13-
14-
/**
15-
* \brief Check that bytes is not 0 and that the alignment is a power of two.
16-
*/
17-
bool verify_args(std::size_t bytes, std::size_t alignment) noexcept {
18-
if (bytes == 0) {
19-
return false;
20-
}
21-
if ((alignment == 0) || (alignment & (alignment - 1)) != 0) {
22-
return false;
23-
}
24-
return true;
25-
}
11+
#include "verify_args.h"
2612

27-
} // namespace
13+
LIBPMR_NAMESPACE_BEG_
2814

2915
/**
3016
* \brief Returns a pointer to a new_delete_resource.

src/libpmr/synchronized_pool_resource.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,38 @@
22
#include "libimp/log.h"
33

44
#include "libpmr/synchronized_pool_resource.h"
5+
#include "libpmr/block_pool.h"
6+
7+
#include "verify_args.h"
58

69
LIBPMR_NAMESPACE_BEG_
710
namespace {
811

912
} // namespace
1013

14+
synchronized_pool_resource *synchronized_pool_resource::get() noexcept {
15+
static synchronized_pool_resource mem_res;
16+
return &mem_res;
17+
}
18+
19+
void *synchronized_pool_resource::allocate(std::size_t bytes, std::size_t alignment) noexcept {
20+
LIBIMP_LOG_();
21+
if (!verify_args(bytes, alignment) || (alignment > alignof(std::max_align_t))) {
22+
log.error("invalid bytes = ", bytes, ", alignment = ", alignment);
23+
return nullptr;
24+
}
25+
return nullptr;
26+
}
27+
28+
void synchronized_pool_resource::deallocate(void *p, std::size_t bytes, std::size_t alignment) noexcept {
29+
LIBIMP_LOG_();
30+
if (p == nullptr) {
31+
return;
32+
}
33+
if (!verify_args(bytes, alignment) || (alignment > alignof(std::max_align_t))) {
34+
log.error("invalid bytes = ", bytes, ", alignment = ", alignment);
35+
return;
36+
}
37+
}
38+
1139
LIBPMR_NAMESPACE_END_

src/libpmr/verify_args.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#pragma once
2+
3+
#include <cstddef>
4+
5+
#include "libpmr/def.h"
6+
7+
LIBPMR_NAMESPACE_BEG_
8+
9+
/**
10+
* \brief Check that bytes is not 0 and that the alignment is a power of two.
11+
*/
12+
inline bool verify_args(std::size_t bytes, std::size_t alignment) noexcept {
13+
if (bytes == 0) {
14+
return false;
15+
}
16+
if ((alignment == 0) || (alignment & (alignment - 1)) != 0) {
17+
return false;
18+
}
19+
return true;
20+
}
21+
22+
LIBPMR_NAMESPACE_END_

test/pmr/test_pmr_new.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
2+
#include "gtest/gtest.h"
3+
4+
#include "libpmr/new.h"
5+

0 commit comments

Comments
 (0)