Eneboo - Documentación para desarrolladores
|
00001 /* -*- C++ -*- */ 00002 00003 #ifndef _LOGHEAP_H_ 00004 #define _LOGHEAP_H_ 00005 00011 #include <assert.h> 00012 #include <math.h> 00013 #include <limits.h> 00014 00015 // UNIX-specific for now... 00016 #include <unistd.h> 00017 00018 #include <fstream> 00019 #include <ios> 00020 00021 00022 using namespace std; 00023 00024 namespace HL { 00025 00026 template <class Obj> 00027 class Log { 00028 public: 00029 00030 enum { MAX_ENTRIES = 300000 }; 00031 00032 Log (void) : 00033 numEntries (0) 00034 { 00035 sprintf (filename, "theLog-%d", getpid()); 00036 } 00037 00038 ~Log (void) { 00039 // writeLog(); 00040 } 00041 00042 void writeLog (void) { 00043 { 00044 ofstream outfile (filename, ios_base::app); 00045 } 00046 write(filename); 00047 } 00048 00049 void dump (void) { 00050 write (filename); 00051 numEntries = 0; 00052 } 00053 00054 int append (const Obj& o) { 00055 if (numEntries < MAX_ENTRIES) { 00056 entries[numEntries] = o; 00057 numEntries++; 00058 return 1; 00059 } else { 00060 return 0; 00061 } 00062 } 00063 00064 void write (char * fname) { 00065 ofstream outfile (fname, ios_base::app); 00066 for (int i = 0; i < numEntries; i++) { 00067 outfile << entries[i] << endl; 00068 } 00069 } 00070 00071 private: 00072 00073 int numEntries; 00074 Obj entries[MAX_ENTRIES]; 00075 char filename[255]; 00076 }; 00077 00078 00079 template <class SuperHeap> 00080 class LogHeap : public SuperHeap { 00081 public: 00082 00083 LogHeap (void) 00084 : allDone (false) 00085 {} 00086 00087 inline void * malloc (size_t sz) { 00088 void * ptr = SuperHeap::malloc (sz); 00089 if (!allDone) { 00090 MemoryRequest m; 00091 m.malloc (ptr, sz); 00092 if (!log.append (m)) { 00093 allDone = true; 00094 log.dump(); 00095 log.append(m); 00096 allDone = false; 00097 } 00098 } 00099 return ptr; 00100 } 00101 00102 void write (void) { 00103 allDone = true; 00104 log.writeLog(); 00105 } 00106 00107 inline void free (void * ptr) { 00108 if (!allDone) { 00109 MemoryRequest m; 00110 m.free (ptr); 00111 log.append (m); 00112 } 00113 SuperHeap::free (ptr); 00114 } 00115 00116 private: 00117 00118 class MemoryRequest { 00119 public: 00120 00121 MemoryRequest (void) 00122 : 00123 #if 0 00124 _sec (LONG_MAX), 00125 _usec (LONG_MAX), 00126 #endif 00127 _size (0), 00128 _address (INVALID) 00129 {} 00130 00131 enum { FREE_OP = 0, 00132 MALLOC_OP, 00133 REALLOC_OP, 00134 REFREE_OP, 00135 ALLOCATE_OP, 00136 DEALLOCATE_OP, 00137 INVALID 00138 }; 00139 00140 friend std::ostream& operator<< (std::ostream& os, MemoryRequest& m) { 00141 switch (m.getType()) { 00142 case FREE_OP: 00143 os << "F\t" << (void *) m.getAddress(); 00144 break; 00145 case MALLOC_OP: 00146 os << "M\t" << m.getSize() << "\t" << (void *) m.getAddress(); 00147 break; 00148 default: 00149 abort(); 00150 } 00151 return os; 00152 } 00153 00154 void malloc (void * addr, 00155 size_t sz) 00156 { 00157 assert ((((unsigned long) addr) & 7) == 0); 00158 _size = sz; 00159 _address = (unsigned long) addr | MALLOC_OP; 00160 // markTime (_sec, _usec); 00161 // printf ("malloc %d (%f)\n", sz, getTime()); 00162 } 00163 00164 00165 void free (void * addr) 00166 { 00167 assert ((((unsigned long) addr) & 7) == 0); 00168 _address = (unsigned long) addr | FREE_OP; 00169 // markTime (_sec, _usec); 00170 // printf ("free %d (%f)\n", _address, getTime()); 00171 } 00172 00173 00174 void allocate (int sz) 00175 { 00176 _address = ALLOCATE_OP; 00177 _size = sz; 00178 markTime (_sec, _usec); 00179 // printf ("allocate %d (%f)\n", sz, getTime()); 00180 } 00181 00182 00183 void deallocate (int sz) 00184 { 00185 _address = DEALLOCATE_OP; 00186 _size = sz; 00187 markTime (_sec, _usec); 00188 // printf ("allocate %d (%f)\n", sz, getTime()); 00189 } 00190 00191 00192 // Set sec & usec to the current time. 00193 void markTime (long& sec, long& usec) 00194 { 00195 #if 0 00196 #ifdef __SVR4 // Solaris 00197 hrtime_t t; 00198 t = gethrtime(); 00199 sec = *((long *) &t); 00200 usec = *((long *) &t + 1); 00201 #else 00202 struct timeval tv; 00203 struct timezone tz; 00204 gettimeofday (&tv, &tz); 00205 sec = tv.tv_sec; 00206 usec = tv.tv_usec; 00207 #endif 00208 #endif 00209 } 00210 00211 int getType (void) { 00212 return _address & 7; 00213 } 00214 00215 int getAllocated (void) { 00216 return _size; 00217 } 00218 00219 int getDeallocated (void) { 00220 return _size; 00221 } 00222 00223 unsigned long getAddress (void) { 00224 return _address & ~7; 00225 } 00226 00227 int getSize (void) { 00228 return _size; 00229 } 00230 00231 #if 0 00232 double getTime (void) { 00233 return (double) _sec + (double) _usec / 1000000.0; 00234 } 00235 00236 long getSeconds (void) { 00237 return _sec; 00238 } 00239 00240 long getUseconds (void) { 00241 return _usec; 00242 } 00243 00244 friend int operator< (MemoryRequest& m, MemoryRequest& n) { 00245 return ((m._sec < n._sec) 00246 || ((m._sec == n._sec) 00247 && (m._usec < n._usec))); 00248 } 00249 00250 friend int operator== (MemoryRequest& m, MemoryRequest& n) { 00251 return ((m._sec == n._sec) && (m._usec == n._usec)); 00252 } 00253 #endif 00254 00255 private: 00256 int _size; // in bytes 00257 unsigned long _address; // The address returned by malloc/realloc 00258 #if 1 00259 long _sec; // seconds as returned by gettimeofday 00260 long _usec; // microseconds as returned by gettimeofday 00261 #endif 00262 }; 00263 00264 Log<MemoryRequest> log; 00265 00266 bool allDone; 00267 00268 00269 }; 00270 00271 } 00272 00273 #endif // _LOGHEAP_H_