From ea0df3e4cb75a7a104a81e050c019049219c4fee Mon Sep 17 00:00:00 2001 From: sapier Date: Fri, 31 Jan 2014 22:16:47 +0100 Subject: [PATCH] jthread remove locks that aren't absolutely required add c++11 atomic support (optional) --- src/jthread/jthread.h | 38 ++++++++++++++++++--- src/jthread/pthread/jthread.cpp | 58 +++------------------------------ src/jthread/win32/jthread.cpp | 52 ++--------------------------- 3 files changed, 39 insertions(+), 109 deletions(-) diff --git a/src/jthread/jthread.h b/src/jthread/jthread.h index f7bce6f9..89743a3e 100644 --- a/src/jthread/jthread.h +++ b/src/jthread/jthread.h @@ -26,9 +26,12 @@ */ #ifndef JTHREAD_H - #define JTHREAD_H +#if __cplusplus >= 201103L +#include +#endif + #include "jthread/jmutex.h" #define ERR_JTHREAD_CANTINITMUTEX -1 @@ -43,11 +46,14 @@ public: JThread(); virtual ~JThread(); int Start(); - void Stop(); + inline void Stop() + { requeststop = true; } int Kill(); virtual void *Thread() = 0; - bool IsRunning(); - bool StopRequested(); + inline bool IsRunning() + { return running; } + inline bool StopRequested() + { return requeststop; } void *GetReturnValue(); bool IsSameThread(); @@ -75,13 +81,35 @@ private: pthread_t threadid; + /* + * reading and writing bool values is atomic on all relevant architectures + * ( x86 + arm ). No need to waste time for locking here. + * once C++11 is supported we can tell compiler to handle cpu caches correct + * too. This should cause additional improvement (and silence thread + * concurrency check tools. + */ +#if __cplusplus >= 201103L + std::atomic_bool started; +#else bool started; +#endif #endif // WIN32 void *retval; + /* + * reading and writing bool values is atomic on all relevant architectures + * ( x86 + arm ). No need to waste time for locking here. + * once C++11 is supported we can tell compiler to handle cpu caches correct + * too. This should cause additional improvement (and silence thread + * concurrency check tools. + */ +#if __cplusplus >= 201103L + std::atomic_bool running; + std::atomic_bool requeststop; +#else bool running; bool requeststop; +#endif - JMutex runningmutex; JMutex continuemutex,continuemutex2; }; diff --git a/src/jthread/pthread/jthread.cpp b/src/jthread/pthread/jthread.cpp index d818b19e..a8e54e31 100644 --- a/src/jthread/pthread/jthread.cpp +++ b/src/jthread/pthread/jthread.cpp @@ -46,38 +46,25 @@ JThread::~JThread() Kill(); } -void JThread::Stop() { - runningmutex.Lock(); - requeststop = true; - runningmutex.Unlock(); -} - void JThread::Wait() { void* status; - runningmutex.Lock(); if (started) { - runningmutex.Unlock(); int pthread_join_retval = pthread_join(threadid,&status); assert(pthread_join_retval == 0); UNUSED(pthread_join_retval); - runningmutex.Lock(); started = false; } - runningmutex.Unlock(); } int JThread::Start() { int status; - runningmutex.Lock(); if (running) { - runningmutex.Unlock(); return ERR_JTHREAD_ALREADYRUNNING; } requeststop = false; - runningmutex.Unlock(); pthread_attr_t attr; pthread_attr_init(&attr); @@ -94,21 +81,15 @@ int JThread::Start() /* Wait until 'running' is set */ - runningmutex.Lock(); while (!running) { - runningmutex.Unlock(); - struct timespec req,rem; req.tv_sec = 0; req.tv_nsec = 1000000; nanosleep(&req,&rem); - - runningmutex.Lock(); } started = true; - runningmutex.Unlock(); continuemutex.Unlock(); @@ -120,63 +101,37 @@ int JThread::Start() int JThread::Kill() { void* status; - runningmutex.Lock(); if (!running) { if (started) { - runningmutex.Unlock(); int pthread_join_retval = pthread_join(threadid,&status); assert(pthread_join_retval == 0); UNUSED(pthread_join_retval); - runningmutex.Lock(); started = false; } - runningmutex.Unlock(); return ERR_JTHREAD_NOTRUNNING; } pthread_cancel(threadid); if (started) { - runningmutex.Unlock(); int pthread_join_retval = pthread_join(threadid,&status); assert(pthread_join_retval == 0); UNUSED(pthread_join_retval); - runningmutex.Lock(); started = false; } running = false; - runningmutex.Unlock(); return 0; } -bool JThread::IsRunning() -{ - bool r; - - runningmutex.Lock(); - r = running; - runningmutex.Unlock(); - return r; -} - -bool JThread::StopRequested() { - bool r; - - runningmutex.Lock(); - r = requeststop; - runningmutex.Unlock(); - return r; -} - void *JThread::GetReturnValue() { void *val; - runningmutex.Lock(); - if (running) + if (running) { val = NULL; - else + } else { val = retval; - runningmutex.Unlock(); + } + return val; } @@ -193,19 +148,14 @@ void *JThread::TheThread(void *param) jthread = (JThread *)param; jthread->continuemutex2.Lock(); - jthread->runningmutex.Lock(); jthread->running = true; - jthread->runningmutex.Unlock(); jthread->continuemutex.Lock(); jthread->continuemutex.Unlock(); ret = jthread->Thread(); - jthread->runningmutex.Lock(); jthread->running = false; - jthread->retval = ret; - jthread->runningmutex.Unlock(); return NULL; } diff --git a/src/jthread/win32/jthread.cpp b/src/jthread/win32/jthread.cpp index 6a745c59..a1cf91a2 100755 --- a/src/jthread/win32/jthread.cpp +++ b/src/jthread/win32/jthread.cpp @@ -44,35 +44,20 @@ JThread::~JThread() Kill(); } -void JThread::Stop() { - runningmutex.Lock(); - requeststop = true; - runningmutex.Unlock(); -} - void JThread::Wait() { - runningmutex.Lock(); if (running) { - runningmutex.Unlock(); WaitForSingleObject(threadhandle, INFINITE); } - else - { - runningmutex.Unlock(); - } } int JThread::Start() { - runningmutex.Lock(); if (running) { - runningmutex.Unlock(); return ERR_JTHREAD_ALREADYRUNNING; } requeststop = false; - runningmutex.Unlock(); continuemutex.Lock(); #ifndef _WIN32_WCE @@ -87,15 +72,10 @@ int JThread::Start() } /* Wait until 'running' is set */ - - runningmutex.Lock(); while (!running) { - runningmutex.Unlock(); Sleep(1); - runningmutex.Lock(); } - runningmutex.Unlock(); continuemutex.Unlock(); @@ -107,48 +87,24 @@ int JThread::Start() int JThread::Kill() { - runningmutex.Lock(); if (!running) { - runningmutex.Unlock(); return ERR_JTHREAD_NOTRUNNING; } TerminateThread(threadhandle,0); CloseHandle(threadhandle); running = false; - runningmutex.Unlock(); return 0; } -bool JThread::IsRunning() -{ - bool r; - - runningmutex.Lock(); - r = running; - runningmutex.Unlock(); - return r; -} - -bool JThread::StopRequested() { - bool r; - - runningmutex.Lock(); - r = requeststop; - runningmutex.Unlock(); - return r; -} - void *JThread::GetReturnValue() { void *val; - runningmutex.Lock(); - if (running) + if (running) { val = NULL; - else + } else { val = retval; - runningmutex.Unlock(); return val; } @@ -169,20 +125,16 @@ DWORD WINAPI JThread::TheThread(void *param) jthread = (JThread *)param; jthread->continuemutex2.Lock(); - jthread->runningmutex.Lock(); jthread->running = true; - jthread->runningmutex.Unlock(); jthread->continuemutex.Lock(); jthread->continuemutex.Unlock(); ret = jthread->Thread(); - jthread->runningmutex.Lock(); jthread->running = false; jthread->retval = ret; CloseHandle(jthread->threadhandle); - jthread->runningmutex.Unlock(); return 0; } -- 2.30.2