# 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
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sat May 10 16:25:00 2008