diff --git a/miniaudio.h b/miniaudio.h index 9e0d8e6b..099f1df8 100644 --- a/miniaudio.h +++ b/miniaudio.h @@ -4782,7 +4782,9 @@ typedef enum } ma_thread_priority; #ifndef MA_NO_THREADING - #if defined(MA_POSIX) + #if defined(MA_VITA) + #define MA_THREADING_BACKEND_VITA + #elif defined(MA_POSIX) #define MA_THREADING_BACKEND_POSIX #elif defined(MA_WIN32) #define MA_THREADING_BACKEND_WIN32 @@ -4797,6 +4799,8 @@ typedef enum typedef ma_pthread_t ma_thread; #elif defined(MA_THREADING_BACKEND_WIN32) typedef ma_handle ma_thread; +#elif defined(MA_THREADING_BACKEND_VITA) + typedef int ma_thread; #else typedef int ma_thread; /* Fallback for platforms without support for threading. Attempting to create a thread will fail. */ #endif @@ -4805,6 +4809,8 @@ typedef enum typedef ma_pthread_mutex_t ma_mutex; #elif defined(MA_THREADING_BACKEND_WIN32) typedef ma_handle ma_mutex; +#elif defined(MA_THREADING_BACKEND_VITA) + typedef int ma_mutex; #else typedef ma_spinlock ma_mutex; /* Fallback for platforms without support for threading. */ #endif @@ -4818,6 +4824,8 @@ typedef enum } ma_event; #elif defined(MA_THREADING_BACKEND_WIN32) typedef ma_handle ma_event; +#elif defined(MA_THREADING_BACKEND_VITA) + typedef int ma_event; #else typedef ma_uint32 ma_event; /* Fallback for platforms without support for threading. */ #endif @@ -4831,6 +4839,8 @@ typedef enum } ma_semaphore; #elif defined(MA_THREADING_BACKEND_WIN32) typedef ma_handle ma_semaphore; +#elif defined(MA_THREADING_BACKEND_VITA) + typedef int ma_semaphore; #else typedef ma_uint32 ma_semaphore; /* Fallback for platforms without support for threading. */ #endif @@ -18358,6 +18368,264 @@ static ma_result ma_semaphore_release__win32(ma_semaphore* pSemaphore) return MA_SUCCESS; } +#elif defined(MA_THREADING_BACKEND_VITA) +#include +#include +#include +#include + +typedef struct +{ + ma_thread_entry_proc entryProc; + void* pData; +} ma_vita_thread_proxy_data; + +static int ma_vita_thread_proxy(SceSize dataSize, void* pData) +{ + ma_vita_thread_proxy_data* pProxyData = (ma_vita_thread_proxy_data*)pData; + + (void)dataSize; + + return (int)pProxyData->entryProc(pProxyData->pData); +} + +static ma_result ma_thread_create__vita(ma_thread* pThread, ma_thread_priority priority, size_t stackSize, ma_thread_entry_proc entryProc, void* pData) +{ + int thd; + const char* pNameBase = "ma_thd_"; + size_t nameBaseLen = strlen(pNameBase); + char name[64]; + static ma_uint32 counter = 0; /* For creating a unique name. Atomically incremented. */ + ma_vita_thread_proxy_data data; + int initPriority; + + if (pThread == NULL) { + return MA_INVALID_ARGS; + } + + ma_strcpy_s(name, sizeof(name), pNameBase); + ma_itoa_s((int)ma_atomic_fetch_add_explicit_32(&counter, 1, ma_atomic_memory_order_relaxed), name + nameBaseLen, sizeof(name) - nameBaseLen, 10); + + /* TODO: Not sure how properly set the priority. */ + (void)priority; + initPriority = 0x10000100; /* This is the value used in the Vita SDK documentation for sceKernelCreateThread(). I'm not quite sure how to properly use this. */ + + /* Make sure we have an appropriate default stack size. */ + if (stackSize == 0) { + stackSize = 0x10000; + } + + thd = sceKernelCreateThread(name, ma_vita_thread_proxy, 0x10000100, (SceSize)stackSize, 0, 0, NULL); + if (thd < 0) { + return MA_ERROR; + } + + data.entryProc = entryProc; + data.pData = pData; + sceKernelStartThread(thd, sizeof(data), &data); + + *pThread = thd; + + return MA_SUCCESS; +} + +static void ma_thread_wait__vita(ma_thread* pThread) +{ + if (pThread == NULL) { + return; + } + + sceKernelWaitThreadEnd(*pThread, NULL, NULL); + sceKernelDeleteThread(*pThread); +} + + +static ma_result ma_mutex_init__vita(ma_mutex* pMutex) +{ + int mtx; + const char* pNameBase = "ma_mtx_"; + size_t nameBaseLen = strlen(pNameBase); + char name[64]; + static ma_uint32 counter = 0; /* For creating a unique name. Atomically incremented. */ + + if (pMutex == NULL) { + return MA_INVALID_ARGS; + } + + ma_strcpy_s(name, sizeof(name), pNameBase); + ma_itoa_s((int)ma_atomic_fetch_add_explicit_32(&counter, 1, ma_atomic_memory_order_relaxed), name + nameBaseLen, sizeof(name) - nameBaseLen, 10); + + mtx = sceKernelCreateMutex(name, 0, 0, NULL); + if (mtx < 0) { + return MA_ERROR; + } + + *pMutex = mtx; + + return MA_SUCCESS; +} + +static void ma_mutex_uninit__vita(ma_mutex* pMutex) +{ + if (pMutex == NULL) { + return; + } + + sceKernelDeleteMutex(*pMutex); +} + +static void ma_mutex_lock__vita(ma_mutex* pMutex) +{ + if (pMutex == NULL) { + return; + } + + sceKernelLockMutex(*pMutex, 1, NULL); +} + +static void ma_mutex_unlock__vita(ma_mutex* pMutex) +{ + if (pMutex == NULL) { + return; + } + + sceKernelUnlockMutex(*pMutex, 1); +} + + +static ma_result ma_event_init__vita(ma_event* pEvent) +{ + int e; + const char* pNameBase = "ma_evt_"; + size_t nameBaseLen = strlen(pNameBase); + char name[64]; + static ma_uint32 counter = 0; /* For creating a unique name. Atomically incremented. */ + + if (pEvent == NULL) { + return MA_INVALID_ARGS; + } + + ma_strcpy_s(name, sizeof(name), pNameBase); + ma_itoa_s((int)ma_atomic_fetch_add_explicit_32(&counter, 1, ma_atomic_memory_order_relaxed), name + nameBaseLen, sizeof(name) - nameBaseLen, 10); + + e = sceKernelCreateEventFlag(name, SCE_EVENT_WAITMULTIPLE, 0, NULL); + if (e < 0) { + return MA_ERROR; + } + + *pEvent = e; + + return MA_SUCCESS; +} + +static void ma_event_uninit__vita(ma_event* pEvent) +{ + if (pEvent == NULL) { + return; + } + + sceKernelDeleteEventFlag(*pEvent); +} + +static ma_result ma_event_wait__vita(ma_event* pEvent) +{ + unsigned int bits; + int result; + + if (pEvent == NULL) { + return MA_INVALID_ARGS; + } + + result = sceKernelWaitEventFlag(*pEvent, 1, SCE_EVENT_WAITAND | SCE_EVENT_WAITCLEAR, &bits, NULL); + if (result < 0) { + return MA_ERROR; + } + + return MA_SUCCESS; +} + +static ma_result ma_event_signal__vita(ma_event* pEvent) +{ + int result; + + if (pEvent == NULL) { + return MA_INVALID_ARGS; + } + + result = sceKernelSetEventFlag(*pEvent, 1); + if (result < 0) { + return MA_ERROR; + } + + return MA_SUCCESS; +} + + +static ma_result ma_semaphore_init__vita(int initialValue, ma_semaphore* pSemaphore) +{ + int sem; + const char* pNameBase = "ma_sem_"; + size_t nameBaseLen = strlen(pNameBase); + char name[64]; + static ma_uint32 counter = 0; /* For creating a unique name. Atomically incremented. */ + + if (pSemaphore == NULL) { + return MA_INVALID_ARGS; + } + + ma_strcpy_s(name, sizeof(name), pNameBase); + ma_itoa_s((int)ma_atomic_fetch_add_explicit_32(&counter, 1, ma_atomic_memory_order_relaxed), name + nameBaseLen, sizeof(name) - nameBaseLen, 10); + + sem = sceKernelCreateSema(name, 0, initialValue, 0x7FFFFFFF, NULL); + if (sem < 0) { + return MA_ERROR; + } + + *pSemaphore = sem; + + return MA_SUCCESS; +} + +static void ma_semaphore_uninit__vita(ma_semaphore* pSemaphore) +{ + if (pSemaphore == NULL) { + return; + } + + sceKernelDeleteSema(*pSemaphore); +} + +static ma_result ma_semaphore_wait__vita(ma_semaphore* pSemaphore) +{ + int result; + + if (pSemaphore == NULL) { + return MA_INVALID_ARGS; + } + + result = sceKernelWaitSema(*pSemaphore, 1, NULL); + if (result < 0) { + return MA_ERROR; + } + + return MA_SUCCESS; +} + +static ma_result ma_semaphore_release__vita(ma_semaphore* pSemaphore) +{ + int result; + + if (pSemaphore == NULL) { + return MA_INVALID_ARGS; + } + + result = sceKernelSignalSema(*pSemaphore, 1); + if (result < 0) { + return MA_ERROR; + } + + return MA_SUCCESS; +} #else static ma_result ma_thread_create__none(ma_thread* pThread, ma_thread_priority priority, size_t stackSize, ma_thread_entry_proc entryProc, void* pData) { @@ -18536,7 +18804,9 @@ MA_API ma_result ma_thread_create(ma_thread* pThread, ma_thread_priority priorit pProxyData->pData = pData; ma_allocation_callbacks_init_copy(&pProxyData->allocationCallbacks, pAllocationCallbacks); -#if defined(MA_THREADING_BACKEND_POSIX) +#if defined(MA_THREADING_BACKEND_VITA) + result = ma_thread_create__vita(pThread, priority, stackSize, ma_thread_entry_proxy, pProxyData); +#elif defined(MA_THREADING_BACKEND_POSIX) result = ma_thread_create__posix(pThread, priority, stackSize, ma_thread_entry_proxy, pProxyData); #elif defined(MA_THREADING_BACKEND_WIN32) result = ma_thread_create__win32(pThread, priority, stackSize, ma_thread_entry_proxy, pProxyData); @@ -18558,7 +18828,9 @@ MA_API void ma_thread_wait(ma_thread* pThread) return; } -#if defined(MA_THREADING_BACKEND_POSIX) +#if defined(MA_THREADING_BACKEND_VITA) + ma_thread_wait__vita(pThread); +#elif defined(MA_THREADING_BACKEND_POSIX) ma_thread_wait__posix(pThread); #elif defined(MA_THREADING_BACKEND_WIN32) ma_thread_wait__win32(pThread); @@ -18575,7 +18847,9 @@ MA_API ma_result ma_mutex_init(ma_mutex* pMutex) return MA_INVALID_ARGS; } -#if defined(MA_THREADING_BACKEND_POSIX) +#if defined(MA_THREADING_BACKEND_VITA) + return ma_mutex_init__vita(pMutex); +#elif defined(MA_THREADING_BACKEND_POSIX) return ma_mutex_init__posix(pMutex); #elif defined(MA_THREADING_BACKEND_WIN32) return ma_mutex_init__win32(pMutex); @@ -18590,7 +18864,9 @@ MA_API void ma_mutex_uninit(ma_mutex* pMutex) return; } -#if defined(MA_THREADING_BACKEND_POSIX) +#if defined(MA_THREADING_BACKEND_VITA) + ma_mutex_uninit__vita(pMutex); +#elif defined(MA_THREADING_BACKEND_POSIX) ma_mutex_uninit__posix(pMutex); #elif defined(MA_THREADING_BACKEND_WIN32) ma_mutex_uninit__win32(pMutex); @@ -18606,7 +18882,9 @@ MA_API void ma_mutex_lock(ma_mutex* pMutex) return; } -#if defined(MA_THREADING_BACKEND_POSIX) +#if defined(MA_THREADING_BACKEND_VITA) + ma_mutex_lock__vita(pMutex); +#elif defined(MA_THREADING_BACKEND_POSIX) ma_mutex_lock__posix(pMutex); #elif defined(MA_THREADING_BACKEND_WIN32) ma_mutex_lock__win32(pMutex); @@ -18622,7 +18900,9 @@ MA_API void ma_mutex_unlock(ma_mutex* pMutex) return; } -#if defined(MA_THREADING_BACKEND_POSIX) +#if defined(MA_THREADING_BACKEND_VITA) + ma_mutex_unlock__vita(pMutex); +#elif defined(MA_THREADING_BACKEND_POSIX) ma_mutex_unlock__posix(pMutex); #elif defined(MA_THREADING_BACKEND_WIN32) ma_mutex_unlock__win32(pMutex); @@ -18639,7 +18919,9 @@ MA_API ma_result ma_event_init(ma_event* pEvent) return MA_INVALID_ARGS; } -#if defined(MA_THREADING_BACKEND_POSIX) +#if defined(MA_THREADING_BACKEND_VITA) + return ma_event_init__vita(pEvent); +#elif defined(MA_THREADING_BACKEND_POSIX) return ma_event_init__posix(pEvent); #elif defined(MA_THREADING_BACKEND_WIN32) return ma_event_init__win32(pEvent); @@ -18682,7 +18964,9 @@ MA_API void ma_event_uninit(ma_event* pEvent) return; } -#if defined(MA_THREADING_BACKEND_POSIX) +#if defined(MA_THREADING_BACKEND_VITA) + ma_event_uninit__vita(pEvent); +#elif defined(MA_THREADING_BACKEND_POSIX) ma_event_uninit__posix(pEvent); #elif defined(MA_THREADING_BACKEND_WIN32) ma_event_uninit__win32(pEvent); @@ -18710,7 +18994,9 @@ MA_API ma_result ma_event_wait(ma_event* pEvent) return MA_INVALID_ARGS; } -#if defined(MA_THREADING_BACKEND_POSIX) +#if defined(MA_THREADING_BACKEND_VITA) + return ma_event_wait__vita(pEvent); +#elif defined(MA_THREADING_BACKEND_POSIX) return ma_event_wait__posix(pEvent); #elif defined(MA_THREADING_BACKEND_WIN32) return ma_event_wait__win32(pEvent); @@ -18726,7 +19012,9 @@ MA_API ma_result ma_event_signal(ma_event* pEvent) return MA_INVALID_ARGS; } -#if defined(MA_THREADING_BACKEND_POSIX) +#if defined(MA_THREADING_BACKEND_VITA) + return ma_event_signal__vita(pEvent); +#elif defined(MA_THREADING_BACKEND_POSIX) return ma_event_signal__posix(pEvent); #elif defined(MA_THREADING_BACKEND_WIN32) return ma_event_signal__win32(pEvent); @@ -18743,7 +19031,9 @@ MA_API ma_result ma_semaphore_init(int initialValue, ma_semaphore* pSemaphore) return MA_INVALID_ARGS; } -#if defined(MA_THREADING_BACKEND_POSIX) +#if defined(MA_THREADING_BACKEND_VITA) + return ma_semaphore_init__vita(initialValue, pSemaphore); +#elif defined(MA_THREADING_BACKEND_POSIX) return ma_semaphore_init__posix(initialValue, pSemaphore); #elif defined(MA_THREADING_BACKEND_WIN32) return ma_semaphore_init__win32(initialValue, pSemaphore); @@ -18759,7 +19049,9 @@ MA_API void ma_semaphore_uninit(ma_semaphore* pSemaphore) return; } -#if defined(MA_THREADING_BACKEND_POSIX) +#if defined(MA_THREADING_BACKEND_VITA) + ma_semaphore_uninit__vita(pSemaphore); +#elif defined(MA_THREADING_BACKEND_POSIX) ma_semaphore_uninit__posix(pSemaphore); #elif defined(MA_THREADING_BACKEND_WIN32) ma_semaphore_uninit__win32(pSemaphore); @@ -18775,7 +19067,9 @@ MA_API ma_result ma_semaphore_wait(ma_semaphore* pSemaphore) return MA_INVALID_ARGS; } -#if defined(MA_THREADING_BACKEND_POSIX) +#if defined(MA_THREADING_BACKEND_VITA) + return ma_semaphore_wait__vita(pSemaphore); +#elif defined(MA_THREADING_BACKEND_POSIX) return ma_semaphore_wait__posix(pSemaphore); #elif defined(MA_THREADING_BACKEND_WIN32) return ma_semaphore_wait__win32(pSemaphore); @@ -18791,7 +19085,9 @@ MA_API ma_result ma_semaphore_release(ma_semaphore* pSemaphore) return MA_INVALID_ARGS; } -#if defined(MA_THREADING_BACKEND_POSIX) +#if defined(MA_THREADING_BACKEND_VITA) + return ma_semaphore_release__vita(pSemaphore); +#elif defined(MA_THREADING_BACKEND_POSIX) return ma_semaphore_release__posix(pSemaphore); #elif defined(MA_THREADING_BACKEND_WIN32) return ma_semaphore_release__win32(pSemaphore);