diff options
author | Luca Muscariello <lumuscar+fdio@cisco.com> | 2017-02-25 23:42:31 +0100 |
---|---|---|
committer | Luca Muscariello <lumuscar+fdio@cisco.com> | 2017-02-25 23:42:31 +0100 |
commit | 05c1a838c881ea502888659848d8792843b28718 (patch) | |
tree | cf0b05b58bd725a1eb6c80325ba986c63dea42aa /libdash/source/portable/MultiThreading.cpp | |
parent | 9b30fc10fb1cbebe651e5a107e8ca5b24de54675 (diff) |
Initial commit: video player - viper
Change-Id: Id5aa33598ce34659bad4a7a9ae5006bfb84f9bd1
Signed-off-by: Luca Muscariello <lumuscar+fdio@cisco.com>
Diffstat (limited to 'libdash/source/portable/MultiThreading.cpp')
-rw-r--r-- | libdash/source/portable/MultiThreading.cpp | 112 |
1 files changed, 112 insertions, 0 deletions
diff --git a/libdash/source/portable/MultiThreading.cpp b/libdash/source/portable/MultiThreading.cpp new file mode 100644 index 00000000..5d1fe9c0 --- /dev/null +++ b/libdash/source/portable/MultiThreading.cpp @@ -0,0 +1,112 @@ +#include "MultiThreading.h" + +THREAD_HANDLE CreateThreadPortable (void *(*start_routine) (void *), void *arg) +{ + #if defined _WIN32 || defined _WIN64 + return CreateThread (0, 0, (LPTHREAD_START_ROUTINE)start_routine, (LPVOID)arg, 0, 0); + #else + THREAD_HANDLE th = (THREAD_HANDLE)malloc(sizeof(pthread_t)); + + if (!th) + { + std::cerr << "Error allocating thread." << std::endl; + return NULL; + } + + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + if(int err = pthread_create(th, &attr, start_routine, arg)) + { + std::cerr << strerror(err) << std::endl; + return NULL; + } + return th; + #endif +} +void DestroyThreadPortable (THREAD_HANDLE th) +{ + #if !defined _WIN32 && !defined _WIN64 + if(th) + free(th); + #endif +} + +/**************************************************************************** +* Condition variables for Windows XP and older windows sytems +*****************************************************************************/ +#if defined WINXPOROLDER + void InitCondition (condition_variable_t *cv) + { + InitializeCriticalSection(&cv->waitersCountLock); + + cv->waitersCount = 0; + cv->waitGenerationCount = 0; + cv->releaseCount = 0; + + cv->waitingEvent = CreateEvent (NULL, // no security + TRUE, // manual-reset + FALSE, // non-signaled initially + NULL); // unnamed + } + void WaitCondition (condition_variable_t *cv, CRITICAL_SECTION *externalMutex) + { + EnterCriticalSection(&cv->waitersCountLock); + + cv->waitersCount++; + + int currentGenerationCount = cv->waitGenerationCount; + + LeaveCriticalSection(&cv->waitersCountLock); + LeaveCriticalSection(externalMutex); + + bool isWaitDone = false; + while(!isWaitDone) + { + WaitForSingleObject (cv->waitingEvent, INFINITE); + EnterCriticalSection (&cv->waitersCountLock); + + isWaitDone = (cv->releaseCount > 0 && cv->waitGenerationCount != currentGenerationCount); + LeaveCriticalSection (&cv->waitersCountLock); + } + + EnterCriticalSection(externalMutex); + EnterCriticalSection(&cv->waitersCountLock); + + cv->waitersCount--; + cv->releaseCount--; + bool isLastWaiter = (cv->releaseCount == 0); + + LeaveCriticalSection(&cv->waitersCountLock); + + if(isLastWaiter) + ResetEvent(cv->waitingEvent); + } + void SignalCondition (condition_variable_t *cv) + { + EnterCriticalSection(&cv->waitersCountLock); + + if(cv->waitersCount > cv->releaseCount) + { + SetEvent(cv->waitingEvent); + cv->releaseCount++; + cv->waitGenerationCount++; + } + + LeaveCriticalSection(&cv->waitersCountLock); + } + void BroadcastCondition (condition_variable_t *cv) + { + EnterCriticalSection(&cv->waitersCountLock); + + if(cv->waitersCount > 0) + { + SetEvent(cv->waitingEvent); + cv->releaseCount = cv->waitersCount; + cv->waitGenerationCount++; + } + + LeaveCriticalSection(&cv->waitersCountLock); +} +#endif |