Remove core:os dependency for base:runtime

This commit is contained in:
gingerBill
2024-01-28 22:40:46 +00:00
parent eee8e0faa2
commit 9a16bc5fc5
19 changed files with 200 additions and 118 deletions
+2 -18
View File
@@ -1,28 +1,12 @@
//+build !windows
//+build !freestanding
//+build !wasi
//+build !js
package runtime
// TODO(bill): reimplement these procedures in the os_specific stuff
import "core:os"
when ODIN_DEFAULT_TO_NIL_ALLOCATOR {
_ :: os
// mem.nil_allocator reimplementation
default_allocator_proc :: nil_allocator_proc
default_allocator :: nil_allocator
} else when ODIN_DEFAULT_TO_PANIC_ALLOCATOR {
_ :: os
default_allocator_proc :: panic_allocator_proc
default_allocator :: panic_allocator
} 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
}
-5
View File
@@ -1,5 +0,0 @@
//+build js
package runtime
default_allocator_proc :: panic_allocator_proc
default_allocator :: panic_allocator
-8
View File
@@ -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,
size, alignment: int,
old_memory: rawptr, old_size: int, loc := #caller_location) -> ([]byte, Allocator_Error) {
@@ -1,5 +0,0 @@
//+build wasi
package runtime
default_allocator_proc :: panic_allocator_proc
default_allocator :: panic_allocator
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
}
-28
View File
@@ -14,12 +14,6 @@ foreign kernel32 {
SetHandleInformation :: proc(hObject: rawptr, dwMask: u32, dwFlags: u32) -> b32 ---
WriteFile :: proc(hFile: rawptr, lpBuffer: rawptr, nNumberOfBytesToWrite: u32, lpNumberOfBytesWritten: ^u32, lpOverlapped: rawptr) -> b32 ---
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 {
@@ -56,28 +50,6 @@ _os_write :: proc "contextless" (data: []byte) -> (n: int, err: _OS_Errno) #no_b
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
View File
@@ -2,7 +2,7 @@
//+private
package mem_virtual
foreign import libc "System.framework"
foreign import libc "system:System.framework"
import "core:c"
PROT_NONE :: 0x0 /* [MC2] no permissions */
+2 -2
View File
@@ -1,8 +1,8 @@
package os
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 "core:strings"
+1 -1
View File
@@ -2,7 +2,7 @@
package filepath
when ODIN_OS == .Darwin {
foreign import libc "System.framework"
foreign import libc "system:System.framework"
} else {
foreign import libc "system:c"
}
+1 -1
View File
@@ -5,7 +5,7 @@ package sync
import "core:c"
import "core:time"
foreign import System "System.framework"
foreign import System "system:System.framework"
foreign System {
// __ulock_wait is not available on 10.15
+1 -1
View File
@@ -5,7 +5,7 @@ package sync
import "core:c"
import "base:intrinsics"
foreign import pthread "System.framework"
foreign import pthread "system:System.framework"
_current_thread_id :: proc "contextless" () -> int {
tid: u64
+1 -1
View File
@@ -1,6 +1,6 @@
package darwin
foreign import pthread "System.framework"
foreign import pthread "system:System.framework"
import "core:c"
+1 -1
View File
@@ -86,7 +86,7 @@ PTHREAD_CANCEL_DISABLE :: 1
PTHREAD_CANCEL_DEFERRED :: 0
PTHREAD_CANCEL_ASYNCHRONOUS :: 1
foreign import pthread "System.framework"
foreign import pthread "system:System.framework"
@(default_calling_convention="c")
foreign pthread {
+1 -1
View File
@@ -2,7 +2,7 @@
package unix
when ODIN_OS == .Darwin {
foreign import libc "System.framework"
foreign import libc "system:System.framework"
} else {
foreign import libc "system:c"
}
+1 -1
View File
@@ -4,7 +4,7 @@ package time
import "core:c"
foreign import libc "System.framework"
foreign import libc "system:System.framework"
foreign libc {
@(link_name="sysctlbyname") _sysctlbyname :: proc(path: cstring, oldp: rawptr, oldlenp: rawptr, newp: rawptr, newlen: int) -> c.int ---
}