|
SuperTinyKernel™ RTOS 1.08.x
Lightweight, high-performance, deterministic, bare-metal C++ RTOS for resource-constrained embedded systems. MIT Open Source License.
|
Thread-safe FIFO communication pipe for inter-task data passing. More...
#include <stk_sync_pipe.h>
Public Member Functions | |
| Pipe (uint8_t *buf, size_t capacity, size_t element_size) | |
| Constructor. | |
| ~Pipe ()=default | |
| Destructor. | |
| EWaitResult | WriteEx (const void *data, Timeout timeout_ticks=WAIT_INFINITE) |
| Write a single element to the pipe, preserving the full wait outcome. | |
| bool | Write (const void *data, Timeout timeout_ticks=WAIT_INFINITE) |
| Write a single element to the pipe. | |
| bool | TryWrite (const void *data) |
| Attempt to write a single element to the pipe without blocking. | |
| EWaitResult | WriteBulkEx (const void *src, size_t count, size_t &written, Timeout timeout_ticks=WAIT_INFINITE) |
| Write multiple elements to the pipe, preserving the full wait outcome. | |
| size_t | WriteBulk (const void *src, size_t count, Timeout timeout_ticks=WAIT_INFINITE) |
| Write multiple elements to the pipe. | |
| size_t | TryWriteBulk (const void *src, size_t count) |
| Attempt to write multiple elements to the pipe without blocking. | |
| EWaitResult | ReadEx (void *data, Timeout timeout_ticks=WAIT_INFINITE) |
| Read a single element from the pipe, preserving the full wait outcome. | |
| bool | Read (void *data, Timeout timeout_ticks=WAIT_INFINITE) |
| Read a single element from the pipe. | |
| bool | TryRead (void *data) |
| Attempt to read a single element from the pipe without blocking. | |
| EWaitResult | ReadBulkEx (void *dst, size_t count, size_t &read_count, Timeout timeout_ticks=WAIT_INFINITE) |
| Read multiple elements from the pipe, preserving the full wait outcome. | |
| size_t | ReadBulk (void *dst, size_t count, Timeout timeout_ticks=WAIT_INFINITE) |
| Read multiple elements from the pipe. | |
| size_t | TryReadBulk (void *dst, size_t count) |
| Attempt to read multiple elements from the pipe without blocking. | |
| EWaitResult | ReadBulkTriggeredEx (void *dst, size_t trigger, size_t max_count, size_t &read_count, Timeout timeout_ticks=WAIT_INFINITE) |
| Read at least trigger elements, then drain up to max_count without blocking, preserving the full wait outcome. | |
| size_t | ReadBulkTriggered (void *dst, size_t trigger, size_t max_count, Timeout timeout_ticks=WAIT_INFINITE) |
| Read at least trigger elements, then drain up to max_count without blocking. | |
| size_t | TryReadBulkTriggered (void *dst, size_t max_count) |
| Non-blocking variant of ReadBulkTriggered. | |
| void | Reset () |
| Discard all elements and reset the pipe to the empty state. | |
| size_t | GetCapacity () const |
| Get the maximum number of elements the pipe can hold. | |
| size_t | GetElementSize () const |
| Get the size of each element in bytes. | |
| size_t | GetCount () const |
| Get the current number of elements in the pipe. | |
| size_t | GetSpace () const |
| Get the number of free slots currently available. | |
| uint8_t * | GetBuffer () |
| Get a pointer to the raw backing buffer. | |
| bool | IsEmpty () const |
| Check if the pipe is currently empty. | |
| bool | IsFull () const |
| Check if the pipe is currently full. | |
| bool | IsStorageValid () const |
| Verify that the backing storage is valid and the pipe is ready for use. | |
| void | SetTraceName (const char *name) |
| Set name. | |
| const char * | GetTraceName () const |
| Get name. | |
Static Public Attributes | |
| static const size_t | CAPACITY_MAX = 0xFFFEU |
| Max capacity supported (number of elements). | |
Private Member Functions | |
| Pipe (const Pipe &)=delete | |
| Pipe & | operator= (const Pipe &)=delete |
| uint8_t * | Slot (size_t idx) const |
| size_t | Next (size_t idx) const |
| size_t | DrainLocked (uint8_t *dst_bytes, size_t count) |
Private Attributes | |
| uint8_t * | m_buffer |
| flat byte ring-buffer: capacity slots of element_size bytes each | |
| const size_t | m_capacity |
| maximum number of elements stored in the pipe | |
| const size_t | m_element_size |
| size of each element in bytes | |
| size_t | m_count |
| current number of elements stored in the pipe | |
| size_t | m_head |
| write index (next slot to be written by Write()) | |
| size_t | m_tail |
| read index (next slot to be read by Read()) | |
| ConditionVariable | m_cv_not_empty |
| signaled by Write() when the pipe transitions from empty | |
| ConditionVariable | m_cv_not_full |
| signaled by Read()/Reset() when the pipe is no longer full | |
Thread-safe FIFO communication pipe for inter-task data passing.
Pipe provides a synchronized ring-buffer mechanism that allows tasks to exchange data safely. It is parameterised on an element byte count (element_size) rather than a C++ type, making it suitable for passing heterogeneous or C-ABI structs without requiring the element type to be copyable via the C++ assignment operator. All element payloads are copied with memcpy.
It follows the following blocking semantics:
Write() blocks if the pipe is full until space becomes available or the timeout expires.Read() blocks if the pipe is empty until data is produced or the timeout expires.The caller is responsible for providing an appropriately sized external buffer and ensuring it remains valid for the entire lifetime of the Pipe object. For a self-contained, type-safe alternative with compile-time capacity and direct typed assignment, see stk::sync::PipeT.
Write(), Read(), WriteBulk(), ReadBulk(), ReadBulkTriggered()) collapse a timeout and a cancellation (IKernel::CancelTaskWait()) into the same failure result. Use the *Ex() variants (WriteEx(), ReadEx(), WriteBulkEx(), ReadBulkEx(), ReadBulkTriggeredEx()) if the caller needs to tell them apart.Definition at line 77 of file stk_sync_pipe.h.
|
inlineexplicit |
Constructor.
| [in] | buf | Pointer to externally-allocated storage. Must be at least capacity * element_size bytes. |
| [in] | capacity | Maximum number of elements [1, CAPACITY_MAX]. |
| [in] | element_size | Size of each element in bytes (>= 1). |
Definition at line 456 of file stk_sync_pipe.h.
References CAPACITY_MAX, m_buffer, m_capacity, m_count, m_element_size, m_head, m_tail, and STK_ASSERT.
Referenced by operator=().
|
default |
Destructor.
References STK_VIRT_DTOR, and stk::WAIT_INFINITE.
|
privatedelete |
|
inlineprivate |
Definition at line 650 of file stk_sync_pipe.h.
References m_capacity, m_count, m_cv_not_full, m_element_size, m_tail, stk::Min(), Slot(), and STK_MEMCPY().
Referenced by ReadBulkEx(), and ReadBulkTriggeredEx().
|
inline |
Get a pointer to the raw backing buffer.
Definition at line 403 of file stk_sync_pipe.h.
References m_buffer.
|
inline |
Get the maximum number of elements the pipe can hold.
Definition at line 378 of file stk_sync_pipe.h.
References m_capacity.
Referenced by stk_pipe_get_capacity(), and xStreamBufferSetTriggerLevel().
|
inline |
Get the current number of elements in the pipe.
Definition at line 391 of file stk_sync_pipe.h.
References m_count.
Referenced by stk_pipe_get_count().
|
inline |
Get the size of each element in bytes.
Definition at line 384 of file stk_sync_pipe.h.
References m_element_size.
Referenced by stk_pipe_get_element_size().
|
inline |
Get the number of free slots currently available.
Definition at line 397 of file stk_sync_pipe.h.
References m_capacity, and m_count.
Referenced by stk_pipe_get_space().
|
inlineinherited |
Get name.
NULL if not set or if STK_SYNC_DEBUG_NAMES is 0. Definition at line 582 of file stk_common.h.
|
inline |
Check if the pipe is currently empty.
true if empty, otherwise false. Definition at line 410 of file stk_sync_pipe.h.
References m_count.
Referenced by stk_pipe_is_empty().
|
inline |
Check if the pipe is currently full.
true if full, otherwise false. Definition at line 417 of file stk_sync_pipe.h.
References m_capacity, and m_count.
Referenced by stk_pipe_is_full().
|
inline |
Verify that the backing storage is valid and the pipe is ready for use.
Always true for pipes constructed with external storage. For heap-constructed pipes, false if operator new failed. Must be checked after the heap constructor when operating without exceptions (the typical embedded configuration).
true if the pipe is ready for use. Definition at line 427 of file stk_sync_pipe.h.
References m_buffer.
Referenced by stk_pipe_is_storage_valid().
|
inlineprivate |
Definition at line 436 of file stk_sync_pipe.h.
References m_capacity.
Referenced by ReadEx(), and WriteEx().
|
inline |
Read a single element from the pipe.
Copies element_size bytes from the oldest slot in the ring buffer into the buffer pointed to by data. If the pipe is empty, the calling task is suspended until data is produced or the timeout expires.
| [out] | data | Destination buffer for the retrieved element (must be at least element_size bytes). |
| [in] | timeout_ticks | Maximum time to wait for data (ticks). Default: WAIT_INFINITE. |
true if data was successfully read, false otherwise (timeout, cancellation or NO_WAIT on an empty pipe). Use ReadEx() to tell these apart. Definition at line 221 of file stk_sync_pipe.h.
References ReadEx(), stk::WAIT_INFINITE, and stk::WAIT_RESULT_SIGNAL.
Referenced by stk_pipe_read(), and TryRead().
|
inline |
Read multiple elements from the pipe.
Attempts to retrieve count elements from the FIFO. If the pipe does not contain enough elements to satisfy the request, it will block until the full amount is read or the timeout expires.
| [out] | dst | Pointer to the destination array (must hold at least count elements of element_size bytes each). |
| [in] | count | Number of elements to read. |
| [in] | timeout_ticks | Maximum time to wait for data (ticks). Default: WAIT_INFINITE. |
count unless a timeout or a cancellation occurred. Use ReadBulkEx() to tell these apart. Definition at line 278 of file stk_sync_pipe.h.
References ReadBulkEx(), STK_UNUSED, and stk::WAIT_INFINITE.
Referenced by stk_pipe_read_bulk(), and TryReadBulk().
|
inline |
Read multiple elements from the pipe, preserving the full wait outcome.
Identical to ReadBulk(), except the caller gets the raw EWaitResult and the number of elements read through read_count, so a cancellation (via IKernel::CancelTaskWait()) can be distinguished from a timeout. Elements already copied into dst before a timeout or cancellation stay valid and are counted.
| [out] | dst | Pointer to the destination array (must hold at least count elements of element_size bytes each). |
| [in] | count | Number of elements to read. |
| [out] | read_count | Number of elements actually read (always set, 0 on WAIT_RESULT_FAIL). |
| [in] | timeout_ticks | Maximum time to wait for data (ticks). Default: WAIT_INFINITE. |
WAIT_RESULT_SIGNAL if all count elements were read (also for count = 0), WAIT_RESULT_TIMEOUT if the timeout expired (or NO_WAIT was passed) before all elements were available, WAIT_RESULT_CANCELED if the wait was cancelled via IKernel::CancelTaskWait(), WAIT_RESULT_FAIL if dst is nullptr or the kernel rejected the wait. On any non-signal result read_count holds the partial count. Definition at line 676 of file stk_sync_pipe.h.
References DrainLocked(), stk::GetTicks(), m_count, m_cv_not_empty, m_element_size, stk::NO_WAIT, stk::WAIT_INFINITE, stk::WAIT_RESULT_FAIL, and stk::WAIT_RESULT_SIGNAL.
Referenced by ReadBulk(), and stk_pipe_read_bulk_ex().
|
inline |
Read at least trigger elements, then drain up to max_count without blocking.
Blocks until at least trigger elements are simultaneously available in the pipe, or the timeout expires. Once the threshold is reached the call dequeues min(max_count, available) elements in a single critical-section pass — no busy-spin, no second call.
| [out] | dst | Destination buffer; must hold at least max_count elements of element_size bytes. |
| [in] | trigger | Minimum number of elements that must be available before any data is dequeued. Clamped to [1, max_count] internally. |
| [in] | max_count | Maximum number of elements to return in total. |
| [in] | timeout_ticks | Maximum time to wait for trigger elements. Default: WAIT_INFINITE. |
ReadBulkTriggeredEx() to tell these apart. Definition at line 342 of file stk_sync_pipe.h.
References ReadBulkTriggeredEx(), STK_UNUSED, and stk::WAIT_INFINITE.
Referenced by stk_pipe_read_bulk_triggered(), TryReadBulkTriggered(), and xStreamBufferReceive().
|
inline |
Read at least trigger elements, then drain up to max_count without blocking, preserving the full wait outcome.
Identical to ReadBulkTriggered(), except the caller gets the raw EWaitResult and the number of elements read through read_count, so a cancellation (via IKernel::CancelTaskWait()) can be distinguished from a timeout. Like the plain variant, whatever is available is drained even when the wait did not succeed.
| [out] | dst | Destination buffer; must hold at least max_count elements of element_size bytes. |
| [in] | trigger | Minimum number of elements that must be available before the wait is considered successful. Clamped to [1, max_count] internally. |
| [in] | max_count | Maximum number of elements to return in total. |
| [out] | read_count | Number of elements actually read (always set, 0 on WAIT_RESULT_FAIL). |
| [in] | timeout_ticks | Maximum time to wait for trigger elements. Default: WAIT_INFINITE. |
WAIT_RESULT_SIGNAL if the trigger threshold was reached (also for max_count = 0), WAIT_RESULT_TIMEOUT if the timeout expired before the threshold was reached, WAIT_RESULT_CANCELED if the wait was cancelled via IKernel::CancelTaskWait(), WAIT_RESULT_FAIL if dst is nullptr or the kernel rejected the wait. On a timeout or cancellation read_count holds the (possibly zero) number of elements that were available and drained. Definition at line 733 of file stk_sync_pipe.h.
References DrainLocked(), stk::GetTicks(), m_count, m_cv_not_empty, stk::NO_WAIT, stk::WAIT_INFINITE, stk::WAIT_RESULT_FAIL, and stk::WAIT_RESULT_SIGNAL.
Referenced by ReadBulkTriggered(), and stk_pipe_read_bulk_triggered_ex().
|
inline |
Read a single element from the pipe, preserving the full wait outcome.
Identical to Read(), except the caller gets the raw EWaitResult, so a cancellation (via IKernel::CancelTaskWait()) can be distinguished from a timeout.
| [out] | data | Destination buffer for the retrieved element (must be at least element_size bytes). |
| [in] | timeout_ticks | Maximum time to wait for data (ticks). Default: WAIT_INFINITE. |
WAIT_RESULT_SIGNAL if an element was read, WAIT_RESULT_TIMEOUT if no data became available before the timeout expired (or NO_WAIT was passed on an empty pipe), WAIT_RESULT_CANCELED if the wait was cancelled via IKernel::CancelTaskWait(), WAIT_RESULT_FAIL if the kernel rejected the wait. Nothing is read on a non-signal result. Definition at line 600 of file stk_sync_pipe.h.
References stk::GetTicks(), m_count, m_cv_not_empty, m_cv_not_full, m_element_size, m_tail, Next(), stk::NO_WAIT, Slot(), STK_ASSERT, STK_MEMCPY(), stk::WAIT_INFINITE, and stk::WAIT_RESULT_SIGNAL.
Referenced by Read(), and stk_pipe_read_ex().
|
inline |
Discard all elements and reset the pipe to the empty state.
Resets head, tail and count to zero. Any tasks blocked in Write() are woken so they can re-evaluate and enqueue into the now-empty pipe.
Definition at line 786 of file stk_sync_pipe.h.
References m_count, m_cv_not_full, m_head, and m_tail.
Referenced by stk_pipe_reset().
|
inlineinherited |
Set name.
| [in] | name | Null-terminated string or NULL. |
Definition at line 570 of file stk_common.h.
References STK_UNUSED.
Referenced by stk::memory::BlockMemoryPool::BlockMemoryPool(), stk::memory::BlockMemoryPool::BlockMemoryPool(), stk::memory::BytePool::BytePool(), stk::memory::BytePool::BytePool(), tx_block_pool_create(), tx_event_flags_create(), tx_mutex_create(), tx_queue_create(), and tx_semaphore_create().
|
inlineprivate |
Definition at line 433 of file stk_sync_pipe.h.
References m_buffer, and m_element_size.
Referenced by DrainLocked(), ReadEx(), WriteBulkEx(), and WriteEx().
|
inline |
Attempt to read a single element from the pipe without blocking.
Dequeues an element only if one is immediately available. Returns false instantly if the pipe is empty.
| [out] | data | Destination buffer for the retrieved element. |
true if data was successfully read, false if the pipe was empty. Definition at line 233 of file stk_sync_pipe.h.
References stk::NO_WAIT, and Read().
Referenced by stk_pipe_tryread().
|
inline |
Attempt to read multiple elements from the pipe without blocking.
Reads as many elements as are currently available without blocking.
| [out] | dst | Pointer to the destination array. |
| [in] | count | Number of elements to read. |
Definition at line 293 of file stk_sync_pipe.h.
References stk::NO_WAIT, and ReadBulk().
Referenced by stk_pipe_tryread_bulk(), and xStreamBufferReceiveFromISR().
|
inline |
Non-blocking variant of ReadBulkTriggered.
Returns immediately with however many elements are available, up to max_count. The trigger threshold is not enforced (equivalent to trigger = 1 with NO_WAIT).
| [out] | dst | Destination buffer. |
| [in] | max_count | Maximum number of elements to read. |
Definition at line 360 of file stk_sync_pipe.h.
References stk::NO_WAIT, and ReadBulkTriggered().
Referenced by stk_pipe_tryread_bulk_triggered().
|
inline |
Attempt to write a single element to the pipe without blocking.
Enqueues the element only if a free slot is immediately available. Returns false instantly if the pipe is full.
| [in] | data | Pointer to the element payload. |
true if data was successfully written, false if no space is available. Definition at line 135 of file stk_sync_pipe.h.
References stk::NO_WAIT, and Write().
Referenced by stk_pipe_trywrite().
|
inline |
Attempt to write multiple elements to the pipe without blocking.
Copies as many elements as possible without blocking. Elements that do not fit are discarded.
| [in] | src | Pointer to the source array. |
| [in] | count | Number of elements to write. |
Definition at line 195 of file stk_sync_pipe.h.
References stk::NO_WAIT, and WriteBulk().
Referenced by stk_pipe_trywrite_bulk(), and xStreamBufferSendFromISR().
|
inline |
Write a single element to the pipe.
Copies element_size bytes from data into the next available slot in the ring buffer. If the pipe is full, the calling task is suspended until space becomes available or the timeout expires.
| [in] | data | Pointer to the element payload (must be at least element_size bytes). |
| [in] | timeout_ticks | Maximum time to wait for space (ticks). Default: WAIT_INFINITE. |
true if data was successfully written, false otherwise (timeout, cancellation or NO_WAIT on a full pipe). Use WriteEx() to tell these apart. Definition at line 123 of file stk_sync_pipe.h.
References stk::WAIT_INFINITE, stk::WAIT_RESULT_SIGNAL, and WriteEx().
Referenced by stk_pipe_write(), and TryWrite().
|
inline |
Write multiple elements to the pipe.
Copies a block of count elements into the FIFO. If the pipe does not have enough space for the entire block, it will block until the full amount can be written or the timeout expires.
| [in] | src | Pointer to the source array (must hold at least count elements of element_size bytes each). |
| [in] | count | Number of elements to write. |
| [in] | timeout_ticks | Maximum time to wait for sufficient space (ticks). Default: WAIT_INFINITE. |
count unless a timeout or a cancellation occurred. Use WriteBulkEx() to tell these apart. Definition at line 179 of file stk_sync_pipe.h.
References STK_UNUSED, stk::WAIT_INFINITE, and WriteBulkEx().
Referenced by stk_pipe_write_bulk(), TryWriteBulk(), and xStreamBufferSend().
|
inline |
Write multiple elements to the pipe, preserving the full wait outcome.
Identical to WriteBulk(), except the caller gets the raw EWaitResult and the number of elements written through written, so a cancellation (via IKernel::CancelTaskWait()) can be distinguished from a timeout. Elements already copied into the pipe before a timeout or cancellation stay in the pipe.
| [in] | src | Pointer to the source array (must hold at least count elements of element_size bytes each). |
| [in] | count | Number of elements to write. |
| [out] | written | Number of elements actually written (always set, 0 on WAIT_RESULT_FAIL). |
| [in] | timeout_ticks | Maximum time to wait for sufficient space (ticks). Default: WAIT_INFINITE. |
WAIT_RESULT_SIGNAL if all count elements were written (also for count = 0), WAIT_RESULT_TIMEOUT if the timeout expired (or NO_WAIT was passed) before all elements fitted, WAIT_RESULT_CANCELED if the wait was cancelled via IKernel::CancelTaskWait(), WAIT_RESULT_FAIL if src is nullptr or the kernel rejected the wait. On any non-signal result written holds the partial count. Definition at line 525 of file stk_sync_pipe.h.
References stk::GetTicks(), m_capacity, m_count, m_cv_not_empty, m_cv_not_full, m_element_size, m_head, stk::NO_WAIT, Slot(), STK_MEMCPY(), stk::WAIT_INFINITE, stk::WAIT_RESULT_FAIL, and stk::WAIT_RESULT_SIGNAL.
Referenced by stk_pipe_write_bulk_ex(), and WriteBulk().
|
inline |
Write a single element to the pipe, preserving the full wait outcome.
Identical to Write(), except the caller gets the raw EWaitResult, so a cancellation (via IKernel::CancelTaskWait()) can be distinguished from a timeout.
| [in] | data | Pointer to the element payload (must be at least element_size bytes). |
| [in] | timeout_ticks | Maximum time to wait for space (ticks). Default: WAIT_INFINITE. |
WAIT_RESULT_SIGNAL if data was written, WAIT_RESULT_TIMEOUT if no space became available before the timeout expired (or NO_WAIT was passed on a full pipe), WAIT_RESULT_CANCELED if the wait was cancelled via IKernel::CancelTaskWait(), WAIT_RESULT_FAIL if the kernel rejected the wait. Nothing is written on a non-signal result. Definition at line 474 of file stk_sync_pipe.h.
References CAPACITY_MAX, stk::GetTicks(), m_capacity, m_count, m_cv_not_empty, m_cv_not_full, m_element_size, m_head, Next(), stk::NO_WAIT, Slot(), STK_ASSERT, STK_MEMCPY(), stk::WAIT_INFINITE, and stk::WAIT_RESULT_SIGNAL.
Referenced by stk_pipe_write_ex(), and Write().
|
static |
Max capacity supported (number of elements).
Definition at line 82 of file stk_sync_pipe.h.
|
private |
flat byte ring-buffer: capacity slots of element_size bytes each
Definition at line 442 of file stk_sync_pipe.h.
Referenced by GetBuffer(), IsStorageValid(), Pipe(), and Slot().
|
private |
maximum number of elements stored in the pipe
Definition at line 443 of file stk_sync_pipe.h.
Referenced by DrainLocked(), GetCapacity(), GetSpace(), IsFull(), Next(), Pipe(), WriteBulkEx(), and WriteEx().
|
private |
current number of elements stored in the pipe
Definition at line 445 of file stk_sync_pipe.h.
Referenced by DrainLocked(), GetCount(), GetSpace(), IsEmpty(), IsFull(), Pipe(), ReadBulkEx(), ReadBulkTriggeredEx(), ReadEx(), Reset(), WriteBulkEx(), and WriteEx().
|
private |
signaled by Write() when the pipe transitions from empty
Definition at line 448 of file stk_sync_pipe.h.
Referenced by ReadBulkEx(), ReadBulkTriggeredEx(), ReadEx(), WriteBulkEx(), and WriteEx().
|
private |
signaled by Read()/Reset() when the pipe is no longer full
Definition at line 449 of file stk_sync_pipe.h.
Referenced by DrainLocked(), ReadEx(), Reset(), WriteBulkEx(), and WriteEx().
|
private |
size of each element in bytes
Definition at line 444 of file stk_sync_pipe.h.
Referenced by DrainLocked(), GetElementSize(), Pipe(), ReadBulkEx(), ReadEx(), Slot(), WriteBulkEx(), and WriteEx().
|
private |
write index (next slot to be written by Write())
Definition at line 446 of file stk_sync_pipe.h.
Referenced by Pipe(), Reset(), WriteBulkEx(), and WriteEx().
|
private |
read index (next slot to be read by Read())
Definition at line 447 of file stk_sync_pipe.h.
Referenced by DrainLocked(), Pipe(), ReadEx(), and Reset().