Memory.cpp

Go to the documentation of this file.
00001 /*
00002 
00003 $Header$
00004 
00005 */
00006 
00007 #ifdef DEBUG_MODE
00008 
00009 #include <stdio.h>
00010 
00011 #include "Error.h"
00012 
00013 #include "Memory.h"
00014 
00015 #include <string.h>
00016 #include <sys/types.h>
00017 #include <unistd.h>
00018 #include <errno.h>
00019 #include <sys/sysinfo.h>
00020 
00021 Memory::MemoryChunkList Memory::_chunks;
00022 
00023 // Public methods.
00024 
00025 void *Memory::calloc(size_t nmemb, size_t size, const char *file, const char *function, const unsigned int line)
00026 {
00027   void *p = ::calloc(nmemb, size);
00028 
00029   if (p)
00030     addChunk(p, nmemb * size, file, function, line);
00031   else
00032     ERROR(MSG_MEMORY_CANNOT_ALLOCATE, nmemb * size, strerror(errno));
00033 
00034   return p;
00035 }
00036 
00037 void *Memory::alloc(size_t size, const char *file, const char *function, const unsigned int line)
00038 {
00039   void *p = ::malloc(size);
00040 
00041   if (p)
00042     addChunk(p, size, file, function, line);
00043   else
00044     ERROR(MSG_MEMORY_CANNOT_ALLOCATE, size, strerror(errno));
00045 
00046   return p;
00047 }
00048 
00049 void Memory::free(void *ptr)
00050 {
00051   removeChunk(ptr);
00052   ::free(ptr);
00053 }
00054 
00055 void *Memory::realloc(void *ptr, size_t size, const char *file, const char *function, const unsigned int line)
00056 {
00057   void *p;
00058 
00059   if (ptr == NULL)
00060     return alloc(size, file, function, line);
00061 
00062   removeChunk(ptr);
00063   if ((p = ::realloc(ptr, size)))
00064     addChunk(p, size, file, function, line);
00065   else
00066     ERROR(MSG_MEMORY_CANNOT_ALLOCATE, size, strerror(errno));
00067 
00068   return p;
00069 }
00070 
00071 long Memory::free()
00072 {
00073   struct sysinfo info;
00074   bzero(&info, sizeof(info));
00075   sysinfo(&info);
00076   return info.freeram;
00077 }
00078 
00079 int Memory::total(long &vsize, long &rss)
00080 {
00081   FILE *f;
00082   char stat[LIMIT_CSTRING_SIZE];
00083   int n = 0;
00084 
00085   snprintf(stat, sizeof(stat), "/proc/%d/stat", getpid());
00086 
00087   if (!(f = fopen(stat, "r")))
00088     return ERROR(MSG_MEMORY_PROC, strerror(errno));
00089 
00090   if (fgets(stat, sizeof(stat), f))
00091     n = sscanf(stat,
00092                "%*s %*s "             // PID, cmd
00093                "%*c %*d "             // state, ppid
00094                "%*s %*s %*s %*s "     // pgrp, session, tty, tpgid
00095                "%*s %*s %*s %*s %*s " // flags, min_flt, cmin_flt, maj_flt, cmaj_flt */
00096                "%*s %*s "             // utime, stime
00097                "%*s %*s %*s "         // cutime, cstime, priority
00098                "%*d "                 // nice
00099                "%*s %*s %*s "         // timeout, it_real_value, start_time
00100                "%ld "                 // vsize
00101                "%ld",                 // rss
00102                &vsize, &rss);
00103   fclose(f);
00104   if (n != 2) {
00105     vsize = -1;
00106     rss = -1;
00107     return ERROR(MSG_MEMORY_PROC, strerror(errno));
00108   }
00109 
00110   return OK;
00111 }
00112 
00113 #ifdef DEBUG_MODE
00114 
00115 int Memory::list(String &text)
00116 {
00117   char line[LIMIT_CSTRING_SIZE];
00118   MemoryChunkList::const_iterator i = _chunks.begin();
00119   MemoryChunkList::const_iterator e = _chunks.end();
00120   const MemoryChunk *chunk;
00121   size_t totalSize = 0;
00122   struct tm *time;
00123   long vsize, rss;
00124   unsigned int n = 1;
00125   int res;
00126 
00127   snprintf(line, sizeof(line), "%s%6s\t%15s\t%9s\t%32s\t%48s\t%6s%s", String::eol(), "#", "TIME", "SIZE", "FILE", "FUNCTION", "LINE", String::eol());
00128   text = MEMORY_COLOR_TITLE(line);
00129   while (i != e) {
00130     chunk = &(i->second);
00131     totalSize += chunk->size;
00132     time = localtime(&(chunk->time.tv_sec));
00133     snprintf(line, sizeof(line), "%6u\t%02u:%02u:%02u:%06u\t%9u\t%32s\t%48s\t%6u%s",
00134              n, time->tm_hour, time->tm_min, time->tm_sec, (unsigned int)chunk->time.tv_usec,
00135              chunk->size, CSTRING(chunk->file), CSTRING(chunk->function), chunk->line, String::eol());
00136     text += line;
00137     ++i;
00138     ++n;
00139   }
00140 
00141   snprintf(line, sizeof(line), "TOTAL  : allocated %u bytes in %u chunks.%s", totalSize, _chunks.size(), String::eol());
00142   text += MEMORY_COLOR_TITLE(line);
00143   if (FAILED(res = total(vsize, rss)))
00144     return ERROR_BACKTRACE(res);
00145   snprintf(line, sizeof(line), "PROCESS: total = %ld bytes, vsize = %ld bytes, rss = %ld bytes.%s", vsize + rss, vsize, rss, String::eol());
00146   text += MEMORY_COLOR_TITLE(line);
00147   snprintf(line, sizeof(line), "FREE   : %ld bytes.%s", free(), String::eol());
00148   text += MEMORY_COLOR_TITLE(line);
00149 
00150   return OK;
00151 }
00152 
00153 #endif
00154 
00155 // Private methods.
00156 
00157 void Memory::addChunk(void *ptr, const size_t size, const char *file, const char *function, const unsigned int line)
00158 {
00159   MemoryChunk chunk;
00160   struct timezone tz;
00161 
00162   chunk.ptr = ptr;
00163   chunk.size = size;
00164   chunk.file = file;
00165   chunk.function = function;
00166   chunk.line = line;
00167   gettimeofday(&(chunk.time), &tz);
00168 
00169   _chunks[ptr] = chunk;
00170 }
00171 
00172 void Memory::removeChunk(void *ptr)
00173 {
00174   MemoryChunkList::iterator f = _chunks.find(ptr);
00175 
00176   if (f != _chunks.end())
00177     _chunks.erase(f);
00178   else
00179     ERROR(MSG_UNKNOWN_MEMORY_CHUNK, (unsigned int)ptr);
00180 }
00181 
00182 #endif

Generated on Thu Sep 6 20:11:25 2007 for Pylon Application Platform by  doxygen 1.5.1