From 1bf33fe3735aeca1beecf9b1a3b648bae35aea3d Mon Sep 17 00:00:00 2001 From: gingerBill Date: Sun, 5 Jan 2025 12:53:20 +0000 Subject: [PATCH] Use static global memory for std handles instead of allocating. --- core/os/os2/allocators.odin | 1 + core/os/os2/file.odin | 2 +- core/os/os2/file_linux.odin | 56 +++++++++++++---------------------- core/os/os2/file_posix.odin | 49 +++++++++++++++++------------- core/os/os2/file_windows.odin | 53 +++++++++++++++++++++++---------- core/os/os2/pipe_linux.odin | 4 +-- core/os/os2/pipe_posix.odin | 4 +-- 7 files changed, 93 insertions(+), 76 deletions(-) diff --git a/core/os/os2/allocators.odin b/core/os/os2/allocators.odin index 864532850..61b3ec25a 100644 --- a/core/os/os2/allocators.odin +++ b/core/os/os2/allocators.odin @@ -2,6 +2,7 @@ package os2 import "base:runtime" +import "core:mem" @(require_results) file_allocator :: proc() -> runtime.Allocator { diff --git a/core/os/os2/file.odin b/core/os/os2/file.odin index eedf8570c..1a25472a1 100644 --- a/core/os/os2/file.odin +++ b/core/os/os2/file.odin @@ -115,7 +115,7 @@ open :: proc(name: string, flags := File_Flags{.Read}, perm := 0o777) -> (^File, @(require_results) new_file :: proc(handle: uintptr, name: string) -> ^File { - file, err := _new_file(handle, name) + file, err := _new_file(handle, name, file_allocator()) if err != nil { panic(error_string(err)) } diff --git a/core/os/os2/file_linux.odin b/core/os/os2/file_linux.odin index ad2892f40..f8e4026da 100644 --- a/core/os/os2/file_linux.odin +++ b/core/os/os2/file_linux.odin @@ -39,37 +39,23 @@ _stderr := File{ @init _standard_stream_init :: proc() { - @static stdin_impl := File_Impl { - name = "/proc/self/fd/0", - fd = 0, + new_std :: proc(impl: ^File_Impl, fd: linux.Fd, name: string) -> ^File { + impl.file.impl = impl + impl.fd = linux.Fd(fd) + impl.allocator = runtime.nil_allocator() + impl.name = name + impl.file.stream = { + data = impl, + procedure = _file_stream_proc, + } + impl.file.fstat = _fstat + return &impl.file } - @static stdout_impl := File_Impl { - name = "/proc/self/fd/1", - fd = 1, - } - - @static stderr_impl := File_Impl { - name = "/proc/self/fd/2", - fd = 2, - } - - stdin_impl.allocator = file_allocator() - stdout_impl.allocator = file_allocator() - stderr_impl.allocator = file_allocator() - - _stdin.impl = &stdin_impl - _stdout.impl = &stdout_impl - _stderr.impl = &stderr_impl - - // cannot define these initially because cyclic reference - _stdin.stream.data = &stdin_impl - _stdout.stream.data = &stdout_impl - _stderr.stream.data = &stderr_impl - - stdin = &_stdin - stdout = &_stdout - stderr = &_stderr + @(static) files: [3]File_Impl + stdin = new_std(&files[0], 0, "/proc/self/fd/0") + stdout = new_std(&files[1], 1, "/proc/self/fd/1") + stderr = new_std(&files[2], 2, "/proc/self/fd/2") } _open :: proc(name: string, flags: File_Flags, perm: int) -> (f: ^File, err: Error) { @@ -100,18 +86,18 @@ _open :: proc(name: string, flags: File_Flags, perm: int) -> (f: ^File, err: Err return nil, _get_platform_error(errno) } - return _new_file(uintptr(fd), name) + return _new_file(uintptr(fd), name, file_allocator()) } -_new_file :: proc(fd: uintptr, _: string = "") -> (f: ^File, err: Error) { - impl := new(File_Impl, file_allocator()) or_return +_new_file :: proc(fd: uintptr, _: string, allocator: runtime.Allocator) -> (f: ^File, err: Error) { + impl := new(File_Impl, allocator) or_return defer if err != nil { - free(impl, file_allocator()) + free(impl, allocator) } impl.file.impl = impl impl.fd = linux.Fd(fd) - impl.allocator = file_allocator() - impl.name = _get_full_path(impl.fd, file_allocator()) or_return + impl.allocator = allocator + impl.name = _get_full_path(impl.fd, impl.allocator) or_return impl.file.stream = { data = impl, procedure = _file_stream_proc, diff --git a/core/os/os2/file_posix.odin b/core/os/os2/file_posix.odin index b7dc43287..184c89368 100644 --- a/core/os/os2/file_posix.odin +++ b/core/os/os2/file_posix.odin @@ -21,23 +21,29 @@ File_Impl :: struct { name: string, cname: cstring, fd: posix.FD, + allocator: runtime.Allocator, } @(init) init_std_files :: proc() { - // NOTE: is this (paths) also the case on non darwin? + new_std :: proc(impl: ^File_Impl, fd: posix.FD, name: cstring) -> ^File { + impl.file.impl = impl + impl.fd = fd + impl.allocator = runtime.nil_allocator() + impl.cname = name + impl.name = string(name) + impl.file.stream = { + data = impl, + procedure = _file_stream_proc, + } + impl.file.fstat = _fstat + return &impl.file + } - stdin = __new_file(posix.STDIN_FILENO) - (^File_Impl)(stdin.impl).name = "/dev/stdin" - (^File_Impl)(stdin.impl).cname = "/dev/stdin" - - stdout = __new_file(posix.STDIN_FILENO) - (^File_Impl)(stdout.impl).name = "/dev/stdout" - (^File_Impl)(stdout.impl).cname = "/dev/stdout" - - stderr = __new_file(posix.STDIN_FILENO) - (^File_Impl)(stderr.impl).name = "/dev/stderr" - (^File_Impl)(stderr.impl).cname = "/dev/stderr" + @(static) files: [3]File_Impl + stdin = new_std(&files[0], posix.STDIN_FILENO, "/dev/stdin") + stdout = new_std(&files[1], posix.STDOUT_FILENO, "/dev/stdout") + stderr = new_std(&files[2], posix.STDERR_FILENO, "/dev/stderr") } _open :: proc(name: string, flags: File_Flags, perm: int) -> (f: ^File, err: Error) { @@ -72,10 +78,10 @@ _open :: proc(name: string, flags: File_Flags, perm: int) -> (f: ^File, err: Err return } - return _new_file(uintptr(fd), name) + return _new_file(uintptr(fd), name, file_allocator()) } -_new_file :: proc(handle: uintptr, name: string) -> (f: ^File, err: Error) { +_new_file :: proc(handle: uintptr, name: string, allocator: runtime.Allocator) -> (f: ^File, err: Error) { if name == "" { err = .Invalid_Path return @@ -84,10 +90,10 @@ _new_file :: proc(handle: uintptr, name: string) -> (f: ^File, err: Error) { return } - crname := _posix_absolute_path(posix.FD(handle), name, file_allocator()) or_return + crname := _posix_absolute_path(posix.FD(handle), name, allocator) or_return rname := string(crname) - f = __new_file(posix.FD(handle)) + f = __new_file(posix.FD(handle), allocator) impl := (^File_Impl)(f.impl) impl.name = rname impl.cname = crname @@ -95,10 +101,11 @@ _new_file :: proc(handle: uintptr, name: string) -> (f: ^File, err: Error) { return f, nil } -__new_file :: proc(handle: posix.FD) -> ^File { - impl := new(File_Impl, file_allocator()) +__new_file :: proc(handle: posix.FD, allocator: runtime.Allocator) -> ^File { + impl := new(File_Impl, allocator) impl.file.impl = impl impl.fd = posix.FD(handle) + impl.allocator = allocator impl.file.stream = { data = impl, procedure = _file_stream_proc, @@ -114,8 +121,10 @@ _close :: proc(f: ^File_Impl) -> (err: Error) { err = _get_platform_error() } - delete(f.cname, file_allocator()) - free(f, file_allocator()) + allocator := f.allocator + + delete(f.cname, allocator) + free(f, allocator) return } diff --git a/core/os/os2/file_windows.odin b/core/os/os2/file_windows.odin index b91a1bc3b..f594cc72f 100644 --- a/core/os/os2/file_windows.odin +++ b/core/os/os2/file_windows.odin @@ -44,17 +44,38 @@ File_Impl :: struct { @(init) init_std_files :: proc() { - stdin = new_file(uintptr(win32.GetStdHandle(win32.STD_INPUT_HANDLE)), "") - stdout = new_file(uintptr(win32.GetStdHandle(win32.STD_OUTPUT_HANDLE)), "") - stderr = new_file(uintptr(win32.GetStdHandle(win32.STD_ERROR_HANDLE)), "") -} -@(fini) -fini_std_files :: proc() { - _destroy((^File_Impl)(stdin.impl)) - _destroy((^File_Impl)(stdout.impl)) - _destroy((^File_Impl)(stderr.impl)) -} + new_std :: proc(impl: ^File_Impl, code: u32, name: string) -> ^File { + impl.file.impl = impl + impl.allocator = runtime.nil_allocator() + impl.fd = win32.GetStdHandle(code) + impl.name = name + impl.wname = nil + + handle := _handle(&impl.file) + kind := File_Impl_Kind.File + if m: u32; win32.GetConsoleMode(handle, &m) { + kind = .Console + } + if win32.GetFileType(handle) == win32.FILE_TYPE_PIPE { + kind = .Pipe + } + impl.kind = kind + + impl.file.stream = { + data = impl, + procedure = _file_stream_proc, + } + impl.file.fstat = _fstat + + return &impl.file + } + + @(static) files: [3]File_Impl + stdin = new_std(&files[0], win32.STD_INPUT_HANDLE, "") + stdout = new_std(&files[1], win32.STD_OUTPUT_HANDLE, "") + stderr = new_std(&files[2], win32.STD_ERROR_HANDLE, "") +} _handle :: proc(f: ^File) -> win32.HANDLE { return win32.HANDLE(_fd(f)) @@ -132,21 +153,21 @@ _open_internal :: proc(name: string, flags: File_Flags, perm: int) -> (handle: u _open :: proc(name: string, flags: File_Flags, perm: int) -> (f: ^File, err: Error) { flags := flags if flags != nil else {.Read} handle := _open_internal(name, flags, perm) or_return - return _new_file(handle, name) + return _new_file(handle, name, file_allocator()) } -_new_file :: proc(handle: uintptr, name: string) -> (f: ^File, err: Error) { +_new_file :: proc(handle: uintptr, name: string, allocator: runtime.Allocator) -> (f: ^File, err: Error) { if handle == INVALID_HANDLE { return } - impl := new(File_Impl, file_allocator()) or_return + impl := new(File_Impl, allocator) or_return defer if err != nil { - free(impl, file_allocator()) + free(impl, allocator) } impl.file.impl = impl - impl.allocator = file_allocator() + impl.allocator = allocator impl.fd = rawptr(handle) impl.name = clone_string(name, impl.allocator) or_return impl.wname = win32_utf8_to_wstring(name, impl.allocator) or_return @@ -180,7 +201,7 @@ _open_buffered :: proc(name: string, buffer_size: uint, flags := File_Flags{.Rea } _new_file_buffered :: proc(handle: uintptr, name: string, buffer_size: uint) -> (f: ^File, err: Error) { - f, err = _new_file(handle, name) + f, err = _new_file(handle, name, file_allocator()) if f != nil && err == nil { impl := (^File_Impl)(f.impl) impl.r_buf = make([]byte, buffer_size, file_allocator()) diff --git a/core/os/os2/pipe_linux.odin b/core/os/os2/pipe_linux.odin index 852674c69..bb4456e1c 100644 --- a/core/os/os2/pipe_linux.odin +++ b/core/os/os2/pipe_linux.odin @@ -10,8 +10,8 @@ _pipe :: proc() -> (r, w: ^File, err: Error) { return nil, nil,_get_platform_error(errno) } - r = _new_file(uintptr(fds[0])) or_return - w = _new_file(uintptr(fds[1])) or_return + r = _new_file(uintptr(fds[0]), "", file_allocator()) or_return + w = _new_file(uintptr(fds[1]), "", file_allocator()) or_return return } diff --git a/core/os/os2/pipe_posix.odin b/core/os/os2/pipe_posix.odin index df9425339..edead2ab3 100644 --- a/core/os/os2/pipe_posix.odin +++ b/core/os/os2/pipe_posix.odin @@ -21,7 +21,7 @@ _pipe :: proc() -> (r, w: ^File, err: Error) { return } - r = __new_file(fds[0]) + r = __new_file(fds[0], file_allocator()) ri := (^File_Impl)(r.impl) rname := strings.builder_make(file_allocator()) @@ -31,7 +31,7 @@ _pipe :: proc() -> (r, w: ^File, err: Error) { ri.name = strings.to_string(rname) ri.cname = strings.to_cstring(&rname) - w = __new_file(fds[1]) + w = __new_file(fds[1], file_allocator()) wi := (^File_Impl)(w.impl) wname := strings.builder_make(file_allocator())