diff --git a/core/mem/virtual/doc.odin b/core/mem/virtual/doc.odin index 614e290c3..6c6ce055f 100644 --- a/core/mem/virtual/doc.odin +++ b/core/mem/virtual/doc.odin @@ -1,7 +1,6 @@ /* A platform agnostic way to reserve/commit/decommit virtual memory. - virtual.Arena usage Example: @@ -56,7 +55,21 @@ Example: vmem.arena_destroy(&arena) } +virtual.map_file usage +Example: + // Source: https://github.com/odin-lang/examples/blob/master/arena_allocator/arena_allocator.odin + import "core:fmt" + + // virtual package implements cross-platform file memory mapping + import vmem "core:mem/virtual" + + main :: proc() { + data, err := virtual.map_file_from_path(#file, {.Read}) + defer virtual.unmap_file(data) + fmt.printfln("Error: %v", err) + fmt.printfln("Data: %s", data) + } */ package mem_virtual diff --git a/core/mem/virtual/file.odin b/core/mem/virtual/file.odin index 2f852b40c..c532335c5 100644 --- a/core/mem/virtual/file.odin +++ b/core/mem/virtual/file.odin @@ -1,6 +1,6 @@ package mem_virtual -import "core:os" +import os "core:os/os2" Map_File_Error :: enum { None, @@ -19,21 +19,20 @@ Map_File_Flags :: distinct bit_set[Map_File_Flag; u32] map_file :: proc{ map_file_from_path, - map_file_from_file_descriptor, + map_file_from_file, } map_file_from_path :: proc(filename: string, flags: Map_File_Flags) -> (data: []byte, error: Map_File_Error) { - fd, err := os.open(filename, os.O_RDWR) + f, err := os.open(filename, os.O_RDWR) if err != nil { return nil, .Open_Failure } - defer os.close(fd) - - return map_file_from_file_descriptor(uintptr(fd), flags) + defer os.close(f) + return map_file_from_file(f, flags) } -map_file_from_file_descriptor :: proc(fd: uintptr, flags: Map_File_Flags) -> (data: []byte, error: Map_File_Error) { - size, os_err := os.file_size(os.Handle(fd)) +map_file_from_file :: proc(f: ^os.File, flags: Map_File_Flags) -> (data: []byte, error: Map_File_Error) { + size, os_err := os.file_size(f) if os_err != nil { return nil, .Stat_Failure } @@ -43,5 +42,12 @@ map_file_from_file_descriptor :: proc(fd: uintptr, flags: Map_File_Flags) -> (da if size != i64(int(size)) { return nil, .Too_Large_Size } + fd := os.fd(f) return _map_file(fd, size, flags) } + +unmap_file :: proc(data: []byte) { + if raw_data(data) != nil { + _unmap_file(data) + } +} \ No newline at end of file diff --git a/core/mem/virtual/virtual_linux.odin b/core/mem/virtual/virtual_linux.odin index f819fbf86..144a8dc59 100644 --- a/core/mem/virtual/virtual_linux.odin +++ b/core/mem/virtual/virtual_linux.odin @@ -49,7 +49,6 @@ _platform_memory_init :: proc "contextless" () { assert_contextless(DEFAULT_PAGE_SIZE != 0 && (DEFAULT_PAGE_SIZE & (DEFAULT_PAGE_SIZE-1)) == 0) } - _map_file :: proc "contextless" (fd: uintptr, size: i64, flags: Map_File_Flags) -> (data: []byte, error: Map_File_Error) { prot: linux.Mem_Protection if .Read in flags { @@ -66,3 +65,7 @@ _map_file :: proc "contextless" (fd: uintptr, size: i64, flags: Map_File_Flags) } return ([^]byte)(addr)[:size], nil } + +_unmap_file :: proc "contextless" (data: []byte) { + _release(raw_data(data), uint(len(data))) +} \ No newline at end of file diff --git a/core/mem/virtual/virtual_other.odin b/core/mem/virtual/virtual_other.odin index c6386e842..8a2e1a61d 100644 --- a/core/mem/virtual/virtual_other.odin +++ b/core/mem/virtual/virtual_other.odin @@ -26,8 +26,13 @@ _protect :: proc "contextless" (data: rawptr, size: uint, flags: Protect_Flags) } _platform_memory_init :: proc "contextless" () { + } -_map_file :: proc "contextless" (fd: uintptr, size: i64, flags: Map_File_Flags) -> (data: []byte, error: Map_File_Error) { +_map_file :: proc "contextless" (f: any, size: i64, flags: Map_File_Flags) -> (data: []byte, error: Map_File_Error) { return nil, .Map_Failure } + +_unmap_file :: proc "contextless" (data: []byte) { + +} \ No newline at end of file diff --git a/core/mem/virtual/virtual_posix.odin b/core/mem/virtual/virtual_posix.odin index 4bb161770..6f257c385 100644 --- a/core/mem/virtual/virtual_posix.odin +++ b/core/mem/virtual/virtual_posix.odin @@ -47,3 +47,7 @@ _map_file :: proc "contextless" (fd: uintptr, size: i64, flags: Map_File_Flags) } return ([^]byte)(addr)[:size], nil } + +_unmap_file :: proc "contextless" (data: []byte) { + _release(raw_data(data), uint(len(data))) +} \ No newline at end of file diff --git a/core/mem/virtual/virtual_windows.odin b/core/mem/virtual/virtual_windows.odin index 1d777af17..0866ebfa1 100644 --- a/core/mem/virtual/virtual_windows.odin +++ b/core/mem/virtual/virtual_windows.odin @@ -82,6 +82,8 @@ foreign Kernel32 { dwFileOffsetLow: u32, dwNumberOfBytesToMap: uint, ) -> rawptr --- + + UnmapViewOfFile :: proc(lpBaseAddress: rawptr) -> b32 --- } @(no_sanitize_address) @@ -185,3 +187,8 @@ _map_file :: proc "contextless" (fd: uintptr, size: i64, flags: Map_File_Flags) file_data := MapViewOfFile(handle, desired_access, 0, 0, uint(size)) return ([^]byte)(file_data)[:size], nil } + +@(no_sanitize_address) +_unmap_file :: proc "contextless" (data: []byte) { + UnmapViewOfFile(raw_data(data)) +} \ No newline at end of file