This document provides a comprehensive guide to the documentation in slick/object_pool.hpp.
slick/object_pool.h is a deprecated compatibility shim retained for 0.1.x
users: it emits a deprecation notice (suppressible with
SLICK_OBJECT_POOL_NO_DEPRECATION_WARNING) and includes the .hpp. It carries no
implementation and will be removed in a future release.
The code uses Doxygen-style documentation comments for automatic API documentation generation.
| Tag | Purpose | Example |
|---|---|---|
@file |
File description | File-level overview |
@brief |
Short description | One-line summary |
@details |
Detailed description | In-depth explanation |
@tparam |
Template parameter | Template type requirements |
@param |
Function parameter | Parameter description |
@return |
Return value | What the function returns |
@throws |
Exception specification | When exceptions are thrown |
@note |
Important note | Additional information |
@warning |
Warning | Critical warnings |
@pre |
Precondition | Requirements before calling |
@post |
Postcondition | State after calling |
@par |
Paragraph heading | Subsection headers |
@code/@endcode |
Code example | Inline code examples |
@section |
Documentation section | Major sections |
/// |
Inline comment | Member variable docs |
Includes:
- Brief description of the library
- Detailed feature list
- Memory layout diagram
- Type requirements
- Thread safety guarantees
- Usage examples
- Author and version information
object_pool Template Class
Comprehensive documentation covering:
- Purpose and design
- Template type requirements
- Thread safety model
- Performance characteristics
- Example usage patterns
- object_pool(uint32_t size)
- Full parameter documentation
- Exception specifications
- Preconditions and postconditions
- Usage examples
- Cleanup behavior documentation
- Important warnings
-
uint32_t size() const
- Pool size query
- Power-of-2 note
-
T allocate()*
- Comprehensive documentation
- Behavior under different conditions
- Heap fallback when the pool is exhausted
- Performance characteristics
- Thread safety guarantees
- Usage examples
- Important warnings
-
T try_allocate()*
- Pooled allocation without heap fallback
- Returns
nullptrwhen the pool is empty - Real-time / latency-critical usage
-
void free(T obj)*
- Dual behavior (pool vs heap)
- Automatic detection mechanism
- Performance notes
- Critical warnings
-
bool try_free(T obj)*
- Returns a pooled object without heap cleanup
- Reports whether the object was pool-owned
- Caller retains ownership of non-pool objects
-
bool is_pool_member(const T obj)*
- Address-range ownership check
- Thread-safe (read-only)
-
void reset()
- Purpose and use cases
- Thread safety warnings
- Testing vs production use
-
uint32_t available()
- Approximate objects currently in the pool, saturated into
[0, size()] - Explicitly documented as an estimate, not a snapshot: both counters are
read unsynchronized, so it is for monitoring and tests rather than for
deciding whether an
allocate()will succeed
- Approximate objects currently in the pool, saturated into
-
uint64_t heap_fallback_count()
- Cumulative count of
allocate()calls that fell through tonew T() - The production signal for an undersized pool, or for caches parking more objects than the pool can spare
- Monotonic;
reset()does not clear it. Only written on the fallback path, so the fast path is unaffected
- Cumulative count of
-
object_pool_cache
- Per-thread freelist that amortizes shared-atomic costs
allocate()/free()/flush()membersdefault_capacity(pool)- the derived default, exposed as a static so it can be queried without constructing a cache- Capacity sizing rule documented on the class (
@section cache_sizing), with the measured floor and ceiling behind it - Not thread-safe; own one per thread
There are no private helper methods - the ring operations are short enough to
live inline in try_free() and try_allocate(), which keeps the memory
ordering of each step visible in one place.
-
Producer -
try_free()- Single
fetch_addsequence claim onreserved_(the only shared operation on the producer side) relaxedstore of the object pointer intofree_objects_[s & mask_]releasestore of the sequence ontocontrol_[s & mask_].data_index, which publishes the payload written above- The slot for a sequence is a pure function of that sequence, so there is no reservation round-trip and no wraparound bookkeeping
- Single
-
Consumer -
try_allocate()relaxedload ofconsumed_, then anacquireload of the slot'sdata_index; the item is available exactly when they are equalacquireload of the payload pointer before claiming the slot- Single
compare_exchange_weakonconsumed_to claim it - Ordering matters here: while
consumed_still equalsci, no producer can reach sequenceci + size_(that would require more completedfree()s than completedallocate()s), so the slot cannot be overwritten, and a successful CAS provesconsumed_never leftci. Reading the payload after the claim races the producer that reuses the slot and silently drops the object published atci
All member variables are documented with inline comments (///):
- Configuration:
size_,mask_ - Storage:
buffer_,lower_bound_,upper_bound_,free_objects_ - Control:
control_,reserved_,consumed_ - Diagnostics:
heap_fallbacks_- cache-line aligned so that writing it on the fallback path does not invalidate the line holdingsize_/mask_, which every operation reads
-
struct slot
- Absolute publication sequence (
data_index) used to test availability - Member documentation
- Absolute publication sequence (
-
Hot counters (64-bit)
reserved_- producer sequence counter (singlefetch_addonfree())consumed_- consumer sequence counter (singleCASon allocate)- Each cache-line aligned to a private line to prevent false sharing
- The consumer never reads
reserved_, so the producer'sfetch_adddoes not invalidate a line the consumer is spinning on
-
Install Doxygen:
# Ubuntu/Debian sudo apt-get install doxygen graphviz # macOS brew install doxygen graphviz # Windows # Download from https://www.doxygen.nl/download.html
-
Create Doxyfile:
cd y:\repo\slick-object-pool doxygen -g
-
Configure Doxyfile:
PROJECT_NAME = "slick-object-pool" PROJECT_BRIEF = "Lock-free object pool for C++20" PROJECT_VERSION = "0.2.0" OUTPUT_DIRECTORY = docs INPUT = include/slick RECURSIVE = YES EXTRACT_ALL = YES EXTRACT_PRIVATE = NO EXTRACT_STATIC = YES GENERATE_HTML = YES GENERATE_LATEX = NO SOURCE_BROWSER = YES INLINE_SOURCES = YES HAVE_DOT = YES CALL_GRAPH = YES CALLER_GRAPH = YES -
Generate Documentation:
doxygen Doxyfile
-
View Documentation:
# Open in browser open docs/html/index.html # macOS xdg-open docs/html/index.html # Linux start docs/html/index.html # Windows
✅ All public APIs - Complete parameter and return value docs ✅ Examples - Working code examples for common use cases ✅ Thread safety - Explicit guarantees and warnings ✅ Performance - Expected performance characteristics ✅ Exceptions - What exceptions are thrown and when ✅ Preconditions - Requirements before calling ✅ Postconditions - Expected state after calling ✅ Warnings - Critical usage warnings ✅ Platform notes - Platform-specific behavior
| Aspect | Coverage |
|---|---|
| Public API | 100% |
| Private methods | 100% |
| Member variables | 100% |
| Code examples | Extensive |
| Thread safety | Explicit |
| Performance notes | Detailed |
| Platform specifics | Complete |
Focus on:
- Constructor documentation
allocate()andfree()methods- Thread safety guarantees
- Code examples
- Warnings and notes
Additionally review:
- Private method documentation
- Internal structure documentation
- Memory layout details
- Platform-specific implementations
Full documentation including:
- Implementation algorithms
- Memory ordering semantics
- Platform-specific details
- Performance characteristics
/**
* @brief Allocate an object from the pool
*
* @details
* Attempts to allocate an object from the pool using lock-free operations.
* If the pool is exhausted, allocates a new object from the heap instead.
*
* This method is thread-safe and lock-free for multiple concurrent callers.
*
* @return Pointer to an object (never returns nullptr)
*
* @par Behavior
* - Pool has available objects: Returns pooled object (fast path)
* - Pool is exhausted: Allocates from heap (slower fallback)
*
* @par Performance
* - Average: O(1) with low latency (~10-30ns typical)
* - Worst case: O(number of concurrent allocators) due to CAS retry
*
* @par Thread Safety
* Lock-free, safe for concurrent calls from multiple threads
*
* @par Example
* @code
* slick::object_pool<MyStruct> pool(1024);
* MyStruct* obj = pool.allocate();
* obj->field = value;
* pool.free(obj);
* @endcode
*
* @note Must be paired with free() to avoid memory leaks
* @note Returned object is NOT automatically initialized
*/
T* allocate();- Brief - One line summary
- Details - In-depth explanation
- Return - What it returns
- Behavior - Different scenarios
- Performance - Expected performance
- Thread Safety - Concurrency guarantees
- Example - Working code
- Notes - Important information
- Adding new public methods
- Changing method signatures
- Modifying behavior
- Adding new features
- Fixing bugs that change semantics
- Performance improvements
When adding/modifying code:
- Add/update
@briefdescription - Add/update
@detailsif complex - Document all parameters with
@param - Document return value with
@return - List exceptions with
@throws - Add thread safety notes
- Include performance characteristics
- Add code example if helpful
- Add warnings if needed
- Update file-level docs if major change
- README.md - User-facing documentation and examples
- CHANGES.md - Migration guide and changelog
- Comments in code - Implementation notes (not in public API docs)
Documentation Version: 1.0 Last Updated: 2025 Maintained By: SlickQuant