From 732cbc3ad5c43bb2cf41f91a2e0b94d5dc589275 Mon Sep 17 00:00:00 2001 From: 3kinox Date: Tue, 18 Nov 2014 14:40:29 +0100 Subject: [PATCH] GSDX-ogl linux: + Implement threads/mutex using std::thread/std::mutex/std::condition_variable + Old implementation can be used by commenting out the "define _STD_THREAD_ in GSThread.h + Commit should be much cleaner than previous one. --- plugins/GSdx/GSThread.cpp | 21 +++++++--- plugins/GSdx/GSThread.h | 88 +++++++++++++++++++++++++++++++++++---- 2 files changed, 96 insertions(+), 13 deletions(-) diff --git a/plugins/GSdx/GSThread.cpp b/plugins/GSdx/GSThread.cpp index 976d8ea211..aee2cd5fd9 100644 --- a/plugins/GSdx/GSThread.cpp +++ b/plugins/GSdx/GSThread.cpp @@ -99,9 +99,9 @@ DWORD WINAPI GSThread::StaticThreadProc(void* lpParam) void* GSThread::StaticThreadProc(void* param) { ((GSThread*)param)->ThreadProc(); - +#ifndef _STD_THREAD_ // exit is done implicitly by std::thread pthread_exit(NULL); - +#endif return NULL; } @@ -114,9 +114,13 @@ void GSThread::CreateThread() m_hThread = ::CreateThread(NULL, 0, StaticThreadProc, (void*)this, 0, &m_ThreadId); #else - + + #ifdef _STD_THREAD_ + t = new thread(StaticThreadProc,(void*)this); + #else pthread_attr_init(&m_thread_attr); pthread_create(&m_thread, &m_thread_attr, StaticThreadProc, (void*)this); + #endif #endif } @@ -140,12 +144,19 @@ void GSThread::CloseThread() } #else - + + #ifdef _STD_THREAD_ + if(t->joinable()) + { + t->join(); + } + delete(t); + #else void* ret = NULL; pthread_join(m_thread, &ret); pthread_attr_destroy(&m_thread_attr); - + #endif #endif } diff --git a/plugins/GSdx/GSThread.h b/plugins/GSdx/GSThread.h index 03faadee74..519c0c16ec 100644 --- a/plugins/GSdx/GSThread.h +++ b/plugins/GSdx/GSThread.h @@ -142,15 +142,25 @@ public: }; #else - +// let us use std::thread for now, comment out the definition to go back to pthread +#define _STD_THREAD_ +#ifdef _STD_THREAD_ +#include +#include +#include +#else #include #include +#endif class GSThread : public IGSThread { + #ifdef _STD_THREAD_ + std::thread *t; + #else pthread_attr_t m_thread_attr; pthread_t m_thread; - + #endif static void* StaticThreadProc(void* param); protected: @@ -164,30 +174,61 @@ public: class GSCritSec : public IGSLock { + #ifdef _STD_THREAD_ + recursive_mutex *mutex_critsec; + #else pthread_mutexattr_t m_mutex_attr; pthread_mutex_t m_mutex; + #endif public: GSCritSec(bool recursive = true) { + #ifdef _STD_THREAD_ + mutex_critsec = new recursive_mutex(); + #else pthread_mutexattr_init(&m_mutex_attr); pthread_mutexattr_settype(&m_mutex_attr, recursive ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL); pthread_mutex_init(&m_mutex, &m_mutex_attr); + #endif } ~GSCritSec() { + #ifdef _STD_THREAD_ + delete(mutex_critsec); + #else pthread_mutex_destroy(&m_mutex); 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);} bool TryLock() {return pthread_mutex_trylock(&m_mutex) == 0;} void Unlock() {pthread_mutex_unlock(&m_mutex);} operator pthread_mutex_t* () {return &m_mutex;} + #endif }; - +#ifndef _STD_THREAD_ class GSEvent : public IGSEvent { protected: @@ -200,7 +241,7 @@ public: 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;} }; - +#endif class GSCondVarLock : public GSCritSec { public: @@ -211,26 +252,54 @@ public: 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; + #endif public: GSCondVar() { + #ifdef _STD_THREAD_ + cond_var = new condition_variable_any(); + #else pthread_condattr_init(&m_cv_attr); pthread_cond_init(&m_cv, &m_cv_attr); + #endif } virtual ~GSCondVar() { + #ifdef _STD_THREAD_ + delete(cond_var); + #else pthread_condattr_destroy(&m_cv_attr); 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;} operator pthread_cond_t* () {return &m_cv;} + #endif }; #endif @@ -299,19 +368,22 @@ public: } #endif - + #ifndef _STD_THREAD_ if(condvar) + #endif { m_notempty = new GSCondVar(); m_empty = new GSCondVar(); m_lock = new GSCondVarLock(); } + #ifndef _STD_THREAD_ else { m_notempty = new GSEvent(); m_empty = new GSEvent(); m_lock = new GSCritSec(); } + #endif CreateThread(); }