jthread remove locks that aren't absolutely required
authorsapier <Sapier at GMX dot net>
Fri, 31 Jan 2014 21:16:47 +0000 (22:16 +0100)
committersapier <Sapier at GMX dot net>
Sat, 19 Apr 2014 08:05:23 +0000 (10:05 +0200)
add c++11 atomic support (optional)

src/jthread/jthread.h
src/jthread/pthread/jthread.cpp
src/jthread/win32/jthread.cpp

index f7bce6f9a42400fdf8bc858f8798a7255814abce..89743a3e3857eab100e739f8d63f9ab0ee14fe92 100644 (file)
 */
 
 #ifndef JTHREAD_H
-
 #define JTHREAD_H
 
+#if __cplusplus >= 201103L
+#include <atomic>
+#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;
 };
 
index d818b19edef37018aee9b694fc8e1754ba385acf..a8e54e315467651fb08516b9a4dafbd8168a9368 100644 (file)
@@ -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;
 }
index 6a745c590262b2b15053f998395071cb8c857fac..a1cf91a2c21238424fc5794a30d0081f0c8ca3e3 100755 (executable)
@@ -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;
 }