diff --git a/angelscript/source/as_config.h b/angelscript/source/as_config.h index 8af33a2..6f09f88 100644 --- a/angelscript/source/as_config.h +++ b/angelscript/source/as_config.h @@ -998,7 +998,7 @@ #define AS_MAX_PORTABILITY #endif #define AS_LINUX - #define AS_POSIX_THREADS + #define AS_STD_THREADS #if !( ( (__GNUC__ == 4) && (__GNUC_MINOR__ >= 1) || __GNUC__ > 4) ) // Only with GCC 4.1 was the atomic instructions available @@ -1273,7 +1273,7 @@ // If the form of threads to use hasn't been chosen // then the library will be compiled without support // for multithreading -#if !defined(AS_POSIX_THREADS) && !defined(AS_WINDOWS_THREADS) +#if !defined(AS_POSIX_THREADS) && !defined(AS_WINDOWS_THREADS) && !defined(AS_STD_THREADS) #define AS_NO_THREADS #endif diff --git a/angelscript/source/as_criticalsection.h b/angelscript/source/as_criticalsection.h index 2e15288..ac84319 100644 --- a/angelscript/source/as_criticalsection.h +++ b/angelscript/source/as_criticalsection.h @@ -179,6 +179,45 @@ protected: // but it gives a compiler error on MSVC6 so I'm leaving it outside static const asUINT maxReaders = 10; +#elif defined(AS_STD_THREADS) + +END_AS_NAMESPACE +#include +#include +#include +BEGIN_AS_NAMESPACE + +class asCThreadCriticalSection +{ +public: + asCThreadCriticalSection(); + ~asCThreadCriticalSection(); + + void Enter(); + void Leave(); + bool TryEnter(); + +protected: + std::mutex _mutex; +}; + +class asCThreadReadWriteLock +{ +public: + asCThreadReadWriteLock(); + ~asCThreadReadWriteLock(); + + void AcquireExclusive(); + void ReleaseExclusive(); + bool TryAcquireExclusive(); + + void AcquireShared(); + void ReleaseShared(); + bool TryAcquireShared(); +protected: + std::shared_mutex _mutex; +}; + #endif #endif diff --git a/angelscript/source/as_thread.cpp b/angelscript/source/as_thread.cpp index 63ab15e..6dd3cca 100644 --- a/angelscript/source/as_thread.cpp +++ b/angelscript/source/as_thread.cpp @@ -226,6 +226,10 @@ asCThreadManager::~asCThreadManager() #endif } +#if defined(AS_STD_THREADS) +thread_local asCThreadLocalData *std_tld; +#endif + int asCThreadManager::CleanupLocalData() { if( threadManager == 0 ) @@ -237,7 +241,9 @@ int asCThreadManager::CleanupLocalData() #elif defined AS_WINDOWS_THREADS #if !defined(_MSC_VER) || !(WINAPI_FAMILY & WINAPI_FAMILY_PHONE_APP) asCThreadLocalData *tld = (asCThreadLocalData*)TlsGetValue((DWORD)threadManager->tlsKey); - #endif + #endif +#elif defined(AS_STD_THREADS) + auto tld = std_tld; #endif if( tld == 0 ) @@ -299,7 +305,13 @@ asCThreadLocalData *asCThreadManager::GetLocalData() tld = asNEW(asCThreadLocalData)(); TlsSetValue((DWORD)threadManager->tlsKey, tld); } - #endif + #endif +#elif defined(AS_STD_THREADS) + if(std_tld == nullptr) + { + std_tld = asNEW(asCThreadLocalData)(); + } + auto tld = std_tld; #endif return tld; @@ -355,6 +367,8 @@ void asCThreadCriticalSection::Enter() pthread_mutex_lock(&cs); #elif defined AS_WINDOWS_THREADS EnterCriticalSection(&cs); +#elif defined(AS_STD_THREADS) + _mutex.lock(); #endif } @@ -364,6 +378,8 @@ void asCThreadCriticalSection::Leave() pthread_mutex_unlock(&cs); #elif defined AS_WINDOWS_THREADS LeaveCriticalSection(&cs); +#elif defined(AS_STD_THREADS) + _mutex.unlock(); #endif } @@ -373,6 +389,8 @@ bool asCThreadCriticalSection::TryEnter() return !pthread_mutex_trylock(&cs); #elif defined AS_WINDOWS_THREADS return TryEnterCriticalSection(&cs) ? true : false; +#elif defined(AS_STD_THREADS) + return _mutex.try_lock(); #else return true; #endif @@ -427,6 +445,8 @@ void asCThreadReadWriteLock::AcquireExclusive() // Allow another writer to lock. It will only be able to // lock the readers when this writer releases them anyway. LeaveCriticalSection(&writeLock); +#elif defined(AS_STD_THREADS) + _mutex.lock(); #endif } @@ -437,6 +457,8 @@ void asCThreadReadWriteLock::ReleaseExclusive() #elif defined AS_WINDOWS_THREADS // Release all readers at once ReleaseSemaphore(readLocks, maxReaders, 0); +#elif defined(AS_STD_THREADS) + _mutex.unlock(); #endif } @@ -447,6 +469,8 @@ void asCThreadReadWriteLock::AcquireShared() #elif defined AS_WINDOWS_THREADS // Lock a reader slot WaitForSingleObjectEx(readLocks, INFINITE, FALSE); +#elif defined(AS_STD_THREADS) + _mutex.lock_shared(); #endif } @@ -457,6 +481,8 @@ void asCThreadReadWriteLock::ReleaseShared() #elif defined AS_WINDOWS_THREADS // Release the reader slot ReleaseSemaphore(readLocks, 1, 0); +#elif defined(AS_STD_THREADS) + _mutex.unlock_shared(); #endif }