sync_linux.odin 1.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. package sync
  2. import "core:sys/unix"
  3. foreign import libc "system:c"
  4. current_thread_id :: proc "contextless" () -> int {
  5. foreign libc {
  6. syscall :: proc(number: i32, #c_vararg args: ..any) -> i32 ---
  7. }
  8. SYS_GETTID :: 186;
  9. return int(syscall(SYS_GETTID));
  10. }
  11. // The Darwin docs say it best:
  12. // A semaphore is much like a lock, except that a finite number of threads can hold it simultaneously.
  13. // Semaphores can be thought of as being much like piles of tokens; multiple threads can take these tokens,
  14. // but when there are none left, a thread must wait until another thread returns one.
  15. Semaphore :: struct #align 16 {
  16. handle: unix.sem_t,
  17. }
  18. semaphore_init :: proc(s: ^Semaphore, initial_count := 0) {
  19. assert(unix.sem_init(&s.handle, 0, u32(initial_count)) == 0);
  20. }
  21. semaphore_destroy :: proc(s: ^Semaphore) {
  22. assert(unix.sem_destroy(&s.handle) == 0);
  23. s.handle = {};
  24. }
  25. semaphore_post :: proc(s: ^Semaphore, count := 1) {
  26. // NOTE: SPEED: If there's one syscall to do this, we should use it instead of the loop.
  27. for in 0..<count {
  28. assert(unix.sem_post(&s.handle) == 0);
  29. }
  30. }
  31. semaphore_wait_for :: proc(s: ^Semaphore) {
  32. assert(unix.sem_wait(&s.handle) == 0);
  33. }