eathread_thread.cpp 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262
  1. ///////////////////////////////////////////////////////////////////////////////
  2. // Copyright (c) Electronic Arts Inc. All rights reserved.
  3. ///////////////////////////////////////////////////////////////////////////////
  4. #include <eathread/internal/config.h>
  5. #include "eathread/internal/eathread_global.h"
  6. #include <eathread/eathread_thread.h>
  7. #include <eathread/eathread_mutex.h>
  8. #include <new> // include new for placement new operator
  9. #if !EA_THREADS_AVAILABLE
  10. // Do nothing
  11. #elif EA_USE_CPP11_CONCURRENCY
  12. #include "cpp11/eathread_thread_cpp11.cpp"
  13. #elif defined(EA_PLATFORM_SONY)
  14. #include "kettle/eathread_thread_kettle.cpp"
  15. #elif defined(EA_PLATFORM_UNIX) || EA_POSIX_THREADS_AVAILABLE
  16. #include "unix/eathread_thread_unix.cpp"
  17. #elif defined(EA_PLATFORM_MICROSOFT)
  18. #include "pc/eathread_thread_pc.cpp"
  19. #endif
  20. namespace EA
  21. {
  22. namespace Thread
  23. {
  24. extern Allocator* gpAllocator;
  25. }
  26. }
  27. EA::Thread::Thread* EA::Thread::ThreadFactory::CreateThread()
  28. {
  29. if(gpAllocator)
  30. return new(gpAllocator->Alloc(sizeof(EA::Thread::Thread))) EA::Thread::Thread;
  31. else
  32. return new EA::Thread::Thread;
  33. }
  34. void EA::Thread::ThreadFactory::DestroyThread(EA::Thread::Thread* pThread)
  35. {
  36. if(gpAllocator)
  37. {
  38. pThread->~Thread();
  39. gpAllocator->Free(pThread);
  40. }
  41. else
  42. delete pThread;
  43. }
  44. size_t EA::Thread::ThreadFactory::GetThreadSize()
  45. {
  46. return sizeof(EA::Thread::Thread);
  47. }
  48. EA::Thread::Thread* EA::Thread::ThreadFactory::ConstructThread(void* pMemory)
  49. {
  50. return new(pMemory) EA::Thread::Thread;
  51. }
  52. void EA::Thread::ThreadFactory::DestructThread(EA::Thread::Thread* pThread)
  53. {
  54. pThread->~Thread();
  55. }
  56. EA::Thread::ThreadEnumData::ThreadEnumData()
  57. : mpThreadDynamicData(NULL)
  58. {
  59. }
  60. EA::Thread::ThreadEnumData::~ThreadEnumData()
  61. {
  62. Release();
  63. }
  64. void EA::Thread::ThreadEnumData::Release()
  65. {
  66. if(mpThreadDynamicData)
  67. {
  68. mpThreadDynamicData->Release();
  69. mpThreadDynamicData = NULL;
  70. }
  71. }
  72. extern const size_t kMaxThreadDynamicDataCount;
  73. EATHREAD_GLOBALVARS_EXTERN_INSTANCE;
  74. ///////////////////////////////////////////////////////////////////////////////
  75. //
  76. size_t EA::Thread::EnumerateThreads(ThreadEnumData* pDataArray, size_t dataArrayCapacity)
  77. {
  78. size_t requiredCount = 0;
  79. if(dataArrayCapacity > EA::Thread::kMaxThreadDynamicDataCount)
  80. dataArrayCapacity = EA::Thread::kMaxThreadDynamicDataCount;
  81. EATHREAD_GLOBALVARS.gThreadDynamicMutex.Lock();
  82. for(size_t i(0); i < EA::Thread::kMaxThreadDynamicDataCount; i++)
  83. {
  84. if(EATHREAD_GLOBALVARS.gThreadDynamicDataAllocated[i].GetValue() != 0)
  85. {
  86. if(requiredCount < dataArrayCapacity)
  87. {
  88. pDataArray[requiredCount].mpThreadDynamicData = (EAThreadDynamicData*)(void*)EATHREAD_GLOBALVARS.gThreadDynamicData[i];
  89. pDataArray[requiredCount].mpThreadDynamicData->AddRef();
  90. }
  91. requiredCount++;
  92. }
  93. }
  94. EATHREAD_GLOBALVARS.gThreadDynamicMutex.Unlock();
  95. return requiredCount;
  96. }
  97. ///////////////////////////////////////////////////////////////////////////////
  98. // non-threaded implementation
  99. ///////////////////////////////////////////////////////////////////////////////
  100. #if !EA_THREADS_AVAILABLE
  101. // If mulitithreading support is not available, we can't implement anything
  102. // here that works. All we do is define a null implementation that links
  103. // but fails all operations.
  104. EA::Thread::ThreadParameters::ThreadParameters()
  105. : mpStack(NULL),
  106. mnStackSize(0),
  107. mnPriority(kThreadPriorityDefault),
  108. mnProcessor(kProcessorDefault),
  109. mpName(""),
  110. mbDisablePriorityBoost(false)
  111. {
  112. }
  113. EA::Thread::Thread::Thread()
  114. {
  115. mThreadData.mpData = NULL;
  116. }
  117. EA::Thread::Thread::Thread(const Thread& /*t*/)
  118. {
  119. }
  120. EA::Thread::Thread& EA::Thread::Thread::operator=(const Thread& /*t*/)
  121. {
  122. return *this;
  123. }
  124. EA::Thread::Thread::~Thread()
  125. {
  126. }
  127. EA::Thread::RunnableFunctionUserWrapper EA::Thread::Thread::sGlobalRunnableFunctionUserWrapper = NULL;
  128. EA::Thread::RunnableClassUserWrapper EA::Thread::Thread::sGlobalRunnableClassUserWrapper = NULL;
  129. EA::Thread::AtomicInt32 EA::Thread::Thread::sDefaultProcessor = kProcessorAny;
  130. EA::Thread::AtomicUint64 EA::Thread::Thread::sDefaultProcessorMask = UINT64_C(0xffffffffffffffff);
  131. EA::Thread::RunnableFunctionUserWrapper EA::Thread::Thread::GetGlobalRunnableFunctionUserWrapper()
  132. {
  133. return sGlobalRunnableFunctionUserWrapper;
  134. }
  135. void EA::Thread::Thread::SetGlobalRunnableFunctionUserWrapper(EA::Thread::RunnableFunctionUserWrapper pUserWrapper)
  136. {
  137. if (sGlobalRunnableFunctionUserWrapper != NULL)
  138. {
  139. // Can only be set once in entire game.
  140. EAT_ASSERT(false);
  141. }
  142. else
  143. sGlobalRunnableFunctionUserWrapper = pUserWrapper;
  144. }
  145. EA::Thread::RunnableClassUserWrapper EA::Thread::Thread::GetGlobalRunnableClassUserWrapper()
  146. {
  147. return sGlobalRunnableClassUserWrapper;
  148. }
  149. void EA::Thread::Thread::SetGlobalRunnableClassUserWrapper(EA::Thread::RunnableClassUserWrapper pUserWrapper)
  150. {
  151. if (sGlobalRunnableClassUserWrapper != NULL)
  152. {
  153. // Can only be set once in entire game.
  154. EAT_ASSERT(false);
  155. }
  156. else
  157. sGlobalRunnableClassUserWrapper = pUserWrapper;
  158. }
  159. EA::Thread::ThreadId EA::Thread::Thread::Begin(RunnableFunction /*pFunction*/, void* /*pContext*/, const ThreadParameters* /*pTP*/, RunnableFunctionUserWrapper /*pUserWrapper*/)
  160. {
  161. return kThreadIdInvalid;
  162. }
  163. EA::Thread::ThreadId EA::Thread::Thread::Begin(IRunnable* /*pRunnable*/, void* /*pContext*/, const ThreadParameters* /*pTP*/, RunnableClassUserWrapper /*pUserWrapper*/)
  164. {
  165. return kThreadIdInvalid;
  166. }
  167. EA::Thread::Thread::Status EA::Thread::Thread::WaitForEnd(const ThreadTime& /*timeoutAbsolute*/, intptr_t* /*pThreadReturnValue*/)
  168. {
  169. return kStatusNone;
  170. }
  171. EA::Thread::Thread::Status EA::Thread::Thread::GetStatus(intptr_t* /*pThreadReturnValue*/) const
  172. {
  173. return kStatusNone;
  174. }
  175. EA::Thread::ThreadId EA::Thread::Thread::GetId() const
  176. {
  177. return (ThreadId)kThreadIdInvalid;
  178. }
  179. int EA::Thread::Thread::GetPriority() const
  180. {
  181. return kThreadPriorityUnknown;
  182. }
  183. bool EA::Thread::Thread::SetPriority(int /*nPriority*/)
  184. {
  185. return false;
  186. }
  187. void EA::Thread::Thread::SetProcessor(int /*nProcessor*/)
  188. {
  189. }
  190. void EA::Thread::Thread::Wake()
  191. {
  192. }
  193. const char* EA::Thread::Thread::GetName() const
  194. {
  195. return "";
  196. }
  197. void EA::Thread::Thread::SetName(const char* /*pName*/)
  198. {
  199. }
  200. #endif // !EA_THREADS_AVAILABLE