OXYGENHUB

core: lock-free run-gate (atomic frames_to_run) e60badb602fb

retro_control_running() is called every instruction; read the run budget as a
relaxed atomic instead of taking the mutex. The mutex still guards the /step
completion handshake (on_frame/do_step).

Git-Commit: d851e270f69dd9fb52b29c8742b3a92e4e731bde
Git-Author: Andy McCall <[email protected]>
Author
Andy McCall @andymccall <[email protected]>
When
· 2026-07-19 22:30 UTC
Signature
◈ sealed by Andy McCall
Hash
e60badb602fbbcd6e49e1813cf72fd10079d85b79ec43f4ca50d2c075d750f58
Depends on
961b3c610c66
Depended on by
nothing yet
In bookmarks
main perf-6
Edits
4 atoms, 0 tree operations, 1 file

Browse the tree at this change

modified core/retro_control.c +9 −6
…
20 unchanged lines
21 21
#else
22 22
23 23
#include <pthread.h>
24 +
#include <stdatomic.h>
24 25
#include <unistd.h>
25 26
#include <errno.h>
26 27
#include <signal.h>
…
14 unchanged lines
41 42
static pthread_mutex_t g_lock = PTHREAD_MUTEX_INITIALIZER;
42 43
static pthread_cond_t  g_cv   = PTHREAD_COND_INITIALIZER;
43 44
44 -
/* run control: -1 free-run, 0 halted, >0 run this many frames then halt */
45 -
static long g_frames_to_run = -1;
45 +
/* run control: -1 free-run, 0 halted, >0 run this many frames then halt.
46 +
 * Atomic so retro_control_running() (called every instruction) reads it without
47 +
 * taking the lock — the mutex is kept only for the /step completion handshake. */
48 +
static _Atomic long g_frames_to_run = -1;
46 49
static int  g_step_waiting  = 0;
47 50
48 51
/* single-slot marshalled request (mem / regs / screenshot) */
…
82 unchanged lines
131 134
int retro_control_running(void)
132 135
{
133 136
    if (!g_be) return 1;
134 -
    pthread_mutex_lock(&g_lock);
135 -
    long f = g_frames_to_run;
136 -
    pthread_mutex_unlock(&g_lock);
137 -
    return f != 0;
137 +
    /* Lock-free hot path: a word-sized atomic read, no mutex. The gate
138 +
     * tolerates a one-iteration-stale value; /step correctness is enforced by
139 +
     * the mutex + condvar in on_frame/do_step, not by this read. */
140 +
    return atomic_load_explicit(&g_frames_to_run, memory_order_relaxed) != 0;
138 141
}
139 142
140 143
void retro_control_on_frame(void)
…
222 unchanged lines