mirror of https://github.com/PCSX2/pcsx2.git
gsdx: always enable the boost queue
ifdef was for VS2010 GSThread.h is useless. I keep it for the transactional queue implementation
This commit is contained in:
parent
3706cfe908
commit
81e056e79a
|
@ -1234,7 +1234,6 @@ void GSRasterizerList::GSWorker::Process(shared_ptr<GSRasterizerData>& item)
|
|||
}
|
||||
|
||||
// GSRasterizerList::GSWorkerSpin
|
||||
#ifdef ENABLE_BOOST
|
||||
GSRasterizerList::GSWorkerSpin::GSWorkerSpin(GSRasterizer* r)
|
||||
: GSJobQueueSpin<shared_ptr<GSRasterizerData>, 256>()
|
||||
, m_r(r)
|
||||
|
@ -1257,4 +1256,3 @@ void GSRasterizerList::GSWorkerSpin::Process(shared_ptr<GSRasterizerData>& item)
|
|||
{
|
||||
m_r->Draw(item.get());
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -26,11 +26,7 @@
|
|||
#include "GSFunctionMap.h"
|
||||
#include "GSAlignedClass.h"
|
||||
#include "GSPerfMon.h"
|
||||
#ifdef ENABLE_BOOST
|
||||
#include "GSThread_CXX11.h"
|
||||
#else
|
||||
#include "GSThread.h"
|
||||
#endif
|
||||
|
||||
__aligned(class, 32) GSRasterizerData : public GSAlignedClass<32>
|
||||
{
|
||||
|
@ -199,7 +195,6 @@ protected:
|
|||
void Process(shared_ptr<GSRasterizerData>& item);
|
||||
};
|
||||
|
||||
#ifdef ENABLE_BOOST
|
||||
class GSWorkerSpin : public GSJobQueueSpin<shared_ptr<GSRasterizerData>, 256>
|
||||
{
|
||||
GSRasterizer* m_r;
|
||||
|
@ -214,14 +209,9 @@ protected:
|
|||
|
||||
void Process(shared_ptr<GSRasterizerData>& item);
|
||||
};
|
||||
#endif
|
||||
|
||||
GSPerfMon* m_perfmon;
|
||||
#ifdef ENABLE_BOOST
|
||||
vector<IGSJobQueue<shared_ptr<GSRasterizerData> > *> m_workers;
|
||||
#else
|
||||
vector<GSWorker*> m_workers;
|
||||
#endif
|
||||
uint8* m_scanline;
|
||||
|
||||
GSRasterizerList(int threads, GSPerfMon* perfmon);
|
||||
|
@ -243,14 +233,10 @@ public:
|
|||
|
||||
for(int i = 0; i < threads; i++)
|
||||
{
|
||||
#ifdef ENABLE_BOOST
|
||||
if (spin_thread)
|
||||
rl->m_workers.push_back(new GSWorkerSpin(new GSRasterizer(new DS(), i, threads, perfmon)));
|
||||
else
|
||||
rl->m_workers.push_back(new GSWorker(new GSRasterizer(new DS(), i, threads, perfmon)));
|
||||
#else
|
||||
rl->m_workers.push_back(new GSWorker(new GSRasterizer(new DS(), i, threads, perfmon)));
|
||||
#endif
|
||||
}
|
||||
|
||||
return rl;
|
||||
|
|
|
@ -20,59 +20,7 @@
|
|||
*/
|
||||
|
||||
#include "stdafx.h"
|
||||
#ifdef ENABLE_BOOST
|
||||
#include "GSThread_CXX11.h"
|
||||
#else
|
||||
#include "GSThread.h"
|
||||
#endif
|
||||
|
||||
#ifdef _WINDOWS
|
||||
|
||||
#ifndef ENABLE_BOOST
|
||||
InitializeConditionVariablePtr pInitializeConditionVariable;
|
||||
WakeConditionVariablePtr pWakeConditionVariable;
|
||||
WakeAllConditionVariablePtr pWakeAllConditionVariable;
|
||||
SleepConditionVariableSRWPtr pSleepConditionVariableSRW;
|
||||
InitializeSRWLockPtr pInitializeSRWLock;
|
||||
AcquireSRWLockExclusivePtr pAcquireSRWLockExclusive;
|
||||
TryAcquireSRWLockExclusivePtr pTryAcquireSRWLockExclusive;
|
||||
ReleaseSRWLockExclusivePtr pReleaseSRWLockExclusive;
|
||||
AcquireSRWLockSharedPtr pAcquireSRWLockShared;
|
||||
TryAcquireSRWLockSharedPtr pTryAcquireSRWLockShared;
|
||||
ReleaseSRWLockSharedPtr pReleaseSRWLockShared;
|
||||
|
||||
class InitCondVar
|
||||
{
|
||||
HMODULE m_kernel32;
|
||||
|
||||
public:
|
||||
InitCondVar()
|
||||
{
|
||||
m_kernel32 = LoadLibrary("kernel32.dll"); // should not call LoadLibrary from DllMain, but kernel32.dll is the only one guaranteed to be loaded already
|
||||
|
||||
pInitializeConditionVariable = (InitializeConditionVariablePtr)GetProcAddress(m_kernel32, "InitializeConditionVariable");
|
||||
pWakeConditionVariable = (WakeConditionVariablePtr)GetProcAddress(m_kernel32, "WakeConditionVariable");
|
||||
pWakeAllConditionVariable = (WakeAllConditionVariablePtr)GetProcAddress(m_kernel32, "WakeAllConditionVariable");
|
||||
pSleepConditionVariableSRW = (SleepConditionVariableSRWPtr)GetProcAddress(m_kernel32, "SleepConditionVariableSRW");
|
||||
pInitializeSRWLock = (InitializeSRWLockPtr)GetProcAddress(m_kernel32, "InitializeSRWLock");
|
||||
pAcquireSRWLockExclusive = (AcquireSRWLockExclusivePtr)GetProcAddress(m_kernel32, "AcquireSRWLockExclusive");
|
||||
pTryAcquireSRWLockExclusive = (TryAcquireSRWLockExclusivePtr)GetProcAddress(m_kernel32, "TryAcquireSRWLockExclusive");
|
||||
pReleaseSRWLockExclusive = (ReleaseSRWLockExclusivePtr)GetProcAddress(m_kernel32, "ReleaseSRWLockExclusive");
|
||||
pAcquireSRWLockShared = (AcquireSRWLockSharedPtr)GetProcAddress(m_kernel32, "AcquireSRWLockShared");
|
||||
pTryAcquireSRWLockShared = (TryAcquireSRWLockSharedPtr)GetProcAddress(m_kernel32, "TryAcquireSRWLockShared");
|
||||
pReleaseSRWLockShared = (ReleaseSRWLockSharedPtr)GetProcAddress(m_kernel32, "ReleaseSRWLockShared");
|
||||
}
|
||||
|
||||
virtual ~InitCondVar()
|
||||
{
|
||||
FreeLibrary(m_kernel32);
|
||||
}
|
||||
};
|
||||
|
||||
static InitCondVar s_icv;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
GSThread::GSThread()
|
||||
{
|
||||
|
|
|
@ -23,365 +23,6 @@
|
|||
|
||||
#include "GSdx.h"
|
||||
|
||||
class IGSThread
|
||||
{
|
||||
protected:
|
||||
virtual void ThreadProc() = 0;
|
||||
};
|
||||
|
||||
class IGSLock
|
||||
{
|
||||
public:
|
||||
virtual void Lock() = 0;
|
||||
virtual bool TryLock() = 0;
|
||||
virtual void Unlock() = 0;
|
||||
virtual ~IGSLock() {}
|
||||
};
|
||||
|
||||
class IGSEvent
|
||||
{
|
||||
public:
|
||||
virtual void Set() = 0;
|
||||
virtual bool Wait(IGSLock* l) = 0;
|
||||
virtual ~IGSEvent() {}
|
||||
};
|
||||
|
||||
#ifdef _WINDOWS
|
||||
|
||||
typedef void (WINAPI * InitializeConditionVariablePtr)(CONDITION_VARIABLE* ConditionVariable);
|
||||
typedef void (WINAPI * WakeConditionVariablePtr)(CONDITION_VARIABLE* ConditionVariable);
|
||||
typedef void (WINAPI * WakeAllConditionVariablePtr)(CONDITION_VARIABLE* ConditionVariable);
|
||||
typedef BOOL (WINAPI * SleepConditionVariableSRWPtr)(CONDITION_VARIABLE* ConditionVariable, SRWLOCK* SRWLock, DWORD dwMilliseconds, ULONG Flags);
|
||||
typedef void (WINAPI * InitializeSRWLockPtr)(SRWLOCK* SRWLock);
|
||||
typedef void (WINAPI * AcquireSRWLockExclusivePtr)(SRWLOCK* SRWLock);
|
||||
typedef BOOLEAN (WINAPI * TryAcquireSRWLockExclusivePtr)(SRWLOCK* SRWLock);
|
||||
typedef void (WINAPI * ReleaseSRWLockExclusivePtr)(SRWLOCK* SRWLock);
|
||||
typedef void (WINAPI * AcquireSRWLockSharedPtr)(SRWLOCK* SRWLock);
|
||||
typedef BOOLEAN (WINAPI * TryAcquireSRWLockSharedPtr)(SRWLOCK* SRWLock);
|
||||
typedef void (WINAPI * ReleaseSRWLockSharedPtr)(SRWLOCK* SRWLock);
|
||||
|
||||
extern InitializeConditionVariablePtr pInitializeConditionVariable;
|
||||
extern WakeConditionVariablePtr pWakeConditionVariable;
|
||||
extern WakeAllConditionVariablePtr pWakeAllConditionVariable;
|
||||
extern SleepConditionVariableSRWPtr pSleepConditionVariableSRW;
|
||||
extern InitializeSRWLockPtr pInitializeSRWLock;
|
||||
extern AcquireSRWLockExclusivePtr pAcquireSRWLockExclusive;
|
||||
extern TryAcquireSRWLockExclusivePtr pTryAcquireSRWLockExclusive;
|
||||
extern ReleaseSRWLockExclusivePtr pReleaseSRWLockExclusive;
|
||||
extern AcquireSRWLockSharedPtr pAcquireSRWLockShared;
|
||||
extern TryAcquireSRWLockSharedPtr pTryAcquireSRWLockShared;
|
||||
extern ReleaseSRWLockSharedPtr pReleaseSRWLockShared;
|
||||
|
||||
class GSThread : public IGSThread
|
||||
{
|
||||
DWORD m_ThreadId;
|
||||
HANDLE m_hThread;
|
||||
|
||||
static DWORD WINAPI StaticThreadProc(void* lpParam);
|
||||
|
||||
protected:
|
||||
void CreateThread();
|
||||
void CloseThread();
|
||||
|
||||
public:
|
||||
GSThread();
|
||||
virtual ~GSThread();
|
||||
};
|
||||
|
||||
class GSCritSec : public IGSLock
|
||||
{
|
||||
CRITICAL_SECTION m_cs;
|
||||
|
||||
public:
|
||||
GSCritSec() {InitializeCriticalSection(&m_cs);}
|
||||
~GSCritSec() {DeleteCriticalSection(&m_cs);}
|
||||
|
||||
void Lock() {EnterCriticalSection(&m_cs);}
|
||||
bool TryLock() {return TryEnterCriticalSection(&m_cs) == TRUE;}
|
||||
void Unlock() {LeaveCriticalSection(&m_cs);}
|
||||
};
|
||||
|
||||
class GSEvent : public IGSEvent
|
||||
{
|
||||
protected:
|
||||
HANDLE m_hEvent;
|
||||
|
||||
public:
|
||||
GSEvent() {m_hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);}
|
||||
~GSEvent() {CloseHandle(m_hEvent);}
|
||||
|
||||
void Set() {SetEvent(m_hEvent);}
|
||||
bool Wait(IGSLock* l) {if(l) l->Unlock(); bool b = WaitForSingleObject(m_hEvent, INFINITE) == WAIT_OBJECT_0; if(l) l->Lock(); return b;}
|
||||
};
|
||||
|
||||
class GSCondVarLock : public IGSLock
|
||||
{
|
||||
SRWLOCK m_lock;
|
||||
|
||||
public:
|
||||
GSCondVarLock() {pInitializeSRWLock(&m_lock);}
|
||||
|
||||
void Lock() {pAcquireSRWLockExclusive(&m_lock);}
|
||||
bool TryLock() {return pTryAcquireSRWLockExclusive(&m_lock) == TRUE;}
|
||||
void Unlock() {pReleaseSRWLockExclusive(&m_lock);}
|
||||
|
||||
operator SRWLOCK* () {return &m_lock;}
|
||||
};
|
||||
|
||||
class GSCondVar : public IGSEvent
|
||||
{
|
||||
CONDITION_VARIABLE m_cv;
|
||||
|
||||
public:
|
||||
GSCondVar() {pInitializeConditionVariable(&m_cv);}
|
||||
|
||||
void Set() {pWakeConditionVariable(&m_cv);}
|
||||
bool Wait(IGSLock* l) {return pSleepConditionVariableSRW(&m_cv, *(GSCondVarLock*)l, INFINITE, 0) != 0;}
|
||||
|
||||
operator CONDITION_VARIABLE* () {return &m_cv;}
|
||||
};
|
||||
|
||||
#else
|
||||
// let us use std::thread for now, comment out the definition to go back to pthread
|
||||
// There are currently some bugs/limitations to std::thread (see various comment)
|
||||
// For the moment let's keep pthread but uses new std object (mutex, cond_var)
|
||||
//#define _STD_THREAD_
|
||||
#ifdef _STD_THREAD_
|
||||
#include <thread>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#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:
|
||||
void CreateThread();
|
||||
void CloseThread();
|
||||
|
||||
public:
|
||||
GSThread();
|
||||
virtual ~GSThread();
|
||||
};
|
||||
|
||||
class GSCritSec : public IGSLock
|
||||
{
|
||||
// XXX Do we really need a recursive mutex
|
||||
// It would allow to use condition_variable instead of condition_variable_any
|
||||
recursive_mutex *mutex_critsec;
|
||||
|
||||
public:
|
||||
GSCritSec(bool recursive = true)
|
||||
{
|
||||
mutex_critsec = new recursive_mutex();
|
||||
}
|
||||
|
||||
~GSCritSec()
|
||||
{
|
||||
delete(mutex_critsec);
|
||||
}
|
||||
|
||||
void Lock()
|
||||
{
|
||||
mutex_critsec->lock();
|
||||
}
|
||||
|
||||
bool TryLock()
|
||||
{
|
||||
return mutex_critsec->try_lock();
|
||||
}
|
||||
|
||||
void Unlock()
|
||||
{
|
||||
mutex_critsec->unlock();
|
||||
}
|
||||
|
||||
recursive_mutex& GetMutex() {return ref(*mutex_critsec);}
|
||||
};
|
||||
|
||||
class GSCondVarLock : public GSCritSec
|
||||
{
|
||||
public:
|
||||
GSCondVarLock() : GSCritSec(false)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
class GSCondVar : public IGSEvent
|
||||
{
|
||||
condition_variable_any *cond_var;
|
||||
|
||||
public:
|
||||
GSCondVar()
|
||||
{
|
||||
cond_var = new condition_variable_any();
|
||||
}
|
||||
|
||||
virtual ~GSCondVar()
|
||||
{
|
||||
delete(cond_var);
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
operator condition_variable_any* () {return cond_var;}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
class GSAutoLock
|
||||
{
|
||||
IGSLock* m_lock;
|
||||
|
||||
public:
|
||||
GSAutoLock(IGSLock* l) {(m_lock = l)->Lock();}
|
||||
~GSAutoLock() {m_lock->Unlock();}
|
||||
};
|
||||
|
||||
template<class T> class GSJobQueue : private GSThread
|
||||
{
|
||||
protected:
|
||||
queue<T> m_queue;
|
||||
volatile long m_count; // NOTE: it is the safest to have our own counter because m_queue.pop() might decrement its own before the last item runs out of its scope and gets destroyed (implementation dependent)
|
||||
volatile bool m_exit;
|
||||
IGSEvent* m_notempty;
|
||||
IGSEvent* m_empty;
|
||||
IGSLock* m_lock;
|
||||
|
||||
void ThreadProc()
|
||||
{
|
||||
m_lock->Lock();
|
||||
|
||||
while(true)
|
||||
{
|
||||
while(m_queue.empty())
|
||||
{
|
||||
m_notempty->Wait(m_lock);
|
||||
|
||||
if(m_exit) {m_lock->Unlock(); return;}
|
||||
}
|
||||
|
||||
T& item = m_queue.front();
|
||||
|
||||
m_lock->Unlock();
|
||||
|
||||
Process(item);
|
||||
|
||||
m_lock->Lock();
|
||||
|
||||
m_queue.pop();
|
||||
|
||||
if(--m_count == 0)
|
||||
{
|
||||
m_empty->Set();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
GSJobQueue()
|
||||
: m_count(0)
|
||||
, m_exit(false)
|
||||
{
|
||||
bool condvar = true;
|
||||
|
||||
#ifdef _WINDOWS
|
||||
|
||||
if(pInitializeConditionVariable == NULL)
|
||||
{
|
||||
condvar = false;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if(condvar)
|
||||
{
|
||||
m_notempty = new GSCondVar();
|
||||
m_empty = new GSCondVar();
|
||||
m_lock = new GSCondVarLock();
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef _WINDOWS
|
||||
m_notempty = new GSEvent();
|
||||
m_empty = new GSEvent();
|
||||
m_lock = new GSCritSec();
|
||||
#endif
|
||||
}
|
||||
|
||||
CreateThread();
|
||||
}
|
||||
|
||||
virtual ~GSJobQueue()
|
||||
{
|
||||
m_exit = true;
|
||||
|
||||
m_notempty->Set();
|
||||
|
||||
CloseThread();
|
||||
|
||||
delete m_notempty;
|
||||
delete m_empty;
|
||||
delete m_lock;
|
||||
}
|
||||
|
||||
bool IsEmpty() const
|
||||
{
|
||||
ASSERT(m_count >= 0);
|
||||
|
||||
return m_count == 0;
|
||||
}
|
||||
|
||||
void Push(const T& item)
|
||||
{
|
||||
m_lock->Lock();
|
||||
|
||||
m_queue.push(item);
|
||||
|
||||
if(m_count++ == 0)
|
||||
{
|
||||
m_notempty->Set();
|
||||
}
|
||||
|
||||
m_lock->Unlock();
|
||||
}
|
||||
|
||||
void Wait()
|
||||
{
|
||||
if(m_count > 0)
|
||||
{
|
||||
m_lock->Lock();
|
||||
|
||||
while(m_count != 0)
|
||||
{
|
||||
m_empty->Wait(m_lock);
|
||||
}
|
||||
|
||||
ASSERT(m_queue.empty());
|
||||
|
||||
m_lock->Unlock();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Process(T& item) = 0;
|
||||
};
|
||||
|
||||
// http://software.intel.com/en-us/blogs/2012/11/06/exploring-intel-transactional-synchronization-extensions-with-intel-software
|
||||
#if 0
|
||||
class TransactionScope
|
||||
|
|
|
@ -60,11 +60,6 @@
|
|||
|
||||
#endif
|
||||
|
||||
// Require at least Visual Studio 2012
|
||||
#if defined(__linux__) || (defined(_MSC_VER) && (_MSC_VER >= 1700))
|
||||
#define ENABLE_BOOST // queue is from boost but it doesn't require a full boost install
|
||||
#endif
|
||||
|
||||
// put these into vc9/common7/ide/usertype.dat to have them highlighted
|
||||
|
||||
typedef unsigned char uint8;
|
||||
|
|
Loading…
Reference in New Issue