OgreMemoryManager.h

Go to the documentation of this file.
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
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sat May 10 16:25:00 2008