Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

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-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
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Feb 12 12:59:47 2006