Merge pull request #348 from 3kinox/master

GSdx-ogl linux: std::thread
This commit is contained in:
Gregory Hainaut 2014-12-02 22:43:29 +01:00
commit 1f5fe7a1db
2 changed files with 96 additions and 13 deletions

View File

@ -99,9 +99,9 @@ DWORD WINAPI GSThread::StaticThreadProc(void* lpParam)
void* GSThread::StaticThreadProc(void* param) void* GSThread::StaticThreadProc(void* param)
{ {
((GSThread*)param)->ThreadProc(); ((GSThread*)param)->ThreadProc();
#ifndef _STD_THREAD_ // exit is done implicitly by std::thread
pthread_exit(NULL); pthread_exit(NULL);
#endif
return NULL; return NULL;
} }
@ -114,9 +114,13 @@ void GSThread::CreateThread()
m_hThread = ::CreateThread(NULL, 0, StaticThreadProc, (void*)this, 0, &m_ThreadId); m_hThread = ::CreateThread(NULL, 0, StaticThreadProc, (void*)this, 0, &m_ThreadId);
#else #else
#ifdef _STD_THREAD_
t = new thread(StaticThreadProc,(void*)this);
#else
pthread_attr_init(&m_thread_attr); pthread_attr_init(&m_thread_attr);
pthread_create(&m_thread, &m_thread_attr, StaticThreadProc, (void*)this); pthread_create(&m_thread, &m_thread_attr, StaticThreadProc, (void*)this);
#endif
#endif #endif
} }
@ -140,12 +144,19 @@ void GSThread::CloseThread()
} }
#else #else
#ifdef _STD_THREAD_
if(t->joinable())
{
t->join();
}
delete(t);
#else
void* ret = NULL; void* ret = NULL;
pthread_join(m_thread, &ret); pthread_join(m_thread, &ret);
pthread_attr_destroy(&m_thread_attr); pthread_attr_destroy(&m_thread_attr);
#endif
#endif #endif
} }

View File

@ -142,15 +142,25 @@ public:
}; };
#else #else
// let us use std::thread for now, comment out the definition to go back to pthread
#define _STD_THREAD_
#ifdef _STD_THREAD_
#include <thread>
#include <mutex>
#include <condition_variable>
#else
#include <pthread.h> #include <pthread.h>
#include <semaphore.h> #include <semaphore.h>
#endif
class GSThread : public IGSThread class GSThread : public IGSThread
{ {
#ifdef _STD_THREAD_
std::thread *t;
#else
pthread_attr_t m_thread_attr; pthread_attr_t m_thread_attr;
pthread_t m_thread; pthread_t m_thread;
#endif
static void* StaticThreadProc(void* param); static void* StaticThreadProc(void* param);
protected: protected:
@ -164,30 +174,61 @@ public:
class GSCritSec : public IGSLock class GSCritSec : public IGSLock
{ {
#ifdef _STD_THREAD_
recursive_mutex *mutex_critsec;
#else
pthread_mutexattr_t m_mutex_attr; pthread_mutexattr_t m_mutex_attr;
pthread_mutex_t m_mutex; pthread_mutex_t m_mutex;
#endif
public: public:
GSCritSec(bool recursive = true) GSCritSec(bool recursive = true)
{ {
#ifdef _STD_THREAD_
mutex_critsec = new recursive_mutex();
#else
pthread_mutexattr_init(&m_mutex_attr); pthread_mutexattr_init(&m_mutex_attr);
pthread_mutexattr_settype(&m_mutex_attr, recursive ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL); pthread_mutexattr_settype(&m_mutex_attr, recursive ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL);
pthread_mutex_init(&m_mutex, &m_mutex_attr); pthread_mutex_init(&m_mutex, &m_mutex_attr);
#endif
} }
~GSCritSec() ~GSCritSec()
{ {
#ifdef _STD_THREAD_
delete(mutex_critsec);
#else
pthread_mutex_destroy(&m_mutex); pthread_mutex_destroy(&m_mutex);
pthread_mutexattr_destroy(&m_mutex_attr); pthread_mutexattr_destroy(&m_mutex_attr);
#endif
}
#ifdef _STD_THREAD_
void Lock()
{
mutex_critsec->lock();
}
bool TryLock()
{
return mutex_critsec->try_lock();
} }
void Unlock()
{
mutex_critsec->unlock();
}
recursive_mutex& GetMutex() {return ref(*mutex_critsec);}
#else
void Lock() {pthread_mutex_lock(&m_mutex);} void Lock() {pthread_mutex_lock(&m_mutex);}
bool TryLock() {return pthread_mutex_trylock(&m_mutex) == 0;} bool TryLock() {return pthread_mutex_trylock(&m_mutex) == 0;}
void Unlock() {pthread_mutex_unlock(&m_mutex);} void Unlock() {pthread_mutex_unlock(&m_mutex);}
operator pthread_mutex_t* () {return &m_mutex;} operator pthread_mutex_t* () {return &m_mutex;}
#endif
}; };
#ifndef _STD_THREAD_
class GSEvent : public IGSEvent class GSEvent : public IGSEvent
{ {
protected: protected:
@ -200,7 +241,7 @@ public:
void Set() {sem_post(&m_sem);} void Set() {sem_post(&m_sem);}
bool Wait(IGSLock* l) {if(l) l->Unlock(); bool b = sem_wait(&m_sem) == 0; if(l) l->Lock(); return b;} bool Wait(IGSLock* l) {if(l) l->Unlock(); bool b = sem_wait(&m_sem) == 0; if(l) l->Lock(); return b;}
}; };
#endif
class GSCondVarLock : public GSCritSec class GSCondVarLock : public GSCritSec
{ {
public: public:
@ -211,26 +252,54 @@ public:
class GSCondVar : public IGSEvent class GSCondVar : public IGSEvent
{ {
pthread_cond_t m_cv; #ifdef _STD_THREAD_
condition_variable_any *cond_var;
#else
pthread_cond_t m_cv;
pthread_condattr_t m_cv_attr; pthread_condattr_t m_cv_attr;
#endif
public: public:
GSCondVar() GSCondVar()
{ {
#ifdef _STD_THREAD_
cond_var = new condition_variable_any();
#else
pthread_condattr_init(&m_cv_attr); pthread_condattr_init(&m_cv_attr);
pthread_cond_init(&m_cv, &m_cv_attr); pthread_cond_init(&m_cv, &m_cv_attr);
#endif
} }
virtual ~GSCondVar() virtual ~GSCondVar()
{ {
#ifdef _STD_THREAD_
delete(cond_var);
#else
pthread_condattr_destroy(&m_cv_attr); pthread_condattr_destroy(&m_cv_attr);
pthread_cond_destroy(&m_cv); pthread_cond_destroy(&m_cv);
} #endif
}
#ifdef _STD_THREAD_
void Set()
{
cond_var->notify_one();
}
bool Wait(IGSLock* l)
{
cond_var->wait((((GSCondVarLock*)l)->GetMutex())); // Predicate is not useful, it is implicit in the loop
return 1; // Anyway this value is not used(and no way to get it from std::thread)
}
void Set() {pthread_cond_signal(&m_cv);} operator condition_variable_any* () {return cond_var;}
#else
void Set() {pthread_cond_signal(&m_cv);}
bool Wait(IGSLock* l) {return pthread_cond_wait(&m_cv, *(GSCondVarLock*)l) == 0;} bool Wait(IGSLock* l) {return pthread_cond_wait(&m_cv, *(GSCondVarLock*)l) == 0;}
operator pthread_cond_t* () {return &m_cv;} operator pthread_cond_t* () {return &m_cv;}
#endif
}; };
#endif #endif
@ -299,19 +368,22 @@ public:
} }
#endif #endif
#ifndef _STD_THREAD_
if(condvar) if(condvar)
#endif
{ {
m_notempty = new GSCondVar(); m_notempty = new GSCondVar();
m_empty = new GSCondVar(); m_empty = new GSCondVar();
m_lock = new GSCondVarLock(); m_lock = new GSCondVarLock();
} }
#ifndef _STD_THREAD_
else else
{ {
m_notempty = new GSEvent(); m_notempty = new GSEvent();
m_empty = new GSEvent(); m_empty = new GSEvent();
m_lock = new GSCritSec(); m_lock = new GSCritSec();
} }
#endif
CreateThread(); CreateThread();
} }