Skip to content

Commit

Permalink
Merge pull request #4603 from avanspector/master
Browse files Browse the repository at this point in the history
Haiku: fix build and add initial `core:sys/posix` support
  • Loading branch information
laytan authored Jan 10, 2025
2 parents 328d893 + cc50fab commit e4ae832
Show file tree
Hide file tree
Showing 61 changed files with 1,583 additions and 419 deletions.
2 changes: 1 addition & 1 deletion build_odin.sh
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ OpenBSD)
LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs)"
;;
Haiku)
CXXFLAGS="$CXXFLAGS $($LLVM_CONFIG --cxxflags --ldflags) -I/system/develop/headers/private/shared -I/system/develop/headers/private/kernel"
CXXFLAGS="$CXXFLAGS -D_GNU_SOURCE $($LLVM_CONFIG --cxxflags --ldflags) -I/system/develop/headers/private/shared -I/system/develop/headers/private/kernel"
LDFLAGS="$LDFLAGS -liconv"
LDFLAGS="$LDFLAGS $($LLVM_CONFIG --libs core native --system-libs)"
;;
Expand Down
15 changes: 8 additions & 7 deletions core/c/libc/errno.odin
Original file line number Diff line number Diff line change
Expand Up @@ -88,14 +88,15 @@ when ODIN_OS == .Haiku {
_get_errno :: proc() -> ^int ---
}

@(private="file")
B_GENERAL_ERROR_BASE :: min(i32)
@(private="file")
B_POSIX_ERROR_BASE :: B_GENERAL_ERROR_BASE + 0x7000
_HAIKU_USE_POSITIVE_POSIX_ERRORS :: #config(HAIKU_USE_POSITIVE_POSIX_ERRORS, false)
_POSIX_ERROR_FACTOR :: -1 when _HAIKU_USE_POSITIVE_POSIX_ERRORS else 1

@(private="file") _GENERAL_ERROR_BASE :: min(int)
@(private="file") _POSIX_ERROR_BASE :: _GENERAL_ERROR_BASE + 0x7000

EDOM :: B_POSIX_ERROR_BASE + 16
EILSEQ :: B_POSIX_ERROR_BASE + 38
ERANGE :: B_POSIX_ERROR_BASE + 17
EDOM :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 16)
EILSEQ :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 38)
ERANGE :: _POSIX_ERROR_FACTOR * (_POSIX_ERROR_BASE + 17)
}

when ODIN_OS == .JS {
Expand Down
2 changes: 1 addition & 1 deletion core/c/libc/locale.odin
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ when ODIN_OS == .Windows {
}
}

when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Windows {
when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .OpenBSD || ODIN_OS == .Haiku || ODIN_OS == .Windows {

LC_ALL :: 0
LC_COLLATE :: 1
Expand Down
15 changes: 15 additions & 0 deletions core/c/libc/stdlib.odin
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,21 @@ when ODIN_OS == .Linux {
}
}

when ODIN_OS == .Haiku {
RAND_MAX :: 0x7fffffff

// GLIBC and MUSL only
@(private="file")
@(default_calling_convention="c")
foreign libc {
__ctype_get_mb_cur_max :: proc() -> ushort ---
}

MB_CUR_MAX :: #force_inline proc() -> size_t {
return size_t(__ctype_get_mb_cur_max())
}
}


when ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .OpenBSD {
RAND_MAX :: 0x7fffffff
Expand Down
2 changes: 1 addition & 1 deletion core/c/libc/time.odin
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ when ODIN_OS == .Linux || ODIN_OS == .FreeBSD || ODIN_OS == .Darwin || ODIN_OS =

time_t :: distinct i64

when ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD {
when ODIN_OS == .FreeBSD || ODIN_OS == .NetBSD || ODIN_OS == .Haiku {
clock_t :: distinct int32_t
} else {
clock_t :: distinct long
Expand Down
2 changes: 1 addition & 1 deletion core/os/dir_unix.odin
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#+build darwin, linux, netbsd, freebsd, openbsd
#+build darwin, linux, netbsd, freebsd, openbsd, haiku
package os

import "core:strings"
Expand Down
34 changes: 25 additions & 9 deletions core/os/os_haiku.odin
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package os

foreign import libc "system:c"
foreign import lib "system:c"

import "base:runtime"
import "core:c"
import "core:c/libc"
import "core:strings"
import "core:sys/haiku"
import "core:sys/posix"

Handle :: i32
Pid :: i32
Expand All @@ -14,7 +16,7 @@ _Platform_Error :: haiku.Errno

MAX_PATH :: haiku.PATH_MAX

ENOSYS :: _Platform_Error(i32(haiku.Errno.POSIX_ERROR_BASE) + 9)
ENOSYS :: _Platform_Error(haiku.Errno.ENOSYS)

INVALID_HANDLE :: ~Handle(0)

Expand Down Expand Up @@ -117,14 +119,13 @@ S_ISBLK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFBLK
S_ISFIFO :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFIFO }
S_ISSOCK :: #force_inline proc(m: u32) -> bool { return (m & S_IFMT) == S_IFSOCK }

__error :: libc.errno
_unix_open :: posix.open

foreign libc {
@(link_name="_errorp") __error :: proc() -> ^c.int ---

foreign lib {
@(link_name="fork") _unix_fork :: proc() -> pid_t ---
@(link_name="getthrid") _unix_getthrid :: proc() -> int ---

@(link_name="open") _unix_open :: proc(path: cstring, flags: c.int, #c_vararg mode: ..u16) -> Handle ---
@(link_name="close") _unix_close :: proc(fd: Handle) -> c.int ---
@(link_name="read") _unix_read :: proc(fd: Handle, buf: rawptr, size: c.size_t) -> c.ssize_t ---
@(link_name="pread") _unix_pread :: proc(fd: Handle, buf: rawptr, size: c.size_t, offset: i64) -> c.ssize_t ---
Expand All @@ -150,14 +151,15 @@ foreign libc {
@(link_name="closedir") _unix_closedir :: proc(dirp: Dir) -> c.int ---
@(link_name="rewinddir") _unix_rewinddir :: proc(dirp: Dir) ---
@(link_name="readdir_r") _unix_readdir_r :: proc(dirp: Dir, entry: ^Dirent, result: ^^Dirent) -> c.int ---
@(link_name="dup") _unix_dup :: proc(fd: Handle) -> Handle ---

@(link_name="malloc") _unix_malloc :: proc(size: c.size_t) -> rawptr ---
@(link_name="calloc") _unix_calloc :: proc(num, size: c.size_t) -> rawptr ---
@(link_name="free") _unix_free :: proc(ptr: rawptr) ---
@(link_name="realloc") _unix_realloc :: proc(ptr: rawptr, size: c.size_t) -> rawptr ---

@(link_name="getenv") _unix_getenv :: proc(cstring) -> cstring ---
@(link_name="realpath") _unix_realpath :: proc(path: cstring, resolved_path: rawptr) -> rawptr ---
@(link_name="realpath") _unix_realpath :: proc(path: cstring, resolved_path: [^]byte = nil) -> cstring ---

@(link_name="exit") _unix_exit :: proc(status: c.int) -> ! ---

Expand Down Expand Up @@ -203,7 +205,7 @@ fork :: proc() -> (Pid, Error) {
open :: proc(path: string, flags: int = O_RDONLY, mode: int = 0) -> (Handle, Error) {
runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD()
cstr := strings.clone_to_cstring(path, context.temp_allocator)
handle := _unix_open(cstr, c.int(flags), u16(mode))
handle := cast(Handle)_unix_open(cstr, transmute(posix.O_Flags)i32(flags), transmute(posix.mode_t)i32(mode))
if handle == -1 {
return INVALID_HANDLE, get_last_error()
}
Expand Down Expand Up @@ -444,7 +446,7 @@ absolute_path_from_relative :: proc(rel: string, allocator := context.allocator)
if path_ptr == nil {
return "", get_last_error()
}
defer _unix_free(path_ptr)
defer _unix_free(rawptr(path_ptr))

path_cstr := cstring(path_ptr)
return strings.clone(string(path_cstr), allocator)
Expand Down Expand Up @@ -488,3 +490,17 @@ exit :: proc "contextless" (code: int) -> ! {
runtime._cleanup_runtime_contextless()
_unix_exit(i32(code))
}

@(require_results)
current_thread_id :: proc "contextless" () -> int {
return int(haiku.find_thread(nil))
}

@(private, require_results)
_dup :: proc(fd: Handle) -> (Handle, Error) {
dup := _unix_dup(fd)
if dup == -1 {
return INVALID_HANDLE, get_last_error()
}
return dup, nil
}
2 changes: 1 addition & 1 deletion core/os/stat_unix.odin
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ File_Info :: struct {
@(private, require_results)
_make_time_from_unix_file_time :: proc(uft: Unix_File_Time) -> time.Time {
return time.Time{
_nsec = uft.nanoseconds + uft.seconds * 1_000_000_000,
_nsec = i64(uft.nanoseconds) + i64(uft.seconds) * 1_000_000_000,
}
}

Expand Down
2 changes: 1 addition & 1 deletion core/path/filepath/path_unix.odin
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#+build linux, darwin, freebsd, openbsd, netbsd
#+build linux, darwin, freebsd, openbsd, netbsd, haiku
package filepath

import "base:runtime"
Expand Down
50 changes: 24 additions & 26 deletions core/sync/futex_haiku.odin
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
#+private
package sync

import "core:c"
import "core:sys/haiku"
import "core:sys/unix"
import "core:sys/posix"
import "core:time"

@(private="file")
Wait_Node :: struct {
thread: unix.pthread_t,
thread: posix.pthread_t,
futex: ^Futex,
prev, next: ^Wait_Node,
}
Expand Down Expand Up @@ -58,7 +57,7 @@ _futex_wait :: proc "contextless" (f: ^Futex, expect: u32) -> (ok: bool) {

head := &waitq.list
waiter := Wait_Node{
thread = unix.pthread_self(),
thread = posix.pthread_self(),
futex = f,
prev = head,
next = head.next,
Expand All @@ -67,25 +66,24 @@ _futex_wait :: proc "contextless" (f: ^Futex, expect: u32) -> (ok: bool) {
waiter.prev.next = &waiter
waiter.next.prev = &waiter

old_mask, mask: haiku.sigset_t
haiku.sigemptyset(&mask)
haiku.sigaddset(&mask, haiku.SIGCONT)
unix.pthread_sigmask(haiku.SIG_BLOCK, &mask, &old_mask)
old_mask, mask: posix.sigset_t
posix.sigemptyset(&mask)
posix.sigaddset(&mask, .SIGCONT)
posix.pthread_sigmask(.BLOCK, &mask, &old_mask)

if u32(atomic_load_explicit(f, .Acquire)) == expect {
waitq_unlock(waitq)
defer waitq_lock(waitq)

sig: c.int
haiku.sigwait(&mask, &sig)
errno := haiku.errno()
ok = errno == .OK
sig: posix.Signal
errno := posix.sigwait(&mask, &sig)
ok = errno == nil
}

waiter.prev.next = waiter.next
waiter.next.prev = waiter.prev

_ = unix.pthread_sigmask(haiku.SIG_SETMASK, &old_mask, nil)
_ = posix.pthread_sigmask(.SETMASK, &old_mask, nil)

// FIXME: Add error handling!
return
Expand All @@ -101,7 +99,7 @@ _futex_wait_with_timeout :: proc "contextless" (f: ^Futex, expect: u32, duration

head := &waitq.list
waiter := Wait_Node{
thread = unix.pthread_self(),
thread = posix.pthread_self(),
futex = f,
prev = head,
next = head.next,
Expand All @@ -110,29 +108,29 @@ _futex_wait_with_timeout :: proc "contextless" (f: ^Futex, expect: u32, duration
waiter.prev.next = &waiter
waiter.next.prev = &waiter

old_mask, mask: haiku.sigset_t
haiku.sigemptyset(&mask)
haiku.sigaddset(&mask, haiku.SIGCONT)
unix.pthread_sigmask(haiku.SIG_BLOCK, &mask, &old_mask)
old_mask, mask: posix.sigset_t
posix.sigemptyset(&mask)
posix.sigaddset(&mask, .SIGCONT)
posix.pthread_sigmask(.BLOCK, &mask, &old_mask)

if u32(atomic_load_explicit(f, .Acquire)) == expect {
waitq_unlock(waitq)
defer waitq_lock(waitq)

info: haiku.siginfo_t
ts := unix.timespec{
tv_sec = i64(duration / 1e9),
info: posix.siginfo_t
ts := posix.timespec{
tv_sec = posix.time_t(i64(duration / 1e9)),
tv_nsec = i64(duration % 1e9),
}
haiku.sigtimedwait(&mask, &info, &ts)
errno := haiku.errno()
ok = errno == .EAGAIN || errno == .OK
errno := posix.errno()
ok = errno == .EAGAIN || errno == nil
}

waiter.prev.next = waiter.next
waiter.next.prev = waiter.prev

unix.pthread_sigmask(haiku.SIG_SETMASK, &old_mask, nil)
posix.pthread_sigmask(.SETMASK, &old_mask, nil)

// FIXME: Add error handling!
return
Expand All @@ -146,7 +144,7 @@ _futex_signal :: proc "contextless" (f: ^Futex) {
head := &waitq.list
for waiter := head.next; waiter != head; waiter = waiter.next {
if waiter.futex == f {
unix.pthread_kill(waiter.thread, haiku.SIGCONT)
posix.pthread_kill(waiter.thread, .SIGCONT)
break
}
}
Expand All @@ -160,7 +158,7 @@ _futex_broadcast :: proc "contextless" (f: ^Futex) {
head := &waitq.list
for waiter := head.next; waiter != head; waiter = waiter.next {
if waiter.futex == f {
unix.pthread_kill(waiter.thread, haiku.SIGCONT)
posix.pthread_kill(waiter.thread, .SIGCONT)
}
}
}
Loading

0 comments on commit e4ae832

Please sign in to comment.