diff options
| author | gingerBill <bill@gingerbill.org> | 2022-03-01 15:38:04 +0000 |
|---|---|---|
| committer | gingerBill <bill@gingerbill.org> | 2022-03-01 15:38:04 +0000 |
| commit | 18607e53cba060558b7618e2c12245b363ad2a7f (patch) | |
| tree | 06385a59fbdb7bc196f15b3d09cdd9e185284876 | |
| parent | ed933b3f219407893826e30f12a3de86cb909c9f (diff) | |
Correct `alloc_from_memory_block`
| -rw-r--r-- | core/mem/virtual/virtual.odin | 40 | ||||
| -rw-r--r-- | core/mem/virtual/virtual_platform.odin | 22 |
2 files changed, 47 insertions, 15 deletions
diff --git a/core/mem/virtual/virtual.odin b/core/mem/virtual/virtual.odin index 38c654254..09d18b934 100644 --- a/core/mem/virtual/virtual.odin +++ b/core/mem/virtual/virtual.odin @@ -82,11 +82,13 @@ 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) or_return + commit_err := platform_memory_commit(pmblock, uint(base_offset) + committed) + assert(commit_err == nil) + // Should be zeroed assert(pmblock.block.used == 0) assert(pmblock.block.prev == nil) - if (do_protection) { + if do_protection { protect(rawptr(uintptr(pmblock) + protect_offset), page_size, Protect_No_Access) } @@ -115,23 +117,37 @@ alloc_from_memory_block :: proc(block: ^Memory_Block, min_size, alignment: int) return alignment_offset } - + do_commit_if_necessary :: proc(block: ^Memory_Block, size: uint) -> (err: Allocator_Error) { + if block.committed - block.used < size { + pmblock := (^Platform_Memory_Block)(block) + base_offset := uint(uintptr(block) - uintptr(pmblock)) + platform_total_commit := base_offset + block.used + size + + assert(pmblock.committed <= pmblock.reserved) + assert(pmblock.committed < platform_total_commit) + + platform_memory_commit(pmblock, platform_total_commit) or_return + + pmblock.committed = platform_total_commit + block.committed = pmblock.committed - base_offset + } + return nil + } + + alignment_offset := calc_alignment_offset(block, uintptr(alignment)) - size := uint(min_size) + alignment_offset - + if block.used + size > block.reserved { err = .Out_Of_Memory return } - - ptr := block.base[block.used:] - ptr = ptr[alignment_offset:] - + assert(block.committed <= block.reserved) + do_commit_if_necessary(block, size) or_return + + data = block.base[block.used+alignment_offset:][:min_size] block.used += size - assert(block.used <= block.reserved) - - return ptr[:min_size], nil + return } diff --git a/core/mem/virtual/virtual_platform.odin b/core/mem/virtual/virtual_platform.odin index c4211ba5e..85caa6419 100644 --- a/core/mem/virtual/virtual_platform.odin +++ b/core/mem/virtual/virtual_platform.odin @@ -4,8 +4,9 @@ package mem_virtual import sync "core:sync/sync2" Platform_Memory_Block :: struct { - block: Memory_Block, - reserved: uint, + block: Memory_Block, + committed: uint, + reserved: uint, prev, next: ^Platform_Memory_Block, } @@ -20,7 +21,8 @@ platform_memory_alloc :: proc(to_commit, to_reserve: uint) -> (block: ^Platform_ commit(raw_data(data), to_commit) block = (^Platform_Memory_Block)(raw_data(data)) - block.reserved = to_reserve + block.committed = to_commit + block.reserved = to_reserve return } @@ -52,3 +54,17 @@ platform_memory_init :: proc() { global_platform_memory_block_sentinel_set = true } } + +platform_memory_commit :: proc(block: ^Platform_Memory_Block, to_commit: uint) -> (err: Allocator_Error) { + if to_commit < block.committed { + return nil + } + if to_commit > block.reserved { + return .Out_Of_Memory + } + + + commit(block, to_commit) or_return + block.committed = to_commit + return nil +} |