UTMemDebugTracker.h

Go to the documentation of this file.
00001 //==================================================================================================
00002 // Copyright (C) 2010  Brian Tietz    sdbtietz at yahoo dot com
00003 //
00004 // This program is free software; you can redistribute it and/or modify it under the terms of the
00005 // GNU General Public License as published by the Free Software Foundation, version 2.0 of the
00006 // License.
00007 //
00008 // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
00009 // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00010 // General Public License for more details.
00011 //
00012 // You should have received a copy of the GNU General Public License along with this program; if
00013 // not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
00014 // 02110-1301, USA.
00015 //
00016 // For commercial software, the copyright holder (Brian Tietz, email sdbtietz at yahoo dot com)
00017 // reserves the right and is willing to waive the proprietary source code disclosure aspects of that
00018 // license as applied to the UT library in exchange for either substantial contributions to the
00019 // development of the UT library or other forms of compensation.  Any such waiver must be
00020 // established in writing between the copyright holder and the commercial entity obtaining such a
00021 // waiver.
00022 //==================================================================================================
00023 
00024 
00025 #ifndef _UT_MEMDEBUG_TRACKER_H_
00026 #define _UT_MEMDEBUG_TRACKER_H_
00027 
00028 #if UT_MEMDEBUG
00029 
00030 
00031 //==================================================================================================
00032 //=== Project headers
00033 //==================================================================================================
00034 #include "UTLists.h"
00035 #include "UTMutex.h"
00036 
00037 
00038 //==================================================================================================
00039 //=== Forward name declarations
00040 //==================================================================================================
00041 class MemDebugPool_t;
00042 
00043 
00044 //==================================================================================================
00045 //=== Types and constants
00046 //==================================================================================================
00047 const int c_memdebug_num_stack_frames = 12;
00048 const int c_memdebug_guard_size = 63;       // This makes sizeof(Alloc_t) a multiple of 4 bytes
00049 const byte c_memdebug_guard_val = 0xca;
00050 const int c_memdebug_num_block_sizes = 20;
00051 struct MemDebugBlockSize_t
00052 {
00053     size_t  max_block_size;
00054     int     allocate_per_pool;
00055 };
00056 
00057 
00058 //==================================================================================================
00059 struct Alloc_t
00060 //==================================================================================================
00061 {
00062     Alloc_t*                    norecycle_newer;
00063     size_t                      alloc_size;
00064     size_t                      max_realloc_size;
00065     void*                       stack[c_memdebug_num_stack_frames];
00066     byte                        checksum;                           // norecycle_newer to stack
00067     byte                        head_guard[c_memdebug_guard_size];
00068 };
00069 
00070 
00071 //==================================================================================================
00072 class MemDebugTracker_t
00073 //==================================================================================================
00074 {
00075     //----------------------------------------------------------------------------------------------
00076     public:
00077     //----------------------------------------------------------------------------------------------
00078                                                     MemDebugTracker_t();
00079                                                     ~MemDebugTracker_t();
00080 
00081     void*                                           Malloc(size_t size);
00082     void                                            Free(void* ptr);
00083     void*                                           Realloc( void* ptr, size_t size );
00084 
00085     void                                            ReportError(    const char* message,
00086                                                                     Alloc_t* alloc );
00087 
00088     //----------------------------------------------------------------------------------------------
00089     private:
00090     //----------------------------------------------------------------------------------------------
00091     void                                            SetNoRecycleLimit();
00092     void*                                           LargeMalloc(size_t size);
00093     MemDebugPool_t*                                 CreatePool(size_t block_size);
00094     void                                            DeleteOldestPoolIfStale();
00095     void                                            CheckNorecycleMemoryUsage();
00096     void                                            SetCaller(Alloc_t* alloc);
00097 
00098     //----------------------------------------------------------------------------------------------
00099     private:
00100     //----------------------------------------------------------------------------------------------
00101     MemDebugBlockSize_t                             m_pool_size_info[c_memdebug_num_block_sizes];
00102 
00103     Mutex_t                                         m_mutex;
00104     bool                                            m_already_in_memdebug_tracker;
00105     bool                                            m_error;
00106 
00107     OwnedBTree_t< MemDebugPool_t, MemDebugPool_t* > m_all_pools_by_addr;
00108     BTree_t< MemDebugPool_t, size_t >               m_avail_pools_by_size;
00109     LinkedList_t<MemDebugPool_t>                    m_delete_pools_by_age;
00110     BTree_t< MemDebugPool_t, size_t >               m_delete_pools_by_size;
00111 
00112     Alloc_t*                                        m_norecycle_oldest;
00113     Alloc_t*                                        m_norecycle_newest;
00114     size_t                                          m_norecycle_current_bytes;
00115     uint32                                          m_norecycle_max_kb;
00116     size_t                                          m_allocations_until_next_system_memcheck;
00117 };
00118 
00119 
00120 //==================================================================================================
00121 class MemDebugPool_t
00122 //==================================================================================================
00123 :   public BTreeNode_t< MemDebugPool_t, MemDebugPool_t* >,
00124     public BTreeNode_t< MemDebugPool_t, size_t >,
00125     public LinkedListNode_t<MemDebugPool_t>
00126 {
00127     //----------------------------------------------------------------------------------------------
00128     public:
00129     //----------------------------------------------------------------------------------------------
00130     void*                   operator new( size_t size, int capacity, size_t block_size );
00131                             MemDebugPool_t( int capacity, size_t block_size );
00132                             ~MemDebugPool_t();
00133     void                    operator delete(void* malloced_block);
00134 
00135     inline size_t           BlockSize() const;
00136     inline int              Capacity() const;
00137     inline bool             AllBlocksAllocated() const;
00138     inline bool             AllBlocksAvailable() const;
00139     bool                    Contains(byte* block) const;
00140     inline void             InitDeleteCounter(int count);
00141     inline bool             DecrementDeleteCounter();
00142 
00143     Alloc_t*                Allocate();
00144     void                    Release(Alloc_t* block);
00145 
00146     inline int              Compare(MemDebugPool_t* address) const;
00147     inline                  operator MemDebugPool_t*() const;
00148     inline int              Compare(size_t block_size) const;
00149     inline                  operator size_t() const;
00150 
00151     //----------------------------------------------------------------------------------------------
00152     private:
00153     //----------------------------------------------------------------------------------------------
00154     size_t                  m_block_size;
00155     int                     m_capacity;
00156     uint32                  m_avail_bitmap;
00157     uint32                  m_avail_bitmap_when_all_avail;
00158     int                     m_delete_counter;
00159 };
00160 
00161 
00162 
00163 
00164 //==================================================================================================
00165 //==================================================================================================
00166 //===
00167 //=== Inline function implementations
00168 //===
00169 //==================================================================================================
00170 //==================================================================================================
00171 inline size_t
00172 MemDebugPool_t::BlockSize() const
00173 {
00174     return m_block_size;
00175 }
00176 
00177 
00178 inline int
00179 MemDebugPool_t::Capacity() const
00180 {
00181     return m_capacity;
00182 }
00183 
00184 
00185 inline bool
00186 MemDebugPool_t::AllBlocksAllocated() const
00187 {
00188     return (m_avail_bitmap == 0);
00189 }
00190 
00191 
00192 inline bool
00193 MemDebugPool_t::AllBlocksAvailable() const
00194 {
00195     return (m_avail_bitmap == m_avail_bitmap_when_all_avail);
00196 }
00197 
00198 
00199 inline void
00200 MemDebugPool_t::InitDeleteCounter(int count)
00201 {
00202     m_delete_counter = count;
00203 }
00204 
00205 
00206 inline bool
00207 MemDebugPool_t::DecrementDeleteCounter()
00208 {
00209     assert(m_delete_counter > 0);
00210     m_delete_counter--;
00211     return (m_delete_counter == 0);
00212 }
00213 
00214 
00215 inline int
00216 MemDebugPool_t::Compare(MemDebugPool_t* address) const
00217 {
00218     // If this comes before other, Compare should return a negative number
00219     if(this < address)
00220         return -1;
00221     else if(this == address)
00222         return 0;
00223     return 1;
00224 }
00225 
00226 
00227 inline
00228 MemDebugPool_t::operator MemDebugPool_t*() const
00229 {
00230     return const_cast<MemDebugPool_t*>(this);
00231 }
00232 
00233 
00234 inline int
00235 MemDebugPool_t::Compare(size_t block_size) const
00236 {
00237     // If this comes before other, Compare should return a negative number
00238     if(m_block_size < block_size)
00239         return -1;
00240     else if(m_block_size == block_size)
00241         return 0;
00242     return 1;
00243 }
00244 
00245 
00246 inline
00247 MemDebugPool_t::operator size_t() const
00248 {
00249     return m_block_size;
00250 }
00251 
00252 
00253 #endif // UT_MEMDEBUG
00254 
00255 #endif // _UT_MEMDEBUG_TRACKER_H_

Generated on Tue Dec 14 22:35:05 2010 for UT library by  doxygen 1.6.1