thread_windows.odin 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. package thread
  2. import "core:runtime"
  3. import "core:sys/win32"
  4. Thread_Proc :: #type proc(^Thread) -> int;
  5. Thread_Os_Specific :: struct {
  6. win32_thread: win32.Handle,
  7. win32_thread_id: u32,
  8. }
  9. Thread :: struct {
  10. using specific: Thread_Os_Specific,
  11. procedure: Thread_Proc,
  12. data: rawptr,
  13. user_index: int,
  14. init_context: runtime.Context,
  15. use_init_context: bool,
  16. }
  17. create :: proc(procedure: Thread_Proc) -> ^Thread {
  18. win32_thread_id: u32;
  19. __windows_thread_entry_proc :: proc "c" (t: ^Thread) -> i32 {
  20. c := context;
  21. if t.use_init_context {
  22. c = t.init_context;
  23. }
  24. context = c;
  25. return i32(t.procedure(t));
  26. }
  27. win32_thread_proc := rawptr(__windows_thread_entry_proc);
  28. thread := new(Thread);
  29. win32_thread := win32.create_thread(nil, 0, win32_thread_proc, thread, win32.CREATE_SUSPENDED, &win32_thread_id);
  30. if win32_thread == nil {
  31. free(thread);
  32. return nil;
  33. }
  34. thread.procedure = procedure;
  35. thread.win32_thread = win32_thread;
  36. thread.win32_thread_id = win32_thread_id;
  37. return thread;
  38. }
  39. start :: proc(using thread: ^Thread) {
  40. win32.resume_thread(win32_thread);
  41. }
  42. is_done :: proc(using thread: ^Thread) -> bool {
  43. res := win32.wait_for_single_object(win32_thread, 0);
  44. return res != win32.WAIT_TIMEOUT;
  45. }
  46. join :: proc(using thread: ^Thread) {
  47. win32.wait_for_single_object(win32_thread, win32.INFINITE);
  48. win32.close_handle(win32_thread);
  49. win32_thread = win32.INVALID_HANDLE;
  50. }
  51. destroy :: proc(thread: ^Thread) {
  52. join(thread);
  53. free(thread);
  54. }
  55. terminate :: proc(using thread : ^Thread, exit_code : u32) {
  56. win32.terminate_thread(win32_thread, exit_code);
  57. }