diff --git a/core/mem/virtual/static_arena.odin b/core/mem/virtual/static_arena.odin index 63f73df1d..67a82c0dd 100644 --- a/core/mem/virtual/static_arena.odin +++ b/core/mem/virtual/static_arena.odin @@ -24,7 +24,7 @@ static_arena_init :: proc(arena: ^Static_Arena, reserved: uint, commit_size: uin committed = min(committed, reserved) ptr := raw_data(data) - commit(ptr, uint(committed)) + commit(ptr, uint(committed)) or_return arena.block = memory_block_alloc(commit_size, reserved, {}) or_return arena.total_used = 0 diff --git a/core/mem/virtual/virtual.odin b/core/mem/virtual/virtual.odin index 97466b8e6..38c654254 100644 --- a/core/mem/virtual/virtual.odin +++ b/core/mem/virtual/virtual.odin @@ -10,13 +10,13 @@ reserve :: proc(size: uint) -> (data: []byte, err: Allocator_Error) { return _reserve(size) } -commit :: proc(data: rawptr, size: uint) { - _commit(data, size) +commit :: proc(data: rawptr, size: uint) -> Allocator_Error { + return _commit(data, size) } reserve_and_commit :: proc(size: uint) -> (data: []byte, err: Allocator_Error) { data = reserve(size) or_return - commit(raw_data(data), size) + commit(raw_data(data), size) or_return return } @@ -82,7 +82,7 @@ memory_block_alloc :: proc(committed, reserved: uint, flags: Memory_Block_Flags) pmblock := platform_memory_alloc(0, total_size) or_return pmblock.block.base = ([^]byte)(uintptr(pmblock) + base_offset) - commit(pmblock.block.base, committed) + commit(pmblock.block.base, committed) or_return // Should be zeroed assert(pmblock.block.used == 0) assert(pmblock.block.prev == nil) diff --git a/core/mem/virtual/virtual_linux.odin b/core/mem/virtual/virtual_linux.odin index 205359fd2..c4dd564ee 100644 --- a/core/mem/virtual/virtual_linux.odin +++ b/core/mem/virtual/virtual_linux.odin @@ -67,7 +67,7 @@ madvise :: proc "contextless" (addr: rawptr, length: uint, advice: c.int) -> c.i _reserve :: proc(size: uint) -> (data: []byte, err: Allocator_Error) { - MAP_FAILED := rawptr(uintptr(~0)) + MAP_FAILED := rawptr(~uintptr(0)) result := mmap(nil, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) if result == MAP_FAILED { return nil, .Out_Of_Memory @@ -75,8 +75,13 @@ _reserve :: proc(size: uint) -> (data: []byte, err: Allocator_Error) { return ([^]byte)(result)[:size], nil } -_commit :: proc(data: rawptr, size: uint) { - mprotect(data, size, PROT_READ|PROT_WRITE) +_commit :: proc(data: rawptr, size: uint) -> Allocator_Error { + result := mprotect(data, size, PROT_READ|PROT_WRITE) + if result != 0 { + // TODO(bill): Handle error value correctly + return .Out_Of_Memory + } + return nil } _decommit :: proc(data: rawptr, size: uint) { mprotect(data, size, PROT_NONE) diff --git a/core/mem/virtual/virtual_windows.odin b/core/mem/virtual/virtual_windows.odin index 7d05cfe7b..623e8d469 100644 --- a/core/mem/virtual/virtual_windows.odin +++ b/core/mem/virtual/virtual_windows.odin @@ -50,11 +50,15 @@ PAGE_WRITECOPY :: 0x08 PAGE_TARGETS_INVALID :: 0x40000000 PAGE_TARGETS_NO_UPDATE :: 0x40000000 +ERROR_INVALID_ADDRESS :: 487 + +@(default_calling_convention="stdcall") foreign Kernel32 { GetSystemInfo :: proc(lpSystemInfo: LPSYSTEM_INFO) --- VirtualAlloc :: proc(lpAddress: rawptr, dwSize: uint, flAllocationType: u32, flProtect: u32) -> rawptr --- VirtualFree :: proc(lpAddress: rawptr, dwSize: uint, dwFreeType: u32) -> b32 --- VirtualProtect :: proc(lpAddress: rawptr, dwSize: uint, flNewProtect: u32, lpflOldProtect: ^u32) -> b32 --- + GetLastError :: proc() -> u32 --- } @@ -68,8 +72,18 @@ _reserve :: proc(size: uint) -> (data: []byte, err: Allocator_Error) { return } -_commit :: proc(data: rawptr, size: uint) { - VirtualAlloc(data, size, MEM_COMMIT, PAGE_READWRITE) +_commit :: proc(data: rawptr, size: uint) -> Allocator_Error { + result := VirtualAlloc(data, size, MEM_COMMIT, PAGE_READWRITE) + if result == nil { + switch err := GetLastError(); err { + case ERROR_INVALID_ADDRESS: + return .Out_Of_Memory + } + + // TODO(bill): Handle errors correctly + return .Invalid_Argument + } + return nil } _decommit :: proc(data: rawptr, size: uint) { VirtualFree(data, size, MEM_DECOMMIT)