From 46489a1cd5ac402114617e46938dce52fcff67bb Mon Sep 17 00:00:00 2001 From: Jeroen van Rijn Date: Tue, 28 Oct 2025 19:01:25 +0100 Subject: [PATCH] In the middle of porting core:testing --- core/fmt/fmt_js.odin | 30 +++++++++++------------ core/fmt/fmt_os.odin | 34 ++++++++++++++------------- core/log/file_console_logger.odin | 34 +++++++++++++-------------- core/os/os2/file.odin | 5 ++++ core/os/os2/file_js.odin | 3 +++ core/os/os2/file_linux.odin | 12 ++++++++++ core/os/os2/file_posix.odin | 6 +++++ core/os/os2/file_posix_darwin.odin | 2 +- core/os/os2/file_wasi.odin | 4 ++++ core/os/os2/file_windows.odin | 5 ++++ core/os/os2/process.odin | 15 ++++++++++++ core/os/os2/process_freebsd.odin | 33 ++++++++++++++++++++++++++ core/os/os2/process_js.odin | 8 +++++++ core/os/os2/process_linux.odin | 18 ++++++++++++++ core/os/os2/process_netbsd.odin | 28 ++++++++++++++++++++++ core/os/os2/process_openbsd.odin | 20 ++++++++++++++++ core/os/os2/process_posix_darwin.odin | 29 +++++++++++++++++++++-- core/os/os2/process_wasi.odin | 8 +++++++ core/os/os2/process_windows.odin | 30 +++++++++++++++++++++++ core/os/os_darwin.odin | 2 +- core/terminal/internal.odin | 8 +++---- core/terminal/terminal_posix.odin | 6 +---- core/terminal/terminal_windows.odin | 5 +--- core/testing/runner.odin | 8 +++---- core/testing/signal_handler_libc.odin | 10 ++++---- 25 files changed, 288 insertions(+), 75 deletions(-) create mode 100644 core/os/os2/process_freebsd.odin create mode 100644 core/os/os2/process_netbsd.odin create mode 100644 core/os/os2/process_openbsd.odin diff --git a/core/fmt/fmt_js.odin b/core/fmt/fmt_js.odin index ce90fbfe7..26a33a630 100644 --- a/core/fmt/fmt_js.odin +++ b/core/fmt/fmt_js.odin @@ -1,9 +1,9 @@ #+build js package fmt -import "core:bufio" -import "core:io" -import "core:os" +import "core:bufio" +import "core:io" +import os "core:os/os2" foreign import "odin_env" @@ -34,52 +34,52 @@ stderr := io.Writer{ } @(private="file") -fd_to_writer :: proc(fd: os.Handle, loc := #caller_location) -> io.Writer { - switch fd { - case 1: return stdout - case 2: return stderr +fd_to_writer :: proc(f: ^os.File, loc := #caller_location) -> io.Writer { + switch { + case f == os.stdout: return stdout + case f == os.stderr: return stderr case: panic("`fmt.fprint` variant called with invalid file descriptor for JS, only 1 (stdout) and 2 (stderr) are supported", loc) } } // fprint formats using the default print settings and writes to fd -fprint :: proc(fd: os.Handle, args: ..any, sep := " ", flush := true, loc := #caller_location) -> int { +fprint :: proc(f: ^os.File, args: ..any, sep := " ", flush := true, loc := #caller_location) -> int { buf: [1024]byte b: bufio.Writer defer bufio.writer_flush(&b) - bufio.writer_init_with_buf(&b, fd_to_writer(fd, loc), buf[:]) + bufio.writer_init_with_buf(&b, fd_to_writer(f, loc), buf[:]) w := bufio.writer_to_writer(&b) return wprint(w, ..args, sep=sep, flush=flush) } // fprintln formats using the default print settings and writes to fd -fprintln :: proc(fd: os.Handle, args: ..any, sep := " ", flush := true, loc := #caller_location) -> int { +fprintln :: proc(f: ^os.File, args: ..any, sep := " ", flush := true, loc := #caller_location) -> int { buf: [1024]byte b: bufio.Writer defer bufio.writer_flush(&b) - bufio.writer_init_with_buf(&b, fd_to_writer(fd, loc), buf[:]) + bufio.writer_init_with_buf(&b, fd_to_writer(f, loc), buf[:]) w := bufio.writer_to_writer(&b) return wprintln(w, ..args, sep=sep, flush=flush) } // fprintf formats according to the specified format string and writes to fd -fprintf :: proc(fd: os.Handle, fmt: string, args: ..any, flush := true, newline := false, loc := #caller_location) -> int { +fprintf :: proc(f: ^os.File, fmt: string, args: ..any, flush := true, newline := false, loc := #caller_location) -> int { buf: [1024]byte b: bufio.Writer defer bufio.writer_flush(&b) - bufio.writer_init_with_buf(&b, fd_to_writer(fd, loc), buf[:]) + bufio.writer_init_with_buf(&b, fd_to_writer(f, loc), buf[:]) w := bufio.writer_to_writer(&b) return wprintf(w, fmt, ..args, flush=flush, newline=newline) } // fprintfln formats according to the specified format string and writes to fd, followed by a newline. -fprintfln :: proc(fd: os.Handle, fmt: string, args: ..any, flush := true, loc := #caller_location) -> int { - return fprintf(fd, fmt, ..args, flush=flush, newline=true, loc=loc) +fprintfln :: proc(f: ^os.File, fmt: string, args: ..any, flush := true, loc := #caller_location) -> int { + return fprintf(f, fmt, ..args, flush=flush, newline=true, loc=loc) } // print formats using the default print settings and writes to stdout diff --git a/core/fmt/fmt_os.odin b/core/fmt/fmt_os.odin index a481061f1..1f292c9e4 100644 --- a/core/fmt/fmt_os.odin +++ b/core/fmt/fmt_os.odin @@ -3,64 +3,66 @@ #+build !orca package fmt -import "base:runtime" -import "core:os" -import "core:io" -import "core:bufio" +import "base:runtime" +import os "core:os/os2" +import "core:io" +import "core:bufio" + +// NOTE(Jeroen): The other option is to deprecate `fprint*` and make it an alias for `wprint*`, using File.stream directly. // fprint formats using the default print settings and writes to fd -fprint :: proc(fd: os.Handle, args: ..any, sep := " ", flush := true) -> int { +fprint :: proc(f: ^os.File, args: ..any, sep := " ", flush := true) -> int { buf: [1024]byte b: bufio.Writer defer bufio.writer_flush(&b) - bufio.writer_init_with_buf(&b, os.stream_from_handle(fd), buf[:]) + bufio.writer_init_with_buf(&b, f.stream, buf[:]) w := bufio.writer_to_writer(&b) return wprint(w, ..args, sep=sep, flush=flush) } // fprintln formats using the default print settings and writes to fd -fprintln :: proc(fd: os.Handle, args: ..any, sep := " ", flush := true) -> int { +fprintln :: proc(f: ^os.File, args: ..any, sep := " ", flush := true) -> int { buf: [1024]byte b: bufio.Writer defer bufio.writer_flush(&b) - bufio.writer_init_with_buf(&b, os.stream_from_handle(fd), buf[:]) + bufio.writer_init_with_buf(&b, f.stream, buf[:]) w := bufio.writer_to_writer(&b) return wprintln(w, ..args, sep=sep, flush=flush) } // fprintf formats according to the specified format string and writes to fd -fprintf :: proc(fd: os.Handle, fmt: string, args: ..any, flush := true, newline := false) -> int { +fprintf :: proc(f: ^os.File, fmt: string, args: ..any, flush := true, newline := false) -> int { buf: [1024]byte b: bufio.Writer defer bufio.writer_flush(&b) - bufio.writer_init_with_buf(&b, os.stream_from_handle(fd), buf[:]) + bufio.writer_init_with_buf(&b, f.stream, buf[:]) w := bufio.writer_to_writer(&b) return wprintf(w, fmt, ..args, flush=flush, newline=newline) } // fprintfln formats according to the specified format string and writes to fd, followed by a newline. -fprintfln :: proc(fd: os.Handle, fmt: string, args: ..any, flush := true) -> int { - return fprintf(fd, fmt, ..args, flush=flush, newline=true) +fprintfln :: proc(f: ^os.File, fmt: string, args: ..any, flush := true) -> int { + return fprintf(f, fmt, ..args, flush=flush, newline=true) } -fprint_type :: proc(fd: os.Handle, info: ^runtime.Type_Info, flush := true) -> (n: int, err: io.Error) { +fprint_type :: proc(f: ^os.File, info: ^runtime.Type_Info, flush := true) -> (n: int, err: io.Error) { buf: [1024]byte b: bufio.Writer defer bufio.writer_flush(&b) - bufio.writer_init_with_buf(&b, os.stream_from_handle(fd), buf[:]) + bufio.writer_init_with_buf(&b, f.stream, buf[:]) w := bufio.writer_to_writer(&b) return wprint_type(w, info, flush=flush) } -fprint_typeid :: proc(fd: os.Handle, id: typeid, flush := true) -> (n: int, err: io.Error) { +fprint_typeid :: proc(f: ^os.File, id: typeid, flush := true) -> (n: int, err: io.Error) { buf: [1024]byte b: bufio.Writer defer bufio.writer_flush(&b) - bufio.writer_init_with_buf(&b, os.stream_from_handle(fd), buf[:]) + bufio.writer_init_with_buf(&b, f.stream, buf[:]) w := bufio.writer_to_writer(&b) return wprint_typeid(w, id, flush=flush) diff --git a/core/log/file_console_logger.odin b/core/log/file_console_logger.odin index f0acc8a22..a9b073c18 100644 --- a/core/log/file_console_logger.odin +++ b/core/log/file_console_logger.odin @@ -2,13 +2,13 @@ #+build !orca package log -import "base:runtime" -import "core:fmt" -import "core:strings" -import "core:os" -import "core:terminal" -import "core:terminal/ansi" -import "core:time" +import "base:runtime" +import "core:fmt" +import "core:strings" +import os "core:os/os2" +import "core:terminal" +import "core:terminal/ansi" +import "core:time" Level_Headers := [?]string{ 0..<10 = "[DEBUG] --- ", @@ -35,7 +35,7 @@ Default_File_Logger_Opts :: Options{ File_Console_Logger_Data :: struct { - file_handle: os.Handle, + file_handle: ^os.File, ident: string, } @@ -66,16 +66,16 @@ init_standard_stream_status :: proc "contextless" () { } } -create_file_logger :: proc(h: os.Handle, lowest := Level.Debug, opt := Default_File_Logger_Opts, ident := "", allocator := context.allocator) -> Logger { +create_file_logger :: proc(f: ^os.File, lowest := Level.Debug, opt := Default_File_Logger_Opts, ident := "", allocator := context.allocator) -> Logger { data := new(File_Console_Logger_Data, allocator) - data.file_handle = h + data.file_handle = f data.ident = ident return Logger{file_logger_proc, data, lowest, opt} } destroy_file_logger :: proc(log: Logger, allocator := context.allocator) { data := cast(^File_Console_Logger_Data)log.data - if data.file_handle != os.INVALID_HANDLE { + if data.file_handle != nil { os.close(data.file_handle) } free(data, allocator) @@ -83,7 +83,7 @@ destroy_file_logger :: proc(log: Logger, allocator := context.allocator) { create_console_logger :: proc(lowest := Level.Debug, opt := Default_Console_Logger_Opts, ident := "", allocator := context.allocator) -> Logger { data := new(File_Console_Logger_Data, allocator) - data.file_handle = os.INVALID_HANDLE + data.file_handle = nil data.ident = ident return Logger{console_logger_proc, data, lowest, opt} } @@ -93,7 +93,7 @@ destroy_console_logger :: proc(log: Logger, allocator := context.allocator) { } @(private) -_file_console_logger_proc :: proc(h: os.Handle, ident: string, level: Level, text: string, options: Options, location: runtime.Source_Code_Location) { +_file_console_logger_proc :: proc(h: ^os.File, ident: string, level: Level, text: string, options: Options, location: runtime.Source_Code_Location) { backing: [1024]byte //NOTE(Hoej): 1024 might be too much for a header backing, unless somebody has really long paths. buf := strings.builder_from_bytes(backing[:]) @@ -106,9 +106,7 @@ _file_console_logger_proc :: proc(h: os.Handle, ident: string, level: Level, tex do_location_header(options, &buf, location) if .Thread_Id in options { - // NOTE(Oskar): not using context.thread_id here since that could be - // incorrect when replacing context for a thread. - fmt.sbprintf(&buf, "[{}] ", os.current_thread_id()) + fmt.sbprintf(&buf, "[{}] ", os.get_current_thread_id()) } if ident != "" { @@ -126,7 +124,7 @@ file_logger_proc :: proc(logger_data: rawptr, level: Level, text: string, option console_logger_proc :: proc(logger_data: rawptr, level: Level, text: string, options: Options, location := #caller_location) { options := options data := cast(^File_Console_Logger_Data)logger_data - h: os.Handle = --- + h: ^os.File = nil if level < Level.Error { h = os.stdout options -= global_subtract_stdout_options @@ -216,4 +214,4 @@ do_location_header :: proc(opts: Options, buf: ^strings.Builder, location := #ca } fmt.sbprint(buf, "] ") -} +} \ No newline at end of file diff --git a/core/os/os2/file.odin b/core/os/os2/file.odin index a9878a563..9bc12cdd4 100644 --- a/core/os/os2/file.odin +++ b/core/os/os2/file.odin @@ -311,6 +311,11 @@ is_directory :: proc(path: string) -> bool { return fi.type == .Directory } +@(require_results) +is_tty :: proc "contextless" (f: ^File) -> bool { + return _is_tty(f) +} + copy_file :: proc(dst_path, src_path: string) -> Error { when #defined(_copy_file_native) { diff --git a/core/os/os2/file_js.odin b/core/os/os2/file_js.odin index fd4bf347c..492e3557f 100644 --- a/core/os/os2/file_js.odin +++ b/core/os/os2/file_js.odin @@ -29,6 +29,9 @@ _fd :: proc(f: ^File) -> uintptr { return 0 } +_is_tty :: proc "contextless" (f: ^File) -> bool { + return true +} _name :: proc(f: ^File) -> string { return "" diff --git a/core/os/os2/file_linux.odin b/core/os/os2/file_linux.odin index 85f639c8b..19eb0f1e8 100644 --- a/core/os/os2/file_linux.odin +++ b/core/os/os2/file_linux.odin @@ -6,6 +6,7 @@ import "core:io" import "core:time" import "core:sync" import "core:sys/linux" +import "core:sys/posix" // Most implementations will EINVAL at some point when doing big writes. // In practice a read/write call would probably never read/write these big buffers all at once, @@ -178,6 +179,17 @@ _fd :: proc(f: ^File) -> uintptr { return uintptr(impl.fd) } +_is_tty :: proc "contextless" (f: ^File) -> bool { + if f == nil || f.impl == nil { + return false + } + impl := (^File_Impl)(f.impl) + + // TODO: Replace `posix.isatty` with `tcgetattr(fd, &termios) == 0` + is_tty := posix.isatty(posix.FD(impl.fd)) + return bool(is_tty) +} + _name :: proc(f: ^File) -> string { return (^File_Impl)(f.impl).name if f != nil && f.impl != nil else "" } diff --git a/core/os/os2/file_posix.odin b/core/os/os2/file_posix.odin index a251a3ae7..cbf35e7fe 100644 --- a/core/os/os2/file_posix.odin +++ b/core/os/os2/file_posix.odin @@ -162,6 +162,12 @@ __fd :: proc(f: ^File) -> posix.FD { return -1 } +is_tty :: proc "contextless" (f: ^File) -> bool { + fd := _fd(f) + is_tty := posix.isatty(posix.FD(fd)) + return bool(is_tty) +} + _name :: proc(f: ^File) -> string { if f != nil && f.impl != nil { return (^File_Impl)(f.impl).name diff --git a/core/os/os2/file_posix_darwin.odin b/core/os/os2/file_posix_darwin.odin index aed3e56f5..521fb345b 100644 --- a/core/os/os2/file_posix_darwin.odin +++ b/core/os/os2/file_posix_darwin.odin @@ -43,4 +43,4 @@ _copy_file_native :: proc(dst_path, src_path: string) -> (err: Error) { } return -} +} \ No newline at end of file diff --git a/core/os/os2/file_wasi.odin b/core/os/os2/file_wasi.odin index f3dbcf660..5578a061a 100644 --- a/core/os/os2/file_wasi.odin +++ b/core/os/os2/file_wasi.odin @@ -271,6 +271,10 @@ __fd :: proc(f: ^File) -> wasi.fd_t { return -1 } +_is_tty :: proc "contextless" (f: ^File) -> bool { + return false +} + _name :: proc(f: ^File) -> string { if f != nil && f.impl != nil { return (^File_Impl)(f.impl).name diff --git a/core/os/os2/file_windows.odin b/core/os/os2/file_windows.odin index b39e65fe2..3bafa852b 100644 --- a/core/os/os2/file_windows.odin +++ b/core/os/os2/file_windows.odin @@ -241,6 +241,11 @@ _fd :: proc "contextless" (f: ^File) -> uintptr { return uintptr((^File_Impl)(f.impl).fd) } +_is_tty :: proc "contextless" (f: ^File) -> bool { + fd := _fd(f) + return win32.GetFileType(win32.HANDLE(fd)) == win32.FILE_TYPE_CHAR +} + _destroy :: proc(f: ^File_Impl) -> Error { if f == nil { return nil diff --git a/core/os/os2/process.odin b/core/os/os2/process.odin index 635befc64..a26553685 100644 --- a/core/os/os2/process.odin +++ b/core/os/os2/process.odin @@ -114,6 +114,21 @@ get_ppid :: proc() -> int { return _get_ppid() } +/* +Obtain the current thread id +*/ +@(require_results) +get_current_thread_id :: proc "contextless" () -> int { + return _get_current_thread_id() +} + +/* +Return the number of cores +*/ +get_processor_core_count :: proc() -> int { + return _get_processor_core_count() +} + /* Obtain ID's of all processes running in the system. */ diff --git a/core/os/os2/process_freebsd.odin b/core/os/os2/process_freebsd.odin new file mode 100644 index 000000000..77f632192 --- /dev/null +++ b/core/os/os2/process_freebsd.odin @@ -0,0 +1,33 @@ +#+private +#+build freebsd + +foreign import libc "system:c" +foreign import dl "system:dl" + +foreign libc { + @(link_name="sysctlbyname") + _sysctlbyname :: proc(path: cstring, oldp: rawptr, oldlenp: rawptr, newp: rawptr, newlen: int) -> c.int --- +} + +foreign dl { + @(link_name="pthread_getthreadid_np") + pthread_getthreadid_np :: proc() -> c.int --- +} + +@(require_results) +_get_current_thread_id :: proc "contextless" () -> int { + return int(pthread_getthreadid_np()) +} + +@(require_results) +_get_processor_core_count :: proc() -> int { + count : int = 0 + count_size := size_of(count) + if _sysctlbyname("hw.ncpu", &count, &count_size, nil, 0) == 0 { + if count > 0 { + return count + } + } + + return 1 +} \ No newline at end of file diff --git a/core/os/os2/process_js.odin b/core/os/os2/process_js.odin index a2db3d56e..a59a79d45 100644 --- a/core/os/os2/process_js.odin +++ b/core/os/os2/process_js.odin @@ -34,6 +34,14 @@ _get_ppid :: proc() -> int { return 0 } +_get_current_thread_id :: proc "contextless" () -> int { + return 0 +} + +_get_processor_core_count :: proc() -> int { + return 1 +} + _process_info_by_handle :: proc(process: Process, selection: Process_Info_Fields, allocator: runtime.Allocator) -> (info: Process_Info, err: Error) { err = .Unsupported return diff --git a/core/os/os2/process_linux.odin b/core/os/os2/process_linux.odin index 43ab78bdb..78df5cc40 100644 --- a/core/os/os2/process_linux.odin +++ b/core/os/os2/process_linux.odin @@ -5,12 +5,20 @@ package os2 import "base:runtime" import "base:intrinsics" +import "core:c" import "core:time" import "core:slice" import "core:strings" import "core:strconv" +import "core:sys/unix" import "core:sys/linux" +foreign import libc "system:c" + +foreign libc { + @(link_name="get_nprocs") _unix_get_nprocs :: proc() -> c.int --- +} + PIDFD_UNASSIGNED :: ~uintptr(0) @(private="package") @@ -48,6 +56,16 @@ _get_ppid :: proc() -> int { return int(linux.getppid()) } +@(private="package") +_get_current_thread_id :: proc "contextless" () -> int { + return unix.sys_gettid() +} + +@(private="package") +_get_processor_core_count :: proc() -> int { + return int(_unix_get_nprocs()) +} + @(private="package") _process_list :: proc(allocator: runtime.Allocator) -> (list: []int, err: Error) { temp_allocator := TEMP_ALLOCATOR_GUARD({ allocator }) diff --git a/core/os/os2/process_netbsd.odin b/core/os/os2/process_netbsd.odin new file mode 100644 index 000000000..53e32a68c --- /dev/null +++ b/core/os/os2/process_netbsd.odin @@ -0,0 +1,28 @@ +#+private +#+build netbsd + +@(private) +foreign libc { + @(link_name="lwp_self") + _lwp_self :: proc() -> i32 --- + + @(link_name="sysctlbyname") + _sysctlbyname :: proc(path: cstring, oldp: rawptr, oldlenp: rawptr, newp: rawptr, newlen: int) -> c.int --- +} + +@(require_results) +_get_current_thread_id :: proc "contextless" () -> int { + return int(lwp_self()) +} + +_get_processor_core_count :: proc() -> int { + count : int = 0 + count_size := size_of(count) + if _sysctlbyname("hw.ncpu", &count, &count_size, nil, 0) == 0 { + if count > 0 { + return count + } + } + + return 1 +} \ No newline at end of file diff --git a/core/os/os2/process_openbsd.odin b/core/os/os2/process_openbsd.odin new file mode 100644 index 000000000..90f2b5412 --- /dev/null +++ b/core/os/os2/process_openbsd.odin @@ -0,0 +1,20 @@ +#+private +#+build openbsd + +@(default_calling_convention="c") +foreign libc { + @(link_name="getthrid") _unix_getthrid :: proc() -> int --- + @(link_name="sysconf") _sysconf :: proc(name: c.int) -> c.long --- +} + +@(require_results) +_get_current_thread_id :: proc "contextless" () -> int { + return _unix_getthrid() +} + +_SC_NPROCESSORS_ONLN :: 503 + +@(private, require_results) +_get_processor_core_count :: proc() -> int { + return int(_sysconf(_SC_NPROCESSORS_ONLN)) +} \ No newline at end of file diff --git a/core/os/os2/process_posix_darwin.odin b/core/os/os2/process_posix_darwin.odin index f655d42a9..d0be228bb 100644 --- a/core/os/os2/process_posix_darwin.odin +++ b/core/os/os2/process_posix_darwin.odin @@ -10,14 +10,39 @@ import "core:sys/posix" import "core:sys/unix" import "core:time" -foreign import lib "system:System" +foreign import libc "system:System" -foreign lib { +foreign libc { sysctl :: proc "c" ( name: [^]i32, namelen: u32, oldp: rawptr, oldlenp: ^uint, newp: rawptr, newlen: uint, ) -> posix.result --- + + @(link_name="sysctlbyname") + _sysctlbyname :: proc(path: cstring, oldp: rawptr, oldlenp: rawptr, newp: rawptr, newlen: int) -> c.int --- +} + +_get_current_thread_id :: proc "contextless" () -> int { + tid: u64 + // NOTE(Oskar): available from OSX 10.6 and iOS 3.2. + // For older versions there is `syscall(SYS_thread_selfid)`, but not really + // the same thing apparently. + foreign pthread { pthread_threadid_np :: proc "c" (rawptr, ^u64) -> c.int --- } + pthread_threadid_np(nil, &tid) + return int(tid) +} + +_processor_core_count :: proc() -> int { + count : int = 0 + count_size := size_of(count) + if _sysctlbyname("hw.logicalcpu", &count, &count_size, nil, 0) == 0 { + if count > 0 { + return count + } + } + + return 1 } _process_info_by_pid :: proc(pid: int, selection: Process_Info_Fields, allocator: runtime.Allocator) -> (info: Process_Info, err: Error) { diff --git a/core/os/os2/process_wasi.odin b/core/os/os2/process_wasi.odin index 9f4d61649..963be04e0 100644 --- a/core/os/os2/process_wasi.odin +++ b/core/os/os2/process_wasi.odin @@ -34,6 +34,14 @@ _get_ppid :: proc() -> int { return 0 } +_get_current_thread_id :: proc "contextless" () -> int { + return 0 +} + +_get_processor_core_count :: proc() -> int { + return 1 +} + _process_info_by_handle :: proc(process: Process, selection: Process_Info_Fields, allocator: runtime.Allocator) -> (info: Process_Info, err: Error) { err = .Unsupported return diff --git a/core/os/os2/process_windows.odin b/core/os/os2/process_windows.odin index 990da6616..fa949071b 100644 --- a/core/os/os2/process_windows.odin +++ b/core/os/os2/process_windows.odin @@ -1,6 +1,7 @@ #+private file package os2 +import "base:intrinsics" import "base:runtime" import "core:strings" @@ -55,6 +56,35 @@ _get_ppid :: proc() -> int { return -1 } +@(private="package") +_get_current_thread_id :: proc "contextless" () -> int { + return int(win32.GetCurrentThreadId()) +} + +@(private="package") +_get_processor_core_count :: proc() -> int { + length : win32.DWORD = 0 + result := win32.GetLogicalProcessorInformation(nil, &length) + + thread_count := 0 + if !result && win32.GetLastError() == 122 && length > 0 { + runtime.DEFAULT_TEMP_ALLOCATOR_TEMP_GUARD() + processors := make([]win32.SYSTEM_LOGICAL_PROCESSOR_INFORMATION, length, context.temp_allocator) + + result = win32.GetLogicalProcessorInformation(&processors[0], &length) + if result { + for processor in processors { + if processor.Relationship == .RelationProcessorCore { + thread := intrinsics.count_ones(processor.ProcessorMask) + thread_count += int(thread) + } + } + } + } + + return thread_count +} + @(private="package") _process_list :: proc(allocator: runtime.Allocator) -> (list: []int, err: Error) { snap := win32.CreateToolhelp32Snapshot(win32.TH32CS_SNAPPROCESS, 0) diff --git a/core/os/os_darwin.odin b/core/os/os_darwin.odin index 77b5825dd..5a8f44672 100644 --- a/core/os/os_darwin.odin +++ b/core/os/os_darwin.odin @@ -598,7 +598,7 @@ foreign libc { @(link_name="fstat64") _unix_fstat :: proc(fd: Handle, stat: ^OS_Stat) -> c.int --- @(link_name="readlink") _unix_readlink :: proc(path: cstring, buf: ^byte, bufsiz: c.size_t) -> c.ssize_t --- @(link_name="access") _unix_access :: proc(path: cstring, mask: c.int) -> c.int --- - @(link_name="fsync") _unix_fsync :: proc(handle: Handle) -> c.int --- + @(link_name="fsync") _unix_fsync :: proc(handle: Handle) -> c.int --- @(link_name="dup") _unix_dup :: proc(handle: Handle) -> Handle --- @(link_name="fdopendir$INODE64") _unix_fdopendir_amd64 :: proc(fd: Handle) -> Dir --- diff --git a/core/terminal/internal.odin b/core/terminal/internal.odin index 9404ff833..524a83239 100644 --- a/core/terminal/internal.odin +++ b/core/terminal/internal.odin @@ -1,9 +1,9 @@ #+private package terminal -import "base:runtime" -import "core:os" -import "core:strings" +import "base:runtime" +import os "core:os/os2" +import "core:strings" // Reference documentation: // @@ -86,4 +86,4 @@ init_terminal :: proc "contextless" () { @(fini) fini_terminal :: proc "contextless" () { _fini_terminal() -} +} \ No newline at end of file diff --git a/core/terminal/terminal_posix.odin b/core/terminal/terminal_posix.odin index 341b9084b..751ef85cf 100644 --- a/core/terminal/terminal_posix.odin +++ b/core/terminal/terminal_posix.odin @@ -4,13 +4,9 @@ package terminal import "base:runtime" import os "core:os/os2" -import "core:sys/posix" _is_terminal :: proc "contextless" (f: ^os.File) -> bool { - context = runtime.default_context() - fd := os.fd(f) - is_tty := posix.isatty(posix.FD(fd)) - return bool(is_tty) + return os.is_tty(f) } _init_terminal :: proc "contextless" () { diff --git a/core/terminal/terminal_windows.odin b/core/terminal/terminal_windows.odin index d1ade13f3..78d21952b 100644 --- a/core/terminal/terminal_windows.odin +++ b/core/terminal/terminal_windows.odin @@ -6,10 +6,7 @@ import os "core:os/os2" import "core:sys/windows" _is_terminal :: proc "contextless" (f: ^os.File) -> bool { - context = runtime.default_context() - fd := os.fd(f) - is_tty := windows.GetFileType(windows.HANDLE(fd)) == windows.FILE_TYPE_CHAR - return is_tty + return os.is_tty(f) } old_modes: [2]struct{ diff --git a/core/testing/runner.odin b/core/testing/runner.odin index b53bd8722..627547843 100644 --- a/core/testing/runner.odin +++ b/core/testing/runner.odin @@ -20,7 +20,7 @@ import "core:io" @require import "core:log" import "core:math/rand" import "core:mem" -import "core:os" +import os "core:os/os2" import "core:slice" @require import "core:strings" import "core:sync/chan" @@ -216,8 +216,8 @@ runner :: proc(internal_tests: []Internal_Test) -> bool { } } - stdout := io.to_writer(os.stream_from_handle(os.stdout)) - stderr := io.to_writer(os.stream_from_handle(os.stderr)) + stdout := os.stdout.stream + stderr := os.stderr.stream // The animations are only ever shown through STDOUT; // STDERR is used exclusively for logging regardless of error level. @@ -314,7 +314,7 @@ runner :: proc(internal_tests: []Internal_Test) -> bool { // -- Set thread count. when TEST_THREADS == 0 { - thread_count := os.processor_core_count() + thread_count := os.get_processor_core_count() } else { thread_count := max(1, TEST_THREADS) } diff --git a/core/testing/signal_handler_libc.odin b/core/testing/signal_handler_libc.odin index 961f5c7ce..0ee9ccfa1 100644 --- a/core/testing/signal_handler_libc.odin +++ b/core/testing/signal_handler_libc.odin @@ -10,11 +10,11 @@ package testing Feoramund: Total rewrite. */ -import "base:intrinsics" -import "core:c/libc" -import "core:os" -import "core:sync" -import "core:terminal/ansi" +import "base:intrinsics" +import "core:c/libc" +import os "core:os/os2" +import "core:sync" +import "core:terminal/ansi" @(private="file") stop_runner_flag: libc.sig_atomic_t