ovr_sdk

view LibOVR/Src/Kernel/OVR_Allocator.h @ 0:1b39a1b46319

initial 0.4.4
author John Tsiombikas <nuclear@member.fsf.org>
date Wed, 14 Jan 2015 06:51:16 +0200
parents
children
line source
1 /************************************************************************************
3 PublicHeader: OVR_Kernel.h
4 Filename : OVR_Allocator.h
5 Content : Installable memory allocator
6 Created : September 19, 2012
7 Notes :
9 Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved.
11 Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License");
12 you may not use the Oculus VR Rift SDK except in compliance with the License,
13 which is provided at the time of installation or download, or which
14 otherwise accompanies this software in either electronic or hard copy form.
16 You may obtain a copy of the License at
18 http://www.oculusvr.com/licenses/LICENSE-3.2
20 Unless required by applicable law or agreed to in writing, the Oculus VR SDK
21 distributed under the License is distributed on an "AS IS" BASIS,
22 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
23 See the License for the specific language governing permissions and
24 limitations under the License.
26 ************************************************************************************/
28 #ifndef OVR_Allocator_h
29 #define OVR_Allocator_h
31 #include "OVR_Types.h"
33 //-----------------------------------------------------------------------------------
35 // ***** Disable template-unfriendly MS VC++ warnings
36 #if defined(OVR_CC_MSVC)
37 // Pragma to prevent long name warnings in in VC++
38 #pragma warning(disable : 4503)
39 #pragma warning(disable : 4786)
40 // In MSVC 7.1, warning about placement new POD default initializer
41 #pragma warning(disable : 4345)
42 #endif
44 // Un-define new so that placement constructors work
45 #undef new
48 //-----------------------------------------------------------------------------------
49 // ***** Placement new overrides
51 // Calls constructor on own memory created with "new(ptr) type"
52 #ifndef __PLACEMENT_NEW_INLINE
53 #define __PLACEMENT_NEW_INLINE
55 # if defined(OVR_CC_MWERKS) || defined(OVR_CC_BORLAND) || defined(OVR_CC_GNU)
56 # include <new>
57 # else
58 // Useful on MSVC
59 OVR_FORCE_INLINE void* operator new (size_t n, void *ptr) { OVR_UNUSED(n); return ptr; }
60 OVR_FORCE_INLINE void operator delete (void *, void *) { }
61 # endif
63 #endif // __PLACEMENT_NEW_INLINE
67 //------------------------------------------------------------------------
68 // ***** Macros to redefine class new/delete operators
70 // Types specifically declared to allow disambiguation of address in
71 // class member operator new.
73 #define OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, check_delete) \
74 void* operator new(size_t sz) \
75 { void *p = OVR_ALLOC_DEBUG(sz, __FILE__, __LINE__); return p; } \
76 void* operator new(size_t sz, const char* file, int line) \
77 { void* p = OVR_ALLOC_DEBUG(sz, file, line); OVR_UNUSED2(file, line); return p; } \
78 void operator delete(void *p) \
79 { check_delete(class_name, p); OVR_FREE(p); } \
80 void operator delete(void *p, const char*, int) \
81 { check_delete(class_name, p); OVR_FREE(p); }
83 #define OVR_MEMORY_DEFINE_PLACEMENT_NEW \
84 void* operator new (size_t n, void *ptr) { OVR_UNUSED(n); return ptr; } \
85 void operator delete (void *ptr, void *ptr2) { OVR_UNUSED2(ptr,ptr2); }
88 #define OVR_MEMORY_CHECK_DELETE_NONE(class_name, p)
90 // Redefined all delete/new operators in a class without custom memory initialization
91 #define OVR_MEMORY_REDEFINE_NEW(class_name) \
92 OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, OVR_MEMORY_CHECK_DELETE_NONE)
95 namespace OVR {
97 //-----------------------------------------------------------------------------------
98 // ***** Construct / Destruct
100 // Construct/Destruct functions are useful when new is redefined, as they can
101 // be called instead of placement new constructors.
104 template <class T>
105 OVR_FORCE_INLINE T* Construct(void *p)
106 {
107 return ::new(p) T();
108 }
110 template <class T>
111 OVR_FORCE_INLINE T* Construct(void *p, const T& source)
112 {
113 return ::new(p) T(source);
114 }
116 // Same as above, but allows for a different type of constructor.
117 template <class T, class S>
118 OVR_FORCE_INLINE T* ConstructAlt(void *p, const S& source)
119 {
120 return ::new(p) T(source);
121 }
123 template <class T, class S1, class S2>
124 OVR_FORCE_INLINE T* ConstructAlt(void *p, const S1& src1, const S2& src2)
125 {
126 return ::new(p) T(src1, src2);
127 }
129 template <class T>
130 OVR_FORCE_INLINE void ConstructArray(void *p, size_t count)
131 {
132 uint8_t *pdata = (uint8_t*)p;
133 for (size_t i=0; i< count; ++i, pdata += sizeof(T))
134 {
135 Construct<T>(pdata);
136 }
137 }
139 template <class T>
140 OVR_FORCE_INLINE void ConstructArray(void *p, size_t count, const T& source)
141 {
142 uint8_t *pdata = (uint8_t*)p;
143 for (size_t i=0; i< count; ++i, pdata += sizeof(T))
144 {
145 Construct<T>(pdata, source);
146 }
147 }
149 template <class T>
150 OVR_FORCE_INLINE void Destruct(T *pobj)
151 {
152 pobj->~T();
153 OVR_UNUSED1(pobj); // Fix incorrect 'unused variable' MSVC warning.
154 }
156 template <class T>
157 OVR_FORCE_INLINE void DestructArray(T *pobj, size_t count)
158 {
159 for (size_t i=0; i<count; ++i, ++pobj)
160 pobj->~T();
161 }
164 //-----------------------------------------------------------------------------------
165 // ***** Allocator
167 // Allocator defines a memory allocation interface that developers can override
168 // to to provide memory for OVR; an instance of this class is typically created on
169 // application startup and passed into System or OVR::System constructor.
170 //
171 //
172 // Users implementing this interface must provide three functions: Alloc, Free,
173 // and Realloc. Implementations of these functions must honor the requested alignment.
174 // Although arbitrary alignment requests are possible, requested alignment will
175 // typically be small, such as 16 bytes or less.
177 class Allocator
178 {
179 friend class System;
180 public:
181 virtual ~Allocator(){}
183 // *** Standard Alignment Alloc/Free
185 // Allocate memory of specified size with default alignment.
186 // Alloc of size==0 will allocate a tiny block & return a valid pointer;
187 // this makes it suitable for new operator.
188 virtual void* Alloc(size_t size) = 0;
189 // Same as Alloc, but provides an option of passing debug data.
190 virtual void* AllocDebug(size_t size, const char* file, unsigned line)
191 { OVR_UNUSED2(file, line); return Alloc(size); }
193 // Reallocate memory block to a new size, copying data if necessary. Returns the pointer to
194 // new memory block, which may be the same as original pointer. Will return 0 if reallocation
195 // failed, in which case previous memory is still valid.
196 // Realloc to decrease size will never fail.
197 // Realloc of pointer == 0 is equivalent to Alloc
198 // Realloc to size == 0, shrinks to the minimal size, pointer remains valid and requires Free().
199 virtual void* Realloc(void* p, size_t newSize) = 0;
201 // Frees memory allocated by Alloc/Realloc.
202 // Free of null pointer is valid and will do nothing.
203 virtual void Free(void *p) = 0;
206 // *** Standard Alignment Alloc/Free
208 // Allocate memory of specified alignment.
209 // Memory allocated with AllocAligned MUST be freed with FreeAligned.
210 // Default implementation will delegate to Alloc/Free after doing rounding.
211 virtual void* AllocAligned(size_t size, size_t align);
212 // Frees memory allocated with AllocAligned.
213 virtual void FreeAligned(void* p);
215 // Returns the pointer to the current globally installed Allocator instance.
216 // This pointer is used for most of the memory allocations.
217 static Allocator* GetInstance() { return pInstance; }
220 protected:
221 // onSystemShutdown is called on the allocator during System::Shutdown.
222 // At this point, all allocations should've been freed.
223 virtual void onSystemShutdown() { }
225 public:
226 static void setInstance(Allocator* palloc)
227 {
228 OVR_ASSERT((pInstance == 0) || (palloc == 0));
229 pInstance = palloc;
230 }
232 private:
234 static Allocator* pInstance;
235 };
239 //------------------------------------------------------------------------
240 // ***** Allocator_SingletonSupport
242 // Allocator_SingletonSupport is a Allocator wrapper class that implements
243 // the InitSystemSingleton static function, used to create a global singleton
244 // used for the OVR::System default argument initialization.
245 //
246 // End users implementing custom Allocator interface don't need to make use of this base
247 // class; they can just create an instance of their own class on stack and pass it to System.
249 template<class D>
250 class Allocator_SingletonSupport : public Allocator
251 {
252 struct AllocContainer
253 {
254 size_t Data[(sizeof(D) + sizeof(size_t)-1) / sizeof(size_t)];
255 bool Initialized;
256 AllocContainer() : Initialized(0) { }
257 };
259 AllocContainer* pContainer;
261 public:
262 Allocator_SingletonSupport() : pContainer(0) { }
264 // Creates a singleton instance of this Allocator class used
265 // on OVR_DEFAULT_ALLOCATOR during System initialization.
266 static D* InitSystemSingleton()
267 {
268 static AllocContainer Container;
269 OVR_ASSERT(Container.Initialized == false);
271 Allocator_SingletonSupport<D> *presult = Construct<D>((void*)Container.Data);
272 presult->pContainer = &Container;
273 Container.Initialized = true;
274 return (D*)presult;
275 }
277 protected:
278 virtual void onSystemShutdown()
279 {
280 Allocator::onSystemShutdown();
281 if (pContainer)
282 {
283 pContainer->Initialized = false;
284 Destruct((D*)this);
285 pContainer = 0;
286 }
287 }
288 };
290 //------------------------------------------------------------------------
291 // ***** Default Allocator
293 // This allocator is created and used if no other allocator is installed.
294 // Default allocator delegates to system malloc.
296 class DefaultAllocator : public Allocator_SingletonSupport<DefaultAllocator>
297 {
298 public:
299 virtual void* Alloc(size_t size);
300 virtual void* AllocDebug(size_t size, const char* file, unsigned line);
301 virtual void* Realloc(void* p, size_t newSize);
302 virtual void Free(void *p);
303 };
306 //------------------------------------------------------------------------
307 // ***** Memory Allocation Macros
309 // These macros should be used for global allocation. In the future, these
310 // macros will allows allocation to be extended with debug file/line information
311 // if necessary.
313 #define OVR_REALLOC(p,s) OVR::Allocator::GetInstance()->Realloc((p),(s))
314 #define OVR_FREE(p) OVR::Allocator::GetInstance()->Free((p))
315 #define OVR_ALLOC_ALIGNED(s,a) OVR::Allocator::GetInstance()->AllocAligned((s),(a))
316 #define OVR_FREE_ALIGNED(p) OVR::Allocator::GetInstance()->FreeAligned((p))
318 #ifdef OVR_BUILD_DEBUG
319 #define OVR_ALLOC(s) OVR::Allocator::GetInstance()->AllocDebug((s), __FILE__, __LINE__)
320 #define OVR_ALLOC_DEBUG(s,f,l) OVR::Allocator::GetInstance()->AllocDebug((s), f, l)
321 #else
322 #define OVR_ALLOC(s) OVR::Allocator::GetInstance()->Alloc((s))
323 #define OVR_ALLOC_DEBUG(s,f,l) OVR::Allocator::GetInstance()->Alloc((s))
324 #endif
326 //------------------------------------------------------------------------
328 // Base class that overrides the new and delete operators.
329 // Deriving from this class, even as a multiple base, incurs no space overhead.
330 class NewOverrideBase
331 {
332 public:
334 // Redefine all new & delete operators.
335 OVR_MEMORY_REDEFINE_NEW(NewOverrideBase)
336 };
339 //------------------------------------------------------------------------
340 // ***** Mapped memory allocation
341 //
342 // Equates to VirtualAlloc/VirtualFree on Windows, mmap/munmap on Unix.
343 // These are useful for when you need system-supplied memory pages.
344 // These are also useful for when you need to allocate memory in a way
345 // that doesn't affect the application heap.
347 void* MMapAlloc(size_t size);
348 void MMapFree(void* memory, size_t size);
351 } // OVR
354 // Redefine operator 'new' if necessary.
355 #if defined(OVR_DEFINE_NEW)
356 #define new OVR_DEFINE_NEW
357 #endif
360 #endif // OVR_Memory