Files
Odin/core/sync/futex_linux.odin

60 lines
1.5 KiB
Odin

#+private
#+build linux
package sync
import "core:time"
import "core:sys/linux"
_futex_wait :: proc "contextless" (futex: ^Futex, expected: u32) -> bool {
errno := linux.futex(cast(^linux.Futex) futex, linux.FUTEX_WAIT, {.PRIVATE}, expected)
if errno == .ETIMEDOUT {
return false
}
#partial switch errno {
case .NONE, .EINTR, .EAGAIN:
return true
case:
// TODO(flysand): More descriptive panic messages based on the vlaue of `errno`
panic_contextless("futex_wait failure")
}
}
_futex_wait_with_timeout :: proc "contextless" (futex: ^Futex, expected: u32, duration: time.Duration) -> bool {
if duration <= 0 {
return false
}
errno := linux.futex(cast(^linux.Futex) futex, linux.FUTEX_WAIT, {.PRIVATE}, expected, &linux.Time_Spec{
time_sec = cast(uint)(duration/1e9),
time_nsec = cast(uint)(duration%1e9),
})
if errno == .ETIMEDOUT {
return false
}
#partial switch errno {
case .NONE, .EINTR, .EAGAIN:
return true
case:
panic_contextless("futex_wait_with_timeout failure")
}
}
_futex_signal :: proc "contextless" (futex: ^Futex) {
_, errno := linux.futex(cast(^linux.Futex) futex, linux.FUTEX_WAKE, {.PRIVATE}, 1)
#partial switch errno {
case .NONE:
return
case:
panic_contextless("futex_wake_single failure")
}
}
_futex_broadcast :: proc "contextless" (futex: ^Futex) {
_, errno := linux.futex(cast(^linux.Futex) futex, linux.FUTEX_WAKE, {.PRIVATE}, max(i32))
#partial switch errno {
case .NONE:
return
case:
panic_contextless("_futex_wake_all failure")
}
}