Pyrogenesis  trunk
vm.h
Go to the documentation of this file.
1 /* Copyright (c) 2011 Wildfire Games
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining
4  * a copy of this software and associated documentation files (the
5  * "Software"), to deal in the Software without restriction, including
6  * without limitation the rights to use, copy, modify, merge, publish,
7  * distribute, sublicense, and/or sell copies of the Software, and to
8  * permit persons to whom the Software is furnished to do so, subject to
9  * the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  */
22 
23 /*
24  * virtual memory interface. supercedes POSIX mmap; provides support for
25  * large pages, autocommit, and specifying protection flags during allocation.
26  */
27 
28 #ifndef INCLUDED_SYSDEP_VM
29 #define INCLUDED_SYSDEP_VM
30 
31 #include "lib/posix/posix_mman.h" // PROT_*
32 
33 namespace vm {
34 
35 // committing large pages (2 MiB) instead of regular 4 KiB pages can
36 // increase TLB coverage and reduce misses for sequential access patterns.
37 // however, small page TLBs have more entries, making them better suited
38 // to random accesses. it may also take a long time to find/free up
39 // contiguous regions of physical memory for large pages. applications
40 // can express their preference or go along with the default,
41 // which depends on several factors such as allocation size.
43 {
44  kLarge, // use large if available
45  kSmall, // always use small
46  kDefault // heuristic
47 };
48 
49 /**
50  * reserve address space and set the parameters for any later
51  * on-demand commits.
52  *
53  * @param size desired number of bytes. any additional space
54  * in the last page is also accessible.
55  * @param commitSize [bytes] how much to commit each time.
56  * larger values reduce the number of page faults at the cost of
57  * additional internal fragmentation. must be a multiple of
58  * largePageSize unless pageType == kSmall.
59  * @param pageType chooses between large/small pages for commits.
60  * @param prot memory protection flags for newly committed pages.
61  * @return base address (aligned to the respective page size) or
62  * 0 if address space/descriptor storage is exhausted
63  * (an error dialog will also be raised).
64  * must be freed via ReleaseAddressSpace.
65 **/
66 LIB_API void* ReserveAddressSpace(size_t size, size_t commitSize = largePageSize, PageType pageType = kDefault, int prot = PROT_READ|PROT_WRITE);
67 
68 /**
69  * release address space and decommit any memory.
70  *
71  * @param p a pointer previously returned by ReserveAddressSpace.
72  * @param size is required by the POSIX implementation and
73  * ignored on Windows. it also ensures compatibility with UniqueRange.
74  **/
75 LIB_API void ReleaseAddressSpace(void* p, size_t size = 0);
76 
77 
78 /**
79  * map physical memory to previously reserved address space.
80  *
81  * @param address, size need not be aligned, but this function commits
82  * any pages intersecting that interval.
83  * @param pageType, prot - see ReserveAddressSpace.
84  * @return whether memory was successfully committed.
85  *
86  * note: committing only maps virtual pages and does not actually allocate
87  * page frames. Windows XP uses a first-touch heuristic - the page will
88  * be taken from the node whose processor caused the fault.
89  * therefore, worker threads should be the first to write to their memory.
90  *
91  * (this is surprisingly slow in XP, possibly due to PFN lock contention)
92  **/
93 LIB_API bool Commit(uintptr_t address, size_t size, PageType pageType = kDefault, int prot = PROT_READ|PROT_WRITE);
94 
95 /**
96  * unmap physical memory.
97  *
98  * @return whether the operation succeeded.
99  **/
100 LIB_API bool Decommit(uintptr_t address, size_t size);
101 
102 
103 /**
104  * set the memory protection flags for all pages that intersect
105  * the given interval.
106  * the pages must currently be committed.
107  *
108  * @param prot memory protection flags: PROT_NONE or a combination of
109  * PROT_READ, PROT_WRITE, PROT_EXEC.
110  **/
111 LIB_API bool Protect(uintptr_t address, size_t size, int prot);
112 
113 
114 /**
115  * reserve address space and commit memory.
116  *
117  * @param size [bytes] to allocate.
118  * @param pageType, prot - see ReserveAddressSpace.
119  * @return zero-initialized memory aligned to the respective
120  * page size.
121  **/
122 LIB_API void* Allocate(size_t size, PageType pageType = kDefault, int prot = PROT_READ|PROT_WRITE);
123 
124 /**
125  * decommit memory and release address space.
126  *
127  * @param p a pointer previously returned by Allocate.
128  * @param size is required by the POSIX implementation and
129  * ignored on Windows. it also ensures compatibility with UniqueRange.
130  *
131  * (this differs from ReleaseAddressSpace, which must account for
132  * extra padding/alignment to largePageSize.)
133  **/
134 LIB_API void Free(void* p, size_t size = 0);
135 
136 
137 /**
138  * install a handler that attempts to commit memory whenever a
139  * read/write page fault is encountered. thread-safe.
140  **/
141 LIB_API void BeginOnDemandCommits();
142 
143 /**
144  * decrements the reference count begun by BeginOnDemandCommit and
145  * removes the page fault handler when it reaches 0. thread-safe.
146  **/
147 LIB_API void EndOnDemandCommits();
148 
149 
150 LIB_API void DumpStatistics();
151 
152 } // namespace vm
153 
154 #endif // #ifndef INCLUDED_SYSDEP_VM
#define PROT_WRITE
Definition: wmman.h:33
Definition: uvm.cpp:38
void BeginOnDemandCommits()
install a handler that attempts to commit memory whenever a read/write page fault is encountered...
Definition: uvm.cpp:120
bool Commit(uintptr_t address, size_t size, PageType pageType, int prot)
map physical memory to previously reserved address space.
Definition: uvm.cpp:59
Definition: vm.h:46
Definition: vm.h:44
PageType
Definition: vm.h:42
void EndOnDemandCommits()
decrements the reference count begun by BeginOnDemandCommit and removes the page fault handler when i...
Definition: uvm.cpp:125
bool Decommit(uintptr_t address, size_t size)
unmap physical memory.
Definition: uvm.cpp:77
bool Protect(uintptr_t address, size_t size, int prot)
set the memory protection flags for all pages that intersect the given interval.
Definition: uvm.cpp:86
void DumpStatistics()
Definition: uvm.cpp:131
#define PROT_READ
Definition: wmman.h:32
void ReleaseAddressSpace(void *p, size_t size)
release address space and decommit any memory.
Definition: uvm.cpp:49
static const size_t largePageSize
Definition: alignment.h:84
Definition: vm.h:45
void * Allocate(size_t size, PageType pageType, int prot)
reserve address space and commit memory.
Definition: uvm.cpp:98
void * ReserveAddressSpace(size_t size, size_t commitSize, PageType pageType, int prot)
reserve address space and set the parameters for any later on-demand commits.
Definition: uvm.cpp:40
void Free(void *p, size_t size)
decommit memory and release address space.
Definition: uvm.cpp:113