ThreadWindows.cpp 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. // Add support for condition variables
  6. #define _WIN32_WINNT _WIN32_WINNT_VISTA
  7. #include <AnKi/Util/Thread.h>
  8. #include <AnKi/Util/Logger.h>
  9. namespace anki {
  10. DWORD ANKI_WINAPI Thread::threadCallback(LPVOID ud)
  11. {
  12. ANKI_ASSERT(ud != nullptr);
  13. Thread* thread = reinterpret_cast<Thread*>(ud);
  14. // Set thread name
  15. if(thread->m_name[0] != '\0')
  16. {
  17. // TODO
  18. }
  19. // Call the callback
  20. ThreadCallbackInfo info;
  21. info.m_userData = thread->m_userData;
  22. info.m_threadName = &thread->m_name[0];
  23. thread->m_returnCode = thread->m_callback(info);
  24. return thread->m_returnCode._getCode();
  25. }
  26. void Thread::start(void* userData, ThreadCallback callback, const ThreadCoreAffinityMask& coreAffintyMask)
  27. {
  28. ANKI_ASSERT(!m_started);
  29. ANKI_ASSERT(callback != nullptr);
  30. m_callback = callback;
  31. m_userData = userData;
  32. #if ANKI_EXTRA_CHECKS
  33. m_started = true;
  34. #endif
  35. m_returnCode = Error::NONE;
  36. m_handle = CreateThread(nullptr, 0, threadCallback, this, 0, nullptr);
  37. if(m_handle == nullptr)
  38. {
  39. ANKI_UTIL_LOGF("CreateThread() failed");
  40. }
  41. if(coreAffintyMask.getAny())
  42. {
  43. pinToCores(coreAffintyMask);
  44. }
  45. }
  46. Error Thread::join()
  47. {
  48. ANKI_ASSERT(m_started);
  49. // Wait thread
  50. WaitForSingleObject(m_handle, INFINITE);
  51. // Delete handle
  52. const BOOL ok = CloseHandle(m_handle);
  53. if(!ok)
  54. {
  55. ANKI_UTIL_LOGF("CloseHandle() failed");
  56. }
  57. m_handle = nullptr;
  58. #if ANKI_EXTRA_CHECKS
  59. m_started = false;
  60. #endif
  61. return m_returnCode;
  62. }
  63. void Thread::pinToCores(const ThreadCoreAffinityMask& coreAffintyMask)
  64. {
  65. static_assert(std::is_same<DWORD_PTR, U64>::value, "See file");
  66. ThreadCoreAffinityMask affinityTest = coreAffintyMask;
  67. DWORD_PTR affinity = 0;
  68. for(DWORD_PTR bit = 0; bit < 64; ++bit)
  69. {
  70. if(coreAffintyMask.get(bit))
  71. {
  72. affinity |= 1ull << bit;
  73. affinityTest.unset(bit);
  74. }
  75. }
  76. if(SetThreadAffinityMask(m_handle, affinity) == 0)
  77. {
  78. ANKI_UTIL_LOGF("SetThreadAffinityMask() failed");
  79. }
  80. if(affinityTest.getEnabledBitCount() > 0)
  81. {
  82. ANKI_UTIL_LOGE("Couldn't set affinity for all cores. Need to refactor the code");
  83. }
  84. }
  85. void Thread::setNameOfCurrentThread(const CString& name)
  86. {
  87. // TODO
  88. }
  89. } // end namespace anki