mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-16 08:04:07 +00:00
Add virtual_linux.odin
This commit is contained in:
101
core/mem/virtual/virtual_linux.odin
Normal file
101
core/mem/virtual/virtual_linux.odin
Normal file
@@ -0,0 +1,101 @@
|
||||
//+build linux
|
||||
//+private
|
||||
package mem_virtual
|
||||
|
||||
import "core:c"
|
||||
import "core:intrinsics"
|
||||
|
||||
when ODIN_ARCH == "amd64" {
|
||||
SYS_mmap :: 9
|
||||
SYS_mprotect :: 10
|
||||
SYS_munmap :: 11
|
||||
SYS_madvise :: 28
|
||||
|
||||
PROT_NONE :: 0x0
|
||||
PROT_READ :: 0x1
|
||||
PROT_WRITE :: 0x2
|
||||
PROT_EXEC :: 0x4
|
||||
PROT_GROWSDOWN :: 0x01000000
|
||||
PROT_GROWSUP :: 0x02000000
|
||||
|
||||
MAP_FIXED :: 0x1
|
||||
MAP_PRIVATE :: 0x2
|
||||
MAP_SHARED :: 0x4
|
||||
MAP_ANONYMOUS :: 0x20
|
||||
|
||||
MADV_NORMAL :: 0
|
||||
MADV_RANDOM :: 1
|
||||
MADV_SEQUENTIAL :: 2
|
||||
MADV_WILLNEED :: 3
|
||||
MADV_DONTNEED :: 4
|
||||
MADV_FREE :: 8
|
||||
MADV_REMOVE :: 9
|
||||
MADV_DONTFORK :: 10
|
||||
MADV_DOFORK :: 11
|
||||
MADV_MERGEABLE :: 12
|
||||
MADV_UNMERGEABLE :: 13
|
||||
MADV_HUGEPAGE :: 14
|
||||
MADV_NOHUGEPAGE :: 15
|
||||
MADV_DONTDUMP :: 16
|
||||
MADV_DODUMP :: 17
|
||||
MADV_WIPEONFORK :: 18
|
||||
MADV_KEEPONFORK :: 19
|
||||
MADV_HWPOISON :: 100
|
||||
} else {
|
||||
#panic("Unsupported architecture")
|
||||
}
|
||||
|
||||
mmap :: proc "contextless" (addr: rawptr, length: uint, prot: c.int, flags: c.int, fd: c.int, offset: uintptr) -> rawptr {
|
||||
res := intrinsics.syscall(SYS_mmap, uintptr(addr), uintptr(length), uintptr(prot), uintptr(flags), uintptr(fd), offset)
|
||||
return rawptr(res)
|
||||
}
|
||||
|
||||
munmap :: proc "contextless" (addr: rawptr, length: uint) -> c.int {
|
||||
res := intrinsics.syscall(SYS_munmap, uintptr(addr), uintptr(length))
|
||||
return c.int(res)
|
||||
}
|
||||
|
||||
mprotect :: proc "contextless" (addr: rawptr, length: uint, prot: c.int) -> c.int {
|
||||
res := intrinsics.syscall(SYS_mprotect, uintptr(addr), uintptr(length), uint(prot))
|
||||
return c.int(res)
|
||||
}
|
||||
|
||||
madvise :: proc "contextless" (addr: rawptr, length: uint, advice: c.int) -> c.int {
|
||||
res := intrinsics.syscall(SYS_madvise, uintptr(addr), uintptr(length), uintptr(advice))
|
||||
return c.int(res)
|
||||
}
|
||||
|
||||
|
||||
_reserve :: proc(size: uint) -> (data: []byte, err: Allocator_Error) {
|
||||
result := mmap(nil, size, PROT_NONE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0)
|
||||
if result == nil {
|
||||
err = .Out_Of_Memory
|
||||
return
|
||||
}
|
||||
data = ([^]byte)(result)[:size]
|
||||
return
|
||||
}
|
||||
|
||||
_commit :: proc(data: rawptr, size: uint) {
|
||||
mprotect(data, size, PROT_READ|PROT_WRITE)
|
||||
}
|
||||
_decommit :: proc(data: rawptr, size: uint) {
|
||||
mprotect(data, size, PROT_NONE)
|
||||
madvise(data, size, MADV_FREE)
|
||||
}
|
||||
_release :: proc(data: rawptr, size: uint) {
|
||||
munmap(data, size)
|
||||
}
|
||||
_protect :: proc(data: rawptr, size: uint) -> bool {
|
||||
err := mprotect(data, size, PROT_NONE)
|
||||
return err != 0
|
||||
}
|
||||
|
||||
|
||||
|
||||
_platform_memory_init :: proc() {
|
||||
DEFAULT_PAGE_SIZE = 4096
|
||||
|
||||
// is power of two
|
||||
assert(DEFAULT_PAGE_SIZE != 0 && (DEFAULT_PAGE_SIZE & (DEFAULT_PAGE_SIZE-1)) == 0)
|
||||
}
|
||||
Reference in New Issue
Block a user