56 lines
1.9 KiB
Markdown
56 lines
1.9 KiB
Markdown
# Channels
|
|
|
|
A `Channel<T>` is a lock-free SPSC (single-producer, single-consumer) ring buffer with atomic wait/notify.
|
|
|
|
## Semantics
|
|
|
|
- **Bounded**: fixed capacity set at construction. Default is 5 items.
|
|
- **Backpressure**: when full, `push()` throws `ChannelOverflowError` immediately — no blocking, no spin.
|
|
- **Blocking consumer**: `pop()` blocks until an item is available or the channel is disabled.
|
|
- **Disable**: `channel.disable()` stops accepting pushes and unblocks any waiting `pop()` with `ChannelClosedError`.
|
|
|
|
## Storage policy
|
|
|
|
Small trivially-copyable types (≤ 8 bytes) are stored by value. Larger types are heap-allocated and passed via `shared_ptr<const T>` — one allocation per push, zero-copy fan-out:
|
|
|
|
```cpp
|
|
--8<-- "examples/04_storage_policy/main.cpp:storage_policy_spec"
|
|
```
|
|
|
|
Specialize `kpn::ChannelDataSize<T>` for accurate bandwidth reporting on heap-owning types:
|
|
|
|
```cpp
|
|
template<>
|
|
struct kpn::ChannelDataSize<cv::Mat> {
|
|
static std::size_t bytes(const cv::Mat& m) { return m.total() * m.elemSize(); }
|
|
};
|
|
```
|
|
|
|
## Named ports
|
|
|
|
`in<"name">` and `out<"name">` tag nodes for readable wiring:
|
|
|
|
```cpp
|
|
--8<-- "examples/02_named_ports/main.cpp:named_port_creation"
|
|
```
|
|
|
|
Named ports are checked at compile time — a typo in a port name is a compile error.
|
|
|
|
## Capacity tuning
|
|
|
|
Set capacity per node at construction:
|
|
|
|
```cpp
|
|
auto node = make_node<my_func>(/*capacity=*/20);
|
|
```
|
|
|
|
Capacity is rounded up internally to the next power of two. Monitor fill levels via diagnostics to tune for your workload — a too-small capacity causes overflows; a too-large one wastes memory and hides producer/consumer speed mismatches.
|
|
|
|
## Spin count
|
|
|
|
`Channel` spins for up to ~4 µs (200 `pause` hints at ~20 ns each on x86) before sleeping on a futex. Set to 0 for power-constrained or predominantly-idle pipelines:
|
|
|
|
```cpp
|
|
Channel<int> ch(/*capacity=*/5, /*spin_count=*/0);
|
|
```
|