oculus1
view libovr/Src/Kernel/OVR_Allocator.h @ 17:cfe4979ab3eb
ops, minor error in the last commit
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 21 Sep 2013 07:09:48 +0300 |
parents | e2f9e4603129 |
children |
line source
1 /************************************************************************************
3 PublicHeader: OVR.h
4 Filename : OVR_Allocator.h
5 Content : Installable memory allocator
6 Created : September 19, 2012
7 Notes :
9 Copyright : Copyright 2012 Oculus VR, Inc. All Rights reserved.
11 Use of this software is subject to the terms of the Oculus license
12 agreement provided at the time of installation or download, or which
13 otherwise accompanies this software in either electronic or hard copy form.
15 ************************************************************************************/
17 #ifndef OVR_Allocator_h
18 #define OVR_Allocator_h
20 #include "OVR_Types.h"
22 //-----------------------------------------------------------------------------------
24 // ***** Disable template-unfriendly MS VC++ warnings
25 #if defined(OVR_CC_MSVC)
26 // Pragma to prevent long name warnings in in VC++
27 #pragma warning(disable : 4503)
28 #pragma warning(disable : 4786)
29 // In MSVC 7.1, warning about placement new POD default initializer
30 #pragma warning(disable : 4345)
31 #endif
33 // Un-define new so that placement constructors work
34 #undef new
37 //-----------------------------------------------------------------------------------
38 // ***** Placement new overrides
40 // Calls constructor on own memory created with "new(ptr) type"
41 #ifndef __PLACEMENT_NEW_INLINE
42 #define __PLACEMENT_NEW_INLINE
44 # if defined(OVR_CC_MWERKS) || defined(OVR_CC_BORLAND) || defined(OVR_CC_GNU)
45 # include <new>
46 # else
47 // Useful on MSVC
48 OVR_FORCE_INLINE void* operator new (OVR::UPInt n, void *ptr) { OVR_UNUSED(n); return ptr; }
49 OVR_FORCE_INLINE void operator delete (void *, void *) { }
50 # endif
52 #endif // __PLACEMENT_NEW_INLINE
56 //------------------------------------------------------------------------
57 // ***** Macros to redefine class new/delete operators
59 // Types specifically declared to allow disambiguation of address in
60 // class member operator new.
62 #define OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, check_delete) \
63 void* operator new(UPInt sz) \
64 { void *p = OVR_ALLOC_DEBUG(sz, __FILE__, __LINE__); return p; } \
65 void* operator new(UPInt sz, const char* file, int line) \
66 { void* p = OVR_ALLOC_DEBUG(sz, file, line); OVR_UNUSED2(file, line); return p; } \
67 void operator delete(void *p) \
68 { check_delete(class_name, p); OVR_FREE(p); } \
69 void operator delete(void *p, const char*, int) \
70 { check_delete(class_name, p); OVR_FREE(p); }
72 #define OVR_MEMORY_DEFINE_PLACEMENT_NEW \
73 void* operator new (UPInt n, void *ptr) { OVR_UNUSED(n); return ptr; } \
74 void operator delete (void *ptr, void *ptr2) { OVR_UNUSED2(ptr,ptr2); }
77 #define OVR_MEMORY_CHECK_DELETE_NONE(class_name, p)
79 // Redefined all delete/new operators in a class without custom memory initialization
80 #define OVR_MEMORY_REDEFINE_NEW(class_name) \
81 OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, OVR_MEMORY_CHECK_DELETE_NONE)
84 namespace OVR {
86 //-----------------------------------------------------------------------------------
87 // ***** Construct / Destruct
89 // Construct/Destruct functions are useful when new is redefined, as they can
90 // be called instead of placement new constructors.
93 template <class T>
94 OVR_FORCE_INLINE T* Construct(void *p)
95 {
96 return ::new(p) T;
97 }
99 template <class T>
100 OVR_FORCE_INLINE T* Construct(void *p, const T& source)
101 {
102 return ::new(p) T(source);
103 }
105 // Same as above, but allows for a different type of constructor.
106 template <class T, class S>
107 OVR_FORCE_INLINE T* ConstructAlt(void *p, const S& source)
108 {
109 return ::new(p) T(source);
110 }
112 template <class T, class S1, class S2>
113 OVR_FORCE_INLINE T* ConstructAlt(void *p, const S1& src1, const S2& src2)
114 {
115 return ::new(p) T(src1, src2);
116 }
118 template <class T>
119 OVR_FORCE_INLINE void ConstructArray(void *p, UPInt count)
120 {
121 UByte *pdata = (UByte*)p;
122 for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
123 {
124 Construct<T>(pdata);
125 }
126 }
128 template <class T>
129 OVR_FORCE_INLINE void ConstructArray(void *p, UPInt count, const T& source)
130 {
131 UByte *pdata = (UByte*)p;
132 for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
133 {
134 Construct<T>(pdata, source);
135 }
136 }
138 template <class T>
139 OVR_FORCE_INLINE void Destruct(T *pobj)
140 {
141 pobj->~T();
142 OVR_UNUSED1(pobj); // Fix incorrect 'unused variable' MSVC warning.
143 }
145 template <class T>
146 OVR_FORCE_INLINE void DestructArray(T *pobj, UPInt count)
147 {
148 for (UPInt i=0; i<count; ++i, ++pobj)
149 pobj->~T();
150 }
153 //-----------------------------------------------------------------------------------
154 // ***** Allocator
156 // Allocator defines a memory allocation interface that developers can override
157 // to to provide memory for OVR; an instance of this class is typically created on
158 // application startup and passed into System or OVR::System constructor.
159 //
160 //
161 // Users implementing this interface must provide three functions: Alloc, Free,
162 // and Realloc. Implementations of these functions must honor the requested alignment.
163 // Although arbitrary alignment requests are possible, requested alignment will
164 // typically be small, such as 16 bytes or less.
166 class Allocator
167 {
168 friend class System;
169 public:
171 // *** Standard Alignment Alloc/Free
173 // Allocate memory of specified size with default alignment.
174 // Alloc of size==0 will allocate a tiny block & return a valid pointer;
175 // this makes it suitable for new operator.
176 virtual void* Alloc(UPInt size) = 0;
177 // Same as Alloc, but provides an option of passing debug data.
178 virtual void* AllocDebug(UPInt size, const char* file, unsigned line)
179 { OVR_UNUSED2(file, line); return Alloc(size); }
181 // Reallocate memory block to a new size, copying data if necessary. Returns the pointer to
182 // new memory block, which may be the same as original pointer. Will return 0 if reallocation
183 // failed, in which case previous memory is still valid.
184 // Realloc to decrease size will never fail.
185 // Realloc of pointer == 0 is equivalent to Alloc
186 // Realloc to size == 0, shrinks to the minimal size, pointer remains valid and requires Free().
187 virtual void* Realloc(void* p, UPInt newSize) = 0;
189 // Frees memory allocated by Alloc/Realloc.
190 // Free of null pointer is valid and will do nothing.
191 virtual void Free(void *p) = 0;
194 // *** Standard Alignment Alloc/Free
196 // Allocate memory of specified alignment.
197 // Memory allocated with AllocAligned MUST be freed with FreeAligned.
198 // Default implementation will delegate to Alloc/Free after doing rounding.
199 virtual void* AllocAligned(UPInt size, UPInt align);
200 // Frees memory allocated with AllocAligned.
201 virtual void FreeAligned(void* p);
203 // Returns the pointer to the current globally installed Allocator instance.
204 // This pointer is used for most of the memory allocations.
205 static Allocator* GetInstance() { return pInstance; }
208 protected:
209 // onSystemShutdown is called on the allocator during System::Shutdown.
210 // At this point, all allocations should've been freed.
211 virtual void onSystemShutdown() { }
213 public:
214 static void setInstance(Allocator* palloc)
215 {
216 OVR_ASSERT((pInstance == 0) || (palloc == 0));
217 pInstance = palloc;
218 }
220 private:
222 static Allocator* pInstance;
223 };
227 //------------------------------------------------------------------------
228 // ***** Allocator_SingletonSupport
230 // Allocator_SingletonSupport is a Allocator wrapper class that implements
231 // the InitSystemSingleton static function, used to create a global singleton
232 // used for the OVR::System default argument initialization.
233 //
234 // End users implementing custom Allocator interface don't need to make use of this base
235 // class; they can just create an instance of their own class on stack and pass it to System.
237 template<class D>
238 class Allocator_SingletonSupport : public Allocator
239 {
240 struct AllocContainer
241 {
242 UPInt Data[(sizeof(D) + sizeof(UPInt)-1) / sizeof(UPInt)];
243 bool Initialized;
244 AllocContainer() : Initialized(0) { }
245 };
247 AllocContainer* pContainer;
249 public:
250 Allocator_SingletonSupport() : pContainer(0) { }
252 // Creates a singleton instance of this Allocator class used
253 // on OVR_DEFAULT_ALLOCATOR during System initialization.
254 static D* InitSystemSingleton()
255 {
256 static AllocContainer Container;
257 OVR_ASSERT(Container.Initialized == false);
259 Allocator_SingletonSupport<D> *presult = Construct<D>((void*)Container.Data);
260 presult->pContainer = &Container;
261 Container.Initialized = true;
262 return (D*)presult;
263 }
265 protected:
266 virtual void onSystemShutdown()
267 {
268 Allocator::onSystemShutdown();
269 if (pContainer)
270 {
271 pContainer->Initialized = false;
272 Destruct((D*)this);
273 pContainer = 0;
274 }
275 }
276 };
278 //------------------------------------------------------------------------
279 // ***** Default Allocator
281 // This allocator is created and used if no other allocator is installed.
282 // Default allocator delegates to system malloc.
284 class DefaultAllocator : public Allocator_SingletonSupport<DefaultAllocator>
285 {
286 public:
287 virtual void* Alloc(UPInt size);
288 virtual void* AllocDebug(UPInt size, const char* file, unsigned line);
289 virtual void* Realloc(void* p, UPInt newSize);
290 virtual void Free(void *p);
291 };
294 //------------------------------------------------------------------------
295 // ***** Memory Allocation Macros
297 // These macros should be used for global allocation. In the future, these
298 // macros will allows allocation to be extended with debug file/line information
299 // if necessary.
301 #define OVR_REALLOC(p,s) OVR::Allocator::GetInstance()->Realloc((p),(s))
302 #define OVR_FREE(p) OVR::Allocator::GetInstance()->Free((p))
303 #define OVR_ALLOC_ALIGNED(s,a) OVR::Allocator::GetInstance()->AllocAligned((s),(a))
304 #define OVR_FREE_ALIGNED(p) OVR::Allocator::GetInstance()->FreeAligned((p))
306 #ifdef OVR_BUILD_DEBUG
307 #define OVR_ALLOC(s) OVR::Allocator::GetInstance()->AllocDebug((s), __FILE__, __LINE__)
308 #define OVR_ALLOC_DEBUG(s,f,l) OVR::Allocator::GetInstance()->AllocDebug((s), f, l)
309 #else
310 #define OVR_ALLOC(s) OVR::Allocator::GetInstance()->Alloc((s))
311 #define OVR_ALLOC_DEBUG(s,f,l) OVR::Allocator::GetInstance()->Alloc((s))
312 #endif
314 //------------------------------------------------------------------------
316 // Base class that overrides the new and delete operators.
317 // Deriving from this class, even as a multiple base, incurs no space overhead.
318 class NewOverrideBase
319 {
320 public:
322 // Redefine all new & delete operators.
323 OVR_MEMORY_REDEFINE_NEW(NewOverrideBase)
324 };
327 } // OVR
330 // Redefine operator 'new' if necessary.
331 #if defined(OVR_DEFINE_NEW)
332 #define new OVR_DEFINE_NEW
333 #endif
336 #endif // OVR_Memory