ThreadWindows.cpp 2.2 KB

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