Corium is a high-performance, header-only C++20 framework designed for Multi-Producer Single-Consumer (MPSC) event-driven architectures.
Engineered equally for high-performance desktop applications (GUI event loops, game engines, audio/DSP processing, real-time desktop tools) and embedded microcontrollers & RTOS (ARM Cortex-M, ESP32, STM32, RP2040, FreeRTOS, Zephyr), Corium guarantees zero dynamic memory allocations on the heap, zero virtual table / RTTI overhead, and pure compile-time static dispatching.
What is Corium?
Traditional C++ event libraries rely heavily on std::function, dynamic memory allocation (new/malloc), and virtual method dispatch (override). In real-time desktop software (game loops, audio engines, responsive UIs) or resource-constrained embedded systems, these mechanisms introduce:
- Non-deterministic latency spikes due to heap allocation and lock contention.
- Memory fragmentation over long execution periods.
- Virtual table (vtables) and RTTI overhead, which bloat binary size and reduce CPU cache efficiency.
- Unsafe ISR execution, as locking mutexes or allocating memory inside hardware interrupt routines results in deadlocks or system crashes.
Corium solves this completely by moving all type resolution, storage allocation, and policy choices to compile time. Multiple concurrent producers (hardware ISRs, background worker threads, user input events, timer loops) push events into a lock-free Vyukov ring buffer without acquiring locks or allocating heap memory. A single consumer thread processes and dispatches events via CRTP static polymorphism and FastDelegates.
Architecture Overview
flowchart TD
subgraph Producers ["Event Producers (Multi-Producer / Lock-Free)"]
ISR["Hardware ISRs (GPIO, Timers, ESP32, ARM)"]
Thread["Background Worker Services (std::jthread)"]
Timer["Zero-Heap Timer Scheduler (ClockPolicy)"]
Main["Main Application Loop / Desktop Window"]
end
subgraph Corium ["Corium Runtime Core (Zero-Heap / Zero-RTTI)"]
IsrSink["IsrEventSink / FreeRtosIsrSink"]
Sink["EventSinkT Handle (Lock-Free Push)"]
Queue["PriorityMpscQueuePolicy / BoundedMpscQueuePolicy"]
Reactor["ReactorT & FastDelegate Dispatcher"]
end
subgraph App ["Application (Single-Consumer)"]
Core["Application (CRTP Static Polymorphism)"]
Handlers["Auto-Deduced Event Handlers"]
end
ISR -->|postFromIsr| IsrSink
IsrSink --> Sink
Thread -->|post| Sink
Timer -->|postDelayed / postPeriodic| Sink
Main -->|post| Sink
Sink --> Queue
Queue -->|tryPop| Reactor
Reactor -->|Static Dispatch| Handlers
Handlers --> Core
Key Features
Core Performance
- Zero-Heap Allocation Guaranteed: Hot-path event enqueueing, timer scheduling, and handler dispatching operate with 0 dynamic heap allocations.
- Zero RTTI & Zero Vtables: Compiles cleanly with
-fno-rtti and -fno-exceptions. Virtual methods are replaced by CRTP static polymorphism and FastDelegates.
- Lock-Free MPSC Engine: Multiple hardware interrupt handlers (ISRs) and worker threads push concurrently into Dmitry Vyukov's lock-free ring buffer algorithm.
Embedded & RTOS Native
- Hardware Clock Policies: Parameterize timers using
ChronoClockPolicy, ManualClockPolicy (simulation & testing), MicrosecondTickClockPolicy<Provider>, MillisecondTickClockPolicy<Provider>, EspTimerClockPolicy (ESP32 esp_timer_get_time()), or FreeRtosClockPolicy (xTaskGetTickCount()).
- Hardware ISR Helpers: Dedicated
IsrEventSink and FreeRtosIsrSink handles supporting non-blocking interrupt pushes and context switch tracking (xHigherPriorityTaskWoken / portYIELD_FROM_ISR()).
- RAII Interrupt Locking:
InterruptLock provides zero-overhead critical section masking across ARM CMSIS (__disable_irq()), ESP32 (portENTER_CRITICAL()), and desktop hosts.
Priority & Overflow Management
- Multi-Tier Event Priorities: Native support for strict event priorities (
EventPriority::High, Normal, Low). High-priority interrupt and emergency events are guaranteed to be dispatched ahead of standard background events.
- Configurable Overflow Policies: Transparent queue saturation strategies (
DropNewestOverflowPolicy, DropOldestOverflowPolicy, AuditOverflowPolicy, PanicOverflowPolicy).
Timers, Services & Safety
- Zero-Heap Timer Scheduler: Schedule single-shot delayed events (
postDelayed()) or recurring periodic events (postPeriodic()) with cancellation handles (cancelTimer()) using static fixed-capacity storage.
- Multi-Threaded Background Services: Managed worker loops using C++20
std::jthread and std::stop_token, posting events concurrently with zero heap allocation.
- C++20 Coroutine Combinators & Channels: Zero-heap asynchronous
Task<T>, bounded async Channel<T, Capacity> with backpressure, counting AsyncSemaphore, parallel whenAll(), fastest-wins whenAny(), atomic CancellationToken, and pull-based Generator<T> lazy sequences.
- Active FSM Engine with Guard Conditions: Variant-based compile-time
StateMachine, predicate Guard conditions, InternalTransition (in-place actions without state exit/entry overhead), composite ActionList, and ShallowHistory.
- Safety, Watchdogs & Observability: Hardware Watchdog supervision (
WatchdogSupervisor), lock-free circuit breaker (CircuitBreaker), circular in-memory flight recorder (FlightRecorderProfiler) exporting to Chrome Tracing / Perfetto, and zero-heap atomic Metrics (Counter, Gauge, Histogram) with Prometheus text export.
- Deterministic Record & Replay: Binary event journal (
EventJournalWriter / EventJournalReader) with CRC-16 checksums and schema validation for black-box telemetry recording.
- Embedded Bus & Network Adapters: Hardware ISR adapters for SPI (
SpiAdapter), I²C (I2cAdapter), CAN/CAN-FD (CanAdapter), DMA UART (DmaUartBuffer), and zero-copy UDP datagrams (StaticUdpChannel).
- Static Topic-Based Event Router: Multi-subscriber publish/subscribe fan-out dispatcher (
EventRouter) with zero heap allocation.
- Zero-Heap Structured Logging: Fast structured zero-heap logging sinks including ANSI console, file, and structured JSON Lines (
JsonLogSink).
š Documentation & Guides
| Guide | Description |
| šļø **Architecture Guide** | In-depth design philosophy, layer breakdown, lock-free queue mechanics, embedded footprint model, and module topology. |
| š **Embedded Integration Guide** | Step-by-step setup for STM32CubeIDE, ESP-IDF, PlatformIO, Keil MDK, IAR, Raspberry Pi Pico SDK, and Zephyr RTOS. |
| š³ **Cookbook & Patterns** | 16 battle-tested design patterns (Request-Response, Parallel Coroutines, FSM Guards, JSON Logging, Zero-Copy IPC, Periodic Sampling, Circuit Breakers, Flight Recorder, Event Journal, SPI/I2C ISR, UDP Telemetry, Async Channels, Async Semaphore, Prometheus Metrics, EventRouter). |
| š **Migration Guide** | Transitioning from std::function, thread pools, boost::asio, or boost::sml to Corium. |
| ā **Frequently Asked Questions (FAQ)** | Answers to common architecture, capacity sizing, and bare-metal embedded questions. |
| š ļø **Contributing Guidelines** | Code standards, zero-heap verification, testing workflows, and commit conventions. |
| š **Changelog** | Complete version history and release notes. |
Feature Comparison Matrix
| Feature | Corium | Traditional Event Systems |
| Dynamic Memory | 0 Heap Allocations (Static Arrays & Inline SBO) | Heap Allocation (new, malloc, std::function) |
| Dispatch Mechanism | CRTP Static Polymorphism & FastDelegate | Virtual Tables (override) & RTTI |
| Thread Safety | Lock-Free MPSC (Signal & ISR Safe) | Mutex Locks & Condition Variables |
| Interrupt Safety (ISR) | 100% Safe (Lock-Free IsrEventSink / FreeRtosIsrSink) | Unsafe (Locks can deadlock ISR) |
| Hardware Bus Adapters | Native SPI, I2C, CAN-FD, DMA UART Adapters | Custom wrapper code with dynamic buffers |
| Network & Telemetry | **Zero-Copy UDP Datagrams (StaticUdpChannel)** | Socket libraries requiring dynamic buffers |
| Hardware Clock Policies | Customizable Clock Sources (Microsecond, Millisecond, ESP32, FreeRTOS, Manual) | Hardcoded std::chrono::steady_clock |
| Priority Channels | Strict Multi-RingBuffer Priority Draining | Dynamic Sorting / Heap Priority Queues |
| Timer Scheduling | Zero-Heap Static Scheduler | Dynamic Heap Timer Wheels / Heap Min-Heaps |
| Async Coroutines | Zero-Heap Tasks, Channels, Semaphore, WhenAll, WhenAny, Generator | Dynamic Coroutine Frame Allocations / Heap Callbacks |
| Finite State Machine | Compile-Time Table, Guards, Internal Transitions, ActionList, History | Dynamic Virtual State Objects / Heap Transitions |
| Observability & Metrics | Prometheus Counters/Gauges/Histograms & Chrome Tracing JSON | External dynamic metric libraries |
| Record & Replay | **Deterministic CRC-16 Event Journal (EventJournalWriter/Reader)** | Ad-hoc text logging without byte integrity |
| Publish/Subscribe Routing | **Topic-Based Static Fan-Out (EventRouter)** | Dynamic subscriber lists with std::vector |
| Structured Logging | Zero-Heap ANSI, File, and JSON Lines (NDJSON) | Heap-allocated string streams / formatting buffers |
| Bare-Metal Support | Full Support (-fno-rtti -fno-exceptions, <1KB RAM, ~4-8KB Flash) | Poor / Requires Heap & RTTI |
Showcase & Samples Catalog
Corium includes 6 focused, production-grade showcase applications in samples/:
| Showcase Sample | Source Path | Key Features Demonstrated |
| 01. Smart Grid Substation Monitor | samples/01_smart_grid_substation/ | Modern C++20 CRTP Application, asynchronous coroutine tasks (AsyncTask), ProducerBackgroundService, periodic diagnostics, and high-priority surge alerts. |
| 02. Aerospace UAV Flight Controller | samples/02_aerospace_flight_controller/ | Strict -fno-rtti -fno-exceptions bare-metal mode, hardware ISR sinks (IsrEventSink), active compile-time FSM (StateMachine), zero heap allocations. |
| 03. HFT Market Data & Execution Engine | samples/03_hft_market_data_engine/ | PriorityMpscQueuePolicy risk cancels ahead of normal market flow, AuditOverflowPolicy dropped micro-burst counting, batch chunk pumping. |
| 04. Automotive Steer-by-Wire ECU | samples/04_automotive_braking_ecu/ | ASIL-D safety, WatchdogSupervisor multi-task deadline SLAs, lock-free CircuitBreaker fault isolation, in-memory FlightRecorder Chrome Tracing / Perfetto JSON export. |
| 05. Drone Ground Control & Avionics IPC | samples/05_drone_ground_control_ipc/ | Binary WirePacket CRC-16 protocol framing, zero-copy POSIX Shared Memory (IpcChannel), UNIX Domain Datagram Sockets (UdsChannel). |
| 06. Industrial Robotics & IoT Edge Gateway | samples/06_industrial_iot_edge_gateway/ | Conditional event filtering (on(predicate, handler)), zero-heap statically-pooled coroutines (PooledTask, PooledGenerator), lock-free AsyncEvent, ABI-validated binary wire serialization. |
Quick Start & Code Examples
1. Minimal Application Example (CRTP & Zero-Heap)
#include <iostream>
public:
void onRegisterHandlers() {
_frameCount++;
std::cout << "Frame #" << _frameCount << " (dt: " << event.deltaTime << "s)\n";
if (_frameCount >= 5) {
requestQuit();
}
});
}
void onInitialize() {
std::cout << "DemoApp initialized.\n";
}
void onShutdown() {
std::cout << "DemoApp shutdown complete.\n";
}
private:
int _frameCount = 0;
};
int main() {
DemoApp app;
}
return 0;
}
Static CRTP base class for applications managed by Corium Runtime. Subclass Application<Derived> or A...
Definition Application.hpp:38
Corium Application Runtime managing MPSC event loops and static policy execution. Zero dynamic heap a...
Definition Runtime.hpp:48
EventSinkT< EventVariant > eventSink() noexcept
Access event sink handle.
Definition Runtime.hpp:313
void shutdown() noexcept
Stop runtime cleanly.
Definition Runtime.hpp:241
void pump()
Pump all pending events in the queue until empty.
Definition Runtime.hpp:133
bool quitRequested() const noexcept
Check if runtime quit has been requested.
Definition Runtime.hpp:264
void initialize(corium::Application< Derived, AppEvents, MaxServices > &application)
Initialize runtime with target application using static CRTP dispatch.
Definition Runtime.hpp:98
Master umbrella header for the entire Corium runtime framework.
Definition Application.hpp:16
Logical update or execution step event.
Definition Events.hpp:28
2. Event Priorities & High-Priority ISR Handling
#include <iostream>
struct NormalUpdateEvent { int frame; };
struct EmergencyStopEvent { const char* reason; };
using AppEvents = std::variant<QuitEvent, NormalUpdateEvent, EmergencyStopEvent>;
using PriorityRuntime = RuntimeBuilder
::WithEvents<AppEvents>
::WithPriorityQueue<256, 1024>
::Build;
public:
void onRegisterHandlers() {
on([](
const NormalUpdateEvent& e) {
std::cout << " [Normal] Processing Frame #" << e.frame << "\n";
});
on([
this](
const EmergencyStopEvent& e) {
std::cout << "[HIGH PRIORITY ISR/EMERGENCY] Triggered: " << e.reason << "\n";
});
}
};
int main() {
PriorityRuntime runtime;
PriorityApp app;
runtime.initialize(app);
auto sink = runtime.eventSink();
sink.post(NormalUpdateEvent{1});
sink.post(NormalUpdateEvent{2});
sink.postHighPriority(EmergencyStopEvent{"Over-temperature threshold exceeded!"});
runtime.pump();
runtime.shutdown();
return 0;
}
void requestQuit()
Request graceful runtime shutdown.
Definition Application.hpp:102
bool on(Handler &&handler)
Register event handler with automatic event type deduction from callable signature.
Definition Application.hpp:60
3. Zero-Heap Timer Scheduler & Hardware Clock Policies
Corium allows customizing the time source for timers and deterministic testing:
#include <iostream>
struct HeartbeatEvent {};
struct DelayedAlertEvent { const char* message; };
using AppEvents = std::variant<QuitEvent, HeartbeatEvent, DelayedAlertEvent>;
using TimerRuntime = RuntimeBuilder
::WithEvents<AppEvents>
::WithClockPolicy<ChronoClockPolicy>
::WithMaxTimers<32>
::Build;
public:
void onRegisterHandlers() {
on([
this](
const HeartbeatEvent&) {
_heartbeats++;
std::cout << "[Periodic Heartbeat #" << _heartbeats << "] System healthy.\n";
if (_heartbeats >= 3) {
}
});
on([](
const DelayedAlertEvent& e) {
std::cout << "[Delayed Notification] " << e.message << "\n";
});
}
void onInitialize() {
postDelayed(DelayedAlertEvent{
"100ms delayed timer fired!"}, std::chrono::milliseconds(100));
heartbeatTimerId =
postPeriodic(HeartbeatEvent{}, std::chrono::milliseconds(50));
}
private:
int _heartbeats = 0;
};
int main() {
TimerRuntime runtime;
TimerApp app;
runtime.initialize(app);
while (!runtime.quitRequested()) {
runtime.waitAndPump(std::chrono::milliseconds(20));
}
runtime.shutdown();
return 0;
}
TimerId postDelayed(EventVariant event, const std::chrono::duration< Rep, Period > &delay, EventPriority priority=EventPriority::Normal)
Schedule a single-shot delayed event.
Definition Application.hpp:83
TimerId postPeriodic(EventVariant event, const std::chrono::duration< Rep, Period > &interval, EventPriority priority=EventPriority::Normal)
Schedule a recurring periodic event.
Definition Application.hpp:90
bool cancelTimer(TimerId id) noexcept
Cancel an active timer.
Definition Application.hpp:96
uint32_t TimerId
Definition TimerScheduler.hpp:22
constexpr TimerId INVALID_TIMER_ID
Definition TimerScheduler.hpp:23
4. ESP32, FreeRTOS & Hardware ISR Integration
Use makeIsrSink and makeFreeRtosIsrSink for safe, lock-free, zero-allocation event posting directly from hardware interrupt service routines:
#include <driver/gpio.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <iostream>
static constexpr gpio_num_t BUTTON_GPIO = GPIO_NUM_27;
struct ButtonPressEvent { uint8_t pin; uint32_t durationMs; };
using Esp32Events = std::variant<QuitEvent, ButtonPressEvent>;
using Esp32Runtime = RuntimeBuilder
::WithEvents<Esp32Events>
::WithCapacity<256>
::WithClockPolicy<EspTimerClockPolicy>
::WithSignalPolicy<NoSignalPolicy>
::WithStoragePolicy<CompactStoragePolicy>
::Build;
public:
void onRegisterHandlers() {
on([](
const ButtonPressEvent& e) {
std::cout << "[ESP32] Button Press ISR on GPIO " << (int)e.pin << "\n";
});
}
};
static Esp32Runtime g_runtime;
static Esp32FirmwareApp g_app;
using IsrSinkType =
IsrEventSink<
decltype(g_runtime.eventSink())>;
static IsrSinkType g_isrSink;
static void IRAM_ATTR gpio_button_isr_handler(void* arg) {
auto isrSink = static_cast<IsrSinkType*>(arg);
isrSink->
postFromIsr(ButtonPressEvent{
static_cast<uint8_t
>(BUTTON_GPIO), 42});
}
static void init_button_gpio(IsrSinkType* isrSink) {
gpio_config_t io_conf{};
io_conf.intr_type = GPIO_INTR_NEGEDGE;
io_conf.mode = GPIO_MODE_INPUT;
io_conf.pin_bit_mask = 1ULL << static_cast<uint64_t>(BUTTON_GPIO);
io_conf.pull_up_en = GPIO_PULLUP_ENABLE;
gpio_config(&io_conf);
gpio_install_isr_service(0);
gpio_isr_handler_add(BUTTON_GPIO, gpio_button_isr_handler, isrSink);
}
static void runtime_task(void* arg) {
auto* runtime = static_cast<Esp32Runtime*>(arg);
while (!runtime->quitRequested()) {
runtime->pump();
vTaskDelay(pdMS_TO_TICKS(10));
}
vTaskDelete(nullptr);
}
extern "C" void app_main(void) {
g_runtime.initialize(g_app);
init_button_gpio(&g_isrSink);
xTaskCreatePinnedToCore(runtime_task, "corium_task", 8192, &g_runtime, 1, nullptr, 1);
}
Lightweight, zero-overhead wrapper around EventSink explicitly tailored for Hardware ISR handlers....
Definition IsrSink.hpp:19
void postFromIsr(Event &&event, EventPriority priority=EventPriority::Normal) noexcept
Post an event safely from hardware ISR context.
Definition IsrSink.hpp:32
Definition CanAdapter.hpp:16
constexpr auto makeIsrSink(EventSinkType sink) noexcept
Helper function to construct an IsrEventSink from an EventSink handle.
Definition IsrSink.hpp:70
5. Multi-Threaded Background Services & <tt>ServiceRegistry</tt>
#include <chrono>
#include <iostream>
#include <thread>
public:
void run(std::stop_token stopToken) {
double elapsed = 0.0;
while (!stopToken.stop_requested()) {
elapsed += 0.2;
std::this_thread::sleep_for(std::chrono::milliseconds(200));
}
}
};
class MultiThreadApp :
public Application<MultiThreadApp> {
public:
SensorService sensorService;
}
void onRegisterHandlers() {
std::cout <<
"Sensor Tick received (time: " << e.
deltaTime <<
"s)\n";
});
}
};
int main() {
MultiThreadApp app;
}
return 0;
}
Multi-threaded background worker service owning a dedicated std::jthread. Integrates incoming event q...
Definition BackgroundService.hpp:35
std::size_t waitAndPump(const std::chrono::duration< Rep, Period > &timeout)
Wait for at least one event to become available (or until timeout), then pump all pending events.
Definition Runtime.hpp:155
Non-allocating ServiceRegistry storing service handles in a fixed stack/static array....
Definition ServiceRegistry.hpp:57
bool registerService(ServiceType &serviceInstance)
Register a background service instance by reference.
Definition ServiceRegistry.hpp:78
Periodic heartbeat or hardware timer tick event.
Definition Events.hpp:18
double deltaTime
Definition Events.hpp:20
6. Zero-Heap Finite State Machine (<tt>corium/fsm/</tt>)
Corium includes a header-only, compile-time Finite State Machine with zero heap allocations and lifecycle transition hooks:
#include <iostream>
struct IdleState {
void onEnter() { std::cout << "-> Entering Idle\n"; }
};
struct ActiveState {
int speed = 0;
void onEnter() { std::cout << "-> Entering Active (Speed: " << speed << ")\n"; }
};
struct StartEvent { int targetSpeed; };
struct StopEvent {};
struct SetSpeedAction {
void operator()(IdleState&, const StartEvent& e, ActiveState& next) const {
next.speed = e.targetSpeed;
}
};
>;
int main() {
std::cout <<
"Is Active: " << fsm.
is<ActiveState>() <<
"\n";
std::cout <<
"Is Idle: " << fsm.
is<IdleState>() <<
"\n";
return 0;
}
Zero-heap, compile-time Finite State Machine.
Definition StateMachine.hpp:89
bool process_event(const Event &event)
Process an incoming event through the state machine transition table.
Definition StateMachine.hpp:143
constexpr bool is() const noexcept
Check if current active state matches type State.
Definition StateMachine.hpp:112
Definition HistoryState.hpp:9
Compile-time table containing all valid state transitions.
Definition Transition.hpp:103
Compile-time transition rule definition.
Definition Transition.hpp:39
7. C++20 Coroutines & Asynchronous Tasks (<tt>corium/async/</tt>)
Write sequential asynchronous logic using co_await yield() and co_await delay():
#include <iostream>
co_await yield();
co_return a + b;
}
std::cout << "Step 1: Starting async workflow...\n";
int result = co_await asyncCompute(10, 20);
std::cout << "Step 2: Computed result = " << result << "\n";
co_await delay(std::chrono::milliseconds(50));
std::cout << "Step 3: Workflow complete.\n";
}
int main() {
auto task = asyncWorkflow();
task.resume();
return 0;
}
Lightweight C++20 coroutine task with zero-heap resumption chaining and configurable frame allocator.
Definition Task.hpp:22
Definition AsyncEvent.hpp:14
8. Real-Time Telemetry & Zero-Overhead Flight Recorder (<tt>corium/profiler/</tt>)
Track event queue latency (time between post() and handler dispatch), execution duration, and export in-memory circular flight logs to Chrome Tracing / Perfetto UI JSON:
#include <fstream>
using ProfiledRuntime = RuntimeBuilder
::WithEvents<DefaultEvents>
::WithFlightRecorder<256>
::Build;
int main() {
ProfiledRuntime runtime;
const auto& profiler = runtime.
profiler();
std::cout << "Avg Queue Latency : " << profiler.averageQueueLatencyUs() << " us\n";
std::cout << "Max Handler Duration: " << profiler.maxExecutionDurationUs() << " us\n";
std::ofstream trace("trace.json");
profiler.exportChromeTracingJson(trace);
return 0;
}
ProfilerPolicyType & profiler() noexcept
Access reference to profiler policy.
Definition Runtime.hpp:319
9. Safety, Watchdog Supervisor & Circuit Breaker (<tt>corium/safety/</tt>)
Ensure mission-critical reliability with multi-service heartbeat tracking, hardware watchdog feeding, and fault-isolating circuit breakers:
enum ServiceId : uint32_t { Motor = 1, Telemetry = 2 };
int main() {
});
supervisor.
beat(ServiceId::Motor);
supervisor.
beat(ServiceId::Telemetry);
return 0;
}
Dedicated safety supervisor monitoring subsystem heartbeats and controlling watchdog refresh....
Definition WatchdogSupervisor.hpp:31
void beat(uint32_t serviceId) noexcept
Submit a heartbeat for a monitored service.
Definition WatchdogSupervisor.hpp:66
bool supervise(const EventSinkType &sink) noexcept
Perform a supervisor check iteration. Kicks the hardware watchdog if healthy; suppresses the kick and...
Definition WatchdogSupervisor.hpp:77
bool registerService(uint32_t serviceId, uint64_t timeoutNs) noexcept
Register a service for supervision.
Definition WatchdogSupervisor.hpp:59
void setWatchdogKickCallback(KickCallbackFn kickFn, void *userData=nullptr) noexcept
Configure the physical hardware/software watchdog kick callback.
Definition WatchdogSupervisor.hpp:40
Definition CircuitBreaker.hpp:13
10. Inter-Process Communication: Shared-Memory & Domain Sockets (<tt>corium/ipc/</tt>)
Exchange typed Corium events between independent operating system processes with sub-microsecond latency and zero heap allocations using either Zero-Copy Shared Memory (for high-frequency telemetry) or UNIX Domain Sockets (for discrete command handling):
struct TelemetryEvent { float rpm; float temp; };
struct SetSpeedCommand { int targetRpm; };
using IpcEvents = std::variant<QuitEvent, TelemetryEvent, SetSpeedCommand>;
void runSharedMemoryExample() {
shmChannel.
create(
"/my_robot_shm");
shmChannel.
post(TelemetryEvent{3000.0f, 42.5f});
}
void runDomainSocketExample() {
udsChannel.
connect(
"/tmp/my_robot_daemon.sock");
udsChannel.
post(SetSpeedCommand{2500});
}
void runHostReceiver() {
uds.
listen(
"/tmp/my_robot_daemon.sock");
}
High-level typed inter-process communication channel for Corium events. Encapsulates OS shared memory...
Definition IpcChannel.hpp:29
bool attach(const std::string &channelName) noexcept
Attach to an existing shared memory channel as a client process.
Definition IpcChannel.hpp:53
bool post(EventType &&event) noexcept
Post an event into the shared memory queue for remote processes. Lock-free, zero-allocation,...
Definition IpcChannel.hpp:78
std::size_t pumpInto(const SinkType &sink, std::size_t maxEvents=0)
Drain incoming shared memory events into a target event sink.
Definition IpcChannel.hpp:98
bool create(const std::string &channelName) noexcept
Create a new shared memory channel as the host/creator process.
Definition IpcChannel.hpp:41
Typed IPC channel operating over UNIX Domain Datagram Sockets. Provides boundary-preserving,...
Definition UdsChannel.hpp:28
bool listen(const std::string &socketPath, bool nonBlocking=true) noexcept
Start listening as an IPC server on a filesystem socket path.
Definition UdsChannel.hpp:40
bool connect(const std::string &serverPath, const std::string &clientPath="") noexcept
Connect as a client to a server socket path.
Definition UdsChannel.hpp:55
bool post(EventType &&event) noexcept
Post a typed event over the socket to the remote receiver.
Definition UdsChannel.hpp:65
std::size_t pumpInto(const SinkType &sink, std::size_t maxEvents=0)
Drain incoming UNIX domain socket events into a target event sink.
Definition UdsChannel.hpp:87
Definition DomainSocket.hpp:35
Policy-Based Architecture & <tt>RuntimeBuilder</tt>
Corium provides a flexible policy-based modular architecture allowing developers to configure queue types, clock sources, overflow handling, signaling strategies, and memory footprints at compile time:
| Policy Area | Available Strategies | Description |
**QueuePolicy** | BoundedMpscQueuePolicy
PriorityMpscQueuePolicy
BlockingQueuePolicy | Lock-free MPSC Vyukov ring buffer, multi-channel priority queue, or mutex-protected queue. |
**ClockPolicy** | ChronoClockPolicy
ManualClockPolicy
MicrosecondTickClockPolicy<Provider>
MillisecondTickClockPolicy<Provider>
EspTimerClockPolicy
FreeRtosClockPolicy | Compile-time clock source for hardware timers, RTOS ticks, simulation, or standard chrono clocks. |
**ProfilerPolicy** | NullProfiler
LatencyTracker
FlightRecorderProfiler<Capacity> | Zero-cost default no-op, live event latency tracker, or circular in-memory flight recorder. |
**OverflowPolicy** | DropNewestOverflowPolicy
DropOldestOverflowPolicy
AuditOverflowPolicy
PanicOverflowPolicy | Defines behavior when queue is full (drop newest, evict oldest, audit atomic counter, or assert/panic). |
**TimerStoragePolicy** | FixedTimerStoragePolicy<MaxTimers, ClockPolicy> | Configures static array capacity and clock source for delayed and periodic timers. |
**SignalPolicy** | NoSignalPolicy
CallbackSignalPolicy
AtomicWaitSignalPolicy
EventFdSignalPolicy | Busy-spin polling, edge callback, C++20 atomic::wait(), or Linux eventfd. |
**StoragePolicy** | DefaultStoragePolicy
CompactStoragePolicy
LargeStoragePolicy | Configures max handlers per event type and FastDelegate inline SBO buffer size. |
Building Custom Runtimes with <tt>RuntimeBuilder</tt>
struct TelemetryData { float temp; };
using MyEvents = std::variant<QuitEvent, TelemetryData>;
using CustomEmbeddedRuntime = RuntimeBuilder
::WithEvents<MyEvents>
::WithPriorityQueue<128, 512>
::WithClockPolicy<EspTimerClockPolicy>
::WithFlightRecorder<256>
::WithOverflowPolicy<AuditOverflowPolicy>
::WithMaxTimers<16>
::WithSignalPolicy<NoSignalPolicy>
::WithStoragePolicy<CompactStoragePolicy>
::Build;
Performance Benchmarks
Corium includes an automated Google Benchmark suite (benchmarks/):
----------------------------------------------------------------------------
Benchmark Time CPU Iterations
----------------------------------------------------------------------------
BM_RingBuffer_SingleProducer 8.97 ns 8.97 ns 77162922
BM_PriorityQueue_HighPriorityPush 8.91 ns 8.91 ns 78687692
BM_EventHandlerDelegate_Dispatch 1.64 ns 1.64 ns 424831532
BM_Reactor_EventDispatch 1.65 ns 1.65 ns 423219295
BM_EventBus_BatchPump 736 ns 737 ns 937956
Running Benchmarks
cmake -B build -DCORIUM_BUILD_BENCHMARKS=ON
cmake --build build
./build/corium_benchmarks
Unit Testing & Verification
Corium includes 72 comprehensive unit tests powered by GoogleTest and CTest:
# Configure and build unit test suite
cmake -B build -DCORIUM_BUILD_TESTS=ON
cmake --build build
# Execute unit tests
ctest --test-dir build --output-on-failure
Strict Bare-Metal Verification (<tt>-fno-rtti -fno-exceptions</tt>)
g++ -std=c++20 -fno-rtti -fno-exceptions -Iinclude samples/02_aerospace_flight_controller/main.cpp -o my_app
./my_app
Single-Header Distribution & Conan Package
Standalone Single Header (<tt>single_include/</tt>)
Generate a single, zero-dependency header file for instant integration into any project:
python3 tools/amalgamate.py
# Produces: single_include/corium.hpp
Conan 2.x Integration
Install and export with Conan:
CMake Integration
cmake_minimum_required(VERSION 3.14)
project(MyProject LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
add_subdirectory(path/to/corium)
add_executable(my_app main.cpp)
target_link_libraries(my_app PRIVATE corium)
License
Corium is open-source software distributed under the [MIT License](LICENSE).