17 #ifndef CYBER_BASE_CONCURRENT_OBJECT_POOL_H_ 18 #define CYBER_BASE_CONCURRENT_OBJECT_POOL_H_ 36 class CCObjectPool :
public std::enable_shared_from_this<CCObjectPool<T>> {
41 template <
typename... Args>
44 template <
typename... Args>
49 uint32_t
size()
const;
57 struct alignas(2 * sizeof(Node *)) Head {
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);
81 template <
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));
110 template <
typename T>
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); });
121 template <
typename T>
122 template <
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);
136 template <
typename T>
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));
154 #endif // CYBER_BASE_CONCURRENT_OBJECT_POOL_H_ void ConstructAll(Args &&... args)
Definition: concurrent_object_pool.h:82
virtual ~CCObjectPool()
Definition: concurrent_object_pool.h:89
PlanningContext is the runtime context in planning. It is persistent across multiple frames...
Definition: atomic_hash_map.h:25
std::shared_ptr< T > ConstructObject(Args &&... args)
Definition: concurrent_object_pool.h:123
void ReleaseObject(T *)
Definition: concurrent_object_pool.h:137
#define FOR_EACH(i, begin, end)
Definition: for_each.h:44
CCObjectPool(uint32_t size)
Definition: concurrent_object_pool.h:73
Definition: concurrent_object_pool.h:36
void * CheckedCalloc(size_t num, size_t size)
Definition: macros.h:67
std::shared_ptr< T > GetObject()
Definition: concurrent_object_pool.h:111
#define cyber_unlikely(x)
Definition: macros.h:28