Pyrogenesis HEAD
Pyrogenesis, a RTS Engine
vm.h
Go to the documentation of this file.
1/* Copyright (C) 2022 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
33namespace 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**/
66void* ReserveAddressSpace(size_t size, size_t commitSize = g_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.
74 **/
75void 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 **/
93bool 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 **/
100bool 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 **/
111bool 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 **/
122void* 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.
130 *
131 * (this differs from ReleaseAddressSpace, which must account for
132 * extra padding/alignment to largePageSize.)
133 **/
134void 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 **/
142
143/**
144 * decrements the reference count begun by BeginOnDemandCommit and
145 * removes the page fault handler when it reaches 0. thread-safe.
146 **/
147void EndOnDemandCommits();
148
149
150void DumpStatistics();
151
152} // namespace vm
153
154#endif // #ifndef INCLUDED_SYSDEP_VM
static const size_t g_LargePageSize
Definition: alignment.h:97
Definition: uvm.cpp:38
void Free(void *p, size_t size)
decommit memory and release address space.
Definition: uvm.cpp:113
bool Decommit(uintptr_t address, size_t size)
unmap physical memory.
Definition: uvm.cpp:77
void EndOnDemandCommits()
decrements the reference count begun by BeginOnDemandCommit and removes the page fault handler when i...
Definition: uvm.cpp:125
void * Allocate(size_t size, PageType pageType, int prot)
reserve address space and commit memory.
Definition: uvm.cpp:98
void ReleaseAddressSpace(void *p, size_t size)
release address space and decommit any memory.
Definition: uvm.cpp:49
bool Commit(uintptr_t address, size_t size, PageType pageType, int prot)
map physical memory to previously reserved address space.
Definition: uvm.cpp:59
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 BeginOnDemandCommits()
install a handler that attempts to commit memory whenever a read/write page fault is encountered.
Definition: uvm.cpp:120
PageType
Definition: vm.h:43
@ kDefault
Definition: vm.h:46
@ kSmall
Definition: vm.h:45
@ kLarge
Definition: vm.h:44
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 DumpStatistics()
Definition: uvm.cpp:131
#define PROT_READ
Definition: wmman.h:32
#define PROT_WRITE
Definition: wmman.h:33