futex_freebsd.odin 1.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. //+private
  2. //+build freebsd
  3. package sync
  4. import "core:c"
  5. import "core:os"
  6. import "core:time"
  7. UMTX_OP_WAIT :: 2
  8. UMTX_OP_WAKE :: 3
  9. foreign import libc "system:c"
  10. foreign libc {
  11. _umtx_op :: proc "c" (obj: rawptr, op: c.int, val: c.ulong, uaddr: rawptr, uaddr2: rawptr) -> c.int ---
  12. }
  13. _futex_wait :: proc(f: ^Futex, expected: u32) -> bool {
  14. timeout := os.Unix_File_Time{
  15. seconds = 5,
  16. nanoseconds = 0,
  17. }
  18. for {
  19. res := _umtx_op(f, UMTX_OP_WAIT, c.ulong(expected), nil, &timeout)
  20. if res != -1 {
  21. return true
  22. }
  23. if os.Errno(os.get_last_error()) == os.ETIMEDOUT {
  24. continue
  25. }
  26. panic("_futex_wait failure")
  27. }
  28. unreachable()
  29. }
  30. _futex_wait_with_timeout :: proc(f: ^Futex, expected: u32, duration: time.Duration) -> bool {
  31. if duration <= 0 {
  32. return false
  33. }
  34. res := _umtx_op(f, UMTX_OP_WAIT, c.ulong(expected), nil, &os.Unix_File_Time{
  35. seconds = (os.time_t)(duration/1e9),
  36. nanoseconds = (c.long)(duration%1e9),
  37. })
  38. if res != -1 {
  39. return true
  40. }
  41. if os.Errno(os.get_last_error()) == os.ETIMEDOUT {
  42. return false
  43. }
  44. panic("_futex_wait_with_timeout failure")
  45. }
  46. _futex_signal :: proc(f: ^Futex) {
  47. res := _umtx_op(f, UMTX_OP_WAKE, 1, nil, nil)
  48. if res == -1 {
  49. panic("_futex_signal failure")
  50. }
  51. }
  52. _futex_broadcast :: proc(f: ^Futex) {
  53. res := _umtx_op(f, UMTX_OP_WAKE, c.ulong(max(i32)), nil, nil)
  54. if res == -1 {
  55. panic("_futex_broadcast failure")
  56. }
  57. }