00001
00002
00003 #ifndef _LOGHEAP_H_
00004 #define _LOGHEAP_H_
00005
00011 #include <assert.h>
00012 #include <math.h>
00013 #include <limits.h>
00014
00015
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
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
00161
00162 }
00163
00164
00165 void free (void * addr)
00166 {
00167 assert ((((unsigned long) addr) & 7) == 0);
00168 _address = (unsigned long) addr | FREE_OP;
00169
00170
00171 }
00172
00173
00174 void allocate (int sz)
00175 {
00176 _address = ALLOCATE_OP;
00177 _size = sz;
00178 markTime (_sec, _usec);
00179
00180 }
00181
00182
00183 void deallocate (int sz)
00184 {
00185 _address = DEALLOCATE_OP;
00186 _size = sz;
00187 markTime (_sec, _usec);
00188
00189 }
00190
00191
00192
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;
00257 unsigned long _address;
00258 #if 1
00259 long _sec;
00260 long _usec;
00261 #endif
00262 };
00263
00264 Log<MemoryRequest> log;
00265
00266 bool allDone;
00267
00268
00269 };
00270
00271 }
00272
00273 #endif // _LOGHEAP_H_