Commit b65221cf authored by David Reid's avatar David Reid

Add a spinlock implementation.

This is private at the moment, but may be made public later.
parent 8d19c235
...@@ -6056,6 +6056,75 @@ static MA_INLINE ma_uint32 ma_swap_endian_uint32(ma_uint32 n) ...@@ -6056,6 +6056,75 @@ static MA_INLINE ma_uint32 ma_swap_endian_uint32(ma_uint32 n)
} }
#if !defined(MA_EMSCRIPTEN)
#ifdef MA_WIN32
static void ma_sleep__win32(ma_uint32 milliseconds)
{
Sleep((DWORD)milliseconds);
}
#endif
#ifdef MA_POSIX
static void ma_sleep__posix(ma_uint32 milliseconds)
{
#ifdef MA_EMSCRIPTEN
(void)milliseconds;
MA_ASSERT(MA_FALSE); /* The Emscripten build should never sleep. */
#else
#if _POSIX_C_SOURCE >= 199309L
struct timespec ts;
ts.tv_sec = milliseconds / 1000;
ts.tv_nsec = milliseconds % 1000 * 1000000;
nanosleep(&ts, NULL);
#else
struct timeval tv;
tv.tv_sec = milliseconds / 1000;
tv.tv_usec = milliseconds % 1000 * 1000;
select(0, NULL, NULL, NULL, &tv);
#endif
#endif
}
#endif
static void ma_sleep(ma_uint32 milliseconds)
{
#ifdef MA_WIN32
ma_sleep__win32(milliseconds);
#endif
#ifdef MA_POSIX
ma_sleep__posix(milliseconds);
#endif
}
#endif
#if !defined(MA_EMSCRIPTEN)
static MA_INLINE void ma_yield()
{
#if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
/* x86/x64 */
#if defined(_MSC_VER) && !defined(__clang__)
#if _MSC_VER >= 1400
_mm_pause();
#else
__asm pause;
#endif
#else
__asm__ __volatile__ ("pause");
#endif
#elif (defined(__arm__) && defined(__ARM_ARCH) && __ARM_ARCH >= 6) || (defined(_M_ARM) && _M_ARM >= 6)
/* ARM */
#if defined(_MSC_VER)
/* Apparently there is a __yield() intrinsic that's compatible with ARM, but I cannot find documentation for it nor can I find where it's declared. */
__yield();
#else
__asm__ __volatile__ ("yield");
#endif
#else
/* Unknown or unsupported architecture. No-op. */
#endif
}
#endif
#ifndef MA_COINIT_VALUE #ifndef MA_COINIT_VALUE
#define MA_COINIT_VALUE 0 /* 0 = COINIT_MULTITHREADED */ #define MA_COINIT_VALUE 0 /* 0 = COINIT_MULTITHREADED */
...@@ -8191,6 +8260,51 @@ c89atomic_bool c89atomic_compare_exchange_strong_explicit_64(volatile c89atomic_ ...@@ -8191,6 +8260,51 @@ c89atomic_bool c89atomic_compare_exchange_strong_explicit_64(volatile c89atomic_
/* c89atomic.h end */ /* c89atomic.h end */
typedef unsigned char ma_spinlock;
static MA_INLINE ma_result ma_spinlock_lock_ex(ma_spinlock* pSpinlock, ma_bool32 yield)
{
if (pSpinlock == NULL) {
return MA_INVALID_ARGS;
}
for (;;) {
if (c89atomic_flag_test_and_set_explicit(pSpinlock, c89atomic_memory_order_acquire) == 0) {
break;
}
while (c89atomic_load_explicit_8(pSpinlock, c89atomic_memory_order_relaxed) == 1) {
if (yield) {
ma_yield();
}
}
}
return MA_SUCCESS;
}
static ma_result ma_spinlock_lock(ma_spinlock* pSpinlock)
{
return ma_spinlock_lock_ex(pSpinlock, MA_TRUE);
}
static ma_result ma_spinlock_lock_noyield(ma_spinlock* pSpinlock)
{
return ma_spinlock_lock_ex(pSpinlock, MA_FALSE);
}
static ma_result ma_spinlock_unlock(ma_spinlock* pSpinlock)
{
if (pSpinlock == NULL) {
return MA_INVALID_ARGS;
}
c89atomic_flag_clear_explicit(pSpinlock, c89atomic_memory_order_release);
return MA_SUCCESS;
}
static void* ma__malloc_default(size_t sz, void* pUserData) static void* ma__malloc_default(size_t sz, void* pUserData)
{ {
(void)pUserData; (void)pUserData;
...@@ -8415,11 +8529,6 @@ static void ma_thread_wait__win32(ma_thread* pThread) ...@@ -8415,11 +8529,6 @@ static void ma_thread_wait__win32(ma_thread* pThread)
WaitForSingleObject((HANDLE)*pThread, INFINITE); WaitForSingleObject((HANDLE)*pThread, INFINITE);
} }
static void ma_sleep__win32(ma_uint32 milliseconds)
{
Sleep((DWORD)milliseconds);
}
static ma_result ma_mutex_init__win32(ma_mutex* pMutex) static ma_result ma_mutex_init__win32(ma_mutex* pMutex)
{ {
...@@ -8608,28 +8717,6 @@ static void ma_thread_wait__posix(ma_thread* pThread) ...@@ -8608,28 +8717,6 @@ static void ma_thread_wait__posix(ma_thread* pThread)
pthread_join(*pThread, NULL); pthread_join(*pThread, NULL);
} }
#if !defined(MA_EMSCRIPTEN)
static void ma_sleep__posix(ma_uint32 milliseconds)
{
#ifdef MA_EMSCRIPTEN
(void)milliseconds;
MA_ASSERT(MA_FALSE); /* The Emscripten build should never sleep. */
#else
#if _POSIX_C_SOURCE >= 199309L
struct timespec ts;
ts.tv_sec = milliseconds / 1000;
ts.tv_nsec = milliseconds % 1000 * 1000000;
nanosleep(&ts, NULL);
#else
struct timeval tv;
tv.tv_sec = milliseconds / 1000;
tv.tv_usec = milliseconds % 1000 * 1000;
select(0, NULL, NULL, NULL, &tv);
#endif
#endif
}
#endif /* MA_EMSCRIPTEN */
static ma_result ma_mutex_init__posix(ma_mutex* pMutex) static ma_result ma_mutex_init__posix(ma_mutex* pMutex)
{ {
...@@ -8808,46 +8895,6 @@ static void ma_thread_wait(ma_thread* pThread) ...@@ -8808,46 +8895,6 @@ static void ma_thread_wait(ma_thread* pThread)
#endif #endif
} }
#if !defined(MA_EMSCRIPTEN)
static void ma_sleep(ma_uint32 milliseconds)
{
#ifdef MA_WIN32
ma_sleep__win32(milliseconds);
#endif
#ifdef MA_POSIX
ma_sleep__posix(milliseconds);
#endif
}
#endif
#if !defined(MA_EMSCRIPTEN)
static MA_INLINE void ma_yield()
{
#if defined(__i386) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64)
/* x86/x64 */
#if defined(_MSC_VER) && !defined(__clang__)
#if _MSC_VER >= 1400
_mm_pause();
#else
__asm pause;
#endif
#else
__asm__ __volatile__ ("pause");
#endif
#elif (defined(__arm__) && defined(__ARM_ARCH) && __ARM_ARCH >= 6) || (defined(_M_ARM) && _M_ARM >= 6)
/* ARM */
#if defined(_MSC_VER)
/* Apparently there is a __yield() intrinsic that's compatible with ARM, but I cannot find documentation for it nor can I find where it's declared. */
__yield();
#else
__asm__ __volatile__ ("yield");
#endif
#else
/* Unknown or unsupported architecture. No-op. */
#endif
}
#endif
MA_API ma_result ma_mutex_init(ma_mutex* pMutex) MA_API ma_result ma_mutex_init(ma_mutex* pMutex)
{ {
...@@ -61781,6 +61828,7 @@ The following miscellaneous changes have also been made. ...@@ -61781,6 +61828,7 @@ The following miscellaneous changes have also been made.
REVISION HISTORY REVISION HISTORY
================ ================
v0.10.11 - TBD v0.10.11 - TBD
- Fix some bugs with device tracking on Core Audio.
- Updates to documentation. - Updates to documentation.
v0.10.10 - 26-06-2020 v0.10.10 - 26-06-2020
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment