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
|
// GSRasterizerList::GSWorkerSpin
|
||||||
#ifdef ENABLE_BOOST
|
|
||||||
GSRasterizerList::GSWorkerSpin::GSWorkerSpin(GSRasterizer* r)
|
GSRasterizerList::GSWorkerSpin::GSWorkerSpin(GSRasterizer* r)
|
||||||
: GSJobQueueSpin<shared_ptr<GSRasterizerData>, 256>()
|
: GSJobQueueSpin<shared_ptr<GSRasterizerData>, 256>()
|
||||||
, m_r(r)
|
, m_r(r)
|
||||||
|
@ -1257,4 +1256,3 @@ void GSRasterizerList::GSWorkerSpin::Process(shared_ptr<GSRasterizerData>& item)
|
||||||
{
|
{
|
||||||
m_r->Draw(item.get());
|
m_r->Draw(item.get());
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
|
@ -26,11 +26,7 @@
|
||||||
#include "GSFunctionMap.h"
|
#include "GSFunctionMap.h"
|
||||||
#include "GSAlignedClass.h"
|
#include "GSAlignedClass.h"
|
||||||
#include "GSPerfMon.h"
|
#include "GSPerfMon.h"
|
||||||
#ifdef ENABLE_BOOST
|
|
||||||
#include "GSThread_CXX11.h"
|
#include "GSThread_CXX11.h"
|
||||||
#else
|
|
||||||
#include "GSThread.h"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
__aligned(class, 32) GSRasterizerData : public GSAlignedClass<32>
|
__aligned(class, 32) GSRasterizerData : public GSAlignedClass<32>
|
||||||
{
|
{
|
||||||
|
@ -199,7 +195,6 @@ protected:
|
||||||
void Process(shared_ptr<GSRasterizerData>& item);
|
void Process(shared_ptr<GSRasterizerData>& item);
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef ENABLE_BOOST
|
|
||||||
class GSWorkerSpin : public GSJobQueueSpin<shared_ptr<GSRasterizerData>, 256>
|
class GSWorkerSpin : public GSJobQueueSpin<shared_ptr<GSRasterizerData>, 256>
|
||||||
{
|
{
|
||||||
GSRasterizer* m_r;
|
GSRasterizer* m_r;
|
||||||
|
@ -214,14 +209,9 @@ protected:
|
||||||
|
|
||||||
void Process(shared_ptr<GSRasterizerData>& item);
|
void Process(shared_ptr<GSRasterizerData>& item);
|
||||||
};
|
};
|
||||||
#endif
|
|
||||||
|
|
||||||
GSPerfMon* m_perfmon;
|
GSPerfMon* m_perfmon;
|
||||||
#ifdef ENABLE_BOOST
|
|
||||||
vector<IGSJobQueue<shared_ptr<GSRasterizerData> > *> m_workers;
|
vector<IGSJobQueue<shared_ptr<GSRasterizerData> > *> m_workers;
|
||||||
#else
|
|
||||||
vector<GSWorker*> m_workers;
|
|
||||||
#endif
|
|
||||||
uint8* m_scanline;
|
uint8* m_scanline;
|
||||||
|
|
||||||
GSRasterizerList(int threads, GSPerfMon* perfmon);
|
GSRasterizerList(int threads, GSPerfMon* perfmon);
|
||||||
|
@ -243,14 +233,10 @@ public:
|
||||||
|
|
||||||
for(int i = 0; i < threads; i++)
|
for(int i = 0; i < threads; i++)
|
||||||
{
|
{
|
||||||
#ifdef ENABLE_BOOST
|
|
||||||
if (spin_thread)
|
if (spin_thread)
|
||||||
rl->m_workers.push_back(new GSWorkerSpin(new GSRasterizer(new DS(), i, threads, perfmon)));
|
rl->m_workers.push_back(new GSWorkerSpin(new GSRasterizer(new DS(), i, threads, perfmon)));
|
||||||
else
|
else
|
||||||
rl->m_workers.push_back(new GSWorker(new GSRasterizer(new DS(), i, threads, perfmon)));
|
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;
|
return rl;
|
||||||
|
|
|
@ -20,59 +20,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
#ifdef ENABLE_BOOST
|
|
||||||
#include "GSThread_CXX11.h"
|
#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()
|
GSThread::GSThread()
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,365 +23,6 @@
|
||||||
|
|
||||||
#include "GSdx.h"
|
#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
|
// http://software.intel.com/en-us/blogs/2012/11/06/exploring-intel-transactional-synchronization-extensions-with-intel-software
|
||||||
#if 0
|
#if 0
|
||||||
class TransactionScope
|
class TransactionScope
|
||||||
|
|
|
@ -60,11 +60,6 @@
|
||||||
|
|
||||||
#endif
|
#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
|
// put these into vc9/common7/ide/usertype.dat to have them highlighted
|
||||||
|
|
||||||
typedef unsigned char uint8;
|
typedef unsigned char uint8;
|
||||||
|
|
Loading…
Reference in New Issue