diff options
Diffstat (limited to 'libs/backends/wavesaudio/wavesapi/Threads/WCThreadSafe.cpp')
-rw-r--r-- | libs/backends/wavesaudio/wavesapi/Threads/WCThreadSafe.cpp | 826 |
1 files changed, 0 insertions, 826 deletions
diff --git a/libs/backends/wavesaudio/wavesapi/Threads/WCThreadSafe.cpp b/libs/backends/wavesaudio/wavesapi/Threads/WCThreadSafe.cpp deleted file mode 100644 index 1ee568af1e..0000000000 --- a/libs/backends/wavesaudio/wavesapi/Threads/WCThreadSafe.cpp +++ /dev/null @@ -1,826 +0,0 @@ -#include "Threads/WCThreadSafe.h" -#include <glib.h> - -#if XPLATFORMTHREADS_WINDOWS - #define _WIN32_WINNT 0x0500 // need at least Windows2000 (for TryEnterCriticalSection() and SignalObjectAndWait() - #include "IncludeWindows.h" - #include <process.h> -#endif // XPLATFORMTHREADS_WINDOWS - - -#if defined(__APPLE__) - #include <CoreServices/CoreServices.h> - #include <stdio.h> -#endif // __APPLE__ - -#if XPLATFORMTHREADS_POSIX - #include </usr/include/unistd.h> // avoid the framework version and use the /usr/include version - #include <pthread.h> - #include <sched.h> - #include <sys/time.h> - #include <errno.h> - #include <signal.h> -// We do this externs because <stdio.h> comes from MSL -extern "C" FILE *popen(const char *command, const char *type); -extern "C" int pclose(FILE *stream); -static int (*BSDfread)( void *, size_t, size_t, FILE * ) = 0; - -#include <string.h> - -#endif //XPLATFORMTHREADS_POSIX - -namespace wvNS { -static const unsigned int knMicrosecondsPerSecond = 1000*1000; -static const unsigned int knNanosecondsPerMicrosecond = 1000; -static const unsigned int knNanosecondsPerSecond = knMicrosecondsPerSecond*knNanosecondsPerMicrosecond; - -namespace wvThread -{ - - //-------------------------------------------------------------------------------- - static inline bool EnsureThreadingInitialized() - { - bool bRetval = true; - - return bRetval; - } - //-------------------------------------------------------------------------------- - - - - - //-------------------------------------------------------------------------------- - static uint32_t CalculateTicksPerMicrosecond(); - static uint32_t CalculateTicksPerMicrosecond() - { - uint32_t nTicksPerMicrosecond=0; -#if defined(_WIN32) - LARGE_INTEGER TSC; - ::QueryPerformanceFrequency(&TSC); - nTicksPerMicrosecond = uint32_t (TSC.QuadPart / knMicrosecondsPerSecond); -#elif defined(__linux__) && defined(__i386__) - static const timediff sktd_TSC_MeasurementPeriod = 40*1000; // delay for CalculateTicksPerMicrosecond() to measure the TSC frequency - uint64_t Tstart, Tend; - timeval tvtmp, tvstart, tvend; - - //--------------------- begin measurement code - // poll to align to a tick of gettimeofday - ::gettimeofday(&tvtmp,0); - do { - ::gettimeofday(&tvstart,0); - __asm__ __volatile__ (".byte 0x0f, 0x31" : "=A" (Tstart)); // RDTSC - } while (tvtmp.tv_usec!=tvstart.tv_usec); - // delay some - ::usleep(sktd_TSC_MeasurementPeriod); - // - ::gettimeofday(&tvtmp,0); - do { - ::gettimeofday(&tvend,0); - __asm__ __volatile__ (".byte 0x0f, 0x31" : "=A" (Tend)); // RDTSC - } while (tvtmp.tv_usec!=tvend.tv_usec); - //--------------------- end measurement code - - suseconds_t elapsed_usec = (tvend.tv_sec-tvstart.tv_sec)*knMicrosecondsPerSecond + (tvend.tv_usec-tvstart.tv_usec); - uint64_t elapsed_ticks = Tend-Tstart; - nTicksPerMicrosecond = uint32_t (elapsed_ticks/elapsed_usec); -#endif - return nTicksPerMicrosecond; - } - -#if defined(__APPLE__) //&& !defined(__MACH__) - - - bool FindNetInterfaceByIPAddress(const char *sIP, char *sInterface) // sIP and sInterface are both char[16] - { - FILE *fProcess , *pSubcall; - char sLine[256]="", *pToken, sCommand[150]; - bool res = false; - int iret; - - fProcess = popen("ifconfig -l inet", "r"); - if (fProcess) - { - memset(sInterface, '\0', 16); - iret = BSDfread(sLine, sizeof(char), sizeof(sLine), fProcess); - pToken = strtok(sLine, " "); - while (pToken) - { - sprintf(sCommand, "ifconfig %s | grep \"inet %s \"", pToken, sIP); - - pSubcall = popen(sCommand, "r"); - if (pSubcall) - { - char sSubline[100]=""; - if (BSDfread(sSubline, sizeof(char), sizeof(sSubline), pSubcall)) - { - // found - strcpy(sInterface, pToken); - res = true; - pclose(pSubcall); - break; - } - } - pclose(pSubcall); - pToken = strtok(NULL, " "); - } - - } - pclose(fProcess); - - return res; - } -#endif // MACOS - - timestamp now(void) - { - EnsureThreadingInitialized(); - static const uint32_t nTicksPerMicrosecond = CalculateTicksPerMicrosecond(); -#if defined(_WIN32) - if (nTicksPerMicrosecond) - { - LARGE_INTEGER TSC; - ::QueryPerformanceCounter(&TSC); - return timestamp(uint32_t(TSC.QuadPart/nTicksPerMicrosecond)); - } - else return timestamp(0); -#elif defined(__APPLE__) - if (nTicksPerMicrosecond) {} // prevent 'unused' warnings - UnsignedWide usecs; - ::Microseconds(&usecs); - return timestamp(usecs.lo); -#elif defined(__linux__) && defined(__i386__) && defined(__gnu_linux__) - uint64_t TSC; - __asm__ __volatile__ (".byte 0x0f, 0x31" : "=A" (TSC)); // RDTSC - return timestamp(TSC/nTicksPerMicrosecond); -#elif defined(__linux__) && defined(__PPC__) && defined(__gnu_linux__) - #warning need to implement maybe -#else - #error Dont know how to get microseconds timer ! -#endif // defined(_WIN32) - } - - - void sleep_milliseconds(unsigned int nMillisecs) - { - EnsureThreadingInitialized(); -#if XPLATFORMTHREADS_WINDOWS - ::Sleep(nMillisecs); -#elif XPLATFORMTHREADS_POSIX - ::usleep(nMillisecs*1000); -#else - #error Not implemented for your OS -#endif - } - - -#if XPLATFORMTHREADS_WINDOWS - inline DWORD win32_milliseconds(timediff td) { return (td+499)/1000; } -#endif - - void sleep(timediff _td) - { - if (_td>0) - { - EnsureThreadingInitialized(); -#if XPLATFORMTHREADS_WINDOWS - ::Sleep(win32_milliseconds(_td)); // This is the best we can do in windows -#elif XPLATFORMTHREADS_POSIX - ::usleep(_td); -#else - #error Not implemented for your OS -#endif - } - } - - -#if XPLATFORMTHREADS_WINDOWS - void yield() { ::Sleep(0); } -#elif XPLATFORMTHREADS_POSIX - void yield() { ::sched_yield(); } -#endif - - - - - class ThreadMutexInited::OSDependentMutex : public noncopyableobject - { -#if defined (XPLATFORMTHREADS_WINDOWS) - protected: - CRITICAL_SECTION m_critsec; - public: - - inline OSDependentMutex() { EnsureThreadingInitialized(); ::InitializeCriticalSection(&m_critsec); } - inline ~OSDependentMutex() { EnsureThreadingInitialized(); ::DeleteCriticalSection (&m_critsec); } - inline void obtain() { EnsureThreadingInitialized(); ::EnterCriticalSection (&m_critsec); } - inline void release() { EnsureThreadingInitialized(); ::LeaveCriticalSection (&m_critsec); } - inline bool tryobtain() { EnsureThreadingInitialized(); return TryEnterCriticalSection(&m_critsec)!=FALSE; } - -#elif defined (XPLATFORMTHREADS_POSIX) - protected: - pthread_mutex_t m_ptmutex; - public: - inline OSDependentMutex() - { - EnsureThreadingInitialized(); - pthread_mutexattr_t attr; - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - ::pthread_mutex_init (&m_ptmutex, &attr); - } - inline ~OSDependentMutex() { EnsureThreadingInitialized(); ::pthread_mutex_destroy(&m_ptmutex); } - inline void obtain() { EnsureThreadingInitialized(); ::pthread_mutex_lock (&m_ptmutex); } - inline void release() { EnsureThreadingInitialized(); ::pthread_mutex_unlock (&m_ptmutex); } - inline bool tryobtain() { EnsureThreadingInitialized(); return ::pthread_mutex_trylock(&m_ptmutex)!=EBUSY; } - -#endif - }; - - ThreadMutexInited::ThreadMutexInited() : - m_osdmutex(0) {} - - void ThreadMutexInited::init() - { - if (! is_init()) - { - m_osdmutex = new OSDependentMutex; - } - } - - void ThreadMutexInited::uninit() - { - if (is_init()) - { - delete m_osdmutex; - m_osdmutex = 0; - } - } - - ThreadMutexInited::~ThreadMutexInited() - { - uninit(); - } - - void ThreadMutexInited::obtain() - { - if (is_init()) - { - m_osdmutex->obtain(); - } - } - - void ThreadMutexInited::release() - { - if (is_init()) - { - m_osdmutex->release(); - } - } - - bool ThreadMutexInited::tryobtain() - { - bool retVal = true; - if (is_init()) - { - retVal = m_osdmutex->tryobtain(); - } - return retVal; - } - - class ThreadConditionSignal::OSDependentObject : public noncopyableobject - { -#if defined (XPLATFORMTHREADS_POSIX) - - protected: - pthread_cond_t m_ptcond; - pthread_mutex_t m_ptmutex; - public: - inline OSDependentObject() - { - EnsureThreadingInitialized(); - ::pthread_mutex_init(&m_ptmutex,0); - ::pthread_cond_init(&m_ptcond, 0); - } - inline ~OSDependentObject() { ::pthread_cond_destroy(&m_ptcond), ::pthread_mutex_destroy(&m_ptmutex); } - inline void signal_unicast() { ::pthread_cond_signal(&m_ptcond); } - inline void signal_broadcast() { ::pthread_cond_broadcast(&m_ptcond); } - inline void await_signal() { ::pthread_cond_wait(&m_ptcond, &m_ptmutex); } - inline bool await_signal(timediff td) - { - timespec tspecDeadline; - timeval tvNow; - ::gettimeofday(&tvNow,0); - tspecDeadline.tv_nsec = (tvNow.tv_usec + td%knMicrosecondsPerSecond)*knNanosecondsPerMicrosecond; - tspecDeadline.tv_sec = tvNow.tv_sec + td/knMicrosecondsPerSecond; - if (!(tspecDeadline.tv_nsec < suseconds_t(knNanosecondsPerSecond))) - ++tspecDeadline.tv_sec, tspecDeadline.tv_nsec-=knNanosecondsPerSecond; - return ::pthread_cond_timedwait(&m_ptcond, &m_ptmutex, &tspecDeadline) != ETIMEDOUT; - } - - void obtain_mutex() { ::pthread_mutex_lock(&m_ptmutex); } - bool tryobtain_mutex() { return ::pthread_mutex_trylock(&m_ptmutex)!=EBUSY; } - void release_mutex() { ::pthread_mutex_unlock(&m_ptmutex); } - - -#elif XPLATFORMTHREADS_WINDOWS - protected: - unsigned int m_nWaiterCount; - CRITICAL_SECTION m_csectWaiterCount; - - HANDLE m_hndSemaphoreSignaller; // We keep this semaphore always at 0 count (non-signalled). We use it to release a controlled number of threads. - HANDLE m_hndEventAllWaitersReleased; // auto-reset - HANDLE m_hndMutex; // the mutex associated with the condition - bool m_bBroadcastSignalled; // means that the last waiter must signal m_hndEventAllWaitersReleased when done waiting - - protected: - // - - - - - - - - - - - - - - - - - - - - - - - - - bool await_signal_win32(DWORD dwTimeout) - { - ::EnterCriticalSection(&m_csectWaiterCount); - ++m_nWaiterCount; - ::LeaveCriticalSection(&m_csectWaiterCount); - // This is the actual wait for the signal - bool bWaitSucceeded = ::SignalObjectAndWait(m_hndMutex, m_hndSemaphoreSignaller, dwTimeout, FALSE) == WAIT_OBJECT_0; - // - ::EnterCriticalSection(&m_csectWaiterCount); - bool bLastWaiter = --m_nWaiterCount==0 && m_bBroadcastSignalled; - ::LeaveCriticalSection(&m_csectWaiterCount); - - // re-acquire the mutex - if (bLastWaiter) - ::SignalObjectAndWait(m_hndEventAllWaitersReleased, m_hndMutex, INFINITE, FALSE); - else - ::WaitForSingleObject(m_hndMutex, INFINITE); - return bWaitSucceeded; - } - - - public: - - inline bool await_signal(timediff td) { return await_signal_win32((win32_milliseconds(td))); } - inline void await_signal() { await_signal_win32(INFINITE); } - - OSDependentObject() : m_nWaiterCount(0), m_bBroadcastSignalled(false) - { - EnsureThreadingInitialized(); - ::InitializeCriticalSection(&m_csectWaiterCount); - m_hndEventAllWaitersReleased = ::CreateEvent( - 0, // security - FALSE, // auto-reset - FALSE, // initial state non-sognalled - 0); // name - m_hndSemaphoreSignaller = ::CreateSemaphore( - 0, // security - 0, // initial count (and will stay this way) - 0x100000, // maximum count (should be as large as the maximum number of waiting threads) - 0); // name - m_hndMutex = ::CreateMutex( - 0, // security - FALSE, // not owned initially - 0); // name - //if (m_hndEventAllWaitersReleased==INVALID_HANDLE_VALUE || m_hndSemaphoreSignaller==INVALID_HANDLE_VALUE) - // throw something(); - } - - ~OSDependentObject() - { - ::CloseHandle(m_hndMutex); - ::CloseHandle(m_hndSemaphoreSignaller); - ::CloseHandle(m_hndEventAllWaitersReleased); - ::DeleteCriticalSection(&m_csectWaiterCount); - } - - inline void signal_unicast() - { - ::EnterCriticalSection(&m_csectWaiterCount); - unsigned int nWaiters = m_nWaiterCount; - ::LeaveCriticalSection(&m_csectWaiterCount); - if (nWaiters) - ::ReleaseSemaphore(m_hndSemaphoreSignaller, 1, 0); // release 1 semaphore credit to release one waiting thread - } - - void signal_broadcast() - { - ::EnterCriticalSection(&m_csectWaiterCount); - unsigned int nWaiters = m_nWaiterCount; - if (nWaiters) - { - m_bBroadcastSignalled = true; - ::ReleaseSemaphore(m_hndSemaphoreSignaller, nWaiters, 0); // release as many credits as there are waiting threads - ::LeaveCriticalSection(&m_csectWaiterCount); - ::WaitForSingleObject(m_hndEventAllWaitersReleased, INFINITE); - // at this point all threads are waiting on m_hndMutex, which would be released outside this function call - m_bBroadcastSignalled = false; - } - else - // no one is waiting - ::LeaveCriticalSection(&m_csectWaiterCount); - } - //------------------------------------------------ - inline void obtain_mutex() { ::WaitForSingleObject(m_hndMutex, INFINITE); } - inline bool tryobtain_mutex() { return ::WaitForSingleObject(m_hndMutex,0) == WAIT_OBJECT_0; } - inline void release_mutex() { ::ReleaseMutex(m_hndMutex); } - //------------------------------------------------ -#endif // OS switch - }; - - void ThreadConditionSignal::obtain_mutex() - { - m_osdepobj.obtain_mutex(); - } - bool ThreadConditionSignal::tryobtain_mutex() { return m_osdepobj.tryobtain_mutex(); } - void ThreadConditionSignal::release_mutex() - { - m_osdepobj.release_mutex(); - } - - void ThreadConditionSignal::await_condition() { m_osdepobj.await_signal(); } - bool ThreadConditionSignal::await_condition(timediff tdTimeout) { return m_osdepobj.await_signal(tdTimeout); } - void ThreadConditionSignal::signal_condition_single() { m_osdepobj.signal_unicast(); } - void ThreadConditionSignal::signal_condition_broadcast() { m_osdepobj.signal_broadcast(); } - - ThreadConditionSignal::ThreadConditionSignal() : m_osdepobj(*new OSDependentObject) {} - ThreadConditionSignal::~ThreadConditionSignal() { delete &m_osdepobj; } - - - - - - - - -#if XPLATFORMTHREADS_POSIX - namespace // anon - { - inline int max_FIFO_schedparam() - { - static const int max_priority = ::sched_get_priority_max(SCHED_FIFO); - return max_priority; - } - inline int schedparam_by_percentage(unsigned short percentage) - { - return (max_FIFO_schedparam()*10*percentage+500)/1000; - } - class POSIXThreadPriority - { - public: - int m_SchedPolicy; - int m_SchedPriority; - POSIXThreadPriority(ThreadPriority pri) - { - switch (pri) - { - case ThreadPriority::TimeCritical: m_SchedPolicy=SCHED_FIFO, m_SchedPriority=schedparam_by_percentage(80); break; - case ThreadPriority::AboveNormal: m_SchedPolicy=SCHED_FIFO, m_SchedPriority=schedparam_by_percentage(20); break; - case ThreadPriority::BelowNormal: // fall through to normal; nothing is below normal in POSIX - case ThreadPriority::Normal: // fall through to default - default: m_SchedPolicy=SCHED_OTHER, m_SchedPriority=0; break; - } - } - }; - - } // namespace anonymous -#endif // XPLATFORMTHREADS_POSIX - -#if XPLATFORMTHREADS_WINDOWS - namespace // anon - { - inline int WinThreadPriority(ThreadPriority pri) - { - switch (pri) - { - case ThreadPriority::BelowNormal: return THREAD_PRIORITY_BELOW_NORMAL; - case ThreadPriority::AboveNormal: return THREAD_PRIORITY_ABOVE_NORMAL; - case ThreadPriority::TimeCritical: return THREAD_PRIORITY_TIME_CRITICAL; - case ThreadPriority::Normal: // fall through to default - default: return THREAD_PRIORITY_NORMAL; - } - } - } // namespace anon -#endif // XPLATFORMTHREADS_WINDOWS - - - - void SetMyThreadPriority(ThreadPriority pri) - { -#if XPLATFORMTHREADS_WINDOWS - ::SetThreadPriority(::GetCurrentThread(), WinThreadPriority(pri)); -#endif // XPLATFORMTHREADS_WINDOWS -#if XPLATFORMTHREADS_POSIX - const POSIXThreadPriority posixpri(pri); - sched_param sparam; - ::memset(&sparam, 0, sizeof(sparam)); - sparam.sched_priority = posixpri.m_SchedPriority; -#if defined(__linux__) - ::sched_setscheduler(0, posixpri.m_SchedPolicy, &sparam); // linux uses this function instead of pthread_ -#else - pthread_setschedparam(pthread_self(), posixpri.m_SchedPolicy, &sparam); -#endif -#endif // XPLATFORMTHREADS_POSIX - } - - - struct ThreadWrapperData - { - ThreadFunction *func; - ThreadFunctionArgument arg; - }; - -#if XPLATFORMTHREADS_WINDOWS - static unsigned int __stdcall ThreadWrapper(void * arg) - { - register ThreadWrapperData *twd = reinterpret_cast<ThreadWrapperData*>(arg); - ThreadFunction *func=twd->func; - ThreadFunctionArgument farg=twd->arg; - delete twd; - return DWORD(func(farg)); - } -#elif XPLATFORMTHREADS_POSIX - static void * ThreadWrapper(void *arg) - { - register ThreadWrapperData *twd = reinterpret_cast<ThreadWrapperData*>(arg); - ThreadFunction *func=twd->func; - ThreadFunctionArgument farg=twd->arg; - delete twd; - return reinterpret_cast<void*>(func(farg)); - } - typedef void*(ThreadWrapperFunction)(void*); - - static ThreadWrapperFunction *ThunkedThreadWrapper = ThreadWrapper; - -#endif // OS switch - - - - - - class ThreadHandle::OSDependent - { - public: - static void StartThread(ThreadWrapperData *, ThreadHandle &, ThreadPriority); - static bool KillThread(ThreadHandle); - static bool JoinThread(ThreadHandle, ThreadFunctionReturnType*); - static void Close(ThreadHandle); -#if XPLATFORMTHREADS_WINDOWS - static inline uintptr_t from_oshandle(HANDLE h) { return reinterpret_cast<uintptr_t>(h); } - static inline HANDLE to_oshandle(uintptr_t h) { return reinterpret_cast<HANDLE>(h); } -#elif XPLATFORMTHREADS_POSIX - static inline uintptr_t from_oshandle(pthread_t pt) { return uintptr_t(pt); } - static inline pthread_t to_oshandle(uintptr_t h) { return pthread_t(h); } -#endif // OS switch - }; - -#if XPLATFORMTHREADS_WINDOWS - const ThreadHandle ThreadHandle::Invalid(OSDependent::from_oshandle(INVALID_HANDLE_VALUE)); -#elif XPLATFORMTHREADS_POSIX - const ThreadHandle ThreadHandle::Invalid(OSDependent::from_oshandle(0)); -#endif // OS switch - - inline void ThreadHandle::OSDependent::StartThread(ThreadWrapperData *ptwdata, ThreadHandle &th, ThreadPriority pri) - { -#if XPLATFORMTHREADS_WINDOWS - uintptr_t h = ::_beginthreadex( - 0, // no security attributes, not inheritable - 0, // default stack size - ThreadWrapper, // function to call - (void*)(ptwdata), // argument for function - 0, // creation flags - 0 // where to store thread ID - ); - - if (h) - { - th.m_oshandle = h; - if (pri!=ThreadPriority::Normal) - ::SetThreadPriority(to_oshandle(h), WinThreadPriority(pri)); - } - else - th=Invalid; -#elif XPLATFORMTHREADS_POSIX - pthread_attr_t my_thread_attr, *pmy_thread_attr = 0; - sched_param my_schedparam; - - if (pri!=ThreadPriority::Normal) - { - pmy_thread_attr = &my_thread_attr; - - const POSIXThreadPriority posixpriority(pri); - int result; - result = pthread_attr_init (pmy_thread_attr); - result = pthread_attr_setschedpolicy(pmy_thread_attr, posixpriority.m_SchedPolicy); - - memset(&my_schedparam, 0, sizeof(my_schedparam)); - my_schedparam.sched_priority = posixpriority.m_SchedPriority; - result = pthread_attr_setschedparam(pmy_thread_attr, &my_schedparam); - } - - pthread_t pt; - int anyerr = pthread_create( - &pt, // variable for thread handle - pmy_thread_attr, // default attributes - ThunkedThreadWrapper, - ptwdata - ); - - if (anyerr) - th=Invalid; - else - th.m_oshandle = OSDependent::from_oshandle(pt); -#endif - } - - inline bool ThreadHandle::OSDependent::KillThread(ThreadHandle h) - { -#if XPLATFORMTHREADS_WINDOWS - return ::TerminateThread(to_oshandle(h.m_oshandle), (DWORD)-1) != 0; -#elif XPLATFORMTHREADS_POSIX - return pthread_cancel(to_oshandle(h.m_oshandle)) == 0; -#endif - } - - bool ThreadHandle::OSDependent::JoinThread(ThreadHandle h, ThreadFunctionReturnType *pretval) - { -#if XPLATFORMTHREADS_WINDOWS - const bool kbReturnedOk = (WAIT_OBJECT_0 == ::WaitForSingleObject(OSDependent::to_oshandle(h.m_oshandle), INFINITE)); - if (kbReturnedOk && pretval) - { - DWORD dwExitCode; - ::GetExitCodeThread(to_oshandle(h.m_oshandle), &dwExitCode); - *pretval = (ThreadFunctionReturnType)(dwExitCode); - } - return kbReturnedOk; -#endif -#if XPLATFORMTHREADS_POSIX - ThreadFunctionReturnType ptrExitCode = 0; - int join_return_code = pthread_join(to_oshandle(h.m_oshandle), (void**)ptrExitCode); - const bool kbReturnedOk = (0 == join_return_code); - if (0 != pretval) - { - *pretval = ptrExitCode; - } - return kbReturnedOk; -#endif - } - -#if XPLATFORMTHREADS_WINDOWS - inline void ThreadHandle::OSDependent::Close(ThreadHandle h) - { - ::CloseHandle(OSDependent::to_oshandle(h.m_oshandle)); - } -#endif // XPLATFORMTHREADS_WINDOWS -#if XPLATFORMTHREADS_POSIX - inline void ThreadHandle::OSDependent::Close(ThreadHandle) {} -#endif // XPLATFORMTHREADS_POSIX - - //********************************************************************************************** - - class WCThreadRef::OSDependent - { - public: - static void GetCurrentThreadRef(WCThreadRef& tid); -#if XPLATFORMTHREADS_WINDOWS - static inline uintptr_t from_os(DWORD thread_id) { return (uintptr_t)(thread_id); } - static inline DWORD to_os(uintptr_t thread_id) { return (DWORD)(thread_id); } -#elif XPLATFORMTHREADS_POSIX - static inline uintptr_t from_os(pthread_t thread_id) { return (uintptr_t)(thread_id); } - static inline pthread_t to_os(uintptr_t thread_id) { return pthread_t(thread_id); } -#endif // OS switch - }; - - //********************************************************************************************** - inline void WCThreadRef::OSDependent::GetCurrentThreadRef(WCThreadRef& tid) - { -#if XPLATFORMTHREADS_WINDOWS - DWORD thread_id = ::GetCurrentThreadId(); - tid.m_osThreadRef = OSDependent::from_os(thread_id); - -#elif XPLATFORMTHREADS_POSIX - pthread_t thread_id = ::pthread_self(); - tid.m_osThreadRef = OSDependent::from_os(thread_id); - -#endif // OS switch - } - - //********************************************************************************************** - - ThreadHandle StartThread(ThreadFunction func, ThreadFunctionArgument arg, ThreadPriority thpri) - { - EnsureThreadingInitialized(); - ThreadWrapperData *ptwdata = new ThreadWrapperData; - ptwdata->func = func; - ptwdata->arg = arg; - ThreadHandle thToReturn; - ThreadHandle::OSDependent::StartThread(ptwdata, thToReturn, thpri); - return thToReturn; - } - - bool KillThread(ThreadHandle h) - { - EnsureThreadingInitialized(); - return ThreadHandle::OSDependent::KillThread(h); - } - - bool JoinThread(ThreadHandle h, ThreadFunctionReturnType *pretval) - { - EnsureThreadingInitialized(); - return ThreadHandle::OSDependent::JoinThread(h, pretval); - } - - void Close(ThreadHandle h) - { - EnsureThreadingInitialized(); - return ThreadHandle::OSDependent::Close(h); - } - - //******************************************************************************************* - - WCThreadRef GetCurrentThreadRef() - { - EnsureThreadingInitialized(); // Is it necessary? - WCThreadRef tRefToReturn; - WCThreadRef::OSDependent::GetCurrentThreadRef(tRefToReturn); - return tRefToReturn; - } - - //******************************************************************************************* - - bool IsThreadExists(const WCThreadRef& threadRef) - { -#if XPLATFORMTHREADS_WINDOWS - DWORD dwThreadId = WCThreadRef::OSDependent::to_os((uintptr_t)threadRef); - HANDLE handle = ::OpenThread(SYNCHRONIZE, // dwDesiredAccess - use of the thread handle in any of the wait functions - FALSE, // bInheritHandle - processes do not inherit this handle - dwThreadId); - - // Now we have the handle, check if the associated thread exists: - DWORD retVal = WaitForSingleObject(handle, 0); - if (retVal == WAIT_FAILED) - return false; // the thread does not exists - else - return true; // the thread exists - -#elif XPLATFORMTHREADS_POSIX - pthread_t pthreadRef = WCThreadRef::OSDependent::to_os((uintptr_t)threadRef); - int retVal = pthread_kill(pthreadRef, 0); // send a signal to the thread, but do nothing - if (retVal == ESRCH) - return false; // the thread does not exists - else - return true; // the thread exists - -#endif // OS switch - } - - //******************************************************************************************* - - bool operator==(const WCThreadRef& first, const WCThreadRef& second) - { - return (first.m_osThreadRef == second.m_osThreadRef); - } - - bool operator!=(const WCThreadRef& first, const WCThreadRef& second) - { - return (first.m_osThreadRef != second.m_osThreadRef); - } - - bool operator<(const WCThreadRef& first, const WCThreadRef& second) - { - return (first.m_osThreadRef < second.m_osThreadRef); - } - - bool operator>(const WCThreadRef& first, const WCThreadRef& second) - { - return (first.m_osThreadRef > second.m_osThreadRef); - } - - bool WCAtomicLock::obtain(const uint32_t in_num_trys) - { - bool retVal = false; - - uint32_t timeOut = in_num_trys; - while (true) - { - retVal = g_atomic_int_compare_and_exchange(&m_the_lock, gint(0), gint(1)); - if (retVal) - { - break; - } - else - { - if (--timeOut == 0) - { - break; - } - sleep_milliseconds(1000); - } - } - - return retVal; - } - - void WCAtomicLock::release() - { - m_the_lock = 0; - } - -} // namespace wvThread -} // namespace wvNS { - |