Browse Source

Remove `core:os` dependency for `base:runtime`

gingerBill 1 year ago
parent
commit
9a16bc5fc5

+ 2 - 18
base/runtime/default_allocators_general.odin

@@ -1,28 +1,12 @@
-//+build !windows
-//+build !freestanding
-//+build !wasi
-//+build !js
 package runtime
 package runtime
 
 
-// TODO(bill): reimplement these procedures in the os_specific stuff
-import "core:os"
-
 when ODIN_DEFAULT_TO_NIL_ALLOCATOR {
 when ODIN_DEFAULT_TO_NIL_ALLOCATOR {
-	_ :: os
-
-	// mem.nil_allocator reimplementation
 	default_allocator_proc :: nil_allocator_proc
 	default_allocator_proc :: nil_allocator_proc
 	default_allocator :: nil_allocator
 	default_allocator :: nil_allocator
 } else when ODIN_DEFAULT_TO_PANIC_ALLOCATOR {
 } else when ODIN_DEFAULT_TO_PANIC_ALLOCATOR {
-	_ :: os
-
 	default_allocator_proc :: panic_allocator_proc
 	default_allocator_proc :: panic_allocator_proc
 	default_allocator :: panic_allocator
 	default_allocator :: panic_allocator
 } else {
 } else {
-
-	default_allocator_proc :: os.heap_allocator_proc
-
-	default_allocator :: proc() -> Allocator {
-		return os.heap_allocator()
-	}
+	default_allocator :: heap_allocator
+	default_allocator_proc :: heap_allocator_proc
 }
 }

+ 0 - 5
base/runtime/default_allocators_js.odin

@@ -1,5 +0,0 @@
-//+build js
-package runtime
-
-default_allocator_proc :: panic_allocator_proc
-default_allocator :: panic_allocator

+ 0 - 8
base/runtime/default_allocators_nil.odin

@@ -31,14 +31,6 @@ nil_allocator :: proc() -> Allocator {
 }
 }
 
 
 
 
-
-when ODIN_OS == .Freestanding {
-	default_allocator_proc :: nil_allocator_proc
-	default_allocator :: nil_allocator
-}
-
-
-
 panic_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
 panic_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
                              size, alignment: int,
                              size, alignment: int,
                              old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, Allocator_Error) {
                              old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, Allocator_Error) {

+ 0 - 5
base/runtime/default_allocators_wasi.odin

@@ -1,5 +0,0 @@
-//+build wasi
-package runtime
-
-default_allocator_proc :: panic_allocator_proc
-default_allocator :: panic_allocator

+ 0 - 44
base/runtime/default_allocators_windows.odin

@@ -1,44 +0,0 @@
-//+build windows
-package runtime
-
-when ODIN_DEFAULT_TO_NIL_ALLOCATOR {
-	// mem.nil_allocator reimplementation
-	default_allocator_proc :: nil_allocator_proc
-	default_allocator :: nil_allocator
-} else {
-	default_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
-	                                size, alignment: int,
-	                                old_memory: rawptr, old_size: int, loc := #caller_location) -> (data: []byte, err: Allocator_Error) {
-		switch mode {
-		case .Alloc, .Alloc_Non_Zeroed:
-			data, err = _windows_default_alloc(size, alignment, mode == .Alloc)
-
-		case .Free:
-			_windows_default_free(old_memory)
-
-		case .Free_All:
-			return nil, .Mode_Not_Implemented
-
-		case .Resize, .Resize_Non_Zeroed:
-			data, err = _windows_default_resize(old_memory, old_size, size, alignment)
-
-		case .Query_Features:
-			set := (^Allocator_Mode_Set)(old_memory)
-			if set != nil {
-				set^ = {.Alloc, .Alloc_Non_Zeroed, .Free, .Resize, .Query_Features}
-			}
-
-		case .Query_Info:
-			return nil, .Mode_Not_Implemented
-		}
-
-		return
-	}
-
-	default_allocator :: proc() -> Allocator {
-		return Allocator{
-			procedure = default_allocator_proc,
-			data = nil,
-		}
-	}
-}

+ 97 - 0
base/runtime/heap_allocator.odin

@@ -0,0 +1,97 @@
+package runtime
+
+import "base:intrinsics"
+
+heap_allocator :: proc() -> Allocator {
+	return Allocator{
+		procedure = heap_allocator_proc,
+		data = nil,
+	}
+}
+
+heap_allocator_proc :: proc(allocator_data: rawptr, mode: Allocator_Mode,
+                            size, alignment: int,
+                            old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, Allocator_Error) {
+	//
+	// NOTE(tetra, 2020-01-14): The heap doesn't respect alignment.
+	// Instead, we overallocate by `alignment + size_of(rawptr) - 1`, and insert
+	// padding. We also store the original pointer returned by heap_alloc right before
+	// the pointer we return to the user.
+	//
+
+	aligned_alloc :: proc(size, alignment: int, old_ptr: rawptr = nil, zero_memory := true) -> ([]byte, Allocator_Error) {
+		a := max(alignment, align_of(rawptr))
+		space := size + a - 1
+
+		allocated_mem: rawptr
+		if old_ptr != nil {
+			original_old_ptr := intrinsics.ptr_offset((^rawptr)(old_ptr), -1)^
+			allocated_mem = heap_resize(original_old_ptr, space+size_of(rawptr))
+		} else {
+			allocated_mem = heap_alloc(space+size_of(rawptr), zero_memory)
+		}
+		aligned_mem := rawptr(intrinsics.ptr_offset((^u8)(allocated_mem), size_of(rawptr)))
+
+		ptr := uintptr(aligned_mem)
+		aligned_ptr := (ptr - 1 + uintptr(a)) & -uintptr(a)
+		diff := int(aligned_ptr - ptr)
+		if (size + diff) > space || allocated_mem == nil {
+			return nil, .Out_Of_Memory
+		}
+
+		aligned_mem = rawptr(aligned_ptr)
+		intrinsics.ptr_offset((^rawptr)(aligned_mem), -1)^ = allocated_mem
+
+		return byte_slice(aligned_mem, size), nil
+	}
+
+	aligned_free :: proc(p: rawptr) {
+		if p != nil {
+			heap_free(intrinsics.ptr_offset((^rawptr)(p), -1)^)
+		}
+	}
+
+	aligned_resize :: proc(p: rawptr, old_size: int, new_size: int, new_alignment: int, zero_memory := true) -> (new_memory: []byte, err: Allocator_Error) {
+		if p == nil {
+			return nil, nil
+		}
+
+		new_memory = aligned_alloc(new_size, new_alignment, p, zero_memory) or_return
+
+		// NOTE: heap_resize does not zero the new memory, so we do it
+		if zero_memory && new_size > old_size {
+			new_region := raw_data(new_memory[old_size:])
+			intrinsics.mem_zero(new_region, new_size - old_size)
+		}
+		return
+	}
+
+	switch mode {
+	case .Alloc, .Alloc_Non_Zeroed:
+		return aligned_alloc(size, alignment, nil, mode == .Alloc)
+
+	case .Free:
+		aligned_free(old_memory)
+
+	case .Free_All:
+		return nil, .Mode_Not_Implemented
+
+	case .Resize, .Resize_Non_Zeroed:
+		if old_memory == nil {
+			return aligned_alloc(size, alignment, nil, mode == .Resize)
+		}
+		return aligned_resize(old_memory, old_size, size, alignment, mode == .Resize)
+
+	case .Query_Features:
+		set := (^Allocator_Mode_Set)(old_memory)
+		if set != nil {
+			set^ = {.Alloc, .Alloc_Non_Zeroed, .Free, .Resize, .Resize_Non_Zeroed, .Query_Features}
+		}
+		return nil, nil
+
+	case .Query_Info:
+		return nil, .Mode_Not_Implemented
+	}
+
+	return nil, nil
+}

+ 15 - 0
base/runtime/heap_allocator_other.odin

@@ -0,0 +1,15 @@
+//+build js, wasi, freestanding, essence
+//+private
+package runtime
+
+heap_alloc :: proc(size: int, zero_memory := true) -> rawptr {
+	unimplemented("base:runtime 'heap_alloc' procedure is not supported on this platform")
+}
+
+heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr {
+	unimplemented("base:runtime 'heap_resize' procedure is not supported on this platform")
+}
+
+heap_free :: proc(ptr: rawptr) {
+	unimplemented("base:runtime 'heap_free' procedure is not supported on this platform")
+}

+ 38 - 0
base/runtime/heap_allocator_unix.odin

@@ -0,0 +1,38 @@
+//+build linux, darwin, freebsd, openbsd
+//+private
+package runtime
+
+when ODIN_OS == .Darwin {
+	foreign import libc "system:System.framework"
+} else {
+	foreign import libc "system:c"
+}
+
+@(default_calling_convention="c")
+foreign libc {
+	@(link_name="malloc")   _unix_malloc   :: proc(size: int) -> rawptr ---
+	@(link_name="calloc")   _unix_calloc   :: proc(num, size: int) -> rawptr ---
+	@(link_name="free")     _unix_free     :: proc(ptr: rawptr) ---
+	@(link_name="realloc")  _unix_realloc  :: proc(ptr: rawptr, size: int) -> rawptr ---
+}
+
+heap_alloc :: proc(size: int, zero_memory := true) -> rawptr {
+	if size <= 0 {
+		return nil
+	}
+	if zero_memory {
+		return _unix_calloc(1, size)
+	} else {
+		return _unix_malloc(size)
+	}
+}
+
+heap_resize :: proc(ptr: rawptr, new_size: int) -> rawptr {
+	// NOTE: _unix_realloc doesn't guarantee new memory will be zeroed on
+	// POSIX platforms. Ensure your caller takes this into account.
+	return _unix_realloc(ptr, new_size)
+}
+
+heap_free :: proc(ptr: rawptr) {
+	_unix_free(ptr)
+}

+ 38 - 0
base/runtime/heap_allocator_windows.odin

@@ -0,0 +1,38 @@
+package runtime
+
+foreign import kernel32 "system:Kernel32.lib"
+
+@(private="file")
+@(default_calling_convention="system")
+foreign kernel32 {
+        // NOTE(bill): The types are not using the standard names (e.g. DWORD and LPVOID) to just minimizing the dependency
+
+        // default_allocator
+        GetProcessHeap :: proc() -> rawptr ---
+        HeapAlloc      :: proc(hHeap: rawptr, dwFlags: u32, dwBytes: uint) -> rawptr ---
+        HeapReAlloc    :: proc(hHeap: rawptr, dwFlags: u32, lpMem: rawptr, dwBytes: uint) -> rawptr ---
+        HeapFree       :: proc(hHeap: rawptr, dwFlags: u32, lpMem: rawptr) -> b32 ---
+}
+
+heap_alloc :: proc "contextless" (size: int, zero_memory := true) -> rawptr {
+        HEAP_ZERO_MEMORY :: 0x00000008
+        return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY if zero_memory else 0, uint(size))
+}
+heap_resize :: proc "contextless" (ptr: rawptr, new_size: int) -> rawptr {
+        if new_size == 0 {
+                heap_free(ptr)
+                return nil
+        }
+        if ptr == nil {
+                return heap_alloc(new_size)
+        }
+
+        HEAP_ZERO_MEMORY :: 0x00000008
+        return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ptr, uint(new_size))
+}
+heap_free :: proc "contextless" (ptr: rawptr) {
+        if ptr == nil {
+                return
+        }
+        HeapFree(GetProcessHeap(), 0, ptr)
+}

+ 0 - 28
base/runtime/os_specific_windows.odin

@@ -14,12 +14,6 @@ foreign kernel32 {
 	SetHandleInformation :: proc(hObject: rawptr, dwMask: u32, dwFlags: u32) -> b32 ---
 	SetHandleInformation :: proc(hObject: rawptr, dwMask: u32, dwFlags: u32) -> b32 ---
 	WriteFile            :: proc(hFile: rawptr, lpBuffer: rawptr, nNumberOfBytesToWrite: u32, lpNumberOfBytesWritten: ^u32, lpOverlapped: rawptr) -> b32 ---
 	WriteFile            :: proc(hFile: rawptr, lpBuffer: rawptr, nNumberOfBytesToWrite: u32, lpNumberOfBytesWritten: ^u32, lpOverlapped: rawptr) -> b32 ---
 	GetLastError         :: proc() -> u32 ---
 	GetLastError         :: proc() -> u32 ---
-
-	// default_allocator
-	GetProcessHeap :: proc() -> rawptr ---
-	HeapAlloc      :: proc(hHeap: rawptr, dwFlags: u32, dwBytes: uint) -> rawptr ---
-	HeapReAlloc    :: proc(hHeap: rawptr, dwFlags: u32, lpMem: rawptr, dwBytes: uint) -> rawptr ---
-	HeapFree       :: proc(hHeap: rawptr, dwFlags: u32, lpMem: rawptr) -> b32 ---
 }
 }
 
 
 _os_write :: proc "contextless" (data: []byte) -> (n: int, err: _OS_Errno) #no_bounds_check {
 _os_write :: proc "contextless" (data: []byte) -> (n: int, err: _OS_Errno) #no_bounds_check {
@@ -56,28 +50,6 @@ _os_write :: proc "contextless" (data: []byte) -> (n: int, err: _OS_Errno) #no_b
 	return
 	return
 }
 }
 
 
-heap_alloc :: proc "contextless" (size: int, zero_memory := true) -> rawptr {
-	HEAP_ZERO_MEMORY :: 0x00000008
-	return HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY if zero_memory else 0, uint(size))
-}
-heap_resize :: proc "contextless" (ptr: rawptr, new_size: int) -> rawptr {
-	if new_size == 0 {
-		heap_free(ptr)
-		return nil
-	}
-	if ptr == nil {
-		return heap_alloc(new_size)
-	}
-
-	HEAP_ZERO_MEMORY :: 0x00000008
-	return HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ptr, uint(new_size))
-}
-heap_free :: proc "contextless" (ptr: rawptr) {
-	if ptr == nil {
-		return
-	}
-	HeapFree(GetProcessHeap(), 0, ptr)
-}
 
 
 
 
 //
 //

+ 1 - 1
core/mem/virtual/virtual_darwin.odin

@@ -2,7 +2,7 @@
 //+private
 //+private
 package mem_virtual
 package mem_virtual
 
 
-foreign import libc "System.framework"
+foreign import libc "system:System.framework"
 import "core:c"
 import "core:c"
 
 
 PROT_NONE  :: 0x0 /* [MC2] no permissions */
 PROT_NONE  :: 0x0 /* [MC2] no permissions */

+ 2 - 2
core/os/os_darwin.odin

@@ -1,8 +1,8 @@
 package os
 package os
 
 
 foreign import dl   "system:dl"
 foreign import dl   "system:dl"
-foreign import libc "System.framework"
-foreign import pthread "System.framework"
+foreign import libc "system:System.framework"
+foreign import pthread "system:System.framework"
 
 
 import "base:runtime"
 import "base:runtime"
 import "core:strings"
 import "core:strings"

+ 1 - 1
core/path/filepath/path_unix.odin

@@ -2,7 +2,7 @@
 package filepath
 package filepath
 
 
 when ODIN_OS == .Darwin {
 when ODIN_OS == .Darwin {
-	foreign import libc "System.framework"
+	foreign import libc "system:System.framework"
 } else {
 } else {
 	foreign import libc "system:c"
 	foreign import libc "system:c"
 }
 }

+ 1 - 1
core/sync/futex_darwin.odin

@@ -5,7 +5,7 @@ package sync
 import "core:c"
 import "core:c"
 import "core:time"
 import "core:time"
 
 
-foreign import System "System.framework"
+foreign import System "system:System.framework"
 
 
 foreign System {
 foreign System {
 	// __ulock_wait is not available on 10.15
 	// __ulock_wait is not available on 10.15

+ 1 - 1
core/sync/primitives_darwin.odin

@@ -5,7 +5,7 @@ package sync
 import "core:c"
 import "core:c"
 import "base:intrinsics"
 import "base:intrinsics"
 
 
-foreign import pthread "System.framework"
+foreign import pthread "system:System.framework"
 
 
 _current_thread_id :: proc "contextless" () -> int {
 _current_thread_id :: proc "contextless" () -> int {
 	tid: u64
 	tid: u64

+ 1 - 1
core/sys/darwin/mach_darwin.odin

@@ -1,6 +1,6 @@
 package darwin
 package darwin
 
 
-foreign import pthread "System.framework"
+foreign import pthread "system:System.framework"
 
 
 import "core:c"
 import "core:c"
 
 

+ 1 - 1
core/sys/unix/pthread_darwin.odin

@@ -86,7 +86,7 @@ PTHREAD_CANCEL_DISABLE      :: 1
 PTHREAD_CANCEL_DEFERRED     :: 0
 PTHREAD_CANCEL_DEFERRED     :: 0
 PTHREAD_CANCEL_ASYNCHRONOUS :: 1
 PTHREAD_CANCEL_ASYNCHRONOUS :: 1
 
 
-foreign import pthread "System.framework"
+foreign import pthread "system:System.framework"
 
 
 @(default_calling_convention="c")
 @(default_calling_convention="c")
 foreign pthread {
 foreign pthread {

+ 1 - 1
core/sys/unix/time_unix.odin

@@ -2,7 +2,7 @@
 package unix
 package unix
 
 
 when ODIN_OS == .Darwin {
 when ODIN_OS == .Darwin {
-	foreign import libc "System.framework"
+	foreign import libc "system:System.framework"
 } else  {
 } else  {
 	foreign import libc "system:c"
 	foreign import libc "system:c"
 }
 }

+ 1 - 1
core/time/tsc_darwin.odin

@@ -4,7 +4,7 @@ package time
 
 
 import "core:c"
 import "core:c"
 
 
-foreign import libc "System.framework"
+foreign import libc "system:System.framework"
 foreign libc {
 foreign libc {
 	@(link_name="sysctlbyname") _sysctlbyname    :: proc(path: cstring, oldp: rawptr, oldlenp: rawptr, newp: rawptr, newlen: int) -> c.int ---
 	@(link_name="sysctlbyname") _sysctlbyname    :: proc(path: cstring, oldp: rawptr, oldlenp: rawptr, newp: rawptr, newlen: int) -> c.int ---
 }
 }