SuperTinyKernel™ RTOS 1.06.x
Lightweight, high-performance, deterministic, bare-metal C++ RTOS for resource-constrained embedded systems. MIT Open Source License.
Loading...
Searching...
No Matches
STK C Memory API

Pure C interface for stk::memory::BlockMemoryPool. More...

Macros

#define STK_C_BLOCKPOOL_MAX   (8U)
 Maximum number of concurrent stk_blockpool_t instances (default: 8).
#define STK_BLOCKPOOL_ALIGN   (sizeof(stk_word_t))
 Required storage alignment in bytes (equals sizeof(void*)).
#define STK_BLOCKPOOL_ALIGN_BLOCK_SIZE(raw_size)
 Compute the internally aligned block size for a given raw byte size.
#define STK_BLOCKPOOL_STORAGE_SIZE(capacity, raw_block_size)
 Compute the minimum external storage buffer size in bytes.
#define STK_BLOCKPOOL_STORAGE_DECL(name, capacity, raw_block_size)
 Declare a correctly sized and aligned external storage array.

Typedefs

typedef struct stk_blockpool_t stk_blockpool_t
 Opaque handle to a stk::memory::BlockMemoryPool instance.

Functions

stk_blockpool_tstk_blockpool_create (size_t capacity, size_t raw_block_size, const char *name)
 Create a block pool backed by heap-allocated storage.
stk_blockpool_tstk_blockpool_create_static (size_t capacity, size_t raw_block_size, uint8_t *storage, size_t storage_size, const char *name)
 Create a block pool backed by caller-supplied (external) storage.
void stk_blockpool_destroy (stk_blockpool_t *pool)
 Destroy a pool and return its slot to the static pool.
void * stk_blockpool_alloc (stk_blockpool_t *pool)
 Allocate one block, blocking indefinitely until one is available.
void * stk_blockpool_timed_alloc (stk_blockpool_t *pool, stk_timeout_t timeout)
 Allocate one block, blocking until one becomes available or the timeout expires.
void * stk_blockpool_try_alloc (stk_blockpool_t *pool)
 Non-blocking allocation attempt.
bool stk_blockpool_free (stk_blockpool_t *pool, void *ptr)
 Return a previously allocated block to the pool.
bool stk_blockpool_is_storage_valid (const stk_blockpool_t *pool)
 Verify that the backing storage is valid and the pool is ready for use.
size_t stk_blockpool_get_capacity (const stk_blockpool_t *pool)
 Get the total block capacity of the pool.
size_t stk_blockpool_get_block_size (const stk_blockpool_t *pool)
 Get the aligned block size used internally by the allocator.
size_t stk_blockpool_get_used_count (const stk_blockpool_t *pool)
 Get the number of currently allocated (outstanding) blocks.
size_t stk_blockpool_get_free_count (const stk_blockpool_t *pool)
 Get the number of free (available) blocks.
bool stk_blockpool_is_full (const stk_blockpool_t *pool)
 Check whether all blocks are currently allocated (pool exhausted).
bool stk_blockpool_is_empty (const stk_blockpool_t *pool)
 Check whether all blocks are free (no outstanding allocations).

Detailed Description

Pure C interface for stk::memory::BlockMemoryPool.

Macro Definition Documentation

◆ STK_BLOCKPOOL_ALIGN

#define STK_BLOCKPOOL_ALIGN   (sizeof(stk_word_t))

Required storage alignment in bytes (equals sizeof(void*)).

Definition at line 84 of file stk_c_memory.h.

◆ STK_BLOCKPOOL_ALIGN_BLOCK_SIZE

#define STK_BLOCKPOOL_ALIGN_BLOCK_SIZE ( raw_size)
Value:
(((raw_size) < STK_BLOCKPOOL_ALIGN) \
: (((raw_size) + (STK_BLOCKPOOL_ALIGN - 1U)) & ~(STK_BLOCKPOOL_ALIGN - 1U)))
#define STK_BLOCKPOOL_ALIGN
Required storage alignment in bytes (equals sizeof(void*)).

Compute the internally aligned block size for a given raw byte size.

Rounds raw_size up to the nearest multiple of STK_BLOCKPOOL_ALIGN, with a minimum of STK_BLOCKPOOL_ALIGN. Use this at compile time to size external storage buffers correctly.

Definition at line 92 of file stk_c_memory.h.

92#define STK_BLOCKPOOL_ALIGN_BLOCK_SIZE(raw_size) \
93 (((raw_size) < STK_BLOCKPOOL_ALIGN) \
94 ? STK_BLOCKPOOL_ALIGN \
95 : (((raw_size) + (STK_BLOCKPOOL_ALIGN - 1U)) & ~(STK_BLOCKPOOL_ALIGN - 1U)))

◆ STK_BLOCKPOOL_STORAGE_DECL

#define STK_BLOCKPOOL_STORAGE_DECL ( name,
capacity,
raw_block_size )
Value:
static stk_word_t name[STK_BLOCKPOOL_STORAGE_SIZE(capacity, raw_block_size) / sizeof(stk_word_t)]
uintptr_t stk_word_t
CPU register type.
Definition stk_c.h:94
#define STK_BLOCKPOOL_STORAGE_SIZE(capacity, raw_block_size)
Compute the minimum external storage buffer size in bytes.

Declare a correctly sized and aligned external storage array.

Expands to a static stk_word_t array with the required size and pointer-sized alignment. Intended for file-scope or function-scope use. STK_BLOCKPOOL_ALIGN_BLOCK_SIZE() guarantees the total byte count is always an exact multiple of sizeof(stk_word_t), so the integer division in the array dimension is lossless by construction.

Parameters
nameC identifier for the array variable.
capacityNumber of blocks the pool will hold.
raw_block_sizeRaw per-block size in bytes.
STK_BLOCKPOOL_STORAGE_DECL(g_BufStorage, 16, sizeof(MyBuf));
16, sizeof(MyBuf), g_BufStorage, sizeof(g_BufStorage), NULL);
struct stk_blockpool_t stk_blockpool_t
Opaque handle to a stk::memory::BlockMemoryPool instance.
stk_blockpool_t * stk_blockpool_create_static(size_t capacity, size_t raw_block_size, uint8_t *storage, size_t storage_size, const char *name)
Create a block pool backed by caller-supplied (external) storage.
#define STK_BLOCKPOOL_STORAGE_DECL(name, capacity, raw_block_size)
Declare a correctly sized and aligned external storage array.

Definition at line 122 of file stk_c_memory.h.

122#define STK_BLOCKPOOL_STORAGE_DECL(name, capacity, raw_block_size) \
123 static stk_word_t name[STK_BLOCKPOOL_STORAGE_SIZE(capacity, raw_block_size) / sizeof(stk_word_t)]

◆ STK_BLOCKPOOL_STORAGE_SIZE

#define STK_BLOCKPOOL_STORAGE_SIZE ( capacity,
raw_block_size )
Value:
((capacity) * STK_BLOCKPOOL_ALIGN_BLOCK_SIZE(raw_block_size))
#define STK_BLOCKPOOL_ALIGN_BLOCK_SIZE(raw_size)
Compute the internally aligned block size for a given raw byte size.

Compute the minimum external storage buffer size in bytes.

Parameters
capacityNumber of blocks the pool will hold.
raw_block_sizeRaw per-block size in bytes.

Definition at line 102 of file stk_c_memory.h.

102#define STK_BLOCKPOOL_STORAGE_SIZE(capacity, raw_block_size) \
103 ((capacity) * STK_BLOCKPOOL_ALIGN_BLOCK_SIZE(raw_block_size))

◆ STK_C_BLOCKPOOL_MAX

#define STK_C_BLOCKPOOL_MAX   (8U)

Maximum number of concurrent stk_blockpool_t instances (default: 8).

Note
Increase if your application needs more simultaneous pools.

Definition at line 74 of file stk_c_memory.h.

Referenced by AcquireSlot(), and FindSlot().

Typedef Documentation

◆ stk_blockpool_t

typedef struct stk_blockpool_t stk_blockpool_t

Opaque handle to a stk::memory::BlockMemoryPool instance.

Definition at line 131 of file stk_c_memory.h.

Function Documentation

◆ stk_blockpool_alloc()

void * stk_blockpool_alloc ( stk_blockpool_t * pool)

Allocate one block, blocking indefinitely until one is available.

Parameters
[in]poolPool handle.
Returns
Pointer to an uninitialized block of at least raw_block_size bytes. Never returns NULL.
Warning
Not ISR-safe.

Definition at line 208 of file stk_c_memory.cpp.

209{
210 STK_ASSERT(pool != nullptr);
211 // stk_blockpool_alloc() blocks indefinitely and must never be called from an ISR.
212 // Use stk_blockpool_try_alloc() or stk_blockpool_timed_alloc(..., STK_NO_WAIT) instead.
214
215 return pool->handle.Alloc();
216}
#define STK_ASSERT(e)
Runtime assertion. Halts execution if the expression e evaluates to false.
Definition stk_defs.h:409
bool IsInsideISR()
Check whether the CPU is currently executing inside a hardware interrupt service routine (ISR).
void * Alloc()
Allocate one block, blocking indefinitely until one is available.
BlockMemoryPool handle

References stk::memory::BlockMemoryPool::Alloc(), stk_blockpool_t::handle, stk::hw::IsInsideISR(), and STK_ASSERT.

Here is the call graph for this function:

◆ stk_blockpool_create()

stk_blockpool_t * stk_blockpool_create ( size_t capacity,
size_t raw_block_size,
const char * name )

Create a block pool backed by heap-allocated storage.

Allocates a flat byte buffer of capacity * AlignBlockSize(raw_block_size) bytes from the heap. Call stk_blockpool_is_storage_valid() immediately after creation when operating without exceptions (typical embedded configuration).

Parameters
[in]capacityTotal number of blocks.
[in]raw_block_sizeRequested per-block size in bytes.
[in]nameOptional human-readable name (may be NULL). Forwarded to ITraceable::SetTraceName().
Returns
Pool handle, or NULL if the static slot pool is exhausted (STK_C_BLOCKPOOL_MAX reached). A non-NULL handle does not guarantee the backing storage was successfully heap-allocated; always call stk_blockpool_is_storage_valid() immediately after creation when operating without exceptions.
Note
Not ISR-safe.
See also
stk_blockpool_is_storage_valid(), stk_blockpool_destroy()

Definition at line 137 of file stk_c_memory.cpp.

138{
139 STK_ASSERT(capacity > 0U);
140 STK_ASSERT(raw_block_size > 0U);
141
143
144 BlockPoolSlot *const slot = AcquireSlot();
145
146 // pool exhausted — increase STK_C_BLOCKPOOL_MAX
147 STK_ASSERT(slot != nullptr);
148
149 stk_blockpool_t *result = nullptr;
150 if (slot != nullptr)
151 {
152 result = new (slot->storage) stk_blockpool_t(capacity, raw_block_size, name);
153 }
154
155 return result;
156}
static BlockPoolSlot * AcquireSlot()
RAII-style low-level synchronization primitive for atomic code execution. Used as building brick for ...
Definition stk_sync_cs.h:54
Word storage[StkGetWordCountForType< stk_blockpool_t >()]

References AcquireSlot(), STK_ASSERT, and BlockPoolSlot::storage.

Here is the call graph for this function:

◆ stk_blockpool_create_static()

stk_blockpool_t * stk_blockpool_create_static ( size_t capacity,
size_t raw_block_size,
uint8_t * storage,
size_t storage_size,
const char * name )

Create a block pool backed by caller-supplied (external) storage.

The pool references storage directly without taking ownership. The caller must keep the buffer alive for the entire lifetime of the pool. The storage is not freed on destruction.

Parameters
[in]capacityTotal number of blocks the pool can hold.
[in]raw_block_sizeRequested per-block size in bytes.
[in]storagePointer to a caller-owned byte buffer. Must be aligned to at least sizeof(void*) and large enough to hold at least STK_BLOCKPOOL_STORAGE_SIZE(capacity, raw_block_size) bytes. Asserted at construction time.
[in]storage_sizeSize of storage in bytes (used for the size assertion).
[in]nameOptional human-readable name (may be NULL).
Returns
Pool handle, or NULL if the static slot pool is exhausted (STK_C_BLOCKPOOL_MAX reached).
Note
Not ISR-safe.
See also
stk_blockpool_destroy()

Definition at line 158 of file stk_c_memory.cpp.

163{
164 STK_ASSERT(capacity > 0U);
165 STK_ASSERT(raw_block_size > 0U);
166 STK_ASSERT(storage_ptr != nullptr);
167 STK_ASSERT(storage_size >= (capacity * BlockMemoryPool::AlignBlockSize(raw_block_size)));
168
170
171 BlockPoolSlot *const slot = AcquireSlot();
172
173 // pool exhausted — increase STK_C_BLOCKPOOL_MAX
174 STK_ASSERT(slot != nullptr);
175
176 stk_blockpool_t *result = nullptr;
177 if (slot != nullptr)
178 {
179 result = new (slot->storage) stk_blockpool_t(capacity, raw_block_size,
180 storage_ptr, storage_size, name);
181 }
182
183 return result;
184}
static constexpr size_t AlignBlockSize(size_t raw_size)
Round a raw block size up to the nearest multiple of BLOCK_ALIGN.

References AcquireSlot(), stk::memory::BlockMemoryPool::AlignBlockSize(), STK_ASSERT, and BlockPoolSlot::storage.

Here is the call graph for this function:

◆ stk_blockpool_destroy()

void stk_blockpool_destroy ( stk_blockpool_t * pool)

Destroy a pool and return its slot to the static pool.

If the pool owns heap storage, it is freed. External storage is never touched.

Parameters
[in]poolPool handle obtained via stk_blockpool_create() or stk_blockpool_create_static().
Warning
Destroying a pool while tasks are blocked in stk_blockpool_alloc() or stk_blockpool_timed_alloc() is a logic error and triggers an assertion in debug builds.
Set the pool pointer to NULL after this call to prevent accidental use-after-destroy (the handle slot may be reused by a subsequent stk_blockpool_create() call).
Note
Not ISR-safe.

Definition at line 186 of file stk_c_memory.cpp.

187{
188 STK_ASSERT(pool != nullptr);
189
191
192 BlockPoolSlot *const slot = FindSlot(pool);
193
194 // pool not found: double-destroy or corruption
195 STK_ASSERT(slot != nullptr);
196 if (slot != nullptr)
197 {
198 // Explicitly run the destructor (frees heap storage if owned).
199 pool->~stk_blockpool_t();
200 slot->busy = false;
201 }
202}
static BlockPoolSlot * FindSlot(const stk_blockpool_t *pool)

References BlockPoolSlot::busy, FindSlot(), and STK_ASSERT.

Here is the call graph for this function:

◆ stk_blockpool_free()

bool stk_blockpool_free ( stk_blockpool_t * pool,
void * ptr )

Return a previously allocated block to the pool.

Pushes the block back onto the free-list head in O(1) and wakes exactly one task blocked inside stk_blockpool_alloc() or stk_blockpool_timed_alloc(), if any.

Parameters
[in]poolPool handle.
[in]ptrPointer previously returned by stk_blockpool_alloc(), stk_blockpool_timed_alloc(), or stk_blockpool_try_alloc(). Must belong to pool. Bounds and alignment are validated; failures trigger an assertion in debug builds.
Returns
true on success. false if ptr is NULL, out of range, or misaligned - each case indicates a caller logic error.
Note
ISR-safe.
Warning
Null the pointer after stk_blockpool_free() to prevent double-free.

Definition at line 236 of file stk_c_memory.cpp.

237{
238 STK_ASSERT(pool != nullptr);
239
240 return pool->handle.Free(ptr);
241}
bool Free(void *ptr)
Return a previously allocated block to the pool.

References stk::memory::BlockMemoryPool::Free(), stk_blockpool_t::handle, and STK_ASSERT.

Here is the call graph for this function:

◆ stk_blockpool_get_block_size()

size_t stk_blockpool_get_block_size ( const stk_blockpool_t * pool)

Get the aligned block size used internally by the allocator.

Equal to STK_BLOCKPOOL_ALIGN_BLOCK_SIZE(raw_block_size) as passed at construction. Always >= STK_BLOCKPOOL_ALIGN.

Parameters
[in]poolPool handle.
Returns
Aligned block size in bytes.
Note
ISR-safe.

Definition at line 261 of file stk_c_memory.cpp.

262{
263 STK_ASSERT(pool != nullptr);
264
265 return pool->handle.GetBlockSize();
266}
size_t GetBlockSize() const
Get the aligned block size used internally by the allocator.

References stk::memory::BlockMemoryPool::GetBlockSize(), stk_blockpool_t::handle, and STK_ASSERT.

Here is the call graph for this function:

◆ stk_blockpool_get_capacity()

size_t stk_blockpool_get_capacity ( const stk_blockpool_t * pool)

Get the total block capacity of the pool.

Parameters
[in]poolPool handle.
Returns
Maximum number of blocks that can be simultaneously allocated.
Note
ISR-safe.

Definition at line 254 of file stk_c_memory.cpp.

255{
256 STK_ASSERT(pool != nullptr);
257
258 return pool->handle.GetCapacity();
259}
size_t GetCapacity() const
Get the total block capacity of the pool.

References stk::memory::BlockMemoryPool::GetCapacity(), stk_blockpool_t::handle, and STK_ASSERT.

Here is the call graph for this function:

◆ stk_blockpool_get_free_count()

size_t stk_blockpool_get_free_count ( const stk_blockpool_t * pool)

Get the number of free (available) blocks.

Parameters
[in]poolPool handle.
Returns
Point-in-time snapshot of capacity - used_count.
Note
ISR-safe.

Definition at line 275 of file stk_c_memory.cpp.

276{
277 STK_ASSERT(pool != nullptr);
278
279 return pool->handle.GetFreeCount();
280}
size_t GetFreeCount() const
Get the number of free (available) blocks.

References stk::memory::BlockMemoryPool::GetFreeCount(), stk_blockpool_t::handle, and STK_ASSERT.

Here is the call graph for this function:

◆ stk_blockpool_get_used_count()

size_t stk_blockpool_get_used_count ( const stk_blockpool_t * pool)

Get the number of currently allocated (outstanding) blocks.

Parameters
[in]poolPool handle.
Returns
Point-in-time snapshot. May be stale immediately after return in a multi-task environment.
Note
ISR-safety depends on target ABI: the counter is a 16-bit value, so a single-instruction atomic read is guaranteed on 32-bit Cortex-M (aligned halfword load) but not on 8-bit targets where two bus cycles may be needed. Treat the result as advisory in all multi-core or 8-bit contexts.

Definition at line 268 of file stk_c_memory.cpp.

269{
270 STK_ASSERT(pool != nullptr);
271
272 return pool->handle.GetUsedCount();
273}
size_t GetUsedCount() const
Get the number of currently allocated (outstanding) blocks.

References stk::memory::BlockMemoryPool::GetUsedCount(), stk_blockpool_t::handle, and STK_ASSERT.

Here is the call graph for this function:

◆ stk_blockpool_is_empty()

bool stk_blockpool_is_empty ( const stk_blockpool_t * pool)

Check whether all blocks are free (no outstanding allocations).

Parameters
[in]poolPool handle.
Returns
true if no blocks are currently allocated.
Note
ISR-safe.

Definition at line 289 of file stk_c_memory.cpp.

290{
291 STK_ASSERT(pool != nullptr);
292
293 return pool->handle.IsEmpty();
294}
bool IsEmpty() const
Check whether all blocks are free (no outstanding allocations).

References stk_blockpool_t::handle, stk::memory::BlockMemoryPool::IsEmpty(), and STK_ASSERT.

Here is the call graph for this function:

◆ stk_blockpool_is_full()

bool stk_blockpool_is_full ( const stk_blockpool_t * pool)

Check whether all blocks are currently allocated (pool exhausted).

Parameters
[in]poolPool handle.
Returns
true if no blocks are available for allocation.
Note
ISR-safe.

Definition at line 282 of file stk_c_memory.cpp.

283{
284 STK_ASSERT(pool != nullptr);
285
286 return pool->handle.IsFull();
287}
bool IsFull() const
Check whether all blocks are currently allocated (pool exhausted).

References stk_blockpool_t::handle, stk::memory::BlockMemoryPool::IsFull(), and STK_ASSERT.

Here is the call graph for this function:

◆ stk_blockpool_is_storage_valid()

bool stk_blockpool_is_storage_valid ( const stk_blockpool_t * pool)

Verify that the backing storage is valid and the pool is ready for use.

Always true for pools created with stk_blockpool_create_static(). For heap-constructed pools (stk_blockpool_create()), false if operator new failed. Must be checked after heap construction when operating without exceptions.

Parameters
[in]poolPool handle.
Returns
true if the pool is ready for use.
Note
ISR-safe.

Definition at line 247 of file stk_c_memory.cpp.

248{
249 STK_ASSERT(pool != nullptr);
250
251 return pool->handle.IsStorageValid();
252}
bool IsStorageValid() const
Verify that the backing storage is valid and the pool is ready for use.

References stk_blockpool_t::handle, stk::memory::BlockMemoryPool::IsStorageValid(), and STK_ASSERT.

Here is the call graph for this function:

◆ stk_blockpool_timed_alloc()

void * stk_blockpool_timed_alloc ( stk_blockpool_t * pool,
stk_timeout_t timeout )

Allocate one block, blocking until one becomes available or the timeout expires.

Parameters
[in]poolPool handle.
[in]timeoutMaximum time to wait in ticks. Pass STK_WAIT_INFINITE to block indefinitely (same as stk_blockpool_alloc()), or STK_NO_WAIT for a non-blocking attempt identical to stk_blockpool_try_alloc().
Returns
Pointer to an uninitialized block, or NULL if the timeout expired before a block became available.
Warning
ISR-safe only when timeout = STK_NO_WAIT; not ISR-safe otherwise.

Definition at line 218 of file stk_c_memory.cpp.

219{
220 STK_ASSERT(pool != nullptr);
221
222 return pool->handle.TimedAlloc(timeout);
223}
void * TimedAlloc(Timeout timeout_ticks=WAIT_INFINITE)
Allocate one block, blocking until one becomes available or the timeout expires.

References stk_blockpool_t::handle, STK_ASSERT, and stk::memory::BlockMemoryPool::TimedAlloc().

Here is the call graph for this function:

◆ stk_blockpool_try_alloc()

void * stk_blockpool_try_alloc ( stk_blockpool_t * pool)

Non-blocking allocation attempt.

Returns a block immediately if one is available, or NULL if the pool is empty. Never suspends the calling task.

Parameters
[in]poolPool handle.
Returns
Pointer to an uninitialized block, or NULL if the pool is empty.
Note
ISR-safe.

Definition at line 225 of file stk_c_memory.cpp.

226{
227 STK_ASSERT(pool != nullptr);
228
229 return pool->handle.TryAlloc();
230}
void * TryAlloc()
Non-blocking allocation attempt.

References stk_blockpool_t::handle, STK_ASSERT, and stk::memory::BlockMemoryPool::TryAlloc().

Here is the call graph for this function: