+#if defined(C64X_DSP)
+
+/* special code for TI C64x DSP */
+#include "spu_c64x.c"
+
+#elif defined(THREAD_ENABLED)
+
+#include <pthread.h>
+#include <semaphore.h>
+#include <unistd.h>
+
+static struct {
+ pthread_t thread;
+ sem_t sem_avail;
+ sem_t sem_done;
+} t;
+
+/* generic pthread implementation */
+
+static void thread_work_start(void)
+{
+ sem_post(&t.sem_avail);
+}
+
+static void thread_work_wait_sync(void)
+{
+ sem_wait(&t.sem_done);
+}
+
+static void *spu_worker_thread(void *unused)
+{
+ while (1) {
+ sem_wait(&t.sem_avail);
+ if (worker->exit_thread)
+ break;
+
+ do_channel_work();
+
+ sem_post(&t.sem_done);
+ }
+
+ return NULL;
+}
+
+static void init_spu_thread(void)
+{
+ int ret;
+
+ if (sysconf(_SC_NPROCESSORS_ONLN) <= 1)
+ return;
+
+ worker = calloc(1, sizeof(*worker));
+ if (worker == NULL)
+ return;
+ ret = sem_init(&t.sem_avail, 0, 0);
+ if (ret != 0)
+ goto fail_sem_avail;
+ ret = sem_init(&t.sem_done, 0, 0);
+ if (ret != 0)
+ goto fail_sem_done;
+
+ ret = pthread_create(&t.thread, NULL, spu_worker_thread, NULL);
+ if (ret != 0)
+ goto fail_thread;
+
+ return;
+
+fail_thread:
+ sem_destroy(&t.sem_done);
+fail_sem_done:
+ sem_destroy(&t.sem_avail);
+fail_sem_avail:
+ free(worker);
+ worker = NULL;
+}
+
+static void exit_spu_thread(void)
+{
+ if (worker == NULL)
+ return;
+ worker->exit_thread = 1;
+ sem_post(&t.sem_avail);
+ pthread_join(t.thread, NULL);
+ sem_destroy(&t.sem_done);
+ sem_destroy(&t.sem_avail);
+ free(worker);
+ worker = NULL;
+}
+
+#else // if !THREAD_ENABLED
+
+static void init_spu_thread(void)
+{
+}
+
+static void exit_spu_thread(void)
+{
+}
+
+#endif