# 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 sMemManager;
    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::sMemManager._getProcessID();
    00350     return Ogre::MemoryManager::sMemManager.op_new_sc( reportedSize, gProcessID );
    00351 }
    00352 inline void *operator new[](size_t reportedSize)
    00353 {
    00354     if( !gProcessID )
    00355         gProcessID = Ogre::MemoryManager::sMemManager._getProcessID();
    00356     return Ogre::MemoryManager::sMemManager.op_new_vc( reportedSize, gProcessID );
    00357 }
    00358
    00359 inline void operator delete(void *reportedAddress)
    00360 {
    00361     Ogre::MemoryManager::sMemManager.op_del_sc( reportedAddress, gProcessID );
    00362 }
    00363 inline void operator delete[](void *reportedAddress)
    00364 {
    00365     Ogre::MemoryManager::sMemManager.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 sMemManager;
    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
Last modified Sun Nov 20 12:36:02 2005