From 992d3cfe73f425300cc55acfd4df9d61ec2d987a Mon Sep 17 00:00:00 2001 From: Shokunin <30949000+tetrisgm@users.noreply.github.com> Date: Tue, 6 Oct 2026 01:06:54 -0700 Subject: [PATCH] Render thread: user-interactive QoS on macOS A default-QoS pthread is scheduled onto efficiency cores when the host is busy, which put the render thread, now on every frame's critical path, behind the emulation thread it is supposed to relieve. Co-Authored-By: Claude Opus 5.5 --- runtime/src/render_thread.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/runtime/src/render_thread.c b/runtime/src/render_thread.c index bdb86e5a..dd7fa91c 100644 --- a/runtime/src/render_thread.c +++ b/runtime/src/render_thread.c @@ -36,6 +36,9 @@ static void cpu_relax(void) { YieldProcessor(); } #else # include # include +# if defined(__APPLE__) +# include +# endif # include typedef pthread_mutex_t rt_mutex; typedef pthread_cond_t rt_cond; @@ -392,7 +395,16 @@ int rt_start(const RtConfig *cfg) { R.thread = CreateThread(NULL, 0, render_main, NULL, 0, NULL); int ok = R.thread != NULL; #else - int ok = pthread_create(&R.thread, NULL, render_main, NULL) == 0; + pthread_attr_t attr; + pthread_attr_init(&attr); +# if defined(__APPLE__) + /* A plain pthread gets the default QoS and, on a busy host, efficiency + * cores. The render thread is on the frame's critical path, like the + * emulation (main) thread, so it asks for the same class. */ + pthread_attr_set_qos_class_np(&attr, QOS_CLASS_USER_INTERACTIVE, 0); +# endif + int ok = pthread_create(&R.thread, &attr, render_main, NULL) == 0; + pthread_attr_destroy(&attr); #endif if (!ok) { atomic_store(&R.running, 0);