Browse Source

Use static global memory for std handles instead of allocating.

gingerBill 7 months ago
parent
commit
1bf33fe373

+ 1 - 0
core/os/os2/allocators.odin

@@ -2,6 +2,7 @@
 package os2
 
 import "base:runtime"
+import "core:mem"
 
 @(require_results)
 file_allocator :: proc() -> runtime.Allocator {

+ 1 - 1
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))
 	}

+ 21 - 35
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,
-	}
-
-	@static stdout_impl := File_Impl {
-		name = "/proc/self/fd/1",
-		fd = 1,
-	}
-
-	@static stderr_impl := File_Impl {
-		name = "/proc/self/fd/2",
-		fd = 2,
+	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
 	}
 
-	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,

+ 29 - 20
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?
-
-	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"
+	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
+	}
 
-	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
 }
 

+ 37 - 16
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)),  "<stdin>")
-	stdout = new_file(uintptr(win32.GetStdHandle(win32.STD_OUTPUT_HANDLE)), "<stdout>")
-	stderr = new_file(uintptr(win32.GetStdHandle(win32.STD_ERROR_HANDLE)),  "<stderr>")
-}
-@(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,  "<stdin>")
+	stdout = new_std(&files[1], win32.STD_OUTPUT_HANDLE, "<stdout>")
+	stderr = new_std(&files[2], win32.STD_ERROR_HANDLE,  "<stderr>")
+}
 
 _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())

+ 2 - 2
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
 }

+ 2 - 2
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())