|
|
|
@ -55,9 +55,11 @@ LOG_CHANNEL(Threading);
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
#ifdef _WIN32
|
|
|
|
#define NATIVE_MUTEX_PTR(storage) static_cast<SRWLOCK*>(static_cast<void*>(&(storage)))
|
|
|
|
#define NATIVE_MUTEX_PTR(storage) static_cast<SRWLOCK*>(static_cast<void*>(&(storage)))
|
|
|
|
|
|
|
|
#define NATIVE_SHARED_MUTEX_PTR(storage) static_cast<SRWLOCK*>(static_cast<void*>(&(storage)))
|
|
|
|
#define NATIVE_CONDITION_VARIABLE_PTR(storage) static_cast<CONDITION_VARIABLE*>(static_cast<void*>(&(storage)))
|
|
|
|
#define NATIVE_CONDITION_VARIABLE_PTR(storage) static_cast<CONDITION_VARIABLE*>(static_cast<void*>(&(storage)))
|
|
|
|
#else
|
|
|
|
#else
|
|
|
|
#define NATIVE_MUTEX_PTR(storage) static_cast<pthread_mutex_t*>(static_cast<void*>(&(storage)))
|
|
|
|
#define NATIVE_MUTEX_PTR(storage) static_cast<pthread_mutex_t*>(static_cast<void*>(&(storage)))
|
|
|
|
|
|
|
|
#define NATIVE_SHARED_MUTEX_PTR(storage) static_cast<pthread_rwlock_t*>(static_cast<void*>(&(storage)))
|
|
|
|
#define NATIVE_CONDITION_VARIABLE_PTR(storage) static_cast<pthread_cond_t*>(static_cast<void*>(&(storage)))
|
|
|
|
#define NATIVE_CONDITION_VARIABLE_PTR(storage) static_cast<pthread_cond_t*>(static_cast<void*>(&(storage)))
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
@ -674,6 +676,86 @@ void Threading::Mutex::unlock()
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef _WIN32
|
|
|
|
#ifndef _WIN32
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Threading::SharedMutex::SharedMutex()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
static_assert(sizeof(m_data) == sizeof(pthread_rwlock_t));
|
|
|
|
|
|
|
|
static_assert(alignof(SharedMutex) >= alignof(pthread_rwlock_t));
|
|
|
|
|
|
|
|
[[maybe_unused]] const int result = pthread_rwlock_init(NATIVE_SHARED_MUTEX_PTR(m_data), nullptr);
|
|
|
|
|
|
|
|
DebugAssert(result == 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Threading::SharedMutex::~SharedMutex()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
[[maybe_unused]] const int result = pthread_rwlock_destroy(NATIVE_SHARED_MUTEX_PTR(m_data));
|
|
|
|
|
|
|
|
DebugAssert(result == 0);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#endif // _WIN32
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Threading::SharedMutex::lock()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
|
|
|
AcquireSRWLockExclusive(NATIVE_SHARED_MUTEX_PTR(m_data));
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
[[maybe_unused]] const int result = pthread_rwlock_wrlock(NATIVE_SHARED_MUTEX_PTR(m_data));
|
|
|
|
|
|
|
|
DebugAssert(result == 0);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Threading::SharedMutex::try_lock()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
|
|
|
return TryAcquireSRWLockExclusive(NATIVE_SHARED_MUTEX_PTR(m_data)) != FALSE;
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
const int result = pthread_rwlock_trywrlock(NATIVE_SHARED_MUTEX_PTR(m_data));
|
|
|
|
|
|
|
|
DebugAssert(result == 0 || result == EBUSY);
|
|
|
|
|
|
|
|
return result == 0;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Threading::SharedMutex::unlock()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
|
|
|
ReleaseSRWLockExclusive(NATIVE_SHARED_MUTEX_PTR(m_data));
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
[[maybe_unused]] const int result = pthread_rwlock_unlock(NATIVE_SHARED_MUTEX_PTR(m_data));
|
|
|
|
|
|
|
|
DebugAssert(result == 0);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Threading::SharedMutex::lock_shared()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
|
|
|
AcquireSRWLockShared(NATIVE_SHARED_MUTEX_PTR(m_data));
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
[[maybe_unused]] const int result = pthread_rwlock_rdlock(NATIVE_SHARED_MUTEX_PTR(m_data));
|
|
|
|
|
|
|
|
DebugAssert(result == 0);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool Threading::SharedMutex::try_lock_shared()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
|
|
|
return TryAcquireSRWLockShared(NATIVE_SHARED_MUTEX_PTR(m_data)) != FALSE;
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
const int result = pthread_rwlock_tryrdlock(NATIVE_SHARED_MUTEX_PTR(m_data));
|
|
|
|
|
|
|
|
DebugAssert(result == 0 || result == EBUSY || result == EAGAIN);
|
|
|
|
|
|
|
|
return result == 0;
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void Threading::SharedMutex::unlock_shared()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
|
|
|
|
ReleaseSRWLockShared(NATIVE_SHARED_MUTEX_PTR(m_data));
|
|
|
|
|
|
|
|
#else
|
|
|
|
|
|
|
|
[[maybe_unused]] const int result = pthread_rwlock_unlock(NATIVE_SHARED_MUTEX_PTR(m_data));
|
|
|
|
|
|
|
|
DebugAssert(result == 0);
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef _WIN32
|
|
|
|
|
|
|
|
|
|
|
|
Threading::ConditionVariable::ConditionVariable()
|
|
|
|
Threading::ConditionVariable::ConditionVariable()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
static_assert(sizeof(m_data) == sizeof(pthread_cond_t));
|
|
|
|
static_assert(sizeof(m_data) == sizeof(pthread_cond_t));
|
|
|
|
@ -937,6 +1019,7 @@ bool Threading::KernelSemaphore::TryWait()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#undef NATIVE_MUTEX_PTR
|
|
|
|
#undef NATIVE_MUTEX_PTR
|
|
|
|
|
|
|
|
#undef NATIVE_SHARED_MUTEX_PTR
|
|
|
|
#undef NATIVE_CONDITION_VARIABLE_PTR
|
|
|
|
#undef NATIVE_CONDITION_VARIABLE_PTR
|
|
|
|
#if !defined(_WIN32)
|
|
|
|
#if !defined(_WIN32)
|
|
|
|
#undef NATIVE_SEMAPHORE
|
|
|
|
#undef NATIVE_SEMAPHORE
|
|
|
|
|