00001 /* 00002 ----------------------------------------------------------------------------- 00003 This source file is part of OGRE 00004 (Object-oriented Graphics Rendering Engine) 00005 For the latest info, see http://www.ogre3d.org/ 00006 00007 Copyright (c) 2000-2006 Torus Knot Software Ltd 00008 Also see acknowledgements in Readme.html 00009 00010 This program is free software; you can redistribute it and/or modify it under 00011 the terms of the GNU Lesser General Public License as published by the Free Software 00012 Foundation; either version 2 of the License, or (at your option) any later 00013 version. 00014 00015 This program is distributed in the hope that it will be useful, but WITHOUT 00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License along with 00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple 00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to 00022 http://www.gnu.org/copyleft/lesser.txt. 00023 00024 You may alternatively use this source under the terms of a specific version of 00025 the OGRE Unrestricted License provided you have obtained such a license from 00026 Torus Knot Software Ltd. 00027 ----------------------------------------------------------------------------- 00028 */ 00029 //---- ORIGINAL COPYRIGHT FOLLOWS ------------------------------------------- 00030 // --------------------------------------------------------------------------------------------------------------------------------- 00031 // Copyright 2000, Paul Nettle. All rights reserved. 00032 // 00033 // You are free to use this source code in any commercial or non-commercial product. 00034 // 00035 // mmgr.cpp - Memory manager & tracking software 00036 // 00037 // The most recent version of this software can be found at: ftp://ftp.GraphicsPapers.com/pub/ProgrammingTools/MemoryManagers/ 00038 // 00039 // [NOTE: Best when viewed with 8-character tabs] 00040 // 00041 // --------------------------------------------------------------------------------------------------------------------------------- 00042 #ifndef __MemoryManager_H__ 00043 #define __MemoryManager_H__ 00044 00045 #include "OgrePlatform.h" 00046 #include "OgreStdHeaders.h" 00047 00048 namespace Ogre { 00049 00091 #if OGRE_DEBUG_MEMORY_MANAGER && OGRE_DEBUG_MODE 00092 00093 #ifndef __FUNCTION__ 00094 #define __FUNCTION__ "???" 00095 #endif 00096 00097 } 00098 00099 //----------------------------------------------------------------------------- 00100 // We have to declare the global new([])/delete([]) operators before declaring 00101 // the Ogre::MemoryManager class since it lists them as friend functions 00102 void *operator new(size_t reportedSize); 00103 void *operator new[](size_t reportedSize); 00104 void operator delete(void *reportedAddress); 00105 void operator delete[](void *reportedAddress); 00106 //----------------------------------------------------------------------------- 00107 00108 namespace Ogre { 00109 00119 typedef struct tag_au 00120 { 00121 size_t actualSize; 00122 size_t reportedSize; 00123 00124 void *actualAddress; 00125 void *reportedAddress; 00126 00127 char sourceFile[40]; 00128 char sourceFunc[40]; 00129 00130 unsigned int sourceLine; 00131 unsigned int allocationType; 00132 00133 bool breakOnDealloc; 00134 bool breakOnRealloc; 00135 00136 unsigned int allocationNumber; 00137 unsigned int processID; 00138 00139 struct tag_au *next; 00140 struct tag_au *prev; 00141 } sAllocUnit; 00142 00143 typedef struct 00144 { 00145 size_t totalReportedMemory; 00146 size_t totalActualMemory; 00147 00148 size_t peakReportedMemory; 00149 size_t peakActualMemory; 00150 00151 size_t accumulatedReportedMemory; 00152 size_t accumulatedActualMemory; 00153 size_t accumulatedAllocUnitCount; 00154 00155 size_t totalAllocUnitCount; 00156 size_t peakAllocUnitCount; 00157 } sMStats; 00158 00159 enum 00160 { 00161 m_alloc_unknown = 0, 00162 m_alloc_new = 1, 00163 m_alloc_new_array = 2, 00164 m_alloc_malloc = 3, 00165 m_alloc_calloc = 4, 00166 m_alloc_realloc = 5, 00167 m_alloc_delete = 6, 00168 m_alloc_delete_array = 7, 00169 m_alloc_free = 8 00170 }; 00171 00174 class _OgreExport MemoryManager 00175 { 00176 friend void * ::operator new(size_t); 00177 friend void * ::operator new[](size_t); 00178 friend void ::operator delete(void*); 00179 friend void ::operator delete[](void*); 00180 00181 public: 00182 static MemoryManager& instance(void); 00183 00184 private: 00186 unsigned m_uProcessIDs; 00188 bool m_bDeinitTime; 00189 00190 #ifndef __BORLANDC__ 00191 private: 00192 #else 00193 public: 00194 #endif 00195 //------------------------------------------------------------------------- 00196 // Wrappers for the new/delete functions 00197 void *op_new_sc( size_t reportedSize, unsigned processID ); 00198 void *op_new_vc( size_t reportedSize, unsigned processID ); 00199 00200 void *op_new_sc( size_t reportedSize, const char *sourceFile, int sourceLine, unsigned processID ); 00201 void *op_new_vc( size_t reportedSize, const char *sourceFile, int sourceLine, unsigned processID ); 00202 00203 void op_del_sc( void *reportedAddress, unsigned processID ); 00204 void op_del_vc( void *reportedAddress, unsigned processID ); 00205 //------------------------------------------------------------------------- 00206 00221 unsigned _getProcessID(); 00222 00223 public: 00224 MemoryManager(); 00225 ~MemoryManager(); 00226 00227 //------------------------------------------------------------------------- 00228 // Used by the macros 00229 void setOwner(const char *file, const unsigned int line, const char *func); 00230 //------------------------------------------------------------------------- 00231 00232 //------------------------------------------------------------------------- 00233 // Allocation breakpoints 00234 bool &breakOnRealloc(void *reportedAddress); 00235 bool &breakOnDealloc( void *reportedAddress ); 00236 void breakOnAlloc( unsigned int count ); 00237 //------------------------------------------------------------------------- 00238 00239 //------------------------------------------------------------------------- 00240 // The meat & potatoes of the memory tracking software 00241 00254 void * allocMem( 00255 const char *sourceFile, 00256 const unsigned int sourceLine, 00257 const char *sourceFunc, 00258 const unsigned int allocationType, 00259 const size_t reportedSize, 00260 const unsigned processID ); 00261 00277 void * rllocMem( 00278 const char *sourceFile, 00279 const unsigned int sourceLine, 00280 const char *sourceFunc, 00281 const unsigned int reallocationType, 00282 const size_t reportedSize, 00283 void *reportedAddress, 00284 const unsigned processID ); 00285 00308 void dllocMem( 00309 const char *sourceFile, 00310 const unsigned int sourceLine, 00311 const char *sourceFunc, 00312 const unsigned int deallocationType, 00313 const void *reportedAddress, 00314 const unsigned processID ); 00315 //------------------------------------------------------------------------- 00316 00317 //------------------------------------------------------------------------- 00318 // Utilitarian functions 00319 bool validateAddr(const void *reportedAddress); 00320 bool validateAlloc(const sAllocUnit *allocUnit); 00321 bool validateAllAllocs(); 00322 //------------------------------------------------------------------------- 00323 00324 //------------------------------------------------------------------------- 00325 // Unused RAM calculations 00326 unsigned int calcUnused( const sAllocUnit *allocUnit ); 00327 unsigned int calcAllUnused(); 00328 //------------------------------------------------------------------------- 00329 00330 //------------------------------------------------------------------------- 00331 // Logging and reporting 00332 void dumpAllocUnit( const sAllocUnit *allocUnit, const char *prefix = "" ); 00333 void dumpMemReport( const char *filename = "memreport.log", const bool overwrite = true ); 00334 sMStats getMemStats(); 00335 //------------------------------------------------------------------------- 00336 }; 00337 } 00338 00345 static unsigned gProcessID = 0; 00346 00347 // When compiling in Visual C++ (occuring in VS2005 Express but not for VC 7.1) with 00348 // managed C++, should put the new([])/delete([]) overrides inside unmanaged context, 00349 // otherwise Visual C++ will link with overridden version of new([]) and CRT version 00350 // of delete([]), thus, mess up both of OGRE memory manager and CRT memory manager. 00351 #if defined(__cplusplus_cli) 00352 #pragma managed(push, off) 00353 #endif 00354 //----------------------------------------------------------------------------- 00355 // Overridden global new([])/delete([]) functions 00356 // 00357 inline void *operator new(size_t reportedSize) 00358 { 00359 if( !gProcessID ) 00360 gProcessID = Ogre::MemoryManager::instance()._getProcessID(); 00361 return Ogre::MemoryManager::instance().op_new_sc( reportedSize, gProcessID ); 00362 } 00363 inline void *operator new[](size_t reportedSize) 00364 { 00365 if( !gProcessID ) 00366 gProcessID = Ogre::MemoryManager::instance()._getProcessID(); 00367 return Ogre::MemoryManager::instance().op_new_vc( reportedSize, gProcessID ); 00368 } 00369 00370 inline void operator delete(void *reportedAddress) 00371 { 00372 Ogre::MemoryManager::instance().op_del_sc( reportedAddress, gProcessID ); 00373 } 00374 inline void operator delete[](void *reportedAddress) 00375 { 00376 Ogre::MemoryManager::instance().op_del_vc( reportedAddress, gProcessID ); 00377 } 00378 //----------------------------------------------------------------------------- 00379 #if defined(__cplusplus_cli) 00380 #pragma managed(pop) 00381 #endif 00382 00383 //----------------------------------------------------------------------------- 00384 // This header adds the *alloc/free macros, wrapping the C functions 00385 #include "OgreMemoryMacros.h" 00386 //----------------------------------------------------------------------------- 00387 00388 #else 00389 00392 class _OgreExport MemoryManager 00393 { 00394 public: 00395 static MemoryManager& instance(void); 00396 00397 MemoryManager(); 00398 ~MemoryManager(); 00399 00402 void *allocMem( const char *szFile, size_t uLine, size_t count ) throw ( ); 00403 00406 void *rllocMem( const char *szFile, size_t uLine, void *ptr , size_t count ) throw ( ); 00407 00410 void *cllocMem( const char *szFile, size_t uLine, size_t num, size_t size ) throw ( ); 00411 00414 void dllocMem( const char *szFile, size_t uLine, void *ptr ) throw ( ); 00415 }; 00416 00417 } 00418 00419 #endif 00420 00421 #endif 00422
Copyright © 2000-2005 by The OGRE Team
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sat May 10 16:25:00 2008