Threading Architecture¶
Real-time safe threading primitives for audio applications.
Features¶
- Real-Time Priority: Platform-specific thread priority management
- Lock-Free Queues: SPSC message queue for inter-thread communication
- Audio Thread: RAII wrapper with automatic priority setup
- Atomic Primitives: Flags and spin locks for synchronization
Modules¶
00_thread_types¶
Platform-independent thread management:
- thread_priority.hpp - Set thread priority (Windows/macOS/Linux)
- audio_thread.hpp - RAII audio thread with real-time priority
02_synchronization¶
Lock-free synchronization primitives:
- message_queue.hpp - SPSC (Single Producer Single Consumer) queue
- atomic_flag.hpp - Atomic flags and spin locks
Usage¶
Basic Audio Thread¶
#include "audio_thread.hpp"
using namespace audiolab::core::threading;
AudioThread audioThread([&]() {
while (running) {
processAudio();
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
});
audioThread.setPriority(); // Set real-time priority
GUI-Audio Communication¶
#include "audio_thread.hpp"
#include "message_queue.hpp"
struct ParameterChange {
uint32_t id;
float value;
};
SPSCMessageQueue<ParameterChange, 256> queue;
// GUI thread
void onParameterChanged(uint32_t id, float value) {
queue.push({id, value});
}
// Audio thread
void audioCallback() {
ParameterChange change;
while (queue.pop(change)) {
applyParameter(change.id, change.value);
}
processAudio();
}
Message Queue Design¶
The SPSC queue is: - Lock-free: No mutexes or blocking - Wait-free: Bounded execution time - Cache-friendly: Aligned indices to prevent false sharing - Real-time safe: No allocations after construction
Performance¶
- Latency: < 100ns per operation
- Throughput: > 10M messages/sec
- Memory: Power-of-2 capacity (e.g., 256 slots = 2KB for 8-byte messages)
Thread Safety Guarantees¶
SPSC Queue¶
- ✅ Single producer thread
- ✅ Single consumer thread
- ❌ NOT thread-safe for multiple producers/consumers
Atomic Operations¶
- ✅
std::memory_order_acquire/releasefor synchronization - ✅ Properly aligned atomic variables
- ✅ No torn reads/writes
Building¶
mkdir build && cd build
cmake ..
cmake --build .
# Run example
./gui_audio_communication
# Run tests
ctest
Examples¶
gui_audio_communication.cpp¶
Complete demo of: - Audio thread with real-time priority - Parameter changes from GUI thread - Lock-free message passing - Thread-safe atomic reads
Expected output:
[AudioEngine] Started with real-time priority
[Audio] Thread started
[GUI] Sending parameter changes...
[GUI] Sent gain: 0.0
[Audio] Gain updated: 0.0
[GUI] Sent gain: 0.1
[Audio] Gain updated: 0.1
...
Platform Support¶
| Platform | Real-Time Priority | CPU Affinity |
|---|---|---|
| Windows | ✅ TIME_CRITICAL | ✅ Affinity mask |
| macOS | ✅ Time constraint | ✅ Affinity policy |
| Linux | ✅ SCHED_FIFO/RR | ✅ cpu_set_t |
Linux Notes¶
Real-time priority requires:
- Root privileges, OR
- CAP_SYS_NICE capability, OR
- /etc/security/limits.conf configuration:
Best Practices¶
- Audio Thread
- Set real-time priority
- Never allocate memory
- Keep processing time < buffer duration
-
Use lock-free communication
-
Message Queue
- Size queue to handle burst traffic
- Handle queue full gracefully (drop or retry)
-
Drain queue at start of audio callback
-
Synchronization
- Prefer atomics over locks
- Use memory order semantics correctly
- Avoid false sharing (align atomic variables)
License¶
Part of AudioLab project.