aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorAndreas T Jonsson <mail@andreasjonsson.se>2024-05-10 09:04:52 +0200
committerAndreas T Jonsson <mail@andreasjonsson.se>2024-05-10 09:04:52 +0200
commitb72c2edabbc9087b07a30b781de1925d6570dd62 (patch)
tree0e96f43038901ec8c6f6b015071c1803a2166d41 /core
parent273e4c6b4ce6f1060870782c8e780fe2b371ede4 (diff)
parent41bd8cf7143902db59c02c56fc5318a7e749d7a5 (diff)
Merge branch 'master' into netbsd
Diffstat (limited to 'core')
-rw-r--r--core/math/big/helpers.odin2
-rw-r--r--core/math/big/internal.odin4
-rw-r--r--core/math/big/radix.odin4
-rw-r--r--core/os/os_freebsd.odin2
-rw-r--r--core/simd/x86/sse3.odin4
-rw-r--r--core/simd/x86/sse41.odin4
-rw-r--r--core/slice/slice.odin36
-rw-r--r--core/sync/extended.odin2
-rw-r--r--core/sync/futex_wasm.odin44
-rw-r--r--core/sys/darwin/sync.odin4
-rw-r--r--core/sys/linux/bits.odin51
-rw-r--r--core/sys/linux/helpers.odin30
-rw-r--r--core/sys/linux/sys.odin2
-rw-r--r--core/thread/thread_unix.odin4
14 files changed, 133 insertions, 60 deletions
diff --git a/core/math/big/helpers.odin b/core/math/big/helpers.odin
index 35be4f1fd..1969fac49 100644
--- a/core/math/big/helpers.odin
+++ b/core/math/big/helpers.odin
@@ -356,7 +356,7 @@ int_count_lsb :: proc(a: ^Int, allocator := context.allocator) -> (count: int, e
}
platform_count_lsb :: #force_inline proc(a: $T) -> (count: int)
- where intrinsics.type_is_integer(T) && intrinsics.type_is_unsigned(T) {
+ where intrinsics.type_is_integer(T), intrinsics.type_is_unsigned(T) {
return int(intrinsics.count_trailing_zeros(a)) if a > 0 else 0
}
diff --git a/core/math/big/internal.odin b/core/math/big/internal.odin
index 07e1e6c03..fa747e46a 100644
--- a/core/math/big/internal.odin
+++ b/core/math/big/internal.odin
@@ -546,7 +546,7 @@ internal_int_shl1 :: proc(dest, src: ^Int, allocator := context.allocator) -> (e
Like `internal_int_mul_digit` but with an integer as the small input.
*/
internal_int_mul_integer :: proc(dest, a: ^Int, b: $T, allocator := context.allocator) -> (err: Error)
-where intrinsics.type_is_integer(T) && T != DIGIT {
+where intrinsics.type_is_integer(T), T != DIGIT {
context.allocator = allocator
t := &Int{}
@@ -2806,7 +2806,7 @@ internal_int_count_lsb :: proc(a: ^Int) -> (count: int, err: Error) {
}
internal_platform_count_lsb :: #force_inline proc(a: $T) -> (count: int)
- where intrinsics.type_is_integer(T) && intrinsics.type_is_unsigned(T) {
+ where intrinsics.type_is_integer(T), intrinsics.type_is_unsigned(T) {
return int(intrinsics.count_trailing_zeros(a)) if a > 0 else 0
}
diff --git a/core/math/big/radix.odin b/core/math/big/radix.odin
index 8d8ea734e..f4eed879f 100644
--- a/core/math/big/radix.odin
+++ b/core/math/big/radix.odin
@@ -469,7 +469,7 @@ internal_int_pack_count :: proc(a: ^Int, $T: typeid, nails := 0) -> (size_needed
Assumes `a` not to be `nil` and to have been initialized.
*/
internal_int_pack :: proc(a: ^Int, buf: []$T, nails := 0, order := Order.LSB_First) -> (written: int, err: Error)
- where intrinsics.type_is_integer(T) && intrinsics.type_is_unsigned(T) && size_of(T) <= 16 {
+ where intrinsics.type_is_integer(T), intrinsics.type_is_unsigned(T), size_of(T) <= 16 {
assert(nails >= 0 && nails < (size_of(T) * 8))
@@ -505,7 +505,7 @@ internal_int_pack :: proc(a: ^Int, buf: []$T, nails := 0, order := Order.LSB_Fir
internal_int_unpack :: proc(a: ^Int, buf: []$T, nails := 0, order := Order.LSB_First, allocator := context.allocator) -> (err: Error)
- where intrinsics.type_is_integer(T) && intrinsics.type_is_unsigned(T) && size_of(T) <= 16 {
+ where intrinsics.type_is_integer(T), intrinsics.type_is_unsigned(T), size_of(T) <= 16 {
assert(nails >= 0 && nails < (size_of(T) * 8))
context.allocator = allocator
diff --git a/core/os/os_freebsd.odin b/core/os/os_freebsd.odin
index be86854dd..cdd44d301 100644
--- a/core/os/os_freebsd.odin
+++ b/core/os/os_freebsd.odin
@@ -159,7 +159,7 @@ blkcnt_t :: i64
blksize_t :: i32
fflags_t :: u32
-when ODIN_ARCH == .amd64 /* LP64 */ {
+when ODIN_ARCH == .amd64 || ODIN_ARCH == .arm64 /* LP64 */ {
time_t :: i64
} else {
time_t :: i32
diff --git a/core/simd/x86/sse3.odin b/core/simd/x86/sse3.odin
index cf5f3b2fa..ca19c3954 100644
--- a/core/simd/x86/sse3.odin
+++ b/core/simd/x86/sse3.odin
@@ -36,7 +36,7 @@ _mm_lddqu_si128 :: #force_inline proc "c" (mem_addr: ^__m128i) -> __m128i {
_mm_movedup_pd :: #force_inline proc "c" (a: __m128d) -> __m128d {
return simd.shuffle(a, a, 0, 0)
}
-@(require_results, enable_target_feature="sse3")
+@(require_results, enable_target_feature="sse2,sse3")
_mm_loaddup_pd :: #force_inline proc "c" (mem_addr: [^]f64) -> __m128d {
return _mm_load1_pd(mem_addr)
}
@@ -65,4 +65,4 @@ foreign _ {
hsubps :: proc(a, b: __m128) -> __m128 ---
@(link_name = "llvm.x86.sse3.ldu.dq")
lddqu :: proc(mem_addr: rawptr) -> i8x16 ---
-} \ No newline at end of file
+}
diff --git a/core/simd/x86/sse41.odin b/core/simd/x86/sse41.odin
index 8c306ba4c..0b9c5986f 100644
--- a/core/simd/x86/sse41.odin
+++ b/core/simd/x86/sse41.odin
@@ -268,7 +268,7 @@ _mm_testnzc_si128 :: #force_inline proc "c" (a: __m128i, mask: __m128i) -> i32 {
_mm_test_all_zeros :: #force_inline proc "c" (a: __m128i, mask: __m128i) -> i32 {
return _mm_testz_si128(a, mask)
}
-@(require_results, enable_target_feature="sse4.1")
+@(require_results, enable_target_feature="sse2,sse4.1")
_mm_test_all_ones :: #force_inline proc "c" (a: __m128i) -> i32 {
return _mm_testc_si128(a, _mm_cmpeq_epi32(a, a))
}
@@ -349,4 +349,4 @@ foreign _ {
ptestc :: proc(a, mask: i64x2) -> i32 ---
@(link_name = "llvm.x86.sse41.ptestnzc")
ptestnzc :: proc(a, mask: i64x2) -> i32 ---
-} \ No newline at end of file
+}
diff --git a/core/slice/slice.odin b/core/slice/slice.odin
index dd8d9868a..03791e7dd 100644
--- a/core/slice/slice.odin
+++ b/core/slice/slice.odin
@@ -701,3 +701,39 @@ enumerated_array :: proc(ptr: ^$T) -> []intrinsics.type_elem_type(T)
where intrinsics.type_is_enumerated_array(T) {
return ([^]intrinsics.type_elem_type(T))(ptr)[:len(T)]
}
+
+// Turn a `[]E` into `bit_set[E]`
+// e.g.:
+// bs := slice.enum_slice_to_bitset(my_flag_slice, rl.ConfigFlags)
+@(require_results)
+enum_slice_to_bitset :: proc(enums: []$E, $T: typeid/bit_set[E]) -> (bits: T) where intrinsics.type_is_enum(E), intrinsics.type_bit_set_elem_type(T) == E {
+ for v in enums {
+ bits |= {v}
+ }
+ return
+}
+
+// Turn a `bit_set[E]` into a `[]E`
+// e.g.:
+// sl := slice.bitset_to_enum_slice(flag_buf[:], bs)
+@(require_results)
+bitset_to_enum_slice_with_buffer :: proc(buf: []$E, bs: $T) -> (slice: []E) where intrinsics.type_is_enum(E), intrinsics.type_bit_set_elem_type(T) == E {
+ count := 0
+ for v in bs {
+ buf[count] = v
+ count += 1
+ }
+ return buf[:count]
+}
+
+// Turn a `bit_set[E]` into a `[]E`, allocates
+// e.g.:
+// sl := slice.bitset_to_enum_slice(bs)
+@(require_results)
+bitset_to_enum_slice_with_make :: proc(bs: $T, $E: typeid, allocator := context.allocator) -> (slice: []E) where intrinsics.type_is_enum(E), intrinsics.type_bit_set_elem_type(T) == E {
+ ones := intrinsics.count_ones(transmute(E)bs)
+ buf := make([]E, int(ones), allocator)
+ return bitset_to_enum_slice(buf, bs)
+}
+
+bitset_to_enum_slice :: proc{bitset_to_enum_slice_with_make, bitset_to_enum_slice_with_buffer} \ No newline at end of file
diff --git a/core/sync/extended.odin b/core/sync/extended.odin
index 76b7686fe..781ed816e 100644
--- a/core/sync/extended.odin
+++ b/core/sync/extended.odin
@@ -433,7 +433,7 @@ One_Shot_Event :: struct #no_copy {
// Blocks the current thread until the event is made available with `one_shot_event_signal`.
one_shot_event_wait :: proc "contextless" (e: ^One_Shot_Event) {
for atomic_load_explicit(&e.state, .Acquire) == 0 {
- futex_wait(&e.state, 1)
+ futex_wait(&e.state, 0)
}
}
diff --git a/core/sync/futex_wasm.odin b/core/sync/futex_wasm.odin
index de1013364..de88e8198 100644
--- a/core/sync/futex_wasm.odin
+++ b/core/sync/futex_wasm.odin
@@ -5,31 +5,49 @@ package sync
import "base:intrinsics"
import "core:time"
+// NOTE: because `core:sync` is in the dependency chain of a lot of the core packages (mostly through `core:mem`)
+// without actually calling into it much, I opted for a runtime panic instead of a compile error here.
+
_futex_wait :: proc "contextless" (f: ^Futex, expected: u32) -> bool {
- s := intrinsics.wasm_memory_atomic_wait32((^u32)(f), expected, -1)
- return s != 0
+ when !intrinsics.has_target_feature("atomics") {
+ _panic("usage of `core:sync` requires the `-target-feature:\"atomics\"` or a `-microarch` that supports it")
+ } else {
+ s := intrinsics.wasm_memory_atomic_wait32((^u32)(f), expected, -1)
+ return s != 0
+ }
}
_futex_wait_with_timeout :: proc "contextless" (f: ^Futex, expected: u32, duration: time.Duration) -> bool {
- s := intrinsics.wasm_memory_atomic_wait32((^u32)(f), expected, i64(duration))
- return s != 0
-
+ when !intrinsics.has_target_feature("atomics") {
+ _panic("usage of `core:sync` requires the `-target-feature:\"atomics\"` or a `-microarch` that supports it")
+ } else {
+ s := intrinsics.wasm_memory_atomic_wait32((^u32)(f), expected, i64(duration))
+ return s != 0
+ }
}
_futex_signal :: proc "contextless" (f: ^Futex) {
- loop: for {
- s := intrinsics.wasm_memory_atomic_notify32((^u32)(f), 1)
- if s >= 1 {
- return
+ when !intrinsics.has_target_feature("atomics") {
+ _panic("usage of `core:sync` requires the `-target-feature:\"atomics\"` or a `-microarch` that supports it")
+ } else {
+ loop: for {
+ s := intrinsics.wasm_memory_atomic_notify32((^u32)(f), 1)
+ if s >= 1 {
+ return
+ }
}
}
}
_futex_broadcast :: proc "contextless" (f: ^Futex) {
- loop: for {
- s := intrinsics.wasm_memory_atomic_notify32((^u32)(f), ~u32(0))
- if s >= 0 {
- return
+ when !intrinsics.has_target_feature("atomics") {
+ _panic("usage of `core:sync` requires the `-target-feature:\"atomics\"` or a `-microarch` that supports it")
+ } else {
+ loop: for {
+ s := intrinsics.wasm_memory_atomic_notify32((^u32)(f), ~u32(0))
+ if s >= 0 {
+ return
+ }
}
}
}
diff --git a/core/sys/darwin/sync.odin b/core/sys/darwin/sync.odin
index c76b30d6b..361b4b8b4 100644
--- a/core/sys/darwin/sync.odin
+++ b/core/sys/darwin/sync.odin
@@ -5,9 +5,9 @@ foreign import system "system:System.framework"
// #define OS_WAIT_ON_ADDR_AVAILABILITY \
// __API_AVAILABLE(macos(14.4), ios(17.4), tvos(17.4), watchos(10.4))
when ODIN_OS == .Darwin {
- when ODIN_PLATFORM_SUBTARGET == .iOS && ODIN_MINIMUM_OS_VERSION > 17_04_00 {
+ when ODIN_PLATFORM_SUBTARGET == .iOS && ODIN_MINIMUM_OS_VERSION >= 17_04_00 {
WAIT_ON_ADDRESS_AVAILABLE :: true
- } else when ODIN_MINIMUM_OS_VERSION > 14_04_00 {
+ } else when ODIN_MINIMUM_OS_VERSION >= 14_04_00 {
WAIT_ON_ADDRESS_AVAILABLE :: true
} else {
WAIT_ON_ADDRESS_AVAILABLE :: false
diff --git a/core/sys/linux/bits.odin b/core/sys/linux/bits.odin
index 4db689643..cfae06013 100644
--- a/core/sys/linux/bits.odin
+++ b/core/sys/linux/bits.odin
@@ -153,22 +153,41 @@ Errno :: enum i32 {
Open_Flags_Bits :: enum {
WRONLY = 0,
RDWR = 1,
- CREAT = 8,
- EXCL = 9,
- NOCTTY = 10,
- TRUNC = 11,
- APPEND = 12,
- NONBLOCK = 14,
- DSYNC = 16,
- ASYNC = 17,
- DIRECT = 18,
- LARGEFILE = 20,
- DIRECTORY = 21,
- NOFOLLOW = 22,
- NOATIME = 24,
- CLOEXEC = 25,
- PATH = 28,
-}
+ CREAT = 6,
+ EXCL = 7,
+ NOCTTY = 8,
+ TRUNC = 9,
+ APPEND = 10,
+ NONBLOCK = 11,
+ DSYNC = 12,
+ ASYNC = 13,
+ DIRECT = 14,
+ LARGEFILE = 15,
+ DIRECTORY = 16,
+ NOFOLLOW = 17,
+ NOATIME = 18,
+ CLOEXEC = 19,
+ PATH = 21,
+}
+
+// https://github.com/torvalds/linux/blob/7367539ad4b0f8f9b396baf02110962333719a48/include/uapi/asm-generic/fcntl.h#L19
+#assert(1 << uint(Open_Flags_Bits.WRONLY) == 0o0000000_1)
+#assert(1 << uint(Open_Flags_Bits.RDWR) == 0o0000000_2)
+#assert(1 << uint(Open_Flags_Bits.CREAT) == 0o00000_100)
+#assert(1 << uint(Open_Flags_Bits.EXCL) == 0o00000_200)
+#assert(1 << uint(Open_Flags_Bits.NOCTTY) == 0o00000_400)
+#assert(1 << uint(Open_Flags_Bits.TRUNC) == 0o0000_1000)
+#assert(1 << uint(Open_Flags_Bits.APPEND) == 0o0000_2000)
+#assert(1 << uint(Open_Flags_Bits.NONBLOCK) == 0o0000_4000)
+#assert(1 << uint(Open_Flags_Bits.DSYNC) == 0o000_10000)
+#assert(1 << uint(Open_Flags_Bits.ASYNC) == 0o000_20000)
+#assert(1 << uint(Open_Flags_Bits.DIRECT) == 0o000_40000)
+#assert(1 << uint(Open_Flags_Bits.LARGEFILE) == 0o00_100000)
+#assert(1 << uint(Open_Flags_Bits.DIRECTORY) == 0o00_200000)
+#assert(1 << uint(Open_Flags_Bits.NOFOLLOW) == 0o00_400000)
+#assert(1 << uint(Open_Flags_Bits.NOATIME) == 0o0_1000000)
+#assert(1 << uint(Open_Flags_Bits.CLOEXEC) == 0o0_2000000)
+#assert(1 << uint(Open_Flags_Bits.PATH) == 0o_10000000)
/*
Bits for FD_Flags bitset
diff --git a/core/sys/linux/helpers.odin b/core/sys/linux/helpers.odin
index 69c648bf1..75fdd586e 100644
--- a/core/sys/linux/helpers.odin
+++ b/core/sys/linux/helpers.odin
@@ -26,7 +26,7 @@ where
@(private)
syscall2 :: #force_inline proc "contextless" (nr: uintptr,p1: $T1, p2: $T2) -> int
where
- size_of(p1) <= size_of(uintptr) &&
+ size_of(p1) <= size_of(uintptr),
size_of(p2) <= size_of(uintptr)
{
return cast(int) intrinsics.syscall(nr,
@@ -36,8 +36,8 @@ where
@(private)
syscall3 :: #force_inline proc "contextless" (nr: uintptr, p1: $T1, p2: $T2, p3: $T3) -> int
where
- size_of(p1) <= size_of(uintptr) &&
- size_of(p2) <= size_of(uintptr) &&
+ size_of(p1) <= size_of(uintptr),
+ size_of(p2) <= size_of(uintptr),
size_of(p3) <= size_of(uintptr)
{
return cast(int) intrinsics.syscall(nr,
@@ -49,9 +49,9 @@ where
@(private)
syscall4 :: #force_inline proc "contextless" (nr: uintptr, p1: $T1, p2: $T2, p3: $T3, p4: $T4) -> int
where
- size_of(p1) <= size_of(uintptr) &&
- size_of(p2) <= size_of(uintptr) &&
- size_of(p3) <= size_of(uintptr) &&
+ size_of(p1) <= size_of(uintptr),
+ size_of(p2) <= size_of(uintptr),
+ size_of(p3) <= size_of(uintptr),
size_of(p4) <= size_of(uintptr)
{
return cast(int) intrinsics.syscall(nr,
@@ -64,10 +64,10 @@ where
@(private)
syscall5 :: #force_inline proc "contextless" (nr: uintptr, p1: $T1, p2: $T2, p3: $T3, p4: $T4, p5: $T5) -> int
where
- size_of(p1) <= size_of(uintptr) &&
- size_of(p2) <= size_of(uintptr) &&
- size_of(p3) <= size_of(uintptr) &&
- size_of(p4) <= size_of(uintptr) &&
+ size_of(p1) <= size_of(uintptr),
+ size_of(p2) <= size_of(uintptr),
+ size_of(p3) <= size_of(uintptr),
+ size_of(p4) <= size_of(uintptr),
size_of(p5) <= size_of(uintptr)
{
return cast(int) intrinsics.syscall(nr,
@@ -81,11 +81,11 @@ where
@(private)
syscall6 :: #force_inline proc "contextless" (nr: uintptr, p1: $T1, p2: $T2, p3: $T3, p4: $T4, p5: $T5, p6: $T6) -> int
where
- size_of(p1) <= size_of(uintptr) &&
- size_of(p2) <= size_of(uintptr) &&
- size_of(p3) <= size_of(uintptr) &&
- size_of(p4) <= size_of(uintptr) &&
- size_of(p5) <= size_of(uintptr) &&
+ size_of(p1) <= size_of(uintptr),
+ size_of(p2) <= size_of(uintptr),
+ size_of(p3) <= size_of(uintptr),
+ size_of(p4) <= size_of(uintptr),
+ size_of(p5) <= size_of(uintptr),
size_of(p6) <= size_of(uintptr)
{
return cast(int) intrinsics.syscall(nr,
diff --git a/core/sys/linux/sys.odin b/core/sys/linux/sys.odin
index 63fb3b776..413c8742b 100644
--- a/core/sys/linux/sys.odin
+++ b/core/sys/linux/sys.odin
@@ -2314,7 +2314,7 @@ futex :: proc {
*/
epoll_create :: proc(size: i32 = 1) -> (Fd, Errno) {
when ODIN_ARCH != .arm64 {
- ret := syscall(SYS_epoll_create)
+ ret := syscall(SYS_epoll_create, i32(1))
return errno_unwrap(ret, Fd)
} else {
ret := syscall(SYS_epoll_create1, i32(0))
diff --git a/core/thread/thread_unix.odin b/core/thread/thread_unix.odin
index e25d3541c..36ee035a5 100644
--- a/core/thread/thread_unix.odin
+++ b/core/thread/thread_unix.odin
@@ -25,7 +25,7 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
when ODIN_OS != .Darwin {
// We need to give the thread a moment to start up before we enable cancellation.
- can_set_thread_cancel_state := unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_DISABLE, nil) == 0
+ can_set_thread_cancel_state := unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_ENABLE, nil) == 0
}
sync.lock(&t.mutex)
@@ -40,7 +40,7 @@ _create :: proc(procedure: Thread_Proc, priority: Thread_Priority) -> ^Thread {
// Enable thread's cancelability.
if can_set_thread_cancel_state {
unix.pthread_setcanceltype (unix.PTHREAD_CANCEL_ASYNCHRONOUS, nil)
- unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_DISABLE, nil)
+ unix.pthread_setcancelstate(unix.PTHREAD_CANCEL_ENABLE, nil)
}
}