althrd_setname.cpp 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #include "config.h"
  2. #include "althrd_setname.h"
  3. #ifdef _WIN32
  4. #define WIN32_LEAN_AND_MEAN
  5. #include <windows.h>
  6. void althrd_setname(const char *name [[maybe_unused]])
  7. {
  8. #if defined(_MSC_VER) && !defined(_M_ARM)
  9. #define MS_VC_EXCEPTION 0x406D1388
  10. #pragma pack(push,8)
  11. struct InfoStruct {
  12. DWORD dwType; // Must be 0x1000.
  13. LPCSTR szName; // Pointer to name (in user addr space).
  14. DWORD dwThreadID; // Thread ID (-1=caller thread).
  15. DWORD dwFlags; // Reserved for future use, must be zero.
  16. };
  17. #pragma pack(pop)
  18. InfoStruct info{};
  19. info.dwType = 0x1000;
  20. info.szName = name;
  21. info.dwThreadID = ~DWORD{0};
  22. info.dwFlags = 0;
  23. /* FIXME: How to do this on MinGW? */
  24. __try {
  25. RaiseException(MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info);
  26. }
  27. __except(EXCEPTION_CONTINUE_EXECUTION) {
  28. }
  29. #undef MS_VC_EXCEPTION
  30. #endif
  31. }
  32. #else
  33. #include <pthread.h>
  34. #ifdef HAVE_PTHREAD_NP_H
  35. #include <pthread_np.h>
  36. #endif
  37. namespace {
  38. using setname_t1 = int(*)(const char*);
  39. using setname_t2 = int(*)(pthread_t, const char*);
  40. using setname_t3 = void(*)(pthread_t, const char*);
  41. using setname_t4 = int(*)(pthread_t, const char*, void*);
  42. [[maybe_unused]] void setname_caller(setname_t1 func, const char *name)
  43. { func(name); }
  44. [[maybe_unused]] void setname_caller(setname_t2 func, const char *name)
  45. { func(pthread_self(), name); }
  46. [[maybe_unused]] void setname_caller(setname_t3 func, const char *name)
  47. { func(pthread_self(), name); }
  48. [[maybe_unused]] void setname_caller(setname_t4 func, const char *name)
  49. { func(pthread_self(), "%s", const_cast<char*>(name)); /* NOLINT(*-const-cast) */ }
  50. } // namespace
  51. void althrd_setname(const char *name [[maybe_unused]])
  52. {
  53. #if defined(HAVE_PTHREAD_SET_NAME_NP)
  54. setname_caller(pthread_set_name_np, name);
  55. #elif defined(HAVE_PTHREAD_SETNAME_NP)
  56. setname_caller(pthread_setname_np, name);
  57. #endif
  58. }
  59. #endif