瀏覽代碼

Allow for nested `temp_allocator()` calls to flip between arenas on `TEMP_ALLOCATOR_GUARD`s

gingerBill 1 年之前
父節點
當前提交
d0709a7de2
共有 3 個文件被更改,包括 30 次插入12 次删除
  1. 25 7
      core/os/os2/allocators.odin
  2. 4 4
      core/os/os2/errors_linux.odin
  3. 1 1
      core/os/os2/path_linux.odin

+ 25 - 7
core/os/os2/allocators.odin

@@ -10,20 +10,29 @@ file_allocator :: proc() -> runtime.Allocator {
 
 temp_allocator_proc :: runtime.arena_allocator_proc
 
+@(private="file")
+MAX_TEMP_ARENA_COUNT :: 2
+
+@(private="file", thread_local)
+global_default_temp_allocator_arenas: [MAX_TEMP_ARENA_COUNT]runtime.Arena
+
 @(private="file", thread_local)
-global_default_temp_allocator_arena: runtime.Arena
+global_default_temp_allocator_index: uint
+
 
 @(require_results)
 temp_allocator :: proc() -> runtime.Allocator {
 	return runtime.Allocator{
 		procedure = temp_allocator_proc,
-		data      = &global_default_temp_allocator_arena,
+		data      = &global_default_temp_allocator_arenas[global_default_temp_allocator_index],
 	}
 }
 
+
+
 @(require_results)
 temp_allocator_temp_begin :: proc(loc := #caller_location) -> (temp: runtime.Arena_Temp) {
-	temp = runtime.arena_temp_begin(&global_default_temp_allocator_arena, loc)
+	temp = runtime.arena_temp_begin(&global_default_temp_allocator_arenas[global_default_temp_allocator_index], loc)
 	return
 }
 
@@ -33,16 +42,25 @@ temp_allocator_temp_end :: proc(temp: runtime.Arena_Temp, loc := #caller_locatio
 
 @(fini, private)
 temp_allocator_fini :: proc() {
-	runtime.arena_destroy(&global_default_temp_allocator_arena)
-	global_default_temp_allocator_arena = {}
+	for &arena in global_default_temp_allocator_arenas {
+		runtime.arena_destroy(&arena)
+	}
+	global_default_temp_allocator_arenas = {}
+}
+
+TEMP_ALLOCATOR_GUARD_END :: proc(temp: runtime.Arena_Temp loc := #caller_location) {
+	runtime.arena_temp_end(temp, loc)
+	global_default_temp_allocator_index = (global_default_temp_allocator_index-1)%MAX_TEMP_ARENA_COUNT
 }
 
-@(deferred_out=temp_allocator_temp_end)
+@(deferred_out=TEMP_ALLOCATOR_GUARD_END)
 TEMP_ALLOCATOR_GUARD :: #force_inline proc(ignore := false, loc := #caller_location) -> (runtime.Arena_Temp, runtime.Source_Code_Location) {
 	if ignore {
 		return {}, loc
 	} else {
-		return temp_allocator_temp_begin(loc), loc
+		tmp := temp_allocator_temp_begin(loc)
+		global_default_temp_allocator_index = (global_default_temp_allocator_index+1)%MAX_TEMP_ARENA_COUNT
+		return tmp, loc
 	}
 }
 

+ 4 - 4
core/os/os2/errors_linux.odin

@@ -4,7 +4,7 @@ package os2
 import "core:sys/linux"
 
 @(rodata)
-_errno_strings := [linux.Error]string{
+_errno_strings := [linux.Errno]string{
 	.NONE            = "",
 	.EPERM           = "Operation not permitted",
 	.ENOENT          = "No such file or directory",
@@ -142,7 +142,7 @@ _errno_strings := [linux.Error]string{
 }
 
 
-_get_platform_error :: proc(errno: linux.Error) -> Error {
+_get_platform_error :: proc(errno: linux.Errno) -> Error {
 	#partial switch errno {
 	case .NONE:
 		return nil
@@ -158,8 +158,8 @@ _get_platform_error :: proc(errno: linux.Error) -> Error {
 }
 
 _error_string :: proc(errno: i32) -> string {
-	if errno >= 0 && errno <= i32(max(linux.Error)) {
-		return _errno_strings[linux.Error(errno)]
+	if errno >= 0 && errno <= i32(max(linux.Errno)) {
+		return _errno_strings[linux.Errno(errno)]
 	}
 	return "Unknown Error"
 }

+ 1 - 1
core/os/os2/path_linux.odin

@@ -59,7 +59,7 @@ _mkdir_all :: proc(path: string, perm: int) -> Error {
 	path_bytes[len(path)] = 0
 
 	dfd: linux.Fd
-	errno: linux.Error
+	errno: linux.Errno
 	if path_bytes[0] == '/' {
 		dfd, errno = linux.open("/", _OPENDIR_FLAGS)
 		path_bytes = path_bytes[1:]