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-2005 The OGRE Team 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 */ 00025 //---- ORIGINAL COPYRIGHT FOLLOWS ------------------------------------------- 00026 // --------------------------------------------------------------------------------------------------------------------------------- 00027 // Copyright 2000, Paul Nettle. All rights reserved. 00028 // 00029 // You are free to use this source code in any commercial or non-commercial product. 00030 // 00031 // mmgr.cpp - Memory manager & tracking software 00032 // 00033 // The most recent version of this software can be found at: ftp://ftp.GraphicsPapers.com/pub/ProgrammingTools/MemoryManagers/ 00034 // 00035 // [NOTE: Best when viewed with 8-character tabs] 00036 // 00037 // --------------------------------------------------------------------------------------------------------------------------------- 00038 #ifndef __MemoryManager_H__ 00039 #define __MemoryManager_H__ 00040 00041 #include "OgrePlatform.h" 00042 #include "OgreStdHeaders.h" 00043 00044 namespace Ogre { 00045 00087 #if OGRE_DEBUG_MEMORY_MANAGER && OGRE_DEBUG_MODE 00088 00089 #ifndef __FUNCTION__ 00090 #define __FUNCTION__ "???" 00091 #endif 00092 00093 } 00094 00095 //----------------------------------------------------------------------------- 00096 // We have to declare the global new([])/delete([]) operators before declaring 00097 // the Ogre::MemoryManager class since it lists them as friend functions 00098 void *operator new(size_t reportedSize); 00099 void *operator new[](size_t reportedSize); 00100 void operator delete(void *reportedAddress); 00101 void operator delete[](void *reportedAddress); 00102 //----------------------------------------------------------------------------- 00103 00104 namespace Ogre { 00105 00115 typedef struct tag_au 00116 { 00117 size_t actualSize; 00118 size_t reportedSize; 00119 00120 void *actualAddress; 00121 void *reportedAddress; 00122 00123 char sourceFile[40]; 00124 char sourceFunc[40]; 00125 00126 unsigned int sourceLine; 00127 unsigned int allocationType; 00128 00129 bool breakOnDealloc; 00130 bool breakOnRealloc; 00131 00132 unsigned int allocationNumber; 00133 unsigned int processID; 00134 00135 struct tag_au *next; 00136 struct tag_au *prev; 00137 } sAllocUnit; 00138 00139 typedef struct 00140 { 00141 size_t totalReportedMemory; 00142 size_t totalActualMemory; 00143 00144 size_t peakReportedMemory; 00145 size_t peakActualMemory; 00146 00147 size_t accumulatedReportedMemory; 00148 size_t accumulatedActualMemory; 00149 size_t accumulatedAllocUnitCount; 00150 00151 size_t totalAllocUnitCount; 00152 size_t peakAllocUnitCount; 00153 } sMStats; 00154 00155 enum 00156 { 00157 m_alloc_unknown = 0, 00158 m_alloc_new = 1, 00159 m_alloc_new_array = 2, 00160 m_alloc_malloc = 3, 00161 m_alloc_calloc = 4, 00162 m_alloc_realloc = 5, 00163 m_alloc_delete = 6, 00164 m_alloc_delete_array = 7, 00165 m_alloc_free = 8 00166 }; 00167 00170 class _OgreExport MemoryManager 00171 { 00172 friend void * ::operator new(size_t); 00173 friend void * ::operator new[](size_t); 00174 friend void ::operator delete(void*); 00175 friend void ::operator delete[](void*); 00176 00177 public: 00178 static MemoryManager& instance(void); 00179 00180 private: 00182 unsigned m_uProcessIDs; 00184 bool m_bDeinitTime; 00185 00186 #ifndef __BORLANDC__ 00187 private: 00188 #else 00189 public: 00190 #endif 00191 //------------------------------------------------------------------------- 00192 // Wrappers for the new/delete functions 00193 void *op_new_sc( size_t reportedSize, unsigned processID ); 00194 void *op_new_vc( size_t reportedSize, unsigned processID ); 00195 00196 void *op_new_sc( size_t reportedSize, const char *sourceFile, int sourceLine, unsigned processID ); 00197 void *op_new_vc( size_t reportedSize, const char *sourceFile, int sourceLine, unsigned processID ); 00198 00199 void op_del_sc( void *reportedAddress, unsigned processID ); 00200 void op_del_vc( void *reportedAddress, unsigned processID ); 00201 //------------------------------------------------------------------------- 00202 00217 unsigned _getProcessID(); 00218 00219 public: 00220 MemoryManager(); 00221 ~MemoryManager(); 00222 00223 //------------------------------------------------------------------------- 00224 // Used by the macros 00225 void setOwner(const char *file, const unsigned int line, const char *func); 00226 //------------------------------------------------------------------------- 00227 00228 //------------------------------------------------------------------------- 00229 // Allocation breakpoints 00230 bool &breakOnRealloc(void *reportedAddress); 00231 bool &breakOnDealloc( void *reportedAddress ); 00232 void breakOnAlloc( unsigned int count ); 00233 //------------------------------------------------------------------------- 00234 00235 //------------------------------------------------------------------------- 00236 // The meat & potatoes of the memory tracking software 00237 00250 void * allocMem( 00251 const char *sourceFile, 00252 const unsigned int sourceLine, 00253 const char *sourceFunc, 00254 const unsigned int allocationType, 00255 const size_t reportedSize, 00256 const unsigned processID ); 00257 00273 void * rllocMem( 00274 const char *sourceFile, 00275 const unsigned int sourceLine, 00276 const char *sourceFunc, 00277 const unsigned int reallocationType, 00278 const size_t reportedSize, 00279 void *reportedAddress, 00280 const unsigned processID ); 00281 00304 void dllocMem( 00305 const char *sourceFile, 00306 const unsigned int sourceLine, 00307 const char *sourceFunc, 00308 const unsigned int deallocationType, 00309 const void *reportedAddress, 00310 const unsigned processID ); 00311 //------------------------------------------------------------------------- 00312 00313 //------------------------------------------------------------------------- 00314 // Utilitarian functions 00315 bool validateAddr(const void *reportedAddress); 00316 bool validateAlloc(const sAllocUnit *allocUnit); 00317 bool validateAllAllocs(); 00318 //------------------------------------------------------------------------- 00319 00320 //------------------------------------------------------------------------- 00321 // Unused RAM calculations 00322 unsigned int calcUnused( const sAllocUnit *allocUnit ); 00323 unsigned int calcAllUnused(); 00324 //------------------------------------------------------------------------- 00325 00326 //------------------------------------------------------------------------- 00327 // Logging and reporting 00328 void dumpAllocUnit( const sAllocUnit *allocUnit, const char *prefix = "" ); 00329 void dumpMemReport( const char *filename = "memreport.log", const bool overwrite = true ); 00330 sMStats getMemStats(); 00331 //------------------------------------------------------------------------- 00332 }; 00333 } 00334 00341 static unsigned gProcessID = 0; 00342 00343 //----------------------------------------------------------------------------- 00344 // Overridden global new([])/delete([]) functions 00345 // 00346 inline void *operator new(size_t reportedSize) 00347 { 00348 if( !gProcessID ) 00349 gProcessID = Ogre::MemoryManager::instance()._getProcessID(); 00350 return Ogre::MemoryManager::instance().op_new_sc( reportedSize, gProcessID ); 00351 } 00352 inline void *operator new[](size_t reportedSize) 00353 { 00354 if( !gProcessID ) 00355 gProcessID = Ogre::MemoryManager::instance()._getProcessID(); 00356 return Ogre::MemoryManager::instance().op_new_vc( reportedSize, gProcessID ); 00357 } 00358 00359 inline void operator delete(void *reportedAddress) 00360 { 00361 Ogre::MemoryManager::instance().op_del_sc( reportedAddress, gProcessID ); 00362 } 00363 inline void operator delete[](void *reportedAddress) 00364 { 00365 Ogre::MemoryManager::instance().op_del_vc( reportedAddress, gProcessID ); 00366 } 00367 //----------------------------------------------------------------------------- 00368 00369 //----------------------------------------------------------------------------- 00370 // This header adds the *alloc/free macros, wrapping the C functions 00371 #include "OgreMemoryMacros.h" 00372 //----------------------------------------------------------------------------- 00373 00374 #else 00375 00378 class _OgreExport MemoryManager 00379 { 00380 public: 00381 static MemoryManager& instance(void); 00382 00383 MemoryManager(); 00384 ~MemoryManager(); 00385 00388 void *allocMem( const char *szFile, size_t uLine, size_t count ) throw ( ); 00389 00392 void *rllocMem( const char *szFile, size_t uLine, void *ptr , size_t count ) throw ( ); 00393 00396 void *cllocMem( const char *szFile, size_t uLine, size_t num, size_t size ) throw ( ); 00397 00400 void dllocMem( const char *szFile, size_t uLine, void *ptr ) throw ( ); 00401 }; 00402 00403 } 00404 00405 #endif 00406 00407 #endif 00408
Copyright © 2000-2005 by The OGRE Team
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Mar 12 14:37:44 2006