Browse Source

Add virtual_linux.odin

gingerBill 3 years ago
parent
commit
728f143e33
1 changed files with 101 additions and 0 deletions
  1. 101 0
      core/mem/virtual/virtual_linux.odin

+ 101 - 0
core/mem/virtual/virtual_linux.odin

@@ -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)
+}