sync_darwin.odin 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. package sync
  2. import "core:sys/darwin"
  3. import "core:c"
  4. foreign import pthread "System.framework"
  5. current_thread_id :: proc "contextless" () -> int {
  6. tid: u64
  7. // NOTE(Oskar): available from OSX 10.6 and iOS 3.2.
  8. // For older versions there is `syscall(SYS_thread_selfid)`, but not really
  9. // the same thing apparently.
  10. foreign pthread { pthread_threadid_np :: proc "c" (rawptr, ^u64) -> c.int --- }
  11. pthread_threadid_np(nil, &tid)
  12. return int(tid)
  13. }
  14. // The Darwin docs say it best:
  15. // A semaphore is much like a lock, except that a finite number of threads can hold it simultaneously.
  16. // Semaphores can be thought of as being much like piles of tokens; multiple threads can take these tokens,
  17. // but when there are none left, a thread must wait until another thread returns one.
  18. Semaphore :: struct #align 16 {
  19. handle: darwin.semaphore_t,
  20. }
  21. // TODO(tetra): Only marked with alignment because we cannot mark distinct integers with alignments.
  22. // See core/sys/unix/pthread_linux.odin/pthread_t.
  23. semaphore_init :: proc(s: ^Semaphore, initial_count := 0) {
  24. ct := darwin.mach_task_self()
  25. res := darwin.semaphore_create(ct, &s.handle, 0, c.int(initial_count))
  26. assert(res == 0)
  27. }
  28. semaphore_destroy :: proc(s: ^Semaphore) {
  29. ct := darwin.mach_task_self()
  30. res := darwin.semaphore_destroy(ct, s.handle)
  31. assert(res == 0)
  32. s.handle = {}
  33. }
  34. semaphore_post :: proc(s: ^Semaphore, count := 1) {
  35. // NOTE: SPEED: If there's one syscall to do this, we should use it instead of the loop.
  36. for in 0..<count {
  37. res := darwin.semaphore_signal(s.handle)
  38. assert(res == 0)
  39. }
  40. }
  41. semaphore_wait_for :: proc(s: ^Semaphore) {
  42. res := darwin.semaphore_wait(s.handle)
  43. assert(res == 0)
  44. }