rev |
line source |
nuclear@0
|
1 /************************************************************************************
|
nuclear@0
|
2
|
nuclear@0
|
3 Filename : OVR_Allocator.cpp
|
nuclear@0
|
4 Content : Installable memory allocator implementation
|
nuclear@0
|
5 Created : September 19, 2012
|
nuclear@0
|
6 Notes :
|
nuclear@0
|
7
|
nuclear@0
|
8 Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
|
nuclear@0
|
9
|
nuclear@0
|
10 Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
|
nuclear@0
|
11 you may not use the Oculus VR Rift SDK except in compliance with the License,
|
nuclear@0
|
12 which is provided at the time of installation or download, or which
|
nuclear@0
|
13 otherwise accompanies this software in either electronic or hard copy form.
|
nuclear@0
|
14
|
nuclear@0
|
15 You may obtain a copy of the License at
|
nuclear@0
|
16
|
nuclear@0
|
17 http://www.oculusvr.com/licenses/LICENSE-3.2
|
nuclear@0
|
18
|
nuclear@0
|
19 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
|
nuclear@0
|
20 distributed under the License is distributed on an "AS IS" BASIS,
|
nuclear@0
|
21 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
nuclear@0
|
22 See the License for the specific language governing permissions and
|
nuclear@0
|
23 limitations under the License.
|
nuclear@0
|
24
|
nuclear@0
|
25 ************************************************************************************/
|
nuclear@0
|
26
|
nuclear@0
|
27 #include "OVR_Allocator.h"
|
nuclear@0
|
28 #ifdef OVR_OS_MAC
|
nuclear@0
|
29 #include <stdlib.h>
|
nuclear@0
|
30 #else
|
nuclear@0
|
31 #include <malloc.h>
|
nuclear@0
|
32 #endif
|
nuclear@0
|
33
|
nuclear@0
|
34 #if defined(OVR_OS_MS)
|
nuclear@0
|
35 #include <Windows.h>
|
nuclear@0
|
36 #elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX)
|
nuclear@0
|
37 #include <unistd.h>
|
nuclear@0
|
38 #include <sys/mman.h>
|
nuclear@0
|
39 #endif
|
nuclear@0
|
40
|
nuclear@0
|
41
|
nuclear@0
|
42 namespace OVR {
|
nuclear@0
|
43
|
nuclear@0
|
44 //-----------------------------------------------------------------------------------
|
nuclear@0
|
45 // ***** Allocator
|
nuclear@0
|
46
|
nuclear@0
|
47 Allocator* Allocator::pInstance = 0;
|
nuclear@0
|
48
|
nuclear@0
|
49 // Default AlignedAlloc implementation will delegate to Alloc/Free after doing rounding.
|
nuclear@0
|
50 void* Allocator::AllocAligned(size_t size, size_t align)
|
nuclear@0
|
51 {
|
nuclear@0
|
52 OVR_ASSERT((align & (align-1)) == 0);
|
nuclear@0
|
53 align = (align > sizeof(size_t)) ? align : sizeof(size_t);
|
nuclear@0
|
54 size_t p = (size_t)Alloc(size+align);
|
nuclear@0
|
55 size_t aligned = 0;
|
nuclear@0
|
56 if (p)
|
nuclear@0
|
57 {
|
nuclear@0
|
58 aligned = (size_t(p) + align-1) & ~(align-1);
|
nuclear@0
|
59 if (aligned == p)
|
nuclear@0
|
60 aligned += align;
|
nuclear@0
|
61 *(((size_t*)aligned)-1) = aligned-p;
|
nuclear@0
|
62 }
|
nuclear@0
|
63 return (void*)aligned;
|
nuclear@0
|
64 }
|
nuclear@0
|
65
|
nuclear@0
|
66 void Allocator::FreeAligned(void* p)
|
nuclear@0
|
67 {
|
nuclear@0
|
68 size_t src = size_t(p) - *(((size_t*)p)-1);
|
nuclear@0
|
69 Free((void*)src);
|
nuclear@0
|
70 }
|
nuclear@0
|
71
|
nuclear@0
|
72
|
nuclear@0
|
73 //------------------------------------------------------------------------
|
nuclear@0
|
74 // ***** Default Allocator
|
nuclear@0
|
75
|
nuclear@0
|
76 // This allocator is created and used if no other allocator is installed.
|
nuclear@0
|
77 // Default allocator delegates to system malloc.
|
nuclear@0
|
78
|
nuclear@0
|
79 void* DefaultAllocator::Alloc(size_t size)
|
nuclear@0
|
80 {
|
nuclear@0
|
81 return malloc(size);
|
nuclear@0
|
82 }
|
nuclear@0
|
83 void* DefaultAllocator::AllocDebug(size_t size, const char* file, unsigned line)
|
nuclear@0
|
84 {
|
nuclear@0
|
85 OVR_UNUSED2(file, line); // should be here for debugopt config
|
nuclear@0
|
86 #if defined(OVR_CC_MSVC) && defined(_CRTDBG_MAP_ALLOC)
|
nuclear@0
|
87 return _malloc_dbg(size, _NORMAL_BLOCK, file, line);
|
nuclear@0
|
88 #else
|
nuclear@0
|
89 return malloc(size);
|
nuclear@0
|
90 #endif
|
nuclear@0
|
91 }
|
nuclear@0
|
92
|
nuclear@0
|
93 void* DefaultAllocator::Realloc(void* p, size_t newSize)
|
nuclear@0
|
94 {
|
nuclear@0
|
95 return realloc(p, newSize);
|
nuclear@0
|
96 }
|
nuclear@0
|
97 void DefaultAllocator::Free(void *p)
|
nuclear@0
|
98 {
|
nuclear@0
|
99 return free(p);
|
nuclear@0
|
100 }
|
nuclear@0
|
101
|
nuclear@0
|
102
|
nuclear@0
|
103
|
nuclear@0
|
104
|
nuclear@0
|
105 void* MMapAlloc(size_t size)
|
nuclear@0
|
106 {
|
nuclear@0
|
107 #if defined(OVR_OS_MS)
|
nuclear@0
|
108 return VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); // size is rounded up to a page. // Returned memory is 0-filled.
|
nuclear@0
|
109
|
nuclear@0
|
110 #elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX)
|
nuclear@0
|
111 #if !defined(MAP_FAILED)
|
nuclear@0
|
112 #define MAP_FAILED ((void*)-1)
|
nuclear@0
|
113 #endif
|
nuclear@0
|
114
|
nuclear@0
|
115 void* result = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); // Returned memory is 0-filled.
|
nuclear@0
|
116 if(result == MAP_FAILED) // mmap returns MAP_FAILED (-1) upon failure.
|
nuclear@0
|
117 result = NULL;
|
nuclear@0
|
118 return result;
|
nuclear@0
|
119 #endif
|
nuclear@0
|
120 }
|
nuclear@0
|
121
|
nuclear@0
|
122
|
nuclear@0
|
123
|
nuclear@0
|
124
|
nuclear@0
|
125 void MMapFree(void* memory, size_t size)
|
nuclear@0
|
126 {
|
nuclear@0
|
127 #if defined(OVR_OS_MS)
|
nuclear@0
|
128 OVR_UNUSED(size);
|
nuclear@0
|
129 VirtualFree(memory, 0, MEM_RELEASE);
|
nuclear@0
|
130
|
nuclear@0
|
131 #elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX)
|
nuclear@0
|
132 size_t pageSize = getpagesize();
|
nuclear@0
|
133 size = (((size + (pageSize - 1)) / pageSize) * pageSize);
|
nuclear@0
|
134 munmap(memory, size); // Must supply the size to munmap.
|
nuclear@0
|
135 #endif
|
nuclear@0
|
136 }
|
nuclear@0
|
137
|
nuclear@0
|
138
|
nuclear@0
|
139
|
nuclear@0
|
140
|
nuclear@0
|
141 } // OVR
|