Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
uvm.cpp
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 #include "precompiled.h"
24 #include "lib/sysdep/vm.h"
25 
26 #include "lib/alignment.h"
27 
28 // "anonymous" effectively means mapping /dev/zero, but is more efficient.
29 // MAP_ANONYMOUS is not in SUSv3, but is a very common extension.
30 // unfortunately, MacOS X only defines MAP_ANON, which Solaris says is
31 // deprecated. workaround there: define MAP_ANONYMOUS in terms of MAP_ANON.
32 #ifndef MAP_ANONYMOUS
33 # define MAP_ANONYMOUS MAP_ANON
34 #endif
35 
37 
38 namespace vm {
39 
40 void* ReserveAddressSpace(size_t size, size_t UNUSED(commitSize), PageType UNUSED(pageType), int UNUSED(prot))
41 {
42  errno = 0;
43  void* p = mmap(0, size, PROT_NONE, mmap_flags|MAP_NORESERVE, -1, 0);
44  if(p == MAP_FAILED)
45  return 0;
46  return p;
47 }
48 
49 void ReleaseAddressSpace(void* p, size_t size)
50 {
51  ENSURE(size != 0);
52 
53  errno = 0;
54  if(munmap(p, size) != 0)
56 }
57 
58 
59 bool Commit(uintptr_t address, size_t size, PageType UNUSED(pageType), int prot)
60 {
61  if(prot == PROT_NONE) // would be understood as a request to decommit
62  {
64  return false;
65  }
66 
67  errno = 0;
68  if(mmap((void*)address, size, prot, mmap_flags|MAP_FIXED, -1, 0) == MAP_FAILED)
69  return false;
70 
71  if(prot != (PROT_READ|PROT_WRITE))
72  (void)Protect(address, size, prot);
73 
74  return true;
75 }
76 
77 bool Decommit(uintptr_t address, size_t size)
78 {
79  errno = 0;
80  if(mmap((void*)address, size, PROT_NONE, mmap_flags|MAP_NORESERVE|MAP_FIXED, -1, 0) == MAP_FAILED)
81  return false;
82  return true;
83 }
84 
85 
86 bool Protect(uintptr_t address, size_t size, int prot)
87 {
88  errno = 0;
89  if(mprotect((void*)address, size, prot) != 0)
90  {
92  return false;
93  }
94  return true;
95 }
96 
97 
98 void* Allocate(size_t size, PageType pageType, int prot)
99 {
100  void* p = ReserveAddressSpace(size);
101  if(!p)
102  return 0;
103 
104  if(!Commit(uintptr_t(p), size, pageType, prot))
105  {
106  ReleaseAddressSpace(p, size);
107  return 0;
108  }
109 
110  return p;
111 }
112 
113 void Free(void* p, size_t size)
114 {
115  // (only the Windows implementation distinguishes between Free and ReleaseAddressSpace)
116  vm::ReleaseAddressSpace(p, size);
117 }
118 
119 
121 {
122  // not yet implemented, but possible with a signal handler
123 }
124 
126 {
127  // not yet implemented, but possible with a signal handler
128 }
129 
130 
132 {
133  // we haven't collected any statistics
134 }
135 
136 } // namespace vm
#define PROT_WRITE
Definition: wmman.h:33
#define UNUSED(param)
mark a function parameter as unused and avoid the corresponding compiler warning. ...
void BeginOnDemandCommits()
install a handler that attempts to commit memory whenever a read/write page fault is encountered...
Definition: uvm.cpp:120
int mprotect(void *addr, size_t len, int prot)
Definition: wmman.cpp:67
bool Commit(uintptr_t address, size_t size, PageType pageType, int prot)
map physical memory to previously reserved address space.
Definition: uvm.cpp:59
#define MAP_ANONYMOUS
Definition: uvm.cpp:33
#define ENSURE(expr)
ensure the expression <expr> evaluates to non-zero.
Definition: debug.h:282
void * mmap(void *start, size_t len, int prot, int flags, int fd, off_t ofs)
Definition: wmman.cpp:202
PageType
Definition: vm.h:42
#define MAP_FAILED
Definition: wmman.h:52
#define MAP_FIXED
Definition: wmman.h:39
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
const Status INVALID_PARAM
Definition: status.h:423
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 DEBUG_WARN_ERR(status)
display the error dialog with text corresponding to the given error code.
Definition: debug.h:331
#define PROT_READ
Definition: wmman.h:32
#define MAP_PRIVATE
Definition: wmman.h:38
Status StatusFromErrno()
Definition: status.cpp:105
static const int mmap_flags
Definition: uvm.cpp:36
void ReleaseAddressSpace(void *p, size_t size)
release address space and decommit any memory.
Definition: uvm.cpp:49
#define MAP_NORESERVE
Definition: wmman.h:42
void * Allocate(size_t size, PageType pageType, int prot)
reserve address space and commit memory.
Definition: uvm.cpp:98
const Status FAIL
Definition: status.h:406
int munmap(void *start, size_t len)
Definition: wmman.cpp:222
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
#define PROT_NONE
Definition: wmman.h:31