windows_thread.c 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #include <iron_thread.h>
  2. #include <Windows.h>
  3. void iron_threads_init() {}
  4. void iron_threads_quit() {}
  5. struct thread_start {
  6. void (*thread)(void *param);
  7. void *param;
  8. };
  9. #define THREAD_STARTS 64
  10. static struct thread_start starts[THREAD_STARTS];
  11. static int thread_start_index = 0;
  12. static DWORD WINAPI ThreadProc(LPVOID arg) {
  13. intptr_t start_index = (intptr_t)arg;
  14. starts[start_index].thread(starts[start_index].param);
  15. return 0;
  16. }
  17. void iron_thread_init(iron_thread_t *thread, void (*func)(void *param), void *param) {
  18. thread->impl.func = func;
  19. thread->impl.param = param;
  20. intptr_t start_index = thread_start_index++;
  21. if (thread_start_index >= THREAD_STARTS) {
  22. thread_start_index = 0;
  23. }
  24. starts[start_index].thread = func;
  25. starts[start_index].param = param;
  26. thread->impl.handle = CreateThread(0, 65536, ThreadProc, (LPVOID)start_index, 0, 0);
  27. }
  28. void iron_thread_wait_and_destroy(iron_thread_t *thread) {
  29. WaitForSingleObject(thread->impl.handle, INFINITE);
  30. CloseHandle(thread->impl.handle);
  31. }
  32. bool iron_thread_try_to_destroy(iron_thread_t *thread) {
  33. DWORD code;
  34. GetExitCodeThread(thread->impl.handle, &code);
  35. if (code != STILL_ACTIVE) {
  36. CloseHandle(thread->impl.handle);
  37. return true;
  38. }
  39. return false;
  40. }
  41. typedef HRESULT(WINAPI *SetThreadDescriptionType)(HANDLE hThread, PCWSTR lpThreadDescription);
  42. static SetThreadDescriptionType MySetThreadDescription = NULL;
  43. static bool set_thread_description_loaded = false;
  44. void iron_thread_set_name(const char *name) {
  45. if (!set_thread_description_loaded) {
  46. HMODULE kernel32 = LoadLibraryA("kernel32.dll");
  47. MySetThreadDescription = (SetThreadDescriptionType)GetProcAddress(kernel32, "SetThreadDescription");
  48. set_thread_description_loaded = true;
  49. }
  50. if (MySetThreadDescription != NULL) {
  51. wchar_t wide_name[256];
  52. MultiByteToWideChar(CP_ACP, 0, name, -1, wide_name, 256);
  53. MySetThreadDescription(GetCurrentThread(), wide_name);
  54. }
  55. }
  56. void iron_thread_sleep(int milliseconds) {
  57. Sleep(milliseconds);
  58. }
  59. void iron_mutex_init(iron_mutex_t *mutex) {
  60. InitializeCriticalSection((LPCRITICAL_SECTION)&mutex->impl.criticalSection);
  61. }
  62. void iron_mutex_destroy(iron_mutex_t *mutex) {
  63. DeleteCriticalSection((LPCRITICAL_SECTION)&mutex->impl.criticalSection);
  64. }
  65. void iron_mutex_lock(iron_mutex_t *mutex) {
  66. EnterCriticalSection((LPCRITICAL_SECTION)&mutex->impl.criticalSection);
  67. }
  68. bool iron_mutex_try_to_lock(iron_mutex_t *mutex) {
  69. return TryEnterCriticalSection((LPCRITICAL_SECTION)&mutex->impl.criticalSection);
  70. }
  71. void iron_mutex_unlock(iron_mutex_t *mutex) {
  72. LeaveCriticalSection((LPCRITICAL_SECTION)&mutex->impl.criticalSection);
  73. }