Memory.h

Go to the documentation of this file.
00001 /*
00002  * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By
00003  * downloading, copying, installing or using the software you agree to
00004  * this license. If you do not agree to this license, do not download,
00005  * install, copy or use the software.
00006  * 
00007  * Intel Open Source License 
00008  * 
00009  * Copyright (c) 2004 Intel Corporation. All rights reserved. 
00010  * 
00011  * Redistribution and use in source and binary forms, with or without
00012  * modification, are permitted provided that the following conditions are
00013  * met:
00014  * 
00015  *   Redistributions of source code must retain the above copyright
00016  *   notice, this list of conditions and the following disclaimer.
00017  * 
00018  *   Redistributions in binary form must reproduce the above copyright
00019  *   notice, this list of conditions and the following disclaimer in the
00020  *   documentation and/or other materials provided with the distribution.
00021  * 
00022  *   Neither the name of the Intel Corporation nor the names of its
00023  *   contributors may be used to endorse or promote products derived from
00024  *   this software without specific prior written permission.
00025  *  
00026  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00027  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00028  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00029  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL OR
00030  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00031  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00032  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00033  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00034  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00035  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00036  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00037  */
00038 #ifndef _OASYS_MEMORY_H_
00039 #define _OASYS_MEMORY_H_
00040 
00041 #include "config.h"
00042 
00043 #ifdef OASYS_DEBUG_MEMORY_ENABLED
00044 
00045 #include <cstddef>
00046 #include <cstdlib>
00047 #include <cstring>
00048 
00049 #include <signal.h>
00050 #include <sys/mman.h>
00051 
00052 #include "../compat/inttypes.h"
00053 #include "../debug/DebugUtils.h"
00054 #include "../debug/Log.h"
00055 #include "../util/jenkins_hash.h"
00056 
00060 void* operator new(size_t size) throw (std::bad_alloc);
00061 
00066 void operator delete(void *ptr) throw ();
00067 
00068 namespace oasys {
00069 
00100 #ifdef __GNUC__
00101 // Align the memory block that are allocated to correct (and bus error free).
00102 #define _ALIGNED __attribute__((aligned))
00103 #else
00104 #error Must define aligned attribute for this compiler.
00105 #endif 
00106 
00107 #define _BYTE               char
00108 #define _DBG_MEM_FRAMES     3
00109 
00110 #ifndef _DBG_MEM_TABLE_EXP
00111 #define _DBG_MEM_TABLE_EXP  10
00112 #endif 
00113 
00114 #define _DBG_MEM_TABLE_SIZE 1<<_DBG_MEM_TABLE_EXP
00115 #define _DBG_MEM_MMAP_HIGH  
00116 
00120 #define PARENT_PTR(_ptr, _type, _field)                 \
00121     ( (_type*) ((_BYTE*)_ptr - offsetof(_type, _field)) )
00122 
00126 struct dbg_mem_entry_t {
00127     void* frames_[_DBG_MEM_FRAMES]; 
00128     int       live_;       
00129     int       last_live_;  
00130     u_int32_t size_;       
00131 };
00132 
00137 struct dbg_mem_t {
00138     unsigned long    magic_;
00139     dbg_mem_entry_t* entry_; 
00140     u_int32_t        size_;
00141     
00142     _BYTE            block_ _ALIGNED; 
00143 };
00144 
00149 class DbgMemInfo {
00150 public:
00151     enum {
00152         NO_FLAGS   = 0,
00153         USE_SIGNAL = 1,   // set up a signal handler for dumping memory information
00154     };
00155 
00156     
00162     static void init(int flags = NO_FLAGS, char* dump_file = 0);
00163 
00164 // Find a matching set of frames
00165 #define MATCH(_f1, _f2)                                                 \
00166     (memcmp((_f1), (_f2), sizeof(void*) * _DBG_MEM_FRAMES) == 0)
00167 
00168 // Mod by a power of 2
00169 #define MOD(_x, _m)                                             \
00170     ((_x) & ((unsigned int)(~0))>>((sizeof(int)*8) - (_m)))
00171 
00175     static inline dbg_mem_entry_t* find(void** frames) {
00176         int key = MOD(jenkins_hash((u_int8_t*)frames, 
00177                                    sizeof(void*) * _DBG_MEM_FRAMES, 0), 
00178                       _DBG_MEM_TABLE_EXP);
00179         dbg_mem_entry_t* entry = &table_[key];
00180     
00181         // XXX/bowei - may want to do quadratic hashing later if things
00182         // get too clustered.
00183         while(entry->frames_[0] != 0 &&
00184               !MATCH(frames, entry->frames_))
00185         {
00186             ++key;
00187             entry = &table_[key];
00188         }
00189 
00190         return entry;
00191     }
00192 
00196     static inline dbg_mem_entry_t* inc(
00197         void**    frames,
00198         u_int32_t size
00199         )
00200     {
00201         dbg_mem_entry_t* entry = find(frames);
00202 
00203         if(entry->frames_[0] == 0) {
00204             memcpy(entry->frames_, frames, sizeof(void*) * _DBG_MEM_FRAMES);
00205             entry->live_      = 1;
00206             entry->last_live_ = 0;
00207         } else {
00208             ++(entry->live_);
00209         }
00210 
00211         entry->size_ += size;
00212         ++entries_;
00213 
00214         return entry;
00215     }
00216 
00220     static inline dbg_mem_entry_t* dec(dbg_mem_t* mem) {
00221         void**    frames = mem->entry_->frames_;
00222         u_int32_t size   = mem->size_;
00223 
00224         dbg_mem_entry_t* entry = find(frames);
00225         
00226         if(entry->frames_[0] == 0) {
00227             PANIC("Decrementing memory entry with no frame info");
00228         } else {
00229             entry->live_ -= 1;
00230             entry->size_ -= size;
00231 
00232             if(entry->live_ < 0) {
00233                 PANIC("Memory object live count < 0");
00234             }
00235         }
00236 
00237         return entry;
00238     }
00239 
00243     static dbg_mem_entry_t** get_table() { return &table_; }
00244 
00250     static void debug_dump(bool only_diffs = false);
00251 
00257     static void dump_to_file(int fd);
00258 
00262     static bool initialized() { return init_; }
00263 
00267     static void signal_handler(int signal, siginfo_t* info, void* context);
00268 
00269 private:
00273     static int              entries_;
00274     static dbg_mem_entry_t* table_;
00275     static bool             init_;
00276     static int              dump_file_;
00277     static struct sigaction signal_;
00278 };
00279 
00280 // clean up namespace
00281 #undef _ALIGNED
00282 #undef _BYTE
00283 
00284 #undef MATCH
00285 #undef MOD
00286 
00287 } // namespace oasys
00288 
00289 #endif // OASYS_DEBUG_MEMORY_ENABLED
00290 
00291 #endif //_OASYS_MEMORY_H_

Generated on Fri Dec 22 14:47:59 2006 for DTN Reference Implementation by  doxygen 1.5.1