libxr
Embedded C++ framework for bare-metal, RTOS and Linux
Loading...
Searching...
No Matches
LibXR::ObjectPool< Data > Class Template Reference

带引用计数的固定槽对象池 / Fixed-slot object pool with reference counting. More...

#include <object_pool.hpp>

Classes

class  ConstHandle
 只读句柄:共享一个槽位,可以复制。 Read-only handle: shares one slot, copyable. More...
 
class  Handle
 可写句柄:独占一个槽位,只能移动。 Writable handle: exclusive owner of one slot, move-only. More...
 
class  Slot
 槽位:引用计数、空闲链接和常驻负载。 Slot: reference count, free-stack link and resident payload. More...
 

Public Types

using ValueType = Data
 槽内对象类型 / Slot object type.
 
using IndexType = uint32_t
 槽索引类型 / Slot index type.
 

Public Member Functions

template<typename T = Data>
requires std::is_default_constructible_v<T>
 ObjectPool (size_t slot_count)
 用内部槽数组构造池 / Construct the pool with internal slots.
 
 ObjectPool (size_t slot_count, Slot *slots)
 用外部槽数组构造池 / Construct the pool with caller-provided slots.
 
 ~ObjectPool ()
 析构池;所有句柄必须已释放 / Destroy the pool; all handles must be released.
 
 ObjectPool (const ObjectPool &)=delete
 
ObjectPool & operator= (const ObjectPool &)=delete
 
 ObjectPool (ObjectPool &&)=delete
 
ObjectPool & operator= (ObjectPool &&)=delete
 
ErrorCode Acquire (Handle &handle)
 获取一个空闲槽位 / Acquire one free slot.
 
size_t EmptySize () const
 返回空闲槽位数 / Return the number of free slots.
 
size_t Size () const
 返回槽位总数 / Return the total number of slots.
 
Data & UnsafeAt (size_t index)
 按槽位索引直接访问对象,不检查所有权。 Access an object by slot index without ownership checks.
 
const Data & UnsafeAt (size_t index) const
 按槽位索引只读访问对象,不检查所有权。 Read-only access by slot index without ownership checks.
 

Detailed Description

template<typename Data>
class LibXR::ObjectPool< Data >

带引用计数的固定槽对象池 / Fixed-slot object pool with reference counting.

写独占、读共享:Acquire 得到只能移动的可写 Handle;写完后移动为可复制的只读 ConstHandle 分发,最后一个引用释放时槽位回到空闲栈。槽内对象随池构造、随池析构, 释放时不析构也不清空,下一个申请方自行写入。运行期操作不分配内存。每槽引用数不得 超过 UINT32_MAX。

One writer, shared readers: Acquire yields a move-only writable Handle; after writing, move it into a copyable read-only ConstHandle to distribute the slot. The final release returns the slot to the free stack. Payloads are constructed and destroyed with the pool; release neither destroys nor clears them, so the next acquirer writes its own data. Runtime operations allocate no memory. Each slot must have at most UINT32_MAX references.

同一池同一时刻只能有一个申请方:申请不得重叠或重入,调试构建会检查。释放可以在 任意线程或 ISR 中并发进行,且不会失败。不同句柄对象可以并发使用,同一句柄对象的 并发访问须由调用方同步。构造和析构须在静止状态下进行,不能在 ISR 中执行;池及 外部槽存储必须比全部句柄活得更久。ISR 使用要求目标平台提供 32 位原子 CAS。

Only one acquirer may use a pool at a time: acquisitions must not overlap or reenter, and debug builds check this. Releases may run concurrently from any thread or ISR and cannot fail. Distinct handle objects may be used concurrently; concurrent access to one handle object requires caller synchronization. Construction and destruction require quiescence outside ISR. The pool and any external slot storage must outlive all handles. ISR use requires 32-bit atomic CAS on the target.

Template Parameters
Data槽内对象类型 / Slot object type.

Definition at line 46 of file object_pool.hpp.

Member Typedef Documentation

◆ IndexType

template<typename Data >
using LibXR::ObjectPool< Data >::IndexType = uint32_t

槽索引类型 / Slot index type.

Definition at line 50 of file object_pool.hpp.

◆ ValueType

template<typename Data >
using LibXR::ObjectPool< Data >::ValueType = Data

槽内对象类型 / Slot object type.

Definition at line 49 of file object_pool.hpp.

Constructor & Destructor Documentation

◆ ObjectPool() [1/2]

template<typename Data >
template<typename T = Data>
requires std::is_default_constructible_v<T>
LibXR::ObjectPool< Data >::ObjectPool ( size_t slot_count)
inlineexplicit

用内部槽数组构造池 / Construct the pool with internal slots.

Parameters
slot_count槽位数量 / Number of slots.

Definition at line 318 of file object_pool.hpp.

319 : slots_(new Slot[slot_count]), slot_count_(slot_count), owns_slots_(true)
320 {
321 InitializeFreeStack();
322 }

◆ ObjectPool() [2/2]

template<typename Data >
LibXR::ObjectPool< Data >::ObjectPool ( size_t slot_count,
Slot * slots )
inline

用外部槽数组构造池 / Construct the pool with caller-provided slots.

Parameters
slot_count槽位数量 / Number of slots.
slots外部槽数组 / Caller-provided slot storage.
Note
slots 必须指向至少 slot_count 个未被其他池使用的 Slot;池不构造也不 析构其中的负载。 slots must point to at least slot_count slots not used by another pool; the pool neither constructs nor destroys their payloads.

Definition at line 334 of file object_pool.hpp.

335 : slots_(slots), slot_count_(slot_count), owns_slots_(false)
336 {
337 ASSERT(slots_ != nullptr);
338 InitializeFreeStack();
339 }

◆ ~ObjectPool()

template<typename Data >
LibXR::ObjectPool< Data >::~ObjectPool ( )
inline

析构池;所有句柄必须已释放 / Destroy the pool; all handles must be released.

Definition at line 344 of file object_pool.hpp.

345 {
346 ASSERT(EmptySize() == slot_count_);
347
348 if (owns_slots_)
349 {
350 delete[] slots_;
351 }
352 }
size_t EmptySize() const
返回空闲槽位数 / Return the number of free slots.

Member Function Documentation

◆ Acquire()

template<typename Data >
ErrorCode LibXR::ObjectPool< Data >::Acquire ( Handle & handle)
inlinenodiscard

获取一个空闲槽位 / Acquire one free slot.

Parameters
handle接收槽位的空句柄 / Empty handle receiving the slot.
Returns
成功返回 ErrorCode::OK,没有空槽返回 ErrorCode::EMPTY,不等待。 ErrorCode::OK on success, ErrorCode::EMPTY without waiting when no slot is free.
Note
同一池的申请不得重叠或重入 / Acquisitions on one pool must not overlap or reenter.

Definition at line 368 of file object_pool.hpp.

369 {
370 ASSERT(!handle.Valid());
371#ifdef LIBXR_DEBUG_BUILD
372 // 重叠申请会让空闲栈出现 ABA,同一槽位被两个申请方取得。
373 // Overlapping acquisitions cause ABA on the free stack and hand one slot to two
374 // acquirers.
375 uint32_t idle = 0U;
376 ASSERT(acquiring_.compare_exchange_strong(idle, 1U, std::memory_order_acquire,
377 std::memory_order_relaxed));
378#endif
379
380 IndexType index = 0;
381 const ErrorCode ec = PopFree(index);
382 if (ec == ErrorCode::OK)
383 {
384 free_count_.fetch_sub(1U, std::memory_order_relaxed);
385 DEV_ASSERT(slots_[index].references_.load(std::memory_order_relaxed) == 0U);
386 slots_[index].references_.store(1U, std::memory_order_relaxed);
387 handle = Handle(this, index);
388 }
389
390#ifdef LIBXR_DEBUG_BUILD
391 acquiring_.store(0U, std::memory_order_release);
392#endif
393 return ec;
394 }
uint32_t IndexType
槽索引类型 / Slot index type.
ErrorCode
定义错误码枚举 / Defines an enumeration for error codes
@ OK
操作成功 / Operation successful

◆ EmptySize()

template<typename Data >
size_t LibXR::ObjectPool< Data >::EmptySize ( ) const
inlinenodiscard

返回空闲槽位数 / Return the number of free slots.

Returns
空闲槽位数;有并发申请或释放时为近似值,只用于监控。 Free slot count; approximate during concurrent acquire or release, for monitoring only.

Definition at line 402 of file object_pool.hpp.

403 {
404 return free_count_.load(std::memory_order_relaxed);
405 }

◆ Size()

template<typename Data >
size_t LibXR::ObjectPool< Data >::Size ( ) const
inlinenodiscard

返回槽位总数 / Return the total number of slots.

Returns
槽位总数 / Total slot count.

Definition at line 411 of file object_pool.hpp.

411{ return slot_count_; }

◆ UnsafeAt() [1/2]

template<typename Data >
Data & LibXR::ObjectPool< Data >::UnsafeAt ( size_t index)
inlinenodiscard

按槽位索引直接访问对象,不检查所有权。 Access an object by slot index without ownership checks.

Parameters
index槽位索引 / Slot index.
Returns
槽内对象的引用 / Reference to the slot object.
Note
只用于调试或调用方已确知槽位状态的场景。 Intended for debugging or when the caller already knows the slot state.

Definition at line 421 of file object_pool.hpp.

422 {
423 ASSERT(index < slot_count_);
424 return slots_[index].data_;
425 }

◆ UnsafeAt() [2/2]

template<typename Data >
const Data & LibXR::ObjectPool< Data >::UnsafeAt ( size_t index) const
inlinenodiscard

按槽位索引只读访问对象,不检查所有权。 Read-only access by slot index without ownership checks.

Parameters
index槽位索引 / Slot index.
Returns
槽内对象的常量引用 / Const reference to the slot object.
Note
只用于调试或调用方已确知槽位状态的场景。 Intended for debugging or when the caller already knows the slot state.

Definition at line 435 of file object_pool.hpp.

436 {
437 ASSERT(index < slot_count_);
438 return slots_[index].data_;
439 }

The documentation for this class was generated from the following file: