I'm a little bit confused in comparing the virtual memory system behaviour in OSX/iOS to that of Windows. The Windows VirtualAlloc() related functions and their behaviour regards reserving and the actual memory commit and de-commit are fairly straight forward.
For OSX which is not well discussed I have been looking at mach_vm_allocate(), mach_vm_map() etc. For example if I wanted to create a set of cross platform functions to expose common virtual memory functionality between Windows and OSX/iOS how would I managed the difference between commit/de-commit on OSX as opposed to Windows?
As I am not sure I understand if you can reserve virtual address range and commit it as a separate action like on Windows? From my understanding mach_vm_allocate() is similar to VirtualAlloc() with MEM_COMMIT | MEM_RESERVE and also trying to compare which is actually a better designed mechanism if any is confusing.
Possibly I need better understanding of how the page managers function in OSX.
On Windows even if you commit a region I suspect it may not actually back it with physical memory until you try accessing it unless perhaps there is currently abundant memory - and that it just guarantees swap file backing when modified.
On OSX I am not sure how to de-commit regions but still keep the address range reserved? For example this sort of behaviour is useful in a 64bit programs (Which I am mostly interested in) to reserve a large virtual address range for an arena/stack/linear allocator with rewind ability - that requires being able to commit and de-commit the ends of regions. In Windows it is obvious how to produce such behaviour but in OSX I don't quite understand how to efficiently replicate it.
EDIT:
I just found this:
That is relevant to my question but surely mmap() goes through the equivalent mach_vm_*() system calls?
EDIT2:
Typical I now find these:
Does mmap with MAP_NORESERVE reserve physical memory?
How can I reserve virtual memory in Linux?
But it still perhaps doesn't clear up how to de-commit the way I would like too - but off to google some more on mmap() ANON stuff - and possibly see if I can find the mmap() source code for OSX (?).
(For sure someone will say use mmap() as it works on linux too if I can figure out the de-commit issue but still I am curious how that gets routed through the mach_vm_*() calls...)
EDIT3:
I found mremap() which together with mmap() looks useful! Obviously using PROT_NONE, MAP_NORESERVE with mmap() look interesting also. But I am still unsure how you can de-commit regions but still keep the address range preserved as mremap() doesn't seem to be able to take MAP_NORESERVE to ditch the swap file backing?
EDIT4:
I found this regards de-commits: https://bugzilla.mozilla.org/show_bug.cgi?id=670596. Which discusses the behaviour on OSX and Linux regards mprotect(addr, len, PROT_NONE) and madvise(). ..
EDIT5: (!)
Digging through my Mac header files I find for madvise():
#define MADV_WILLNEED POSIX_MADV_WILLNEED
#define MADV_DONTNEED POSIX_MADV_DONTNEED
#define MADV_FREE 5 /* pages unneeded, discard contents */
#define MADV_ZERO_WIRED_PAGES 6 /* zero the wired pages that have not been unwired before the entry is deleted */
#define MADV_FREE_REUSABLE 7 /* pages can be reused (by anyone) */
#define MADV_FREE_REUSE 8 /* caller wants to reuse those pages */
#define MADV_CAN_REUSE 9
So I am guessing MADV_FREE_REUSE should be preferred usage for de-commits?
EDIT6: I have asked the question on the iOS/OSX developer forums and in the meantime I have come across these that may be helpful to other people wondering the same thing:
http://lists.apple.com/archives/PerfOptimization-dev/2009/Apr/msg00024.html http://markmail.org/message/yqwqd3zuawz6v5dd
Also this:
http://fxr.watson.org/fxr/source/bsd/kern/kern_mman.c?v=xnu-1228;im=bigexcerpts#L824
Which seems like the key is mmap(), and madvise(), or mach_vm_allocate() and mach_vm_behavior_set() with flag VM_BEHAVIOR_DONTNEED.
Will report back for the benefit of others after experimenting with this...
EDIT7:
Latest for now OSX 10.9 source code for mmap() and madvise() I think: http://www.opensource.apple.com/source/xnu/xnu-2422.1.72/bsd/kern/kern_mman.c
Seems to confirm mach_vm_behavior_set()
EDIT8:
Ok now so far as I can tell from OSX 10.9:
http://www.opensource.apple.com/source/xnu/xnu-2422.1.72/osfmk/vm/vm_map.c
I should use mach_vm_allocate() and vm_map_behavior_set() with the (suggestive) flags being roughly equivalent in Windows VirtualAlloc() parlance too:
VM_BEHAVIOR_WILLNEED => Commit address range
VM_BEHAVIOR_DONTNEED => Decommit address range
VM_BEHAVIOR_FREE => Decommit and completely release address range(?)
But I am not sure what these mean exactly still(?):
VM_BEHAVIOR_REUSABLE
VM_BEHAVIOR_REUSE
VM_BEHAVIOR_CAN_REUSE
I am hoping from confirmation from apple on the preferred usage pattern but I guess I am close to answering my own question with the above...
This is the first time I have had the pleasure to dig through some very clean open source code :-)