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 <noreply@anthropic.com>
This commit is contained in:
Shokunin
2026-10-06 01:06:54 -07:00
parent 46f2abebcf
commit 992d3cfe73
+13 -1
View File
@@ -36,6 +36,9 @@ static void cpu_relax(void) { YieldProcessor(); }
#else
# include <pthread.h>
# include <sched.h>
# if defined(__APPLE__)
# include <pthread/qos.h>
# endif
# include <time.h>
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);