PixelLightAPI
.
|
00001 /*********************************************************\ 00002 * File: MemoryManager.h * 00003 * 00004 * Copyright (C) 2002-2011 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 */ 00116 static inline void Copy(void *pDestination, const void *pSource, uint32 nNumOfBytes); 00117 00118 /** 00119 * @brief 00120 * Sets memory to a specified character 00121 * 00122 * @param[in] pDestination 00123 * Destination buffer (MUST be valid!) 00124 * @param[in] nCharacter 00125 * Character to set 00126 * @param[in] nNumOfBytes 00127 * Number of bytes to set 00128 * 00129 * @note 00130 * - 'memset'-wrapper 00131 */ 00132 static inline void Set(void *pDestination, int nCharacter, uint32 nNumOfBytes); 00133 00134 /** 00135 * @brief 00136 * Compares memory 00137 * 00138 * @param[in] pFirstBuffer 00139 * First buffer (MUST be valid!) 00140 * @param[in] pSecondBuffer 00141 * Second buffer (MUST be valid!) 00142 * @param[in] nNumOfBytes 00143 * Number of bytes to compare 00144 * 00145 * @return 00146 * < 0 = First buffer is less than second buffer 00147 * 0 = First buffer identical to second buffer 00148 * > 0 = First buffer is greater than second buffer 00149 * 00150 * @note 00151 * - 'memcmp'-wrapper 00152 */ 00153 static inline int Compare(const void *pFirstBuffer, const void *pSecondBuffer, uint32 nNumOfBytes); 00154 00155 /** 00156 * @brief 00157 * Reallocates memory 00158 * 00159 * @param[in] pAddress 00160 * Previous memory, can be a null pointer (if not a null pointer, it MUST be valid!) 00161 * @param[in] nNumOfBytes 00162 * Number of bytes to allocate 00163 * @param[in] nType 00164 * Allocator type 00165 * @param[in] pszSourceFile 00166 * Source file, can be a null pointer 00167 * @param[in] nSourceLine 00168 * Source line 00169 * 00170 * @return 00171 * The new allocated memory, a null pointer on error 00172 */ 00173 static inline void *Reallocator(void *pAddress, size_t nNumOfBytes, EType nType = NewArray, const char *pszSourceFile = nullptr, int nSourceLine = -1); 00174 00175 /** 00176 * @brief 00177 * Allocates new memory 00178 * 00179 * @param[in] nType 00180 * Allocator type 00181 * @param[in] nNumOfBytes 00182 * Number of bytes to allocate 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 * @note 00192 * - Normally there's no reason using this function directly, use the 'new' keyword instead 00193 */ 00194 static inline void *Allocator(EType nType, size_t nNumOfBytes, const char *pszSourceFile = nullptr, int nSourceLine = -1); 00195 00196 /** 00197 * @brief 00198 * Frees memory 00199 * 00200 * @param[in] nType 00201 * Allocator type 00202 * @param[in] pAddress 00203 * Memory to free (MUST be valid!) 00204 * @param[in] pszSourceFile 00205 * Source file, can be a null pointer 00206 * @param[in] nSourceLine 00207 * Source line 00208 * 00209 * @note 00210 * - Normally there's no reason using this function directly, use the 'delete' keyword instead 00211 */ 00212 static inline void Deallocator(EType nType, void *pAddress, const char *pszSourceFile = nullptr, int nSourceLine = -1); 00213 00214 00215 }; 00216 00217 00218 00219 //[-------------------------------------------------------] 00220 //[ Namespace ] 00221 //[-------------------------------------------------------] 00222 } // PLCore 00223 00224 00225 //[-------------------------------------------------------] 00226 //[ Implementation ] 00227 //[-------------------------------------------------------] 00228 #include "PLCore/Core/MemoryManager.inl" 00229 00230 00231 //[-------------------------------------------------------] 00232 //[ Variations of global 'new' and 'delete' operators ] 00233 //[-------------------------------------------------------] 00234 void *operator new(size_t nNumOfBytes); 00235 void *operator new[](size_t nNumOfBytes); 00236 void operator delete(void *pAddress); 00237 void operator delete[](void *pAddress); 00238 // This two special new-operators are also used by 'Microsoft's memory tracker', so there's no undesired interfering 00239 void *operator new(size_t nNumOfBytes, const char *pszSourceFile, int nSourceLine); 00240 void *operator new[](size_t nNumOfBytes, const char *pszSourceFile, int nSourceLine); 00241 void operator delete(void *pAddress, const char *pszSourceFile, int nSourceLine); 00242 void operator delete[](void *pAddress, const char *pszSourceFile, int nSourceLine); 00243 00244 00245 #endif // __PLCORE_MEMORYMANAGER_H__
|