jthread remove locks that aren't absolutely required
add c++11 atomic support (optional)
This commit is contained in:
parent
c00ed9dac3
commit
ea0df3e4cb
|
@ -26,9 +26,12 @@
|
|||
*/
|
||||
|
||||
#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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue