Memory.h

Go to the documentation of this file.
00001 /*
00002  *    Copyright 2004-2006 Intel Corporation
00003  * 
00004  *    Licensed under the Apache License, Version 2.0 (the "License");
00005  *    you may not use this file except in compliance with the License.
00006  *    You may obtain a copy of the License at
00007  * 
00008  *        http://www.apache.org/licenses/LICENSE-2.0
00009  * 
00010  *    Unless required by applicable law or agreed to in writing, software
00011  *    distributed under the License is distributed on an "AS IS" BASIS,
00012  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00013  *    See the License for the specific language governing permissions and
00014  *    limitations under the License.
00015  */
00016 
00017 #ifndef _OASYS_MEMORY_H_
00018 #define _OASYS_MEMORY_H_
00019 
00020 #include "config.h"
00021 
00022 #ifdef OASYS_DEBUG_MEMORY_ENABLED
00023 
00024 #include <cstddef>
00025 #include <cstdlib>
00026 #include <cstring>
00027 
00028 #include <signal.h>
00029 #include <sys/mman.h>
00030 
00031 #include "../compat/inttypes.h"
00032 #include "../debug/DebugUtils.h"
00033 #include "../debug/Log.h"
00034 #include "../util/jenkins_hash.h"
00035 
00039 void* operator new(size_t size) throw (std::bad_alloc);
00040 
00045 void operator delete(void *ptr) throw ();
00046 
00047 namespace oasys {
00048 
00079 #ifdef __GNUC__
00080 // Align the memory block that are allocated to correct (and bus error free).
00081 #define _ALIGNED __attribute__((aligned))
00082 #else
00083 #error Must define aligned attribute for this compiler.
00084 #endif 
00085 
00086 #define _BYTE               char
00087 #define _DBG_MEM_FRAMES     3
00088 
00089 #ifndef _DBG_MEM_TABLE_EXP
00090 #define _DBG_MEM_TABLE_EXP  10
00091 #endif 
00092 
00093 #define _DBG_MEM_TABLE_SIZE 1<<_DBG_MEM_TABLE_EXP
00094 #define _DBG_MEM_MMAP_HIGH  
00095 
00099 #define PARENT_PTR(_ptr, _type, _field)                 \
00100     ( (_type*) ((_BYTE*)_ptr - offsetof(_type, _field)) )
00101 
00105 struct dbg_mem_entry_t {
00106     void* frames_[_DBG_MEM_FRAMES]; 
00107     int       live_;       
00108     int       last_live_;  
00109     u_int32_t size_;       
00110 };
00111 
00116 struct dbg_mem_t {
00117     unsigned long    magic_;
00118     dbg_mem_entry_t* entry_; 
00119     u_int32_t        size_;
00120     
00121     _BYTE            block_ _ALIGNED; 
00122 };
00123 
00128 class DbgMemInfo {
00129 public:
00130     enum {
00131         NO_FLAGS   = 0,
00132         USE_SIGNAL = 1,   // set up a signal handler for dumping memory information
00133     };
00134 
00135     
00141     static void init(int flags = NO_FLAGS, char* dump_file = 0);
00142 
00143 // Find a matching set of frames
00144 #define MATCH(_f1, _f2)                                                 \
00145     (memcmp((_f1), (_f2), sizeof(void*) * _DBG_MEM_FRAMES) == 0)
00146 
00147 // Mod by a power of 2
00148 #define MOD(_x, _m)                                             \
00149     ((_x) & ((unsigned int)(~0))>>((sizeof(int)*8) - (_m)))
00150 
00154     static inline dbg_mem_entry_t* find(void** frames) {
00155         int key = MOD(jenkins_hash((u_int8_t*)frames, 
00156                                    sizeof(void*) * _DBG_MEM_FRAMES, 0), 
00157                       _DBG_MEM_TABLE_EXP);
00158         dbg_mem_entry_t* entry = &table_[key];
00159     
00160         // XXX/bowei - may want to do quadratic hashing later if things
00161         // get too clustered.
00162         while(entry->frames_[0] != 0 &&
00163               !MATCH(frames, entry->frames_))
00164         {
00165             ++key;
00166             entry = &table_[key];
00167         }
00168 
00169         return entry;
00170     }
00171 
00175     static inline dbg_mem_entry_t* inc(
00176         void**    frames,
00177         u_int32_t size
00178         )
00179     {
00180         dbg_mem_entry_t* entry = find(frames);
00181 
00182         if(entry->frames_[0] == 0) {
00183             memcpy(entry->frames_, frames, sizeof(void*) * _DBG_MEM_FRAMES);
00184             entry->live_      = 1;
00185             entry->last_live_ = 0;
00186         } else {
00187             ++(entry->live_);
00188         }
00189 
00190         entry->size_ += size;
00191         ++entries_;
00192 
00193         return entry;
00194     }
00195 
00199     static inline dbg_mem_entry_t* dec(dbg_mem_t* mem) {
00200         void**    frames = mem->entry_->frames_;
00201         u_int32_t size   = mem->size_;
00202 
00203         dbg_mem_entry_t* entry = find(frames);
00204         
00205         if(entry->frames_[0] == 0) {
00206             PANIC("Decrementing memory entry with no frame info");
00207         } else {
00208             entry->live_ -= 1;
00209             entry->size_ -= size;
00210 
00211             if(entry->live_ < 0) {
00212                 PANIC("Memory object live count < 0");
00213             }
00214         }
00215 
00216         return entry;
00217     }
00218 
00222     static dbg_mem_entry_t** get_table() { return &table_; }
00223 
00229     static void debug_dump(bool only_diffs = false);
00230 
00236     static void dump_to_file(int fd);
00237 
00241     static bool initialized() { return init_; }
00242 
00246     static void signal_handler(int signal, siginfo_t* info, void* context);
00247 
00248 private:
00252     static int              entries_;
00253     static dbg_mem_entry_t* table_;
00254     static bool             init_;
00255     static int              dump_file_;
00256     static struct sigaction signal_;
00257 };
00258 
00259 // clean up namespace
00260 #undef _ALIGNED
00261 #undef _BYTE
00262 
00263 #undef MATCH
00264 #undef MOD
00265 
00266 } // namespace oasys
00267 
00268 #endif // OASYS_DEBUG_MEMORY_ENABLED
00269 
00270 #endif //_OASYS_MEMORY_H_

Generated on Thu Jun 7 16:56:50 2007 for DTN Reference Implementation by  doxygen 1.5.1