[redcode/crythread-2nd-pass] removed CrySimpleThread and related code
Signed-off-by: AMZN-ScottR <24445312+AMZN-ScottR@users.noreply.github.com>
This commit is contained in:
@@ -85,81 +85,6 @@ public:
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
typedef CryAutoLock<CryCriticalSection> CryAutoCriticalSection;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Threads.
|
||||
|
||||
// Base class for runnable objects.
|
||||
//
|
||||
// A runnable is an object with a Run() and a Cancel() method. The Run()
|
||||
// method should perform the runnable's job. The Cancel() method may be
|
||||
// called by another thread requesting early termination of the Run() method.
|
||||
// The runnable may ignore the Cancel() call, the default implementation of
|
||||
// Cancel() does nothing.
|
||||
class CryRunnable
|
||||
{
|
||||
public:
|
||||
virtual ~CryRunnable() { }
|
||||
virtual void Run() = 0;
|
||||
virtual void Cancel() { }
|
||||
};
|
||||
|
||||
// Class holding information about a thread.
|
||||
//
|
||||
// A reference to the thread information can be obtained by calling GetInfo()
|
||||
// on the CrySimpleThread (or derived class) instance.
|
||||
//
|
||||
// NOTE:
|
||||
// If the code is compiled with NO_THREADINFO defined, then the GetInfo()
|
||||
// method will return a reference to a static dummy instance of this
|
||||
// structure. It is currently undecided if NO_THREADINFO will be defined for
|
||||
// release builds!
|
||||
|
||||
struct CryThreadInfo
|
||||
{
|
||||
// The symbolic name of the thread.
|
||||
//
|
||||
// You may set this name directly or through the SetName() method of
|
||||
// CrySimpleThread (or derived class).
|
||||
AZStd::string m_Name;
|
||||
|
||||
|
||||
// A thread identification number.
|
||||
// The number is unique but architecture specific. Do not assume anything
|
||||
// about that number except for being unique.
|
||||
//
|
||||
// This field is filled when the thread is started (i.e. before the Run()
|
||||
// method or thread routine is called). It is advised that you do not
|
||||
// change this number manually.
|
||||
uint32 m_ID;
|
||||
};
|
||||
|
||||
// Simple thread class.
|
||||
//
|
||||
// CrySimpleThread is a simple wrapper around a system thread providing
|
||||
// nothing but system-level functionality of a thread. There are two typical
|
||||
// ways to use a simple thread:
|
||||
//
|
||||
// 1. Derive from the CrySimpleThread class and provide an implementation of
|
||||
// the Run() (and optionally Cancel()) methods.
|
||||
// 2. Specify a runnable object when the thread is started. The default
|
||||
// runnable type is CryRunnable.
|
||||
//
|
||||
// The Runnable class specfied as the template argument must provide Run()
|
||||
// and Cancel() methods compatible with the following signatures:
|
||||
//
|
||||
// void Runnable::Run();
|
||||
// void Runnable::Cancel();
|
||||
//
|
||||
// If the Runnable does not support cancellation, then the Cancel() method
|
||||
// should do nothing.
|
||||
//
|
||||
// The same instance of CrySimpleThread may be used for multiple thread
|
||||
// executions /in sequence/, i.e. it is valid to re-start the thread by
|
||||
// calling Start() after the thread has been joined by calling WaitForThread().
|
||||
template<class Runnable = CryRunnable>
|
||||
class CrySimpleThread;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Include architecture specific code.
|
||||
#if AZ_LEGACY_CRYCOMMON_TRAIT_USE_PTHREADS
|
||||
|
||||
@@ -14,13 +14,6 @@
|
||||
|
||||
#include "CryThread_pthreads.h"
|
||||
|
||||
#if PLATFORM_SUPPORTS_THREADLOCAL
|
||||
THREADLOCAL CrySimpleThreadSelf
|
||||
* CrySimpleThreadSelf::m_Self = NULL;
|
||||
#else
|
||||
TLS_DEFINE(CrySimpleThreadSelf*, g_CrySimpleThreadSelf)
|
||||
#endif
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CryEvent(Timed) implementation
|
||||
|
||||
@@ -12,16 +12,6 @@
|
||||
#include <AzCore/PlatformIncl.h>
|
||||
#include <AzCore/std/parallel/semaphore.h> // for CreateSemaphore
|
||||
|
||||
struct SThreadNameDesc
|
||||
{
|
||||
DWORD dwType;
|
||||
LPCSTR szName;
|
||||
DWORD dwThreadID;
|
||||
DWORD dwFlags;
|
||||
};
|
||||
|
||||
THREADLOCAL CrySimpleThreadSelf* CrySimpleThreadSelf::m_Self = NULL;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CryEvent::CryEvent()
|
||||
{
|
||||
@@ -302,44 +292,3 @@ void CryFastSemaphore::Release()
|
||||
m_Semaphore.Release();
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
CrySimpleThreadSelf::CrySimpleThreadSelf()
|
||||
: m_thread(NULL)
|
||||
, m_threadId(0)
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
void CrySimpleThreadSelf::WaitForThread()
|
||||
{
|
||||
assert(m_thread);
|
||||
PREFAST_ASSUME(m_thread);
|
||||
if (GetCurrentThreadId() != m_threadId)
|
||||
{
|
||||
WaitForSingleObject((HANDLE)m_thread, INFINITE);
|
||||
}
|
||||
}
|
||||
|
||||
CrySimpleThreadSelf::~CrySimpleThreadSelf()
|
||||
{
|
||||
if (m_thread)
|
||||
{
|
||||
CloseHandle(m_thread);
|
||||
}
|
||||
}
|
||||
|
||||
void CrySimpleThreadSelf::StartThread(unsigned (__stdcall * func)(void*), void* argList)
|
||||
{
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#include AZ_RESTRICTED_FILE(CryThreadImpl_windows_h)
|
||||
#endif
|
||||
#if defined(AZ_RESTRICTED_SECTION_IMPLEMENTED)
|
||||
#undef AZ_RESTRICTED_SECTION_IMPLEMENTED
|
||||
#else
|
||||
m_thread = (void*)_beginthreadex(NULL, 0, func, argList, CREATE_SUSPENDED, &m_threadId);
|
||||
#endif
|
||||
assert(m_thread);
|
||||
PREFAST_ASSUME(m_thread);
|
||||
ResumeThread((HANDLE)m_thread);
|
||||
}
|
||||
|
||||
@@ -653,444 +653,4 @@ private:
|
||||
|
||||
typedef CryEventTimed CryEvent;
|
||||
|
||||
#if !PLATFORM_SUPPORTS_THREADLOCAL
|
||||
TLS_DECLARE(class CrySimpleThreadSelf*, g_CrySimpleThreadSelf);
|
||||
#endif
|
||||
|
||||
class CrySimpleThreadSelf
|
||||
{
|
||||
protected:
|
||||
#if PLATFORM_SUPPORTS_THREADLOCAL
|
||||
|
||||
static CrySimpleThreadSelf* GetSelf()
|
||||
{
|
||||
return m_Self;
|
||||
}
|
||||
|
||||
static void SetSelf(CrySimpleThreadSelf* pSelf)
|
||||
{
|
||||
m_Self = pSelf;
|
||||
}
|
||||
private:
|
||||
static THREADLOCAL CrySimpleThreadSelf* m_Self;
|
||||
|
||||
#else
|
||||
|
||||
static CrySimpleThreadSelf* GetSelf()
|
||||
{
|
||||
return TLS_GET(CrySimpleThreadSelf*, g_CrySimpleThreadSelf);
|
||||
}
|
||||
|
||||
static void SetSelf(CrySimpleThreadSelf* pSelf)
|
||||
{
|
||||
TLS_SET(g_CrySimpleThreadSelf, pSelf);
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
template<class Runnable>
|
||||
class CrySimpleThread
|
||||
: public CryRunnable
|
||||
, protected CrySimpleThreadSelf
|
||||
{
|
||||
public:
|
||||
typedef void (* ThreadFunction)(void*);
|
||||
typedef CryRunnable RunnableT;
|
||||
|
||||
const volatile bool& GetStartedState() const { return m_bIsStarted; }
|
||||
|
||||
private:
|
||||
#if !defined(NO_THREADINFO)
|
||||
CryThreadInfo m_Info;
|
||||
#endif
|
||||
pthread_t m_ThreadID;
|
||||
unsigned m_CpuMask;
|
||||
Runnable* m_Runnable;
|
||||
struct
|
||||
{
|
||||
ThreadFunction m_ThreadFunction;
|
||||
void* m_ThreadParameter;
|
||||
} m_ThreadFunction;
|
||||
volatile bool m_bIsStarted;
|
||||
volatile bool m_bIsRunning;
|
||||
|
||||
protected:
|
||||
virtual void Terminate()
|
||||
{
|
||||
// This method must be empty.
|
||||
// Derived classes overriding Terminate() are not required to call this
|
||||
// method.
|
||||
}
|
||||
|
||||
private:
|
||||
#if !defined(NO_THREADINFO)
|
||||
static void SetThreadInfo(CrySimpleThread<Runnable>* self)
|
||||
{
|
||||
pthread_t thread = pthread_self();
|
||||
self->m_Info.m_ID = (uint32)(TRUNCATE_PTR)thread;
|
||||
#if defined(APPLE)
|
||||
pthread_setname_np(self->m_Info.m_Name.c_str());
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
static void SetThreadInfo(CrySimpleThread<Runnable>* self) { }
|
||||
#endif
|
||||
|
||||
static void* PthreadRunRunnable(void* thisPtr)
|
||||
{
|
||||
CrySimpleThread<Runnable>* const self = (CrySimpleThread<Runnable>*)thisPtr;
|
||||
SetSelf(self);
|
||||
self->m_bIsStarted = true;
|
||||
self->m_bIsRunning = true;
|
||||
SetThreadInfo(self);
|
||||
self->m_Runnable->Run();
|
||||
self->m_bIsRunning = false;
|
||||
self->Terminate();
|
||||
SetSelf(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void* PthreadRunThis(void* thisPtr)
|
||||
{
|
||||
CrySimpleThread<Runnable>* const self = (CrySimpleThread<Runnable>*)thisPtr;
|
||||
SetSelf(self);
|
||||
self->m_bIsStarted = true;
|
||||
self->m_bIsRunning = true;
|
||||
SetThreadInfo(self);
|
||||
self->Run();
|
||||
self->m_bIsRunning = false;
|
||||
self->Terminate();
|
||||
SetSelf(NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CrySimpleThread(const CrySimpleThread<Runnable>&);
|
||||
void operator = (const CrySimpleThread<Runnable>&);
|
||||
|
||||
public:
|
||||
CrySimpleThread()
|
||||
: m_CpuMask(0)
|
||||
, m_bIsStarted(false)
|
||||
, m_bIsRunning(false)
|
||||
{
|
||||
m_ThreadFunction.m_ThreadFunction = NULL;
|
||||
m_ThreadFunction.m_ThreadParameter = NULL;
|
||||
#if !defined(NO_THREADINFO)
|
||||
m_Info.m_Name = "<Thread>";
|
||||
m_Info.m_ID = 0;
|
||||
#endif
|
||||
memset(&m_ThreadID, 0, sizeof m_ThreadID);
|
||||
m_Runnable = NULL;
|
||||
}
|
||||
|
||||
virtual ~CrySimpleThread()
|
||||
{
|
||||
if (IsStarted())
|
||||
{
|
||||
// Note: We don't want to cache a pointer to ISystem and/or ILog to
|
||||
// gain more freedom on when the threading classes are used (e.g.
|
||||
// threads may be started very early in the initialization).
|
||||
ISystem* pSystem = GetISystem();
|
||||
ILog* pLog = NULL;
|
||||
if (pSystem != NULL)
|
||||
{
|
||||
pLog = pSystem->GetILog();
|
||||
}
|
||||
if (pLog != NULL)
|
||||
{
|
||||
pLog->LogError("Runaway thread %s", GetName());
|
||||
}
|
||||
Cancel();
|
||||
WaitForThread();
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(NO_THREADINFO)
|
||||
CryThreadInfo& GetInfo() { return m_Info; }
|
||||
const char* GetName()
|
||||
{
|
||||
return m_Info.m_Name.c_str();
|
||||
}
|
||||
|
||||
// Set the name of the called thread.
|
||||
//
|
||||
// WIN32:
|
||||
// If the thread is started, then the VC debugger is informed about the new
|
||||
// thread name. If the thread is not started, then the VC debugger will be
|
||||
// informed lated when the thread is started through one of the Start()
|
||||
// methods.
|
||||
//
|
||||
// If the parameter Name is NULL, then the name of the thread is kept
|
||||
// unchanged. This may be used to sent the current thread name to the VC
|
||||
// debugger.
|
||||
void SetName(const char* Name)
|
||||
{
|
||||
if (Name != NULL)
|
||||
{
|
||||
if (m_ThreadID)
|
||||
{
|
||||
RegisterThreadName(m_ThreadID, Name);
|
||||
}
|
||||
m_Info.m_Name = Name;
|
||||
}
|
||||
#if defined(WIN32)
|
||||
if (IsStarted())
|
||||
{
|
||||
// The VC debugger gets the information about a thread's name through
|
||||
// the exception 0x406D1388.
|
||||
struct
|
||||
{
|
||||
DWORD Type;
|
||||
const char* Name;
|
||||
DWORD ID;
|
||||
DWORD Flags;
|
||||
} Info = { 0x1000, NULL, 0, 0 };
|
||||
Info.ID = (DWORD)m_Info.m_ID;
|
||||
__try
|
||||
{
|
||||
RaiseException(
|
||||
0x406D1388, 0, sizeof Info / sizeof(DWORD), (ULONG_PTR*)&Info);
|
||||
}
|
||||
__except (EXCEPTION_CONTINUE_EXECUTION)
|
||||
{
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
#if !defined(NO_THREADINFO)
|
||||
CryThreadInfo& GetInfo()
|
||||
{
|
||||
static CryThreadInfo dummyInfo = { "<dummy>", 0 };
|
||||
return dummyInfo;
|
||||
}
|
||||
#endif
|
||||
const char* GetName() { return "<dummy>"; }
|
||||
void SetName(const char* Name) { }
|
||||
#endif
|
||||
|
||||
virtual void Run()
|
||||
{
|
||||
// This Run() implementation supports the void StartFunction() method.
|
||||
// However, code using this class (or derived classes) should eventually
|
||||
// be refactored to use one of the other Start() methods. This code will
|
||||
// be removed some day and the default implementation of Run() will be
|
||||
// empty.
|
||||
if (m_ThreadFunction.m_ThreadFunction != NULL)
|
||||
{
|
||||
m_ThreadFunction.m_ThreadFunction(m_ThreadFunction.m_ThreadParameter);
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel the running thread.
|
||||
//
|
||||
// If the thread class is implemented as a derived class of CrySimpleThread,
|
||||
// then the derived class should provide an appropriate implementation for
|
||||
// this method. Calling the base class implementation is _not_ required.
|
||||
//
|
||||
// If the thread was started by specifying a Runnable (template argument),
|
||||
// then the Cancel() call is passed on to the specified runnable.
|
||||
//
|
||||
// If the thread was started using the StartFunction() method, then the
|
||||
// caller must find other means to inform the thread about the cancellation
|
||||
// request.
|
||||
virtual void Cancel()
|
||||
{
|
||||
if (IsStarted() && m_Runnable != NULL)
|
||||
{
|
||||
UnRegisterThreadName(m_ThreadID);
|
||||
m_Runnable->Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Start(Runnable& runnable, unsigned cpuMask = 0, const char* name = NULL, int32 StackSize = (SIMPLE_THREAD_STACK_SIZE_KB * 1024))
|
||||
{
|
||||
#if defined(LARGE_THREAD_STACK)
|
||||
StackSize *= 4;//debug code needs a lot more than profile
|
||||
#endif
|
||||
assert(m_ThreadID == 0);
|
||||
pthread_attr_t threadAttr;
|
||||
pthread_attr_init(&threadAttr);
|
||||
pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_JOINABLE);
|
||||
pthread_attr_setstacksize(&threadAttr, StackSize);
|
||||
if (name)
|
||||
{
|
||||
this->m_Info.m_Name = name;
|
||||
}
|
||||
#if CRYTHREAD_PTHREADS_H_TRAIT_SET_THREAD_NAME
|
||||
threadAttr.name = (char*)name;
|
||||
#endif
|
||||
m_CpuMask = cpuMask;
|
||||
#if defined(PTHREAD_NPTL)
|
||||
if (cpuMask != ~0 && cpuMask != 0)
|
||||
{
|
||||
cpu_set_t cpuSet;
|
||||
CPU_ZERO(&cpuSet);
|
||||
for (int cpu = 0; cpu < sizeof(cpuMask) * 8; ++cpu)
|
||||
{
|
||||
if (cpuMask & (1 << cpu))
|
||||
{
|
||||
CPU_SET(cpu, &cpuSet);
|
||||
}
|
||||
}
|
||||
pthread_attr_setaffinity_np(&threadAttr, sizeof cpuSet, &cpuSet);
|
||||
}
|
||||
#elif defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION CRYTHREAD_PTHREADS_H_SECTION_START_RUNNABLE
|
||||
#include AZ_RESTRICTED_FILE(CryThread_pthreads_h)
|
||||
#endif
|
||||
m_Runnable = &runnable;
|
||||
int err = pthread_create(
|
||||
&m_ThreadID,
|
||||
&threadAttr,
|
||||
PthreadRunRunnable,
|
||||
this);
|
||||
pthread_attr_destroy(&threadAttr);
|
||||
RegisterThreadName(m_ThreadID, name);
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION CRYTHREAD_PTHREADS_H_SECTION_START_RUNNABLE_CPUMASK_POSTCREATE
|
||||
#include AZ_RESTRICTED_FILE(CryThread_pthreads_h)
|
||||
#endif
|
||||
assert(err == 0);
|
||||
}
|
||||
|
||||
virtual void Start(unsigned cpuMask = 0, const char* name = NULL, int32 Priority = THREAD_PRIORITY_NORMAL, int32 StackSize = (SIMPLE_THREAD_STACK_SIZE_KB * 1024))
|
||||
{
|
||||
#if defined(LARGE_THREAD_STACK)
|
||||
StackSize *= 4;//debug code needs a lot more than profile
|
||||
#endif
|
||||
assert(m_ThreadID == 0);
|
||||
pthread_attr_t threadAttr;
|
||||
sched_param schedParam;
|
||||
pthread_attr_init(&threadAttr);
|
||||
pthread_attr_getschedparam(&threadAttr, &schedParam);
|
||||
schedParam.sched_priority = Priority;
|
||||
pthread_attr_setschedparam(&threadAttr, &schedParam);
|
||||
pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_JOINABLE);
|
||||
pthread_attr_setstacksize(&threadAttr, StackSize);
|
||||
if (name)
|
||||
{
|
||||
this->m_Info.m_Name = name;
|
||||
}
|
||||
#if CRYTHREAD_PTHREADS_H_TRAIT_SET_THREAD_NAME
|
||||
threadAttr.name = (char*)name;
|
||||
#endif
|
||||
m_CpuMask = cpuMask;
|
||||
#if defined(PTHREAD_NPTL)
|
||||
if (cpuMask != ~0 && cpuMask != 0)
|
||||
{
|
||||
cpu_set_t cpuSet;
|
||||
CPU_ZERO(&cpuSet);
|
||||
for (int cpu = 0; cpu < sizeof(cpuMask) * 8; ++cpu)
|
||||
{
|
||||
if (cpuMask & (1 << cpu))
|
||||
{
|
||||
CPU_SET(cpu, &cpuSet);
|
||||
}
|
||||
}
|
||||
pthread_attr_setaffinity_np(&threadAttr, sizeof cpuSet, &cpuSet);
|
||||
}
|
||||
#elif defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION CRYTHREAD_PTHREADS_H_SECTION_START_CPUMASK
|
||||
#include AZ_RESTRICTED_FILE(CryThread_pthreads_h)
|
||||
#endif
|
||||
int err = pthread_create(
|
||||
&m_ThreadID,
|
||||
&threadAttr,
|
||||
PthreadRunThis,
|
||||
this);
|
||||
pthread_attr_destroy(&threadAttr);
|
||||
RegisterThreadName(m_ThreadID, name);
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION CRYTHREAD_PTHREADS_H_SECTION_START_CPUMASK_POSTCREATE
|
||||
#include AZ_RESTRICTED_FILE(CryThread_pthreads_h)
|
||||
#endif
|
||||
assert(err == 0);
|
||||
}
|
||||
|
||||
void StartFunction(
|
||||
ThreadFunction threadFunction,
|
||||
void* threadParameter = NULL,
|
||||
unsigned cpuMask = 0
|
||||
)
|
||||
{
|
||||
m_ThreadFunction.m_ThreadFunction = threadFunction;
|
||||
m_ThreadFunction.m_ThreadParameter = threadParameter;
|
||||
Start(cpuMask);
|
||||
}
|
||||
|
||||
static CrySimpleThread<Runnable>* Self()
|
||||
{
|
||||
return reinterpret_cast<CrySimpleThread<Runnable>*>(GetSelf());
|
||||
}
|
||||
|
||||
void Exit()
|
||||
{
|
||||
assert(m_ThreadID == pthread_self());
|
||||
m_bIsRunning = false;
|
||||
Terminate();
|
||||
SetSelf(NULL);
|
||||
pthread_exit(NULL);
|
||||
UnRegisterThreadName(m_ThreadID);
|
||||
}
|
||||
|
||||
void WaitForThread()
|
||||
{
|
||||
if (pthread_self() != m_ThreadID)
|
||||
{
|
||||
int err = pthread_join(m_ThreadID, NULL);
|
||||
assert(err == 0);
|
||||
}
|
||||
m_bIsStarted = false;
|
||||
memset(&m_ThreadID, 0, sizeof m_ThreadID);
|
||||
}
|
||||
|
||||
unsigned SetCpuMask(unsigned cpuMask)
|
||||
{
|
||||
int oldCpuMask = m_CpuMask;
|
||||
if (cpuMask == m_CpuMask)
|
||||
{
|
||||
return oldCpuMask;
|
||||
}
|
||||
m_CpuMask = cpuMask;
|
||||
#if defined(PTHREAD_NPTL)
|
||||
cpu_set_t cpuSet;
|
||||
CPU_ZERO(&cpuSet);
|
||||
if (cpuMask != ~0 && cpuMask != 0)
|
||||
{
|
||||
for (int cpu = 0; cpu < sizeof(cpuMask) * 8; ++cpu)
|
||||
{
|
||||
if (cpuMask & (1 << cpu))
|
||||
{
|
||||
CPU_SET(cpu, &cpuSet);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
CPU_ZERO(&cpuSet);
|
||||
for (int cpu = 0; i < sizeof(cpuSet) * 8; ++cpu)
|
||||
{
|
||||
CPU_SET(cpu, &cpuSet);
|
||||
}
|
||||
}
|
||||
pthread_attr_setaffinity_np(&threadAttr, sizeof cpuSet, &cpuSet);
|
||||
#elif defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION CRYTHREAD_PTHREADS_H_SECTION_SETCPUMASK
|
||||
#include AZ_RESTRICTED_FILE(CryThread_pthreads_h)
|
||||
#endif
|
||||
return oldCpuMask;
|
||||
}
|
||||
|
||||
unsigned GetCpuMask() { return m_CpuMask; }
|
||||
|
||||
void Stop()
|
||||
{
|
||||
m_bIsStarted = false;
|
||||
}
|
||||
|
||||
bool IsStarted() const { return m_bIsStarted; }
|
||||
bool IsRunning() const { return m_bIsRunning; }
|
||||
};
|
||||
|
||||
#include "MemoryAccess.h"
|
||||
|
||||
@@ -179,209 +179,3 @@ private:
|
||||
CrySemaphore m_Semaphore;
|
||||
volatile int32 m_nCounter;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
class CrySimpleThreadSelf
|
||||
{
|
||||
public:
|
||||
CrySimpleThreadSelf();
|
||||
void WaitForThread();
|
||||
virtual ~CrySimpleThreadSelf();
|
||||
protected:
|
||||
void StartThread(unsigned (__stdcall * func)(void*), void* argList);
|
||||
static THREADLOCAL CrySimpleThreadSelf* m_Self;
|
||||
private:
|
||||
CrySimpleThreadSelf(const CrySimpleThreadSelf&);
|
||||
CrySimpleThreadSelf& operator = (const CrySimpleThreadSelf&);
|
||||
protected:
|
||||
void* m_thread;
|
||||
uint32 m_threadId;
|
||||
};
|
||||
|
||||
template<class Runnable>
|
||||
class CrySimpleThread
|
||||
: public CryRunnable
|
||||
, public CrySimpleThreadSelf
|
||||
{
|
||||
public:
|
||||
typedef void (* ThreadFunction)(void*);
|
||||
typedef CryRunnable RunnableT;
|
||||
|
||||
void SetName(const char* Name)
|
||||
{
|
||||
m_name = Name;
|
||||
}
|
||||
const char* GetName() { return m_name; }
|
||||
|
||||
const volatile bool& GetStartedState() const { return m_bIsStarted; }
|
||||
|
||||
private:
|
||||
Runnable* m_Runnable;
|
||||
struct
|
||||
{
|
||||
ThreadFunction m_ThreadFunction;
|
||||
void* m_ThreadParameter;
|
||||
} m_ThreadFunction;
|
||||
volatile bool m_bIsStarted;
|
||||
volatile bool m_bIsRunning;
|
||||
volatile bool m_bCreatedThread;
|
||||
string m_name;
|
||||
|
||||
protected:
|
||||
virtual void Terminate()
|
||||
{
|
||||
// This method must be empty.
|
||||
// Derived classes overriding Terminate() are not required to call this
|
||||
// method.
|
||||
}
|
||||
|
||||
private:
|
||||
static unsigned __stdcall RunRunnable(void* thisPtr)
|
||||
{
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION CRYTHREAD_WINDOWS_H_SECTION_1
|
||||
#include AZ_RESTRICTED_FILE(CryThread_windows_h)
|
||||
#endif
|
||||
CrySimpleThread<Runnable>* const self = (CrySimpleThread<Runnable>*)thisPtr;
|
||||
self->m_bIsStarted = true;
|
||||
self->m_bIsRunning = true;
|
||||
|
||||
self->m_Runnable->Run();
|
||||
self->m_bIsRunning = false;
|
||||
self->m_bCreatedThread = false;
|
||||
self->Terminate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned __stdcall RunThis(void* thisPtr)
|
||||
{
|
||||
#if defined(AZ_RESTRICTED_PLATFORM)
|
||||
#define AZ_RESTRICTED_SECTION CRYTHREAD_WINDOWS_H_SECTION_2
|
||||
#include AZ_RESTRICTED_FILE(CryThread_windows_h)
|
||||
#endif
|
||||
CrySimpleThread<Runnable>* const self = (CrySimpleThread<Runnable>*)thisPtr;
|
||||
self->m_bIsStarted = true;
|
||||
self->m_bIsRunning = true;
|
||||
|
||||
self->Run();
|
||||
self->m_bIsRunning = false;
|
||||
self->m_bCreatedThread = false;
|
||||
self->Terminate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
CrySimpleThread(const CrySimpleThread<Runnable>&);
|
||||
void operator = (const CrySimpleThread<Runnable>&);
|
||||
|
||||
public:
|
||||
CrySimpleThread()
|
||||
: m_bIsStarted(false)
|
||||
, m_bIsRunning(false)
|
||||
, m_bCreatedThread(false)
|
||||
{
|
||||
m_thread = NULL;
|
||||
m_Runnable = NULL;
|
||||
}
|
||||
void* GetHandle() { return m_thread; }
|
||||
|
||||
virtual ~CrySimpleThread()
|
||||
{
|
||||
if (IsStarted())
|
||||
{
|
||||
if (gEnv && gEnv->pLog)
|
||||
{
|
||||
gEnv->pLog->LogError("Runaway thread %p '%s'", m_thread, m_name.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (m_bCreatedThread)
|
||||
{
|
||||
Cancel();
|
||||
WaitForThread();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Run()
|
||||
{
|
||||
// This Run() implementation supports the void StartFunction() method.
|
||||
// However, code using this class (or derived classes) should eventually
|
||||
// be refactored to use one of the other Start() methods. This code will
|
||||
// be removed some day and the default implementation of Run() will be
|
||||
// empty.
|
||||
if (m_ThreadFunction.m_ThreadFunction != NULL)
|
||||
{
|
||||
m_ThreadFunction.m_ThreadFunction(m_ThreadFunction.m_ThreadParameter);
|
||||
}
|
||||
}
|
||||
|
||||
// Cancel the running thread.
|
||||
//
|
||||
// If the thread class is implemented as a derived class of CrySimpleThread,
|
||||
// then the derived class should provide an appropriate implementation for
|
||||
// this method. Calling the base class implementation is _not_ required.
|
||||
//
|
||||
// If the thread was started by specifying a Runnable (template argument),
|
||||
// then the Cancel() call is passed on to the specified runnable.
|
||||
//
|
||||
// If the thread was started using the StartFunction() method, then the
|
||||
// caller must find other means to inform the thread about the cancellation
|
||||
// request.
|
||||
virtual void Cancel()
|
||||
{
|
||||
if (IsStarted() && m_Runnable != NULL)
|
||||
{
|
||||
m_Runnable->Cancel();
|
||||
}
|
||||
}
|
||||
|
||||
virtual void Start(Runnable& runnable, [[maybe_unused]] unsigned cpuMask = 0, const char* = NULL, int32 = 0)
|
||||
{
|
||||
if (m_bCreatedThread)
|
||||
{
|
||||
// Don't start thread more than once!
|
||||
return;
|
||||
}
|
||||
m_Runnable = &runnable;
|
||||
m_bCreatedThread = true;
|
||||
StartThread(RunRunnable, this);
|
||||
}
|
||||
|
||||
virtual void Start([[maybe_unused]] unsigned cpuMask = 0, const char* = NULL, int32 = 0, int32 = 0)
|
||||
{
|
||||
if (m_bCreatedThread)
|
||||
{
|
||||
// Don't start thread more than once!
|
||||
return;
|
||||
}
|
||||
m_bCreatedThread = true;
|
||||
StartThread(RunThis, this);
|
||||
}
|
||||
|
||||
void StartFunction(
|
||||
ThreadFunction threadFunction,
|
||||
void* threadParameter = NULL
|
||||
)
|
||||
{
|
||||
m_ThreadFunction.m_ThreadFunction = threadFunction;
|
||||
m_ThreadFunction.m_ThreadParameter = threadParameter;
|
||||
Start();
|
||||
}
|
||||
|
||||
static CrySimpleThread<Runnable>* Self()
|
||||
{
|
||||
return reinterpret_cast<CrySimpleThread<Runnable>*>(m_Self);
|
||||
}
|
||||
|
||||
void Exit()
|
||||
{
|
||||
assert(!"implemented");
|
||||
}
|
||||
|
||||
void Stop()
|
||||
{
|
||||
m_bIsStarted = false;
|
||||
}
|
||||
|
||||
bool IsStarted() const { return m_bIsStarted; }
|
||||
bool IsRunning() const { return m_bIsRunning; }
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user