OVR_Allocator.h
Go to the documentation of this file.
00001 /************************************************************************************
00002 
00003 PublicHeader:   OVR.h
00004 Filename    :   OVR_Allocator.h
00005 Content     :   Installable memory allocator
00006 Created     :   September 19, 2012
00007 Notes       : 
00008 
00009 Copyright   :   Copyright 2012 Oculus VR, Inc. All Rights reserved.
00010 
00011 Use of this software is subject to the terms of the Oculus license
00012 agreement provided at the time of installation or download, or which
00013 otherwise accompanies this software in either electronic or hard copy form.
00014 
00015 ************************************************************************************/
00016 
00017 #ifndef OVR_Allocator_h
00018 #define OVR_Allocator_h
00019 
00020 #include "OVR_Types.h"
00021 
00022 //-----------------------------------------------------------------------------------
00023 
00024 // ***** Disable template-unfriendly MS VC++ warnings
00025 #if defined(OVR_CC_MSVC)
00026 // Pragma to prevent long name warnings in in VC++
00027 #pragma warning(disable : 4503)
00028 #pragma warning(disable : 4786)
00029 // In MSVC 7.1, warning about placement new POD default initializer
00030 #pragma warning(disable : 4345)
00031 #endif
00032 
00033 // Un-define new so that placement constructors work
00034 #undef new
00035 
00036 
00037 //-----------------------------------------------------------------------------------
00038 // ***** Placement new overrides
00039 
00040 // Calls constructor on own memory created with "new(ptr) type"
00041 #ifndef __PLACEMENT_NEW_INLINE
00042 #define __PLACEMENT_NEW_INLINE
00043 
00044 #   if defined(OVR_CC_MWERKS) || defined(OVR_CC_BORLAND) || defined(OVR_CC_GNU)
00045 #      include <new>
00046 #   else
00047     // Useful on MSVC
00048     OVR_FORCE_INLINE void* operator new     (OVR::UPInt n, void *ptr) { OVR_UNUSED(n); return ptr; }
00049     OVR_FORCE_INLINE void  operator delete  (void *, void *)     { }
00050 #   endif
00051 
00052 #endif // __PLACEMENT_NEW_INLINE
00053 
00054 
00055 
00056 //------------------------------------------------------------------------
00057 // ***** Macros to redefine class new/delete operators
00058 
00059 // Types specifically declared to allow disambiguation of address in
00060 // class member operator new.
00061 
00062 #define OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, check_delete)                          \
00063     void*   operator new(UPInt sz)                                                      \
00064     { void *p = OVR_ALLOC_DEBUG(sz, __FILE__, __LINE__); return p; }                                              \
00065     void*   operator new(UPInt sz, const char* file, int line)                          \
00066     { void* p = OVR_ALLOC_DEBUG(sz, file, line); OVR_UNUSED2(file, line); return p; }   \
00067     void    operator delete(void *p)                                                    \
00068     { check_delete(class_name, p); OVR_FREE(p); }                                       \
00069     void    operator delete(void *p, const char*, int)                                  \
00070     { check_delete(class_name, p); OVR_FREE(p); }                          
00071 
00072 #define OVR_MEMORY_DEFINE_PLACEMENT_NEW                                                 \
00073     void*   operator new        (UPInt n, void *ptr)    { OVR_UNUSED(n); return ptr; }  \
00074     void    operator delete     (void *ptr, void *ptr2) { OVR_UNUSED2(ptr,ptr2); }
00075 
00076 
00077 #define OVR_MEMORY_CHECK_DELETE_NONE(class_name, p)
00078 
00079 // Redefined all delete/new operators in a class without custom memory initialization
00080 #define OVR_MEMORY_REDEFINE_NEW(class_name) \
00081     OVR_MEMORY_REDEFINE_NEW_IMPL(class_name, OVR_MEMORY_CHECK_DELETE_NONE)
00082 
00083 
00084 namespace OVR {
00085 
00086 //-----------------------------------------------------------------------------------
00087 // ***** Construct / Destruct
00088 
00089 // Construct/Destruct functions are useful when new is redefined, as they can
00090 // be called instead of placement new constructors.
00091 
00092 
00093 template <class T>
00094 OVR_FORCE_INLINE T*  Construct(void *p)
00095 {
00096     return ::new(p) T;
00097 }
00098 
00099 template <class T>
00100 OVR_FORCE_INLINE T*  Construct(void *p, const T& source)
00101 {
00102     return ::new(p) T(source);
00103 }
00104 
00105 // Same as above, but allows for a different type of constructor.
00106 template <class T, class S>
00107 OVR_FORCE_INLINE T*  ConstructAlt(void *p, const S& source)
00108 {
00109     return ::new(p) T(source);
00110 }
00111 
00112 template <class T, class S1, class S2>
00113 OVR_FORCE_INLINE T*  ConstructAlt(void *p, const S1& src1, const S2& src2)
00114 {
00115     return ::new(p) T(src1, src2);
00116 }
00117 
00118 template <class T>
00119 OVR_FORCE_INLINE void ConstructArray(void *p, UPInt count)
00120 {
00121     UByte *pdata = (UByte*)p;
00122     for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
00123     {
00124         Construct<T>(pdata);
00125     }
00126 }
00127 
00128 template <class T>
00129 OVR_FORCE_INLINE void ConstructArray(void *p, UPInt count, const T& source)
00130 {
00131     UByte *pdata = (UByte*)p;
00132     for (UPInt i=0; i< count; ++i, pdata += sizeof(T))
00133     {
00134         Construct<T>(pdata, source);
00135     }
00136 }
00137 
00138 template <class T>
00139 OVR_FORCE_INLINE void Destruct(T *pobj)
00140 {
00141     pobj->~T();
00142     OVR_UNUSED1(pobj); // Fix incorrect 'unused variable' MSVC warning.
00143 }
00144 
00145 template <class T>
00146 OVR_FORCE_INLINE void DestructArray(T *pobj, UPInt count)
00147 {   
00148     for (UPInt i=0; i<count; ++i, ++pobj)
00149         pobj->~T();
00150 }
00151 
00152 
00153 //-----------------------------------------------------------------------------------
00154 // ***** Allocator
00155 
00156 // Allocator defines a memory allocation interface that developers can override
00157 // to to provide memory for OVR; an instance of this class is typically created on
00158 // application startup and passed into System or OVR::System constructor.
00159 // 
00160 //
00161 // Users implementing this interface must provide three functions: Alloc, Free,
00162 // and Realloc. Implementations of these functions must honor the requested alignment.
00163 // Although arbitrary alignment requests are possible, requested alignment will
00164 // typically be small, such as 16 bytes or less.
00165 
00166 class Allocator
00167 {
00168     friend class System;
00169 public:
00170 
00171     // *** Standard Alignment Alloc/Free
00172 
00173     // Allocate memory of specified size with default alignment.
00174     // Alloc of size==0 will allocate a tiny block & return a valid pointer;
00175     // this makes it suitable for new operator.
00176     virtual void*   Alloc(UPInt size) = 0;
00177     // Same as Alloc, but provides an option of passing debug data.
00178     virtual void*   AllocDebug(UPInt size, const char* file, unsigned line)
00179     { OVR_UNUSED2(file, line); return Alloc(size); }
00180 
00181     // Reallocate memory block to a new size, copying data if necessary. Returns the pointer to
00182     // new memory block, which may be the same as original pointer. Will return 0 if reallocation
00183     // failed, in which case previous memory is still valid.
00184     // Realloc to decrease size will never fail.
00185     // Realloc of pointer == 0 is equivalent to Alloc
00186     // Realloc to size == 0, shrinks to the minimal size, pointer remains valid and requires Free().
00187     virtual void*   Realloc(void* p, UPInt newSize) = 0;
00188 
00189     // Frees memory allocated by Alloc/Realloc.
00190     // Free of null pointer is valid and will do nothing.
00191     virtual void    Free(void *p) = 0;
00192 
00193 
00194     // *** Standard Alignment Alloc/Free
00195 
00196     // Allocate memory of specified alignment.
00197     // Memory allocated with AllocAligned MUST be freed with FreeAligned.
00198     // Default implementation will delegate to Alloc/Free after doing rounding.
00199     virtual void*   AllocAligned(UPInt size, UPInt align);    
00200     // Frees memory allocated with AllocAligned.
00201     virtual void    FreeAligned(void* p);
00202     
00203     // Returns the pointer to the current globally installed Allocator instance.
00204     // This pointer is used for most of the memory allocations.
00205     static Allocator* GetInstance() { return pInstance; }
00206 
00207 
00208 protected:
00209     // onSystemShutdown is called on the allocator during System::Shutdown.
00210     // At this point, all allocations should've been freed.
00211     virtual void    onSystemShutdown() { }
00212 
00213 public:
00214     static  void    setInstance(Allocator* palloc)    
00215     {
00216         OVR_ASSERT((pInstance == 0) || (palloc == 0));
00217         pInstance = palloc;
00218     }
00219 
00220 private:
00221 
00222     static Allocator* pInstance;
00223 };
00224 
00225 
00226 
00227 //------------------------------------------------------------------------
00228 // ***** Allocator_SingletonSupport
00229 
00230 // Allocator_SingletonSupport is a Allocator wrapper class that implements
00231 // the InitSystemSingleton static function, used to create a global singleton
00232 // used for the OVR::System default argument initialization.
00233 //
00234 // End users implementing custom Allocator interface don't need to make use of this base
00235 // class; they can just create an instance of their own class on stack and pass it to System.
00236 
00237 template<class D>
00238 class Allocator_SingletonSupport : public Allocator
00239 {
00240     struct AllocContainer
00241     {        
00242         UPInt Data[(sizeof(D) + sizeof(UPInt)-1) / sizeof(UPInt)];
00243         bool  Initialized;
00244         AllocContainer() : Initialized(0) { }
00245     };
00246 
00247     AllocContainer* pContainer;
00248 
00249 public:
00250     Allocator_SingletonSupport() : pContainer(0) { }
00251 
00252     // Creates a singleton instance of this Allocator class used
00253     // on OVR_DEFAULT_ALLOCATOR during System initialization.
00254     static  D*  InitSystemSingleton()
00255     {
00256         static AllocContainer Container;
00257         OVR_ASSERT(Container.Initialized == false);
00258 
00259         Allocator_SingletonSupport<D> *presult = Construct<D>((void*)Container.Data);
00260         presult->pContainer   = &Container;
00261         Container.Initialized = true;
00262         return (D*)presult;
00263     }
00264 
00265 protected:
00266     virtual void onSystemShutdown()
00267     {
00268         Allocator::onSystemShutdown();
00269         if (pContainer)
00270         {
00271             pContainer->Initialized = false;
00272             Destruct((D*)this);
00273             pContainer = 0;
00274         }
00275     }
00276 };
00277 
00278 //------------------------------------------------------------------------
00279 // ***** Default Allocator
00280 
00281 // This allocator is created and used if no other allocator is installed.
00282 // Default allocator delegates to system malloc.
00283 
00284 class DefaultAllocator : public Allocator_SingletonSupport<DefaultAllocator>
00285 {
00286 public:
00287     virtual void*   Alloc(UPInt size);
00288     virtual void*   AllocDebug(UPInt size, const char* file, unsigned line);
00289     virtual void*   Realloc(void* p, UPInt newSize);
00290     virtual void    Free(void *p);
00291 };
00292 
00293 
00294 //------------------------------------------------------------------------
00295 // ***** Memory Allocation Macros
00296 
00297 // These macros should be used for global allocation. In the future, these
00298 // macros will allows allocation to be extended with debug file/line information
00299 // if necessary.
00300 
00301 #define OVR_REALLOC(p,s)        OVR::Allocator::GetInstance()->Realloc((p),(s))
00302 #define OVR_FREE(p)             OVR::Allocator::GetInstance()->Free((p))
00303 #define OVR_ALLOC_ALIGNED(s,a)  OVR::Allocator::GetInstance()->AllocAligned((s),(a))
00304 #define OVR_FREE_ALIGNED(p)     OVR::Allocator::GetInstance()->FreeAligned((p))
00305 
00306 #ifdef OVR_BUILD_DEBUG
00307 #define OVR_ALLOC(s)            OVR::Allocator::GetInstance()->AllocDebug((s), __FILE__, __LINE__)
00308 #define OVR_ALLOC_DEBUG(s,f,l)  OVR::Allocator::GetInstance()->AllocDebug((s), f, l)
00309 #else
00310 #define OVR_ALLOC(s)            OVR::Allocator::GetInstance()->Alloc((s))
00311 #define OVR_ALLOC_DEBUG(s,f,l)  OVR::Allocator::GetInstance()->Alloc((s))
00312 #endif
00313 
00314 //------------------------------------------------------------------------
00315 
00316 // Base class that overrides the new and delete operators.
00317 // Deriving from this class, even as a multiple base, incurs no space overhead.
00318 class NewOverrideBase
00319 {
00320 public:
00321 
00322     // Redefine all new & delete operators.
00323     OVR_MEMORY_REDEFINE_NEW(NewOverrideBase)
00324 };
00325 
00326 
00327 } // OVR
00328 
00329 
00330 // Redefine operator 'new' if necessary.
00331 #if defined(OVR_DEFINE_NEW)
00332 #define new OVR_DEFINE_NEW
00333 #endif
00334 
00335 
00336 #endif // OVR_Memory


oculus_sdk
Author(s): Tully Foote
autogenerated on Thu Jun 6 2019 20:13:48