virtual_windows.odin 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. //+build windows
  2. //+private
  3. package mem_virtual
  4. foreign import Kernel32 "system:Kernel32.lib"
  5. LPSYSTEM_INFO :: ^SYSTEM_INFO
  6. SYSTEM_INFO :: struct {
  7. using DUMMYUNIONNAME: struct #raw_union {
  8. dwOemId: u32,
  9. using DUMMYSTRUCTNAME:struct {
  10. wProcessorArchitecture: u16,
  11. wReserved: u16,
  12. },
  13. },
  14. dwPageSize: u32,
  15. lpMinimumApplicationAddress: rawptr,
  16. lpMaximumApplicationAddress: rawptr,
  17. dwActiveProcessorMask: uint,
  18. dwNumberOfProcessors: u32,
  19. dwProcessorType: u32,
  20. dwAllocationGranularity: u32,
  21. wProcessorLevel: u16,
  22. wProcessorRevision: u16,
  23. }
  24. MEM_COMMIT :: 0x00001000
  25. MEM_RESERVE :: 0x00002000
  26. MEM_RESET :: 0x00080000
  27. MEM_RESET_UNDO :: 0x01000000
  28. MEM_LARGE_PAGES :: 0x20000000
  29. MEM_PHYSICAL :: 0x00400000
  30. MEM_TOP_DOWN :: 0x00100000
  31. MEM_WRITE_WATCH :: 0x00200000
  32. MEM_DECOMMIT :: 0x00004000
  33. MEM_RELEASE :: 0x00008000
  34. MEM_COALESCE_PLACEHOLDERS :: 0x00000001
  35. MEM_PRESERVE_PLACEHOLDER :: 0x00000002
  36. PAGE_EXECUTE :: 0x10
  37. PAGE_EXECUTE_READ :: 0x20
  38. PAGE_EXECUTE_READWRITE :: 0x40
  39. PAGE_EXECUTE_WRITECOPY :: 0x80
  40. PAGE_NOACCESS :: 0x01
  41. PAGE_READONLY :: 0x02
  42. PAGE_READWRITE :: 0x04
  43. PAGE_WRITECOPY :: 0x08
  44. PAGE_TARGETS_INVALID :: 0x40000000
  45. PAGE_TARGETS_NO_UPDATE :: 0x40000000
  46. ERROR_INVALID_ADDRESS :: 487
  47. @(default_calling_convention="stdcall")
  48. foreign Kernel32 {
  49. GetSystemInfo :: proc(lpSystemInfo: LPSYSTEM_INFO) ---
  50. VirtualAlloc :: proc(lpAddress: rawptr, dwSize: uint, flAllocationType: u32, flProtect: u32) -> rawptr ---
  51. VirtualFree :: proc(lpAddress: rawptr, dwSize: uint, dwFreeType: u32) -> b32 ---
  52. VirtualProtect :: proc(lpAddress: rawptr, dwSize: uint, flNewProtect: u32, lpflOldProtect: ^u32) -> b32 ---
  53. GetLastError :: proc() -> u32 ---
  54. }
  55. _reserve :: proc(size: uint) -> (data: []byte, err: Allocator_Error) {
  56. result := VirtualAlloc(nil, size, MEM_RESERVE, PAGE_READWRITE)
  57. if result == nil {
  58. err = .Out_Of_Memory
  59. return
  60. }
  61. data = ([^]byte)(result)[:size]
  62. return
  63. }
  64. _commit :: proc(data: rawptr, size: uint) -> Allocator_Error {
  65. result := VirtualAlloc(data, size, MEM_COMMIT, PAGE_READWRITE)
  66. if result == nil {
  67. switch err := GetLastError(); err {
  68. case ERROR_INVALID_ADDRESS:
  69. return .Out_Of_Memory
  70. }
  71. // TODO(bill): Handle errors correctly
  72. return .Invalid_Argument
  73. }
  74. return nil
  75. }
  76. _decommit :: proc(data: rawptr, size: uint) {
  77. VirtualFree(data, size, MEM_DECOMMIT)
  78. }
  79. _release :: proc(data: rawptr, size: uint) {
  80. VirtualFree(data, 0, MEM_RELEASE)
  81. }
  82. _protect :: proc(data: rawptr, size: uint, flags: Protect_Flags) -> bool {
  83. pflags: u32
  84. pflags = PAGE_NOACCESS
  85. switch flags {
  86. case {}: pflags = PAGE_NOACCESS
  87. case {.Read}: pflags = PAGE_READONLY
  88. case {.Read, .Write}: pflags = PAGE_READWRITE
  89. case {.Write}: pflags = PAGE_WRITECOPY
  90. case {.Execute}: pflags = PAGE_EXECUTE
  91. case {.Execute, .Read}: pflags = PAGE_EXECUTE_READ
  92. case {.Execute, .Read, .Write}: pflags = PAGE_EXECUTE_READWRITE
  93. case {.Execute, .Write}: pflags = PAGE_EXECUTE_WRITECOPY
  94. case:
  95. return false
  96. }
  97. old_protect: u32
  98. ok := VirtualProtect(data, size, pflags, &old_protect)
  99. return bool(ok)
  100. }
  101. _platform_memory_init :: proc() {
  102. sys_info: SYSTEM_INFO
  103. GetSystemInfo(&sys_info)
  104. DEFAULT_PAGE_SIZE = max(DEFAULT_PAGE_SIZE, uint(sys_info.dwPageSize))
  105. // is power of two
  106. assert(DEFAULT_PAGE_SIZE != 0 && (DEFAULT_PAGE_SIZE & (DEFAULT_PAGE_SIZE-1)) == 0)
  107. }