[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:
AMZN-ScottR
2021-08-09 11:18:38 -07:00
parent 3e7d7d150e
commit 635b9686c6
5 changed files with 0 additions and 779 deletions
-75
View File
@@ -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);
}
-440
View File
@@ -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"
-206
View File
@@ -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; }
};