CMS 3D CMS Logo

IgProfMem.cc

Go to the documentation of this file.
00001 #include "IgTools/IgProf/src/IgProf.h"
00002 #include "IgTools/IgProf/src/IgProfTrace.h"
00003 #include "IgTools/IgHook/interface/IgHook.h"
00004 #include "IgTools/IgHook/interface/IgHookTrace.h"
00005 #include <cstdlib>
00006 #include <cstring>
00007 #include <cstdio>
00008 #include <pthread.h>
00009 
00010 // -------------------------------------------------------------------
00011 // Traps for this profiler module
00012 IGPROF_DUAL_HOOK(1, void *, domalloc, _main, _libc,
00013                  (size_t n), (n),
00014                  "malloc", 0, "libc.so.6")
00015 IGPROF_DUAL_HOOK(2, void *, docalloc, _main, _libc,
00016                  (size_t n, size_t m), (n, m),
00017                  "calloc", 0, "libc.so.6")
00018 IGPROF_DUAL_HOOK(2, void *, dorealloc, _main, _libc,
00019                  (void *ptr, size_t n), (ptr, n),
00020                  "realloc", 0, "libc.so.6")
00021 IGPROF_DUAL_HOOK(3, int, dopmemalign, _main, _libc,
00022                  (void **ptr, size_t alignment, size_t size),
00023                  (ptr, alignment, size),
00024                  "posix_memalign", 0, "libc.so.6")
00025 IGPROF_DUAL_HOOK(2, void *, domemalign, _main, _libc,
00026                  (size_t alignment, size_t size), (alignment, size),
00027                  "memalign", 0, "libc.so.6")
00028 IGPROF_DUAL_HOOK(1, void *, dovalloc, _main, _libc,
00029                  (size_t size), (size),
00030                  "valloc", 0, "libc.so.6")
00031 IGPROF_DUAL_HOOK(1, void, dofree, _main, _libc,
00032                  (void *ptr), (ptr),
00033                  "free", 0, "libc.so.6")
00034 
00035 // Data for this profiler module
00036 static IgProfTrace::CounterDef  s_ct_total      = { "MEM_TOTAL",    IgProfTrace::TICK, -1 };
00037 static IgProfTrace::CounterDef  s_ct_largest    = { "MEM_MAX",      IgProfTrace::MAX, -1 };
00038 static IgProfTrace::CounterDef  s_ct_live       = { "MEM_LIVE",     IgProfTrace::TICK_PEAK, -1 };
00039 static bool                     s_count_total   = 0;
00040 static bool                     s_count_largest = 0;
00041 static bool                     s_count_live    = 0;
00042 static bool                     s_initialized   = false;
00043 static int                      s_moduleid      = -1;
00044 
00048 static void  __attribute__((noinline))
00049 add(void *ptr, size_t size)
00050 {
00051   IgProfTrace *buf = IgProf::buffer(s_moduleid);
00052   if (! buf)
00053     return;
00054 
00055   void                  *addresses [IgProfTrace::MAX_DEPTH];
00056   int                   depth = IgHookTrace::stacktrace(addresses, IgProfTrace::MAX_DEPTH);
00057   IgProfTrace::Record   entries [3];
00058   int                   nentries = 0;
00059 
00060   if (s_count_total)
00061   {
00062     entries[nentries].type = IgProfTrace::COUNT;
00063     entries[nentries].def = &s_ct_total;
00064     entries[nentries].amount = size;
00065     entries[nentries].ticks = 1;
00066     nentries++;
00067   }
00068 
00069   if (s_count_largest)
00070   {
00071     entries[nentries].type = IgProfTrace::COUNT;
00072     entries[nentries].def = &s_ct_largest;
00073     entries[nentries].amount = size;
00074     entries[nentries].ticks = 1;
00075     nentries++;
00076   }
00077 
00078   if (s_count_live)
00079   {
00080     entries[nentries].type = IgProfTrace::COUNT | IgProfTrace::ACQUIRE;
00081     entries[nentries].def = &s_ct_live;
00082     entries[nentries].amount = size;
00083     entries[nentries].ticks = 1;
00084     entries[nentries].resource = (IgProfTrace::Address) ptr;
00085     nentries++;
00086   }
00087 
00088   // Drop two bottom frames, four top ones (stacktrace, me, two for hook).
00089   buf->push(addresses+4, depth-5, entries, nentries);
00090 }
00091 
00095 static void
00096 remove (void *ptr)
00097 {
00098   if (s_count_live && ptr)
00099   {
00100     IgProfTrace *buf = IgProf::buffer(s_moduleid);
00101     if (! buf)
00102       return;
00103 
00104     IgProfTrace::Record entry
00105       = { IgProfTrace::RELEASE, &s_ct_live, 0, 0, (IgProfTrace::Address) ptr };
00106     buf->push(0, 0, &entry, 1);
00107   }
00108 }
00109 
00110 // -------------------------------------------------------------------
00113 static void
00114 initialize(void)
00115 {
00116   if (s_initialized) return;
00117   s_initialized = true;
00118 
00119   const char    *options = IgProf::options();
00120   bool          enable = false;
00121   bool          opts = false;
00122 
00123   while (options && *options)
00124   {
00125     while (*options == ' ' || *options == ',')
00126       ++options;
00127 
00128     if (! strncmp(options, "mem", 3))
00129     {
00130       enable = true;
00131       options += 3;
00132       while (*options)
00133       {
00134         if (! strncmp(options, ":total", 6))
00135         {
00136           s_count_total = 1;
00137           options += 6;
00138           opts = true;
00139         }
00140         else if (! strncmp(options, ":largest", 8))
00141         {
00142           s_count_largest = 1;
00143           options += 8;
00144           opts = true;
00145         }
00146         else if (! strncmp(options, ":live", 5))
00147         {
00148           s_count_live = 1;
00149           options += 5;
00150           opts = true;
00151         }
00152         else if (! strncmp(options, ":all", 4))
00153         {
00154           s_count_total = 1;
00155           s_count_largest = 1;
00156           s_count_live = 1;
00157           options += 4;
00158           opts = true;
00159         }
00160         else
00161           break;
00162       }
00163     }
00164     else
00165       options++;
00166 
00167     while (*options && *options != ',' && *options != ' ')
00168       options++;
00169   }
00170 
00171   if (! enable)
00172     return;
00173 
00174   if (! IgProf::initialize(&s_moduleid, 0, false))
00175     return;
00176 
00177   IgProf::disable(true);
00178   if (! opts)
00179   {
00180     IgProf::debug("Memory: defaulting to total memory counting\n");
00181     s_count_total = 1;
00182   }
00183   else
00184   {
00185     if (s_count_total)
00186       IgProf::debug("Memory: enabling total counting\n");
00187     if (s_count_largest)
00188       IgProf::debug("Memory: enabling max counting\n");
00189     if (s_count_live)
00190       IgProf::debug("Memory: enabling live counting\n");
00191   }
00192 
00193   IgHook::hook(domalloc_hook_main.raw);
00194   IgHook::hook(docalloc_hook_main.raw);
00195   IgHook::hook(dorealloc_hook_main.raw);
00196   IgHook::hook(dopmemalign_hook_main.raw);
00197   IgHook::hook(domemalign_hook_main.raw);
00198   IgHook::hook(dovalloc_hook_main.raw);
00199   IgHook::hook(dofree_hook_main.raw);
00200 #if __linux
00201   if (domalloc_hook_main.raw.chain)    IgHook::hook(domalloc_hook_libc.raw);
00202   if (docalloc_hook_main.raw.chain)    IgHook::hook(docalloc_hook_libc.raw);
00203   if (domemalign_hook_main.raw.chain)  IgHook::hook(domemalign_hook_libc.raw);
00204   if (dovalloc_hook_main.raw.chain)    IgHook::hook(dovalloc_hook_libc.raw);
00205   if (dofree_hook_main.raw.chain)      IgHook::hook(dofree_hook_libc.raw);
00206 #endif
00207   IgProf::debug("Memory profiler enabled\n");
00208   IgProf::enable(true);
00209 }
00210 
00211 // -------------------------------------------------------------------
00212 // Traps for this profiler module.  Track memory allocation routines.
00213 static void *
00214 domalloc(IgHook::SafeData<igprof_domalloc_t> &hook, size_t n)
00215 {
00216   bool enabled = IgProf::disable(false);
00217   void *result = (*hook.chain)(n);
00218 
00219   if (enabled && result)
00220     add(result, n);
00221 
00222   IgProf::enable(false);
00223   return result;
00224 }
00225 
00226 static void *
00227 docalloc(IgHook::SafeData<igprof_docalloc_t> &hook, size_t n, size_t m)
00228 {
00229   bool enabled = IgProf::disable(false);
00230   void *result = (*hook.chain)(n, m);
00231 
00232   if (enabled && result)
00233     add(result, n * m);
00234 
00235   IgProf::enable(false);
00236   return result;
00237 }
00238 
00239 static void *
00240 dorealloc(IgHook::SafeData<igprof_dorealloc_t> &hook, void *ptr, size_t n)
00241 {
00242   bool enabled = IgProf::disable(false);
00243   void *result = (*hook.chain)(ptr, n);
00244 
00245   if (result)
00246   {
00247     if (ptr) remove(ptr);
00248     if (enabled && result) add(result, n);
00249   }
00250 
00251   IgProf::enable(false);
00252   return result;
00253 }
00254 
00255 static void *
00256 domemalign(IgHook::SafeData<igprof_domemalign_t> &hook, size_t alignment, size_t size)
00257 {
00258   bool enabled = IgProf::disable(false);
00259   void *result = (*hook.chain)(alignment, size);
00260 
00261   if (enabled && result)
00262     add(result, size);
00263 
00264   IgProf::enable(false);
00265   return result;
00266 }
00267 
00268 static void *
00269 dovalloc(IgHook::SafeData<igprof_dovalloc_t> &hook, size_t size)
00270 {
00271   bool enabled = IgProf::disable(false);
00272   void *result = (*hook.chain)(size);
00273 
00274   if (enabled && result)
00275     add(result, size);
00276 
00277   IgProf::enable(false);
00278   return result;
00279 }
00280 
00281 static int
00282 dopmemalign(IgHook::SafeData<igprof_dopmemalign_t> &hook,
00283             void **ptr, size_t alignment, size_t size)
00284 {
00285   bool enabled = IgProf::disable(false);
00286   int result = (*hook.chain)(ptr, alignment, size);
00287 
00288   if (enabled && ptr && *ptr)
00289     add(*ptr, size);
00290 
00291   IgProf::enable(false);
00292   return result;
00293 }
00294 
00295 static void
00296 dofree(IgHook::SafeData<igprof_dofree_t> &hook, void *ptr)
00297 {
00298   IgProf::disable(false);
00299   remove(ptr);
00300   (*hook.chain)(ptr);
00301   IgProf::enable(false);
00302 }
00303 
00304 // -------------------------------------------------------------------
00305 static bool autoboot = (initialize(), true);

Generated on Tue Jun 9 17:38:08 2009 for CMSSW by  doxygen 1.5.4