PixelLightAPI
.
|
00001 /*********************************************************\ 00002 * File: MemoryManager.h * 00003 * 00004 * Copyright (C) 2002-2012 The PixelLight Team (http://www.pixellight.org/) 00005 * 00006 * This file is part of PixelLight. 00007 * 00008 * PixelLight is free software: you can redistribute it and/or modify 00009 * it under the terms of the GNU Lesser General Public License as published by 00010 * the Free Software Foundation, either version 3 of the License, or 00011 * (at your option) any later version. 00012 * 00013 * PixelLight is distributed in the hope that it will be useful, 00014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 * GNU Lesser General Public License for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public License 00019 * along with PixelLight. If not, see <http://www.gnu.org/licenses/>. 00020 \*********************************************************/ 00021 00022 00023 #ifndef __PLCORE_MEMORYMANAGER_H__ 00024 #define __PLCORE_MEMORYMANAGER_H__ 00025 #pragma once 00026 00027 00028 //[-------------------------------------------------------] 00029 //[ Includes ] 00030 //[-------------------------------------------------------] 00031 #include "PLCore/PLCore.h" 00032 00033 00034 //[-------------------------------------------------------] 00035 //[ Namespace ] 00036 //[-------------------------------------------------------] 00037 namespace PLCore { 00038 00039 00040 //[-------------------------------------------------------] 00041 //[ Classes ] 00042 //[-------------------------------------------------------] 00043 /** 00044 * @brief 00045 * Static memory manager class 00046 * 00047 * @remarks 00048 * By using this memory manager together with the overwritten variations of global 'new' and 00049 * 'delete' operators we avoid some nasty memory problems when using for instance multiple 00050 * dynamic libraries. ALL memory allocation/deallocation happens inside the PLCore module and 00051 * goes 'through' this memory manager, so we can also create statistics, perform security checks 00052 * and so on. 00053 * When using the PixelLight way dealing with for instance application entry points (PLMain) or 00054 * modules (pl_module) by including 'PLCore/ModuleMain.h' or 'PLCore/Main.h' this 00055 * memory manager is 'activated' automatically. If not (why didn't you use this comfortable way? :) 00056 * you need to include 'PLCore/Core/MemoryManager.inl' once per project. 00057 * There are multiple allocation/deallocation types supported - also some legacy types that are only 00058 * supported for optimal compatibility. 00059 * 00060 * @note 00061 * - The __FUNCTION__ information is not used, because some systems don't support it and we may 00062 * get some conflicts with the overloaded new-operators of 'Microsoft's memory tracker' 00063 * - There are some simple wrapper functions you can use to avoid for instance nasty 00064 * standard header includes when they are undesired 00065 * - We intentionally do NOT offer memory macros (like an overwritten 'malloc') because experience 00066 * shows that they are making more troubles than adding advantages! 00067 * - Try to avoid the allocation/deallocation legacy types (Malloc, Calloc, Realloc, Free) to avoid 00068 * possible memory problems! 00069 * - Do NOT mix allocation/deallocation types like using 'delete []' to deallocate memory allocated 00070 * 'with (none array) 'new'! 00071 * - To get information about for instance the current free physical memory have a look at the 'System'-class 00072 */ 00073 class MemoryManager { 00074 00075 00076 //[-------------------------------------------------------] 00077 //[ Public definitions ] 00078 //[-------------------------------------------------------] 00079 public: 00080 /** 00081 * @brief 00082 * Allocation/deallocation types 00083 */ 00084 enum EType { 00085 Unknown, /**< ? */ 00086 New, /**< new <type name> */ 00087 NewArray, /**< new [<number of elements>] <type name> */ 00088 Delete, /**< delete <pointer> */ 00089 DeleteArray, /**< delete [] <pointer> */ 00090 // The following legacy types are only supported for optimal compatibility, try to avoid them! 00091 Malloc, /**< malloc(<bytes to allocate>), legacy type */ 00092 Calloc, /**< calloc(<number of elements>, <bytes per element>), legacy type */ 00093 Realloc, /**< realloc(<pointer to previously memory>, <new size in bytes>), legacy type */ 00094 Free /**< free(<pointer>), legacy type */ 00095 }; 00096 00097 00098 //[-------------------------------------------------------] 00099 //[ Public static functions ] 00100 //[-------------------------------------------------------] 00101 public: 00102 /** 00103 * @brief 00104 * Copies memory 00105 * 00106 * @param[in] pDestination 00107 * Destination buffer (MUST be valid!) 00108 * @param[in] pSource 00109 * Source buffer (MUST be valid!) 00110 * @param[in] nNumOfBytes 00111 * Number of bytes to copy 00112 * 00113 * @note 00114 * - 'memcpy'-wrapper 00115 * - The memory areas should not overlap 00116 */ 00117 static inline void Copy(void *pDestination, const void *pSource, uint32 nNumOfBytes); 00118 00119 /** 00120 * @brief 00121 * Moves memory 00122 * 00123 * @param[in] pDestination 00124 * Destination buffer (MUST be valid!) 00125 * @param[in] pSource 00126 * Source buffer (MUST be valid!) 00127 * @param[in] nNumOfBytes 00128 * Number of bytes to copy 00129 * 00130 * @note 00131 * - 'memmove'-wrapper 00132 * - The memory areas may overlap 00133 */ 00134 static inline void Move(void *pDestination, const void *pSource, uint32 nNumOfBytes); 00135 00136 /** 00137 * @brief 00138 * Sets memory to a specified character 00139 * 00140 * @param[in] pDestination 00141 * Destination buffer (MUST be valid!) 00142 * @param[in] nCharacter 00143 * Character to set 00144 * @param[in] nNumOfBytes 00145 * Number of bytes to set 00146 * 00147 * @note 00148 * - 'memset'-wrapper 00149 */ 00150 static inline void Set(void *pDestination, int nCharacter, uint32 nNumOfBytes); 00151 00152 /** 00153 * @brief 00154 * Compares memory 00155 * 00156 * @param[in] pFirstBuffer 00157 * First buffer (MUST be valid!) 00158 * @param[in] pSecondBuffer 00159 * Second buffer (MUST be valid!) 00160 * @param[in] nNumOfBytes 00161 * Number of bytes to compare 00162 * 00163 * @return 00164 * < 0 = First buffer is less than second buffer 00165 * 0 = First buffer identical to second buffer 00166 * > 0 = First buffer is greater than second buffer 00167 * 00168 * @note 00169 * - 'memcmp'-wrapper 00170 */ 00171 static inline int Compare(const void *pFirstBuffer, const void *pSecondBuffer, uint32 nNumOfBytes); 00172 00173 /** 00174 * @brief 00175 * Reallocates memory 00176 * 00177 * @param[in] pAddress 00178 * Previous memory, can be a null pointer (if not a null pointer, it MUST be valid!) 00179 * @param[in] nNumOfBytes 00180 * Number of bytes to allocate 00181 * @param[in] nType 00182 * Allocator type 00183 * @param[in] pszSourceFile 00184 * Source file, can be a null pointer 00185 * @param[in] nSourceLine 00186 * Source line 00187 * 00188 * @return 00189 * The new allocated memory, a null pointer on error 00190 */ 00191 static inline void *Reallocator(void *pAddress, size_t nNumOfBytes, EType nType = NewArray, const char *pszSourceFile = nullptr, int nSourceLine = -1); 00192 00193 /** 00194 * @brief 00195 * Allocates new memory 00196 * 00197 * @param[in] nType 00198 * Allocator type 00199 * @param[in] nNumOfBytes 00200 * Number of bytes to allocate 00201 * @param[in] pszSourceFile 00202 * Source file, can be a null pointer 00203 * @param[in] nSourceLine 00204 * Source line 00205 * 00206 * @return 00207 * The new allocated memory, a null pointer on error 00208 * 00209 * @note 00210 * - Normally there's no reason using this function directly, use the 'new' keyword instead 00211 */ 00212 static inline void *Allocator(EType nType, size_t nNumOfBytes, const char *pszSourceFile = nullptr, int nSourceLine = -1); 00213 00214 /** 00215 * @brief 00216 * Frees memory 00217 * 00218 * @param[in] nType 00219 * Allocator type 00220 * @param[in] pAddress 00221 * Memory to free (MUST be valid!) 00222 * @param[in] pszSourceFile 00223 * Source file, can be a null pointer 00224 * @param[in] nSourceLine 00225 * Source line 00226 * 00227 * @note 00228 * - Normally there's no reason using this function directly, use the 'delete' keyword instead 00229 */ 00230 static inline void Deallocator(EType nType, void *pAddress, const char *pszSourceFile = nullptr, int nSourceLine = -1); 00231 00232 00233 }; 00234 00235 00236 00237 //[-------------------------------------------------------] 00238 //[ Namespace ] 00239 //[-------------------------------------------------------] 00240 } // PLCore 00241 00242 00243 //[-------------------------------------------------------] 00244 //[ Implementation ] 00245 //[-------------------------------------------------------] 00246 #include "PLCore/Core/MemoryManager.inl" 00247 00248 00249 //[-------------------------------------------------------] 00250 //[ Variations of global 'new' and 'delete' operators ] 00251 //[-------------------------------------------------------] 00252 void *operator new(size_t nNumOfBytes); 00253 void *operator new[](size_t nNumOfBytes); 00254 void operator delete(void *pAddress); 00255 void operator delete[](void *pAddress); 00256 // This two special new-operators are also used by 'Microsoft's memory tracker', so there's no undesired interfering 00257 void *operator new(size_t nNumOfBytes, const char *pszSourceFile, int nSourceLine); 00258 void *operator new[](size_t nNumOfBytes, const char *pszSourceFile, int nSourceLine); 00259 void operator delete(void *pAddress, const char *pszSourceFile, int nSourceLine); 00260 void operator delete[](void *pAddress, const char *pszSourceFile, int nSourceLine); 00261 00262 00263 #endif // __PLCORE_MEMORYMANAGER_H__
|