feat: implement lock-free command queue and atomic state for thread safety
Co-authored-by: aider (deepseek/deepseek-coder) <aider@aider.chat>
This commit is contained in:
44
engine.h
44
engine.h
@@ -5,6 +5,7 @@
|
||||
#include <jack/midiport.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdatomic.h>
|
||||
|
||||
#define MAX_SCENES 8
|
||||
#define MAX_CHANNELS 8
|
||||
@@ -46,6 +47,31 @@ typedef struct {
|
||||
bool is_playing;
|
||||
} Clip;
|
||||
|
||||
// Maximum number of queued commands from frontend to audio thread
|
||||
#define MAX_QUEUED_COMMANDS 64
|
||||
|
||||
typedef enum {
|
||||
CMD_TRIGGER_CLIP,
|
||||
CMD_TRIGGER_SCENE,
|
||||
CMD_RESET_CLIP,
|
||||
CMD_SET_QUANTIZE_MODE,
|
||||
CMD_SET_QUANTIZE_THRESHOLD,
|
||||
CMD_RESET_TRANSPORT
|
||||
} CommandType;
|
||||
|
||||
typedef struct {
|
||||
CommandType type;
|
||||
int index; // clip_index, scene_index, or mode value
|
||||
jack_nframes_t value; // threshold value or other numeric param
|
||||
} Command;
|
||||
|
||||
// Lock-free single-producer single-consumer ring buffer
|
||||
typedef struct {
|
||||
Command buffer[MAX_QUEUED_COMMANDS];
|
||||
atomic_uint write_index;
|
||||
atomic_uint read_index;
|
||||
} CommandQueue;
|
||||
|
||||
// Queued trigger for quantization
|
||||
typedef struct QueuedTrigger {
|
||||
int clip_index;
|
||||
@@ -76,6 +102,18 @@ typedef struct {
|
||||
jack_nframes_t quantize_threshold; // in samples (lookahead)
|
||||
QueuedTrigger *queued_triggers;
|
||||
|
||||
// Thread-safe command queue for frontend -> audio thread communication
|
||||
CommandQueue command_queue;
|
||||
|
||||
// Atomic flags for simple state that frontend reads
|
||||
atomic_int transport_rolling; // bool
|
||||
atomic_uint transport_clock_count;
|
||||
atomic_uint transport_beat_position;
|
||||
atomic_uint transport_bar_position;
|
||||
atomic_uint transport_sample_position;
|
||||
atomic_int quantize_mode_atomic; // QuantizeMode
|
||||
atomic_uint quantize_threshold_atomic;
|
||||
|
||||
bool running;
|
||||
} Engine;
|
||||
|
||||
@@ -98,6 +136,12 @@ void engine_reset_transport(Engine *engine);
|
||||
// Queue management (exposed for testing)
|
||||
void queue_trigger(Engine *engine, int clip_index, bool is_scene, jack_nframes_t time);
|
||||
|
||||
// Thread-safe command submission (called from frontend threads)
|
||||
int engine_submit_command(Engine *engine, CommandType type, int index, jack_nframes_t value);
|
||||
|
||||
// Process pending commands (called from audio thread)
|
||||
void engine_process_commands(Engine *engine);
|
||||
|
||||
// Utility
|
||||
const char* clip_state_to_string(ClipState state);
|
||||
uint8_t clip_state_to_velocity(ClipState state);
|
||||
|
||||
Reference in New Issue
Block a user