SuperTinyKernel™ RTOS 1.08.x
Lightweight, high-performance, deterministic, bare-metal C++ RTOS for resource-constrained embedded systems. MIT Open Source License.
Loading...
Searching...
No Matches
stk::sync::Pipe Class Reference

Thread-safe FIFO communication pipe for inter-task data passing. More...

#include <stk_sync_pipe.h>

Inheritance diagram for stk::sync::Pipe:
Collaboration diagram for stk::sync::Pipe:

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

Detailed Description

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.

Note
The boolean / count-returning calls (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.
// Example: Producer-Consumer pattern with external buffer
struct Sample { uint32_t timestamp_ms; int16_t value; };
static uint8_t s_buf[8 * sizeof(Sample)];
stk::sync::Pipe g_DataPipe(s_buf, 8, sizeof(Sample));
void Task_Producer() {
Sample s = { GetTicks(), ReadSensor() };
// blocks if pipe is full
g_DataPipe.Write(&s);
}
void Task_Consumer() {
Sample received;
// blocks until data is available, with a 1 s timeout
if (g_DataPipe.Read(&received, 1000)) {
// ... process received value ...
}
}
static Ticks GetTicks()
Get number of ticks elapsed since kernel start.
Definition stk_helper.h:452
Thread-safe FIFO communication pipe for inter-task data passing.
See also
PipeT, MessageQueue, ConditionVariable
Note
Only available when kernel is compiled with KERNEL_SYNC mode enabled.
Examples
D:/SVN/private/stk/interop/c/include/stk_c.h.

Definition at line 77 of file stk_sync_pipe.h.

Constructor & Destructor Documentation

◆ Pipe() [1/2]

stk::sync::Pipe::Pipe ( uint8_t * buf,
size_t capacity,
size_t element_size )
inlineexplicit

Constructor.

Parameters
[in]bufPointer to externally-allocated storage. Must be at least capacity * element_size bytes.
[in]capacityMaximum number of elements [1, CAPACITY_MAX].
[in]element_sizeSize of each element in bytes (>= 1).

Definition at line 456 of file stk_sync_pipe.h.

457: m_buffer(buf),
458 m_capacity(capacity),
459 m_element_size(element_size),
460 m_count(0U),
461 m_head(0U),
462 m_tail(0U)
463{
464 STK_ASSERT(buf != nullptr);
465 STK_ASSERT(capacity >= 1U);
466 STK_ASSERT(capacity <= CAPACITY_MAX);
467 STK_ASSERT(element_size >= 1U);
468}
#define STK_ASSERT(e)
Runtime assertion. Halts execution if the expression e evaluates to false.
Definition stk_defs.h:516
const size_t m_capacity
maximum number of elements stored in the pipe
size_t m_head
write index (next slot to be written by Write())
const size_t m_element_size
size of each element in bytes
static const size_t CAPACITY_MAX
Max capacity supported (number of elements).
size_t m_tail
read index (next slot to be read by Read())
uint8_t * m_buffer
flat byte ring-buffer: capacity slots of element_size bytes each
size_t m_count
current number of elements stored in the pipe

References CAPACITY_MAX, m_buffer, m_capacity, m_count, m_element_size, m_head, m_tail, and STK_ASSERT.

Referenced by operator=().

Here is the caller graph for this function:

◆ ~Pipe()

stk::sync::Pipe::~Pipe ( )
default

Destructor.

Note
If tasks are still waiting at destruction time it is considered a logical error (dangling waiters). An assertion is triggered in debug builds via the ConditionVariable destructors.
MISRA deviation: [STK-DEV-005] Rule 10-3-2.

References STK_VIRT_DTOR, and stk::WAIT_INFINITE.

◆ Pipe() [2/2]

stk::sync::Pipe::Pipe ( const Pipe & )
privatedelete

Member Function Documentation

◆ DrainLocked()

size_t stk::sync::Pipe::DrainLocked ( uint8_t * dst_bytes,
size_t count )
inlineprivate

Definition at line 650 of file stk_sync_pipe.h.

651{
652 const size_t to_read = Min(count, m_count);
653 const size_t first_part = m_capacity - m_tail;
654
655 if (to_read <= first_part)
656 {
657 STK_MEMCPY(dst_bytes, Slot(m_tail), to_read * m_element_size);
658 }
659 else
660 {
661 STK_MEMCPY(dst_bytes, Slot(m_tail), first_part * m_element_size);
662 STK_MEMCPY(dst_bytes + (first_part * m_element_size), Slot(0U), (to_read - first_part) * m_element_size);
663 }
664
665 m_tail = (m_tail + to_read) % m_capacity;
666 m_count -= to_read;
667
668 m_cv_not_full.NotifyAll_CS();
669 return to_read;
670}
static void STK_MEMCPY(void *const dest, const void *const src, const size_t size)
Implementation of STK_MEMCPY.
Definition stk_arch.h:731
static constexpr T Min(T a, T b) noexcept
Compile-time minimum of two values.
Definition stk_defs.h:753
uint8_t * Slot(size_t idx) const
ConditionVariable m_cv_not_full
signaled by Read()/Reset() when the pipe is no longer full

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().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ GetBuffer()

uint8_t * stk::sync::Pipe::GetBuffer ( )
inline

Get a pointer to the raw backing buffer.

Returns
Pointer to the beginning of the element buffer.
Note
ISR-safe.

Definition at line 403 of file stk_sync_pipe.h.

403{ return m_buffer; }

References m_buffer.

◆ GetCapacity()

size_t stk::sync::Pipe::GetCapacity ( ) const
inline

Get the maximum number of elements the pipe can hold.

Returns
Construction-time capacity.
Note
ISR-safe.

Definition at line 378 of file stk_sync_pipe.h.

378{ return m_capacity; }

References m_capacity.

Referenced by stk_pipe_get_capacity(), and xStreamBufferSetTriggerLevel().

Here is the caller graph for this function:

◆ GetCount()

size_t stk::sync::Pipe::GetCount ( ) const
inline

Get the current number of elements in the pipe.

Returns
Point-in-time snapshot of the element count. May be stale by the time the caller acts on it in a multi-task environment.
Note
ISR-safe on targets where a size_t-aligned read is atomic.

Definition at line 391 of file stk_sync_pipe.h.

391{ return m_count; }

References m_count.

Referenced by stk_pipe_get_count().

Here is the caller graph for this function:

◆ GetElementSize()

size_t stk::sync::Pipe::GetElementSize ( ) const
inline

Get the size of each element in bytes.

Returns
Construction-time element size.
Note
ISR-safe.

Definition at line 384 of file stk_sync_pipe.h.

384{ return m_element_size; }

References m_element_size.

Referenced by stk_pipe_get_element_size().

Here is the caller graph for this function:

◆ GetSpace()

size_t stk::sync::Pipe::GetSpace ( ) const
inline

Get the number of free slots currently available.

Returns
Point-in-time snapshot of the free-slot count.
Note
ISR-safe.

Definition at line 397 of file stk_sync_pipe.h.

397{ return (m_capacity - m_count); }

References m_capacity, and m_count.

Referenced by stk_pipe_get_space().

Here is the caller graph for this function:

◆ GetTraceName()

const char * stk::ITraceable::GetTraceName ( ) const
inlineinherited

Get name.

Returns
Name string, or NULL if not set or if STK_SYNC_DEBUG_NAMES is 0.

Definition at line 582 of file stk_common.h.

583 {
584 #if STK_SYNC_DEBUG_NAMES
585 return m_trace_name;
586 #else
587 return nullptr;
588 #endif
589 }

◆ IsEmpty()

bool stk::sync::Pipe::IsEmpty ( ) const
inline

Check if the pipe is currently empty.

Returns
true if empty, otherwise false.
Note
The returned value is a point-in-time snapshot.
ISR-safe.

Definition at line 410 of file stk_sync_pipe.h.

410{ return (m_count == 0U); }

References m_count.

Referenced by stk_pipe_is_empty().

Here is the caller graph for this function:

◆ IsFull()

bool stk::sync::Pipe::IsFull ( ) const
inline

Check if the pipe is currently full.

Returns
true if full, otherwise false.
Note
The returned value is a point-in-time snapshot.
ISR-safe.

Definition at line 417 of file stk_sync_pipe.h.

417{ return (m_count == m_capacity); }

References m_capacity, and m_count.

Referenced by stk_pipe_is_full().

Here is the caller graph for this function:

◆ IsStorageValid()

bool stk::sync::Pipe::IsStorageValid ( ) const
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).

Returns
true if the pipe is ready for use.
Note
ISR-safe.

Definition at line 427 of file stk_sync_pipe.h.

427{ return (m_buffer != nullptr); }

References m_buffer.

Referenced by stk_pipe_is_storage_valid().

Here is the caller graph for this function:

◆ Next()

size_t stk::sync::Pipe::Next ( size_t idx) const
inlineprivate

Definition at line 436 of file stk_sync_pipe.h.

436{ return (idx + 1U) % m_capacity; }

References m_capacity.

Referenced by ReadEx(), and WriteEx().

Here is the caller graph for this function:

◆ operator=()

Pipe & stk::sync::Pipe::operator= ( const Pipe & )
privatedelete

References Pipe().

Here is the call graph for this function:

◆ Read()

bool stk::sync::Pipe::Read ( void * data,
Timeout timeout_ticks = WAIT_INFINITE )
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.

Parameters
[out]dataDestination buffer for the retrieved element (must be at least element_size bytes).
[in]timeout_ticksMaximum time to wait for data (ticks). Default: WAIT_INFINITE.
Warning
ISR-safe only with timeout_ticks=NO_WAIT, ISR-unsafe otherwise.
Returns
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.

222 {
223 return (ReadEx(data, timeout_ticks) == WAIT_RESULT_SIGNAL);
224 }
@ WAIT_RESULT_SIGNAL
The wake was caused by a signal.
Definition stk_common.h:139
EWaitResult ReadEx(void *data, Timeout timeout_ticks=WAIT_INFINITE)
Read a single element from the pipe, preserving the full wait outcome.

References ReadEx(), stk::WAIT_INFINITE, and stk::WAIT_RESULT_SIGNAL.

Referenced by stk_pipe_read(), and TryRead().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ReadBulk()

size_t stk::sync::Pipe::ReadBulk ( void * dst,
size_t count,
Timeout timeout_ticks = WAIT_INFINITE )
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.

Parameters
[out]dstPointer to the destination array (must hold at least count elements of element_size bytes each).
[in]countNumber of elements to read.
[in]timeout_ticksMaximum time to wait for data (ticks). Default: WAIT_INFINITE.
Warning
ISR-safe only with timeout_ticks=NO_WAIT, ISR-unsafe otherwise.
Returns
Number of elements actually read. Equal to count unless a timeout or a cancellation occurred. Use ReadBulkEx() to tell these apart.
// Example:
Sample frame[64];
size_t result = g_Pipe.ReadBulk(frame, 64, 500);
if (result == 64) {
// process full frame
} else {
// handle partial read / timeout
}

Definition at line 278 of file stk_sync_pipe.h.

279 {
280 size_t read_count = 0U;
281 const EWaitResult result = ReadBulkEx(dst, count, read_count, timeout_ticks);
282 STK_UNUSED(result);
283 return read_count;
284 }
#define STK_UNUSED(X)
Explicitly marks a variable as unused to suppress compiler warnings.
Definition stk_defs.h:715
EWaitResult
Wait result (see IKernelService::Wait).
Definition stk_common.h:137
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.

References ReadBulkEx(), STK_UNUSED, and stk::WAIT_INFINITE.

Referenced by stk_pipe_read_bulk(), and TryReadBulk().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ReadBulkEx()

EWaitResult stk::sync::Pipe::ReadBulkEx ( void * dst,
size_t count,
size_t & read_count,
Timeout timeout_ticks = WAIT_INFINITE )
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.

Parameters
[out]dstPointer to the destination array (must hold at least count elements of element_size bytes each).
[in]countNumber of elements to read.
[out]read_countNumber of elements actually read (always set, 0 on WAIT_RESULT_FAIL).
[in]timeout_ticksMaximum time to wait for data (ticks). Default: WAIT_INFINITE.
Warning
ISR-safe only with timeout_ticks=NO_WAIT, ISR-unsafe otherwise.
Returns
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.

677{
678 read_count = 0U;
679
680 // null destination is rejected, an empty request is trivially satisfied
681 EWaitResult result = ((dst != nullptr) ? WAIT_RESULT_SIGNAL : WAIT_RESULT_FAIL);
682
683 if ((dst != nullptr) && (count != 0U))
684 {
685 uint8_t *const dst_bytes = static_cast<uint8_t *>(dst);
686 const bool timed_wait = (timeout_ticks != WAIT_INFINITE) && (timeout_ticks != NO_WAIT);
687
688 // capture an absolute deadline once, before entering the wait loop,
689 // preventing the timeout from resetting on intermediate partial reads
690 const Timeout deadline = (timed_wait ?
691 static_cast<Timeout>(GetTicks() + timeout_ticks) : timeout_ticks);
692
693 ScopedCriticalSection cs_;
694
695 while (read_count < count)
696 {
697 // wait until there is at least 1 element available
698 while (m_count == 0U)
699 {
700 Timeout remaining = deadline;
701 if (timed_wait)
702 {
703 const Timeout now = static_cast<Timeout>(GetTicks());
704 remaining = (now >= deadline ? NO_WAIT : (deadline - now));
705 }
706
707 const EWaitResult wr = m_cv_not_empty.WaitEx(cs_, remaining);
708 if (wr != WAIT_RESULT_SIGNAL)
709 {
710 result = wr;
711 break; // break inner condition variable loop
712 }
713 }
714
715 // if the wait failed (timeout, cancellation), drop out of the chunk processing loop
716 if (result != WAIT_RESULT_SIGNAL)
717 {
718 break;
719 }
720
721 // drain data using the state tracker's relative byte offsets
722 read_count += DrainLocked(dst_bytes + (read_count * m_element_size), count - read_count);
723 }
724 }
725
726 return result;
727}
static constexpr Timeout NO_WAIT
Timeout value: return immediately if the synchronization object is not yet signaled (non-blocking pol...
Definition stk_common.h:234
@ WAIT_RESULT_FAIL
IKernelService::Wait returned with error without waiting.
Definition stk_common.h:138
int32_t Timeout
Timeout time (ticks).
Definition stk_common.h:170
static constexpr Timeout WAIT_INFINITE
Timeout value: block indefinitely until the synchronization object is signaled.
Definition stk_common.h:228
ConditionVariable m_cv_not_empty
signaled by Write() when the pipe transitions from empty
size_t DrainLocked(uint8_t *dst_bytes, size_t count)

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().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ReadBulkTriggered()

size_t stk::sync::Pipe::ReadBulkTriggered ( void * dst,
size_t trigger,
size_t max_count,
Timeout timeout_ticks = WAIT_INFINITE )
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.

Parameters
[out]dstDestination buffer; must hold at least max_count elements of element_size bytes.
[in]triggerMinimum number of elements that must be available before any data is dequeued. Clamped to [1, max_count] internally.
[in]max_countMaximum number of elements to return in total.
[in]timeout_ticksMaximum time to wait for trigger elements. Default: WAIT_INFINITE.
Warning
ISR-safe only with timeout_ticks=NO_WAIT, ISR-unsafe otherwise.
Returns
Number of elements actually read.
  • Equal to zero if timeout fired before a single element arrived.
  • Greater than zero but less than trigger if a partial trigger's worth of data was written before timeout (this can only happen when trigger > 1 and the timeout expires after some — but not enough — elements arrive).
  • Greater than or equal to trigger if the threshold was satisfied (the caller may then assume the trigger callback condition is met).
Note
A cancellation (IKernel::CancelTaskWait()) is reported the same way as a timeout. Use ReadBulkTriggeredEx() to tell these apart.

Definition at line 342 of file stk_sync_pipe.h.

344 {
345 size_t read_count = 0U;
346 const EWaitResult result = ReadBulkTriggeredEx(dst, trigger, max_count, read_count, timeout_ticks);
347 STK_UNUSED(result);
348 return read_count;
349 }
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...

References ReadBulkTriggeredEx(), STK_UNUSED, and stk::WAIT_INFINITE.

Referenced by stk_pipe_read_bulk_triggered(), TryReadBulkTriggered(), and xStreamBufferReceive().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ReadBulkTriggeredEx()

EWaitResult stk::sync::Pipe::ReadBulkTriggeredEx ( void * dst,
size_t trigger,
size_t max_count,
size_t & read_count,
Timeout timeout_ticks = WAIT_INFINITE )
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.

Parameters
[out]dstDestination buffer; must hold at least max_count elements of element_size bytes.
[in]triggerMinimum number of elements that must be available before the wait is considered successful. Clamped to [1, max_count] internally.
[in]max_countMaximum number of elements to return in total.
[out]read_countNumber of elements actually read (always set, 0 on WAIT_RESULT_FAIL).
[in]timeout_ticksMaximum time to wait for trigger elements. Default: WAIT_INFINITE.
Warning
ISR-safe only with timeout_ticks=NO_WAIT, ISR-unsafe otherwise.
Returns
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.

735{
736 read_count = 0U;
737
738 // null destination is rejected, an empty request is trivially satisfied
739 EWaitResult result = ((dst != nullptr) ? WAIT_RESULT_SIGNAL : WAIT_RESULT_FAIL);
740
741 if ((dst != nullptr) && (max_count != 0U))
742 {
743 // trigger must be in [1, max_count]
744 if (trigger == 0U) { trigger = 1U; }
745 if (trigger > max_count) { trigger = max_count; }
746
747 uint8_t *const dst_bytes = static_cast<uint8_t *>(dst);
748 const bool timed_wait = (timeout_ticks != WAIT_INFINITE) && (timeout_ticks != NO_WAIT);
749
750 // capture an absolute deadline once, before entering the wait loop,
751 // preventing the timeout from resetting on intermediate spurious wakeups
752 const Timeout deadline = (timed_wait ?
753 static_cast<Timeout>(GetTicks() + timeout_ticks) : timeout_ticks);
754
755 ScopedCriticalSection cs_;
756
757 while (m_count < trigger)
758 {
759 Timeout remaining = deadline;
760 if (timed_wait)
761 {
762 const Timeout now = static_cast<Timeout>(GetTicks());
763 remaining = (now >= deadline ? NO_WAIT : (deadline - now));
764 }
765
766 const EWaitResult wr = m_cv_not_empty.WaitEx(cs_, remaining);
767 if (wr != WAIT_RESULT_SIGNAL)
768 {
769 result = wr;
770 break; // break the waiting loop on timeout, cancellation or failure
771 }
772 }
773
774 // whether we broke out via satisfying the trigger or a failed wait (timeout,
775 // cancellation), we drain whatever is currently available up to max_count
776 read_count = DrainLocked(dst_bytes, max_count);
777 }
778
779 return result;
780}

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().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ ReadEx()

EWaitResult stk::sync::Pipe::ReadEx ( void * data,
Timeout timeout_ticks = WAIT_INFINITE )
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.

Parameters
[out]dataDestination buffer for the retrieved element (must be at least element_size bytes).
[in]timeout_ticksMaximum time to wait for data (ticks). Default: WAIT_INFINITE.
Warning
ISR-safe only with timeout_ticks=NO_WAIT, ISR-unsafe otherwise.
Returns
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.

601{
602 STK_ASSERT(data != nullptr);
603
604 ScopedCriticalSection cs_;
606
607 const bool timed_wait = (timeout_ticks != WAIT_INFINITE) && (timeout_ticks != NO_WAIT);
608
609 // capture an absolute deadline once, before entering the wait loop; a different
610 // consumer can steal the just-produced element between NotifyOne_CS() and this
611 // task re-acquiring the critical section (Mesa-style wakeup, not a direct handoff),
612 // so re-passing the original timeout_ticks on each retry would silently restart it
613 const Timeout deadline = (timed_wait ?
614 static_cast<Timeout>(GetTicks() + timeout_ticks) : timeout_ticks);
615
616 while (m_count == 0U)
617 {
618 Timeout remaining = deadline;
619 if (timed_wait)
620 {
621 const Timeout now = static_cast<Timeout>(GetTicks());
622 remaining = (now >= deadline ? NO_WAIT : (deadline - now));
623 }
624
625 result = m_cv_not_empty.WaitEx(cs_, remaining);
626 if (result != WAIT_RESULT_SIGNAL)
627 {
628 // timeout, cancellation or kernel failure: nothing is read
629 break;
630 }
631 }
632
633 if (result == WAIT_RESULT_SIGNAL)
634 {
636 m_tail = Next(m_tail);
637 m_count--;
638
639 // notify producer that space is now available
640 m_cv_not_full.NotifyOne_CS();
641 }
642
643 return result;
644}
size_t Next(size_t idx) const

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().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Reset()

void stk::sync::Pipe::Reset ( )
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.

Warning
Elements that were in the pipe are silently discarded. Ensure no consumers depend on them before calling Reset().
ISR-safe.

Definition at line 786 of file stk_sync_pipe.h.

787{
788 const ScopedCriticalSection cs_;
789
790 m_count = 0U;
791 m_head = 0U;
792 m_tail = 0U;
793
794 // wake all blocked producers: the pipe is now entirely empty, every slot is free
795 // note: we do not release readers here
796 m_cv_not_full.NotifyAll_CS();
797}

References m_count, m_cv_not_full, m_head, and m_tail.

Referenced by stk_pipe_reset().

Here is the caller graph for this function:

◆ SetTraceName()

void stk::ITraceable::SetTraceName ( const char * name)
inlineinherited

Set name.

Parameters
[in]nameNull-terminated string or NULL.
Note
If STK_SYNC_DEBUG_NAMES is 0 then calling this function has no effect.

Definition at line 570 of file stk_common.h.

571 {
572 #if STK_SYNC_DEBUG_NAMES
573 m_trace_name = name;
574 #else
575 STK_UNUSED(name);
576 #endif
577 }

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().

Here is the caller graph for this function:

◆ Slot()

uint8_t * stk::sync::Pipe::Slot ( size_t idx) const
inlineprivate

Definition at line 433 of file stk_sync_pipe.h.

433{ return m_buffer + (idx * m_element_size); }

References m_buffer, and m_element_size.

Referenced by DrainLocked(), ReadEx(), WriteBulkEx(), and WriteEx().

Here is the caller graph for this function:

◆ TryRead()

bool stk::sync::Pipe::TryRead ( void * data)
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.

Parameters
[out]dataDestination buffer for the retrieved element.
Warning
ISR-safe.
Returns
true if data was successfully read, false if the pipe was empty.

Definition at line 233 of file stk_sync_pipe.h.

233{ return Read(data, NO_WAIT); }
bool Read(void *data, Timeout timeout_ticks=WAIT_INFINITE)
Read a single element from the pipe.

References stk::NO_WAIT, and Read().

Referenced by stk_pipe_tryread().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ TryReadBulk()

size_t stk::sync::Pipe::TryReadBulk ( void * dst,
size_t count )
inline

Attempt to read multiple elements from the pipe without blocking.

Reads as many elements as are currently available without blocking.

Parameters
[out]dstPointer to the destination array.
[in]countNumber of elements to read.
Warning
ISR-safe.
Returns
Number of elements actually read.

Definition at line 293 of file stk_sync_pipe.h.

293{ return ReadBulk(dst, count, NO_WAIT); }
size_t ReadBulk(void *dst, size_t count, Timeout timeout_ticks=WAIT_INFINITE)
Read multiple elements from the pipe.

References stk::NO_WAIT, and ReadBulk().

Referenced by stk_pipe_tryread_bulk(), and xStreamBufferReceiveFromISR().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ TryReadBulkTriggered()

size_t stk::sync::Pipe::TryReadBulkTriggered ( void * dst,
size_t max_count )
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).

Parameters
[out]dstDestination buffer.
[in]max_countMaximum number of elements to read.
Warning
ISR-safe.
Returns
Number of elements actually read.

Definition at line 360 of file stk_sync_pipe.h.

361 {
362 return ReadBulkTriggered(dst, 1U, max_count, NO_WAIT);
363 }
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.

References stk::NO_WAIT, and ReadBulkTriggered().

Referenced by stk_pipe_tryread_bulk_triggered().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ TryWrite()

bool stk::sync::Pipe::TryWrite ( const void * data)
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.

Parameters
[in]dataPointer to the element payload.
Warning
ISR-safe.
Returns
true if data was successfully written, false if no space is available.

Definition at line 135 of file stk_sync_pipe.h.

135{ return Write(data, NO_WAIT); }
bool Write(const void *data, Timeout timeout_ticks=WAIT_INFINITE)
Write a single element to the pipe.

References stk::NO_WAIT, and Write().

Referenced by stk_pipe_trywrite().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ TryWriteBulk()

size_t stk::sync::Pipe::TryWriteBulk ( const void * src,
size_t count )
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.

Parameters
[in]srcPointer to the source array.
[in]countNumber of elements to write.
Warning
ISR-safe.
Returns
Number of elements actually written.

Definition at line 195 of file stk_sync_pipe.h.

195{ return WriteBulk(src, count, NO_WAIT); }
size_t WriteBulk(const void *src, size_t count, Timeout timeout_ticks=WAIT_INFINITE)
Write multiple elements to the pipe.

References stk::NO_WAIT, and WriteBulk().

Referenced by stk_pipe_trywrite_bulk(), and xStreamBufferSendFromISR().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ Write()

bool stk::sync::Pipe::Write ( const void * data,
Timeout timeout_ticks = WAIT_INFINITE )
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.

Parameters
[in]dataPointer to the element payload (must be at least element_size bytes).
[in]timeout_ticksMaximum time to wait for space (ticks). Default: WAIT_INFINITE.
Warning
ISR-safe only with timeout_ticks=NO_WAIT, ISR-unsafe otherwise.
Returns
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.

124 {
125 return (WriteEx(data, timeout_ticks) == WAIT_RESULT_SIGNAL);
126 }
EWaitResult WriteEx(const void *data, Timeout timeout_ticks=WAIT_INFINITE)
Write a single element to the pipe, preserving the full wait outcome.

References stk::WAIT_INFINITE, stk::WAIT_RESULT_SIGNAL, and WriteEx().

Referenced by stk_pipe_write(), and TryWrite().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ WriteBulk()

size_t stk::sync::Pipe::WriteBulk ( const void * src,
size_t count,
Timeout timeout_ticks = WAIT_INFINITE )
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.

Parameters
[in]srcPointer to the source array (must hold at least count elements of element_size bytes each).
[in]countNumber of elements to write.
[in]timeout_ticksMaximum time to wait for sufficient space (ticks). Default: WAIT_INFINITE.
Warning
ISR-safe only with timeout_ticks=NO_WAIT, ISR-unsafe otherwise.
Returns
Number of elements actually written. Equal to count unless a timeout or a cancellation occurred. Use WriteBulkEx() to tell these apart.
// Example:
Sample frame[64];
FillFrame(frame);
size_t result = g_Pipe.WriteBulk(frame, 64, 500);
if (result < 64) {
// handle partial write / timeout
}

Definition at line 179 of file stk_sync_pipe.h.

180 {
181 size_t written = 0U;
182 const EWaitResult result = WriteBulkEx(src, count, written, timeout_ticks);
183 STK_UNUSED(result);
184 return written;
185 }
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.

References STK_UNUSED, stk::WAIT_INFINITE, and WriteBulkEx().

Referenced by stk_pipe_write_bulk(), TryWriteBulk(), and xStreamBufferSend().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ WriteBulkEx()

EWaitResult stk::sync::Pipe::WriteBulkEx ( const void * src,
size_t count,
size_t & written,
Timeout timeout_ticks = WAIT_INFINITE )
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.

Parameters
[in]srcPointer to the source array (must hold at least count elements of element_size bytes each).
[in]countNumber of elements to write.
[out]writtenNumber of elements actually written (always set, 0 on WAIT_RESULT_FAIL).
[in]timeout_ticksMaximum time to wait for sufficient space (ticks). Default: WAIT_INFINITE.
Warning
ISR-safe only with timeout_ticks=NO_WAIT, ISR-unsafe otherwise.
Returns
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.

526{
527 written = 0U;
528
529 // null source is rejected, an empty request is trivially satisfied
530 EWaitResult result = ((src != nullptr) ? WAIT_RESULT_SIGNAL : WAIT_RESULT_FAIL);
531
532 if ((src != nullptr) && (count != 0U))
533 {
534 const uint8_t *const src_bytes = static_cast<const uint8_t *>(src);
535 const bool timed_wait = (timeout_ticks != WAIT_INFINITE) && (timeout_ticks != NO_WAIT);
536
537 // capture an absolute deadline once, before entering the wait loop,
538 // preventing the timeout from resetting on intermediate partial writes
539 const Timeout deadline = (timed_wait ?
540 static_cast<Timeout>(GetTicks() + timeout_ticks) : timeout_ticks);
541
542 ScopedCriticalSection cs_;
543
544 while (written < count)
545 {
546 // wait until there is at least 1 free slot
547 while (m_count == m_capacity)
548 {
549 Timeout remaining = deadline;
550 if (timed_wait)
551 {
552 const Timeout now = static_cast<Timeout>(GetTicks());
553 remaining = (now >= deadline ? NO_WAIT : (deadline - now));
554 }
555
556 const EWaitResult wr = m_cv_not_full.WaitEx(cs_, remaining);
557 if (wr != WAIT_RESULT_SIGNAL)
558 {
559 result = wr;
560 break; // break inner condition variable loop
561 }
562 }
563
564 // if the wait failed (timeout, cancellation), drop out of the chunk processing loop
565 if (result != WAIT_RESULT_SIGNAL)
566 {
567 break;
568 }
569
570 const size_t available = m_capacity - m_count;
571 const size_t to_write = ((count - written) < available) ? (count - written) : available;
572 const size_t first_part = m_capacity - m_head;
573
574 if (to_write <= first_part)
575 {
576 STK_MEMCPY(Slot(m_head), src_bytes + (written * m_element_size), to_write * m_element_size);
577 }
578 else
579 {
580 STK_MEMCPY(Slot(m_head), src_bytes + (written * m_element_size), first_part * m_element_size);
581 STK_MEMCPY(Slot(0U), src_bytes + ((written + first_part) * m_element_size), (to_write - first_part) * m_element_size);
582 }
583
584 written += to_write;
585 m_head = (m_head + to_write) % m_capacity;
586 m_count += to_write;
587
588 // notify consumers that data is ready
589 m_cv_not_empty.NotifyAll_CS();
590 }
591 }
592
593 return result;
594}

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().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ WriteEx()

EWaitResult stk::sync::Pipe::WriteEx ( const void * data,
Timeout timeout_ticks = WAIT_INFINITE )
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.

Parameters
[in]dataPointer to the element payload (must be at least element_size bytes).
[in]timeout_ticksMaximum time to wait for space (ticks). Default: WAIT_INFINITE.
Warning
ISR-safe only with timeout_ticks=NO_WAIT, ISR-unsafe otherwise.
Returns
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.

475{
476 STK_ASSERT(data != nullptr);
478
479 ScopedCriticalSection cs_;
481
482 const bool timed_wait = (timeout_ticks != WAIT_INFINITE) && (timeout_ticks != NO_WAIT);
483
484 // capture an absolute deadline once, before entering the wait loop; a different
485 // producer can steal the just-freed slot between NotifyOne_CS() and this task
486 // re-acquiring the critical section (Mesa-style wakeup, not a direct handoff),
487 // so re-passing the original timeout_ticks on each retry would silently restart it
488 const Timeout deadline = (timed_wait ?
489 static_cast<Timeout>(GetTicks() + timeout_ticks) : timeout_ticks);
490
491 while (m_count == m_capacity)
492 {
493 Timeout remaining = deadline;
494 if (timed_wait)
495 {
496 const Timeout now = static_cast<Timeout>(GetTicks());
497 remaining = (now >= deadline ? NO_WAIT : (deadline - now));
498 }
499
500 result = m_cv_not_full.WaitEx(cs_, remaining);
501 if (result != WAIT_RESULT_SIGNAL)
502 {
503 // timeout, cancellation or kernel failure: nothing is written
504 break;
505 }
506 }
507
508 if (result == WAIT_RESULT_SIGNAL)
509 {
511 m_head = Next(m_head);
512 m_count++;
513
514 // notify consumer that data is ready
515 m_cv_not_empty.NotifyOne_CS();
516 }
517
518 return result;
519}

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().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ CAPACITY_MAX

const size_t stk::sync::Pipe::CAPACITY_MAX = 0xFFFEU
static

Max capacity supported (number of elements).

Definition at line 82 of file stk_sync_pipe.h.

Referenced by Pipe(), and WriteEx().

◆ m_buffer

uint8_t* stk::sync::Pipe::m_buffer
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().

◆ m_capacity

const size_t stk::sync::Pipe::m_capacity
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().

◆ m_count

size_t stk::sync::Pipe::m_count
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().

◆ m_cv_not_empty

ConditionVariable stk::sync::Pipe::m_cv_not_empty
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().

◆ m_cv_not_full

ConditionVariable stk::sync::Pipe::m_cv_not_full
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().

◆ m_element_size

const size_t stk::sync::Pipe::m_element_size
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().

◆ m_head

size_t stk::sync::Pipe::m_head
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().

◆ m_tail

size_t stk::sync::Pipe::m_tail
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().


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