sync_darwin.odin 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. package sync
  2. import "core:sys/darwin"
  3. import "core:c"
  4. // The Darwin docs say it best:
  5. // A semaphore is much like a lock, except that a finite number of threads can hold it simultaneously.
  6. // Semaphores can be thought of as being much like piles of tokens; multiple threads can take these tokens,
  7. // but when there are none left, a thread must wait until another thread returns one.
  8. Semaphore :: struct #align 16 {
  9. handle: darwin.semaphore_t,
  10. }
  11. // TODO(tetra): Only marked with alignment because we cannot mark distinct integers with alignments.
  12. // See core/sys/unix/pthread_linux.odin/pthread_t.
  13. semaphore_init :: proc(s: ^Semaphore, initial_count := 0) {
  14. ct := darwin.mach_task_self();
  15. res := darwin.semaphore_create(ct, &s.handle, 0, c.int(initial_count));
  16. assert(res == 0);
  17. }
  18. semaphore_destroy :: proc(s: ^Semaphore) {
  19. ct := darwin.mach_task_self();
  20. res := darwin.semaphore_destroy(ct, s.handle);
  21. assert(res == 0);
  22. s.handle = {};
  23. }
  24. semaphore_post :: proc(s: ^Semaphore, count := 1) {
  25. // NOTE: SPEED: If there's one syscall to do this, we should use it instead of the loop.
  26. for in 0..count-1 {
  27. res := darwin.semaphore_signal(s.handle);
  28. assert(res == 0);
  29. }
  30. }
  31. semaphore_wait_for :: proc(s: ^Semaphore) {
  32. res := darwin.semaphore_wait(s.handle);
  33. assert(res == 0);
  34. }