17#ifndef CYBER_BASE_CONCURRENT_OBJECT_POOL_H_
18#define CYBER_BASE_CONCURRENT_OBJECT_POOL_H_
36class CCObjectPool :
public std::enable_shared_from_this<CCObjectPool<T>> {
41 template <
typename... Args>
44 template <
typename... Args>
57 struct alignas(2 * sizeof(Node *)) Head {
63 CCObjectPool(CCObjectPool &) =
delete;
64 CCObjectPool &operator=(CCObjectPool &) =
delete;
65 bool FindFreeHead(Head *head);
67 std::atomic<Head> free_head_;
68 Node *node_arena_ =
nullptr;
69 uint32_t capacity_ = 0;
74 node_arena_ =
static_cast<Node *
>(
CheckedCalloc(capacity_,
sizeof(Node)));
75 FOR_EACH(i, 0, capacity_ - 1) { node_arena_[i].next = node_arena_ + 1 + i; }
76 node_arena_[capacity_ - 1].next =
nullptr;
77 free_head_.store({0, node_arena_}, std::memory_order_relaxed);
81template <
typename... Args>
84 new (node_arena_ + i) T(std::forward<Args>(args)...);
90 std::free(node_arena_);
96 Head old_head = free_head_.load(std::memory_order_acquire);
101 new_head.node = old_head.node->next;
102 new_head.count = old_head.count + 1;
103 }
while (!free_head_.compare_exchange_weak(old_head, new_head,
104 std::memory_order_acq_rel,
105 std::memory_order_acquire));
116 auto self = this->shared_from_this();
117 return std::shared_ptr<T>(
reinterpret_cast<T *
>(free_head.node),
118 [self](T *
object) { self->ReleaseObject(object); });
122template <
typename... Args>
128 auto self = this->shared_from_this();
129 T *ptr =
new (free_head.node) T(std::forward<Args>(args)...);
130 return std::shared_ptr<T>(ptr, [self](T *
object) {
132 self->ReleaseObject(
object);
139 Node *node =
reinterpret_cast<Node *
>(object);
140 Head old_head = free_head_.load(std::memory_order_acquire);
142 node->next = old_head.node;
143 new_head.node = node;
144 new_head.count = old_head.count + 1;
145 }
while (!free_head_.compare_exchange_weak(old_head, new_head,
146 std::memory_order_acq_rel,
147 std::memory_order_acquire));
Node is the fundamental building block of Cyber RT.
std::shared_ptr< T > GetObject()
void ConstructAll(Args &&... args)
std::shared_ptr< T > ConstructObject(Args &&... args)
CCObjectPool(uint32_t size)
#define cyber_unlikely(x)
void * CheckedCalloc(size_t num, size_t size)
#define FOR_EACH(i, begin, end)