initial OpenBSD support

This commit is contained in:
Sébastien Marie
2022-02-25 08:49:25 +00:00
parent 3a469dc13e
commit 5676c9e7eb
30 changed files with 1151 additions and 27 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
// +build linux, darwin, freebsd
// +build linux, darwin, freebsd, openbsd
package sync
import "core:time"
+78
View File
@@ -0,0 +1,78 @@
//+private
//+build openbsd
package sync2
import "core:c"
import "core:os"
import "core:time"
FUTEX_WAIT :: 1
FUTEX_WAKE :: 2
FUTEX_PRIVATE_FLAG :: 128
FUTEX_WAIT_PRIVATE :: (FUTEX_WAIT | FUTEX_PRIVATE_FLAG)
FUTEX_WAKE_PRIVATE :: (FUTEX_WAKE | FUTEX_PRIVATE_FLAG)
foreign import libc "system:c"
foreign libc {
@(link_name="futex")
_unix_futex :: proc "c" (f: ^Futex, op: c.int, val: u32, timeout: rawptr) -> c.int ---
}
_futex_wait :: proc(f: ^Futex, expected: u32) -> bool {
res := _unix_futex(f, FUTEX_WAIT_PRIVATE, expected, nil)
if res != -1 {
return true
}
if os.Errno(os.get_last_error()) == os.ETIMEDOUT {
return false
}
panic("futex_wait failure")
}
_futex_wait_with_timeout :: proc(f: ^Futex, expected: u32, duration: time.Duration) -> bool {
if duration <= 0 {
return false
}
timespec_t :: struct {
tv_sec: c.long,
tv_nsec: c.long,
}
res := _unix_futex(f, FUTEX_WAIT_PRIVATE, expected, &timespec_t{
tv_sec = (c.long)(duration/1e9),
tv_nsec = (c.long)(duration%1e9),
})
if res != -1 {
return true
}
if os.Errno(os.get_last_error()) == os.ETIMEDOUT {
return false
}
panic("futex_wait_with_timeout failure")
}
_futex_signal :: proc(f: ^Futex) {
res := _unix_futex(f, FUTEX_WAKE_PRIVATE, 1, nil)
if res == -1 {
panic("futex_wake_single failure")
}
}
_futex_broadcast :: proc(f: ^Futex) {
res := _unix_futex(f, FUTEX_WAKE_PRIVATE, u32(max(i32)), nil)
if res == -1 {
panic("_futex_wake_all failure")
}
}
+9
View File
@@ -0,0 +1,9 @@
//+build openbsd
//+private
package sync2
import "core:os"
_current_thread_id :: proc "contextless" () -> int {
return os.current_thread_id()
}
+1 -1
View File
@@ -1,4 +1,4 @@
//+build linux, freebsd
//+build linux, freebsd, openbsd
//+private
package sync2
+36
View File
@@ -0,0 +1,36 @@
package sync
import "core:sys/unix"
import "core:os"
current_thread_id :: proc "contextless" () -> int {
return os.current_thread_id()
}
// The Darwin docs say it best:
// A semaphore is much like a lock, except that a finite number of threads can hold it simultaneously.
// Semaphores can be thought of as being much like piles of tokens; multiple threads can take these tokens,
// but when there are none left, a thread must wait until another thread returns one.
Semaphore :: struct #align 16 {
handle: unix.sem_t,
}
semaphore_init :: proc(s: ^Semaphore, initial_count := 0) {
assert(unix.sem_init(&s.handle, 0, u32(initial_count)) == 0)
}
semaphore_destroy :: proc(s: ^Semaphore) {
assert(unix.sem_destroy(&s.handle) == 0)
s.handle = {}
}
semaphore_post :: proc(s: ^Semaphore, count := 1) {
// NOTE: SPEED: If there's one syscall to do this, we should use it instead of the loop.
for in 0..<count {
assert(unix.sem_post(&s.handle) == 0)
}
}
semaphore_wait_for :: proc(s: ^Semaphore) {
assert(unix.sem_wait(&s.handle) == 0)
}
+1 -1
View File
@@ -1,4 +1,4 @@
// +build linux, darwin, freebsd
// +build linux, darwin, freebsd, openbsd
package sync
import "core:sys/unix"