spu: use common thread code
authornotaz <notasas@gmail.com>
Sun, 15 Mar 2026 01:02:31 +0000 (03:02 +0200)
committernotaz <notasas@gmail.com>
Sun, 15 Mar 2026 21:00:29 +0000 (23:00 +0200)
also don't start the thread when it's disabled

12 files changed:
frontend/libretro.c
frontend/libretro_core_options.h
frontend/menu.c
frontend/pcsxr-threads.c
frontend/pcsxr-threads.h
frontend/plugin.c
libpcsxcore/plugins.c
libpcsxcore/plugins.h
plugins/dfsound/spu.c
plugins/dfsound/spu.h
plugins/dfsound/spu_config.h
plugins/spunull/spunull.c

index 9124626..32a8a9b 100644 (file)
@@ -2613,10 +2613,13 @@ static void update_variables(bool in_flight)
    var.key = "pcsx_rearmed_spu_thread";
    if (environ_cb(RETRO_ENVIRONMENT_GET_VARIABLE, &var) && var.value)
    {
+      int spu_thread_old = spu_config.iUseThread;
       if (strcmp(var.value, "enabled") == 0)
          spu_config.iUseThread = 1;
       else
          spu_config.iUseThread = 0;
+      if (spu_config.iUseThread != spu_thread_old)
+         SPU_configure();
    }
 #endif
 
index f073498..8b02f7c 100644 (file)
@@ -420,7 +420,7 @@ struct retro_core_option_v2_definition option_defs_us[] = {
       "pcsx_rearmed_display_fps_v2",
       "Display Internal FPS",
       NULL,
-      "Show the internal frame rate at which the emulated PlayStation system is rendering content. Note: Requires on-screen notifications to be enabled in the libretro frontend.",
+      "Show the internal frame rate at which the emulated system is rendering content. Note: Requires on-screen notifications to be enabled in the libretro frontend.",
       NULL,
       "video",
       {
index a7706ab..fd1bebe 100644 (file)
@@ -41,6 +41,7 @@
 #include "../libpcsxcore/ppf.h"
 #include "../libpcsxcore/new_dynarec/new_dynarec.h"
 #include "../plugins/dfsound/spu_config.h"
+#include "pcsxr-threads.h"
 #include "psemu_plugin_defs.h"
 #include "compiler_features.h"
 #include "arm_features.h"
@@ -1631,14 +1632,17 @@ static menu_entry e_menu_main2[];
 static int menu_loop_plugin_options(int id, int keys)
 {
        static int sel = 0;
+       int spu_thread_old = spu_config.iUseThread;
        menu_iopts[0] = Config.SlowBoot;
        menu_iopts[1] = pl_rearmed_cbs.thread_rendering + 1;
 #ifndef C64X_DSP
-       me_enable(e_menu_plugin_options, MA_OPT_SPU_THREAD, spu_config.iThreadAvail);
+       me_enable(e_menu_plugin_options, MA_OPT_SPU_THREAD, pcsxr_sthread_core_count > 1);
 #endif
        me_loop(e_menu_plugin_options, &sel);
        Config.SlowBoot = menu_iopts[0];
        pl_rearmed_cbs.thread_rendering = menu_iopts[1] - 1;
+       if (spu_config.iUseThread != spu_thread_old)
+               SPU_configure();
 
        // sync BIOS/plugins
        snprintf(Config.Bios[0], sizeof(Config.Bios[0]), "%s", bioses[bios_sel]);
index 3f6348d..3df5ee5 100644 (file)
@@ -18,6 +18,7 @@ extern void SysPrintf(const char *fmt, ...);
 
 #ifndef USE_C11_THREADS
 
+#include "rthreads/rthreads.h"
 #include "../deps/libretro-common/rthreads/rthreads.c"
 #include "features/features_cpu.h"
 
index 48c06b6..76c5877 100644 (file)
@@ -17,13 +17,30 @@ void pcsxr_sthread_init(void);
 #ifndef USE_C11_THREADS
 
 /* use libretro-common rthreads */
-#include "rthreads/rthreads.h"
+//#include "rthreads/rthreads.h"
+struct sthread;
+struct slock;
+struct scond;
+typedef struct sthread sthread_t;
+typedef struct slock slock_t;
+typedef struct scond scond_t;
 
 #define STRHEAD_RET_TYPE void
 #define STRHEAD_RETURN()
 
-sthread_t *pcsxr_sthread_create(void (*thread_func)(void*),
+struct sthread *pcsxr_sthread_create(void (*thread_func)(void*),
        enum pcsxr_thread_type type);
+void sthread_join(struct sthread *thread);
+
+struct slock *slock_new(void);
+void slock_free(struct slock *lock);
+void slock_lock(struct slock *lock);
+void slock_unlock(struct slock *lock);
+
+struct scond *scond_new(void);
+void scond_free(struct scond *cond);
+void scond_wait(struct scond *cond, struct slock *lock);
+void scond_signal(struct scond *cond);
 
 #else
 
index 83ed65b..20f2e93 100644 (file)
@@ -112,6 +112,7 @@ static const struct {
        DIRECT_SPU(SPUshutdown),
        DIRECT_SPU(SPUopen),
        DIRECT_SPU(SPUclose),
+       DIRECT_SPU(SPUconfigure),
        DIRECT_SPU(SPUwriteRegister),
        DIRECT_SPU(SPUreadRegister),
        DIRECT_SPU(SPUwriteDMAMem),
index aefbb64..d568aef 100644 (file)
@@ -50,6 +50,7 @@ SPUinit               SPU_init;
 SPUshutdown           SPU_shutdown;
 SPUopen               SPU_open;
 SPUclose              SPU_close;
+SPUconfigure          SPU_configure;
 SPUwriteRegister      SPU_writeRegister;
 SPUreadRegister       SPU_readRegister;
 SPUwriteDMAMem        SPU_writeDMAMem;
@@ -189,6 +190,7 @@ static int LoadSPUplugin(const char *SPUdll) {
        LoadSpuSym1(shutdown, "SPUshutdown");
        LoadSpuSym1(open, "SPUopen");
        LoadSpuSym1(close, "SPUclose");
+       LoadSpuSym1(configure, "SPUconfigure");
        LoadSpuSym1(writeRegister, "SPUwriteRegister");
        LoadSpuSym1(readRegister, "SPUreadRegister");
        LoadSpuSym1(writeDMAMem, "SPUwriteDMAMem");
index 1fe6246..fff2fdb 100644 (file)
@@ -91,6 +91,7 @@ int CDR__getStatus(struct CdrStat *stat);
 typedef long (CALLBACK* SPUinit)(void);                                \r
 typedef long (CALLBACK* SPUshutdown)(void);    \r
 typedef long (CALLBACK* SPUclose)(void);                       \r
+typedef void (CALLBACK* SPUconfigure)(void);                   \r
 typedef void (CALLBACK* SPUwriteRegister)(unsigned long, unsigned short, unsigned int);\r
 typedef unsigned short (CALLBACK* SPUreadRegister)(unsigned long, unsigned int);\r
 typedef void (CALLBACK* SPUwriteDMAMem)(unsigned short *, int, unsigned int);\r
@@ -109,6 +110,7 @@ extern SPUinit             SPU_init;
 extern SPUshutdown         SPU_shutdown;\r
 extern SPUopen             SPU_open;\r
 extern SPUclose            SPU_close;\r
+extern SPUconfigure        SPU_configure;\r
 extern SPUwriteRegister    SPU_writeRegister;\r
 extern SPUreadRegister     SPU_readRegister;\r
 extern SPUwriteDMAMem      SPU_writeDMAMem;\r
index 7e7f827..b4ac7b6 100644 (file)
@@ -1300,12 +1300,14 @@ static void RemoveStreams(void)
 
 #elif P_HAVE_PTHREAD
 
-#include <pthread.h>
+#include "../../frontend/pcsxr-threads.h"
+#ifdef _3DS
+#include <3ds/svc.h> // semaphore.h dep
+#endif
 #include <semaphore.h>
-#include <unistd.h>
 
 static struct {
pthread_t thread;
sthread_t *thread;
  sem_t sem_avail;
  sem_t sem_done;
 } t;
@@ -1331,7 +1333,7 @@ static void thread_sync_caches(void)
 {
 }
 
-static void *spu_worker_thread(void *unused)
+static STRHEAD_RET_TYPE spu_worker_thread(void *unused)
 {
  struct work_item *work;
 
@@ -1347,18 +1349,15 @@ static void *spu_worker_thread(void *unused)
   sem_post(&t.sem_done);
  }
 
return NULL;
STRHEAD_RETURN();
 }
 
 static void init_spu_thread(void)
 {
  int ret;
 
- spu.sb_thread = spu.sb_thread_;
-
- if (sysconf(_SC_NPROCESSORS_ONLN) <= 1)
+ if (worker)
   return;
-
  worker = calloc(1, sizeof(*worker));
  if (worker == NULL)
   return;
@@ -1369,11 +1368,10 @@ static void init_spu_thread(void)
  if (ret != 0)
   goto fail_sem_done;
 
ret = pthread_create(&t.thread, NULL, spu_worker_thread, NULL);
- if (ret != 0)
t.thread = pcsxr_sthread_create(spu_worker_thread, PCSXRT_SPU);
+ if (!t.thread)
   goto fail_thread;
 
- spu_config.iThreadAvail = 1;
  return;
 
 fail_thread:
@@ -1383,7 +1381,6 @@ fail_sem_done:
 fail_sem_avail:
  free(worker);
  worker = NULL;
- spu_config.iThreadAvail = 0;
 }
 
 static void exit_spu_thread(void)
@@ -1392,7 +1389,7 @@ static void exit_spu_thread(void)
   return;
  worker->exit_thread = 1;
  sem_post(&t.sem_avail);
pthread_join(t.thread, NULL);
sthread_join(t.thread);
  sem_destroy(&t.sem_done);
  sem_destroy(&t.sem_avail);
  free(worker);
@@ -1441,7 +1438,11 @@ long CALLBACK SPUinit(void)
  if (spu_config.iVolume == 0)
   spu_config.iVolume = 768; // 1024 is 1.0
 
- init_spu_thread();
+ spu.sb_thread = spu.sb_thread_;
+#ifndef C64X_DSP
+ if (spu_config.iUseThread)
+#endif
+  init_spu_thread();
 
  for (i = 0; i < MAXCHAN; i++)                         // loop sound channels
   {
@@ -1501,6 +1502,14 @@ long CALLBACK SPUshutdown(void)
  return 0;
 }
 
+void CALLBACK SPUconfigure(void)
+{
+ if (spu.bSpuInit && spu_config.iUseThread)
+  init_spu_thread();
+ else
+  exit_spu_thread();
+}
+
 // SETUP CALLBACKS
 // this functions will be called once, 
 // passes a callback that should be called on SPU-IRQ/cdda volume change
index 45f84e4..b986a42 100644 (file)
@@ -25,6 +25,7 @@ long CALLBACK SPUopen(void);
 long CALLBACK SPUinit(void);\r
 long CALLBACK SPUshutdown(void);\r
 long CALLBACK SPUclose(void);\r
+void CALLBACK SPUconfigure(void);\r
 void CALLBACK SPUwriteRegister(unsigned long, unsigned short, unsigned int);\r
 unsigned short CALLBACK SPUreadRegister(unsigned long, unsigned int);\r
 void CALLBACK SPUregisterCallback(void (*cb)(int));\r
index b830142..4289bb3 100644 (file)
@@ -12,8 +12,10 @@ typedef struct
  int        iTempo;
  int        iUseThread;
 
+#ifdef C64X_DSP
  // status
  int        iThreadAvail;
+#endif
 } SPUConfig;
 
 extern SPUConfig spu_config;
index 35f9a26..cd27205 100644 (file)
@@ -331,6 +331,10 @@ long CALLBACK SPUshutdown(void)
  return 0;
 }
 
+void CALLBACK SPUconfigure(void)
+{
+}
+
 ////////////////////////////////////////////////////////////////////////
 // MISC STUFF
 ////////////////////////////////////////////////////////////////////////