CMS 3D CMS Logo

IgProfFileDesc.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 <cerrno>
00009 #include <sys/socket.h>
00010 #include <pthread.h>
00011 
00012 // -------------------------------------------------------------------
00013 // Traps for this profiling module
00014 IGPROF_DUAL_HOOK(3, int, doopen, _main, _libc,
00015                  (const char *fn, int flags, int mode), (fn, flags, mode),
00016                  "open", 0, "libc.so.6")
00017 IGPROF_DUAL_HOOK(3, int, doopen64, _main, _libc,
00018                  (const char *fn, int flags, int mode), (fn, flags, mode),
00019                  "__open64", 0, "libc.so.6")
00020 IGPROF_DUAL_HOOK(1, int, doclose, _main, _libc,
00021                  (int fd), (fd),
00022                  "close", 0, "libc.so.6")
00023 IGPROF_DUAL_HOOK(1, int, dodup, _main, _libc,
00024                  (int fd), (fd),
00025                  "dup", 0, "libc.so.6")
00026 IGPROF_DUAL_HOOK(2, int, dodup2, _main, _libc,
00027                  (int fd, int newfd), (fd, newfd),
00028                  "dup2", 0, "libc.so.6")
00029 IGPROF_DUAL_HOOK(3, int, dosocket, _main, _libc,
00030                  (int domain, int type, int proto), (domain, type, proto),
00031                  "socket", 0, "libc.so.6")
00032 IGPROF_DUAL_HOOK(3, int, doaccept, _main, _libc,
00033                  (int fd, sockaddr *addr, socklen_t *len), (fd, addr, len),
00034                  "accept", 0, "libc.so.6")
00035 
00036 // Data for this profiling module
00037 static IgProfTrace::CounterDef  s_ct_used       = { "FD_USED", IgProfTrace::TICK, -1 };
00038 static IgProfTrace::CounterDef  s_ct_live       = { "FD_LIVE", IgProfTrace::TICK_PEAK, -1 };
00039 static bool                     s_count_used    = 0;
00040 static bool                     s_count_live    = 0;
00041 static bool                     s_initialized   = false;
00042 static int                      s_moduleid      = -1;
00043 
00045 static void __attribute__((noinline))
00046 add (int fd)
00047 {
00048   IgProfTrace *buf = IgProf::buffer(s_moduleid);
00049   if (! buf)
00050     return;
00051 
00052   void                  *addresses[IgProfTrace::MAX_DEPTH];
00053   int                   depth = IgHookTrace::stacktrace(addresses, IgProfTrace::MAX_DEPTH);
00054   IgProfTrace::Record   entries [2];
00055   int                   nentries = 0;
00056 
00057   if (s_count_used)
00058   {
00059     entries[nentries].type = IgProfTrace::COUNT;
00060     entries[nentries].def = &s_ct_used;
00061     entries[nentries].amount = 1;
00062     entries[nentries].ticks = 1;
00063     nentries++;
00064   }
00065 
00066   if (s_count_live)
00067   {
00068     entries[nentries].type = IgProfTrace::COUNT | IgProfTrace::ACQUIRE;
00069     entries[nentries].def = &s_ct_live;
00070     entries[nentries].amount = 1;
00071     entries[nentries].ticks = 1;
00072     entries[nentries].resource = fd;
00073     nentries++;
00074   }
00075 
00076   // Drop two bottom frames, four top ones (stacktrace, me, two for hook).
00077   buf->push(addresses+4, depth-5, entries, nentries);
00078 }
00079 
00083 static void
00084 remove (int fd)
00085 {
00086   if (s_count_live)
00087   {
00088     IgProfTrace *buf = IgProf::buffer(s_moduleid);
00089     if (! buf)
00090       return;
00091 
00092     IgProfTrace::Record entry
00093       = { IgProfTrace::RELEASE, &s_ct_live, 0, 0, fd };
00094     buf->push(0, 0, &entry, 1);
00095   }
00096 }
00097 
00098 // -------------------------------------------------------------------
00101 static void
00102 initialize(void)
00103 {
00104   if (s_initialized) return;
00105   s_initialized = true;
00106 
00107   const char    *options = IgProf::options();
00108   bool          enable = false;
00109   bool          opts = false;
00110 
00111   while (options && *options)
00112   {
00113     while (*options == ' ' || *options == ',')
00114       ++options;
00115 
00116     if (! strncmp(options, "fd", 2))
00117     {
00118       enable = true;
00119       options += 2;
00120       while (*options)
00121       {
00122         if (! strncmp(options, ":used", 5))
00123         {
00124           s_count_used = 1;
00125           options += 5;
00126           opts = true;
00127         }
00128         else if (! strncmp(options, ":live", 5))
00129         {
00130           s_count_live = 1;
00131           options += 5;
00132           opts = true;
00133         }
00134         else if (! strncmp(options, ":all", 4))
00135         {
00136           s_count_used = 1;
00137           s_count_live = 1;
00138           options += 4;
00139           opts = true;
00140         }
00141         else
00142           break;
00143       }
00144     }
00145     else
00146       options++;
00147 
00148     while (*options && *options != ',' && *options != ' ')
00149       options++;
00150   }
00151 
00152   if (! enable)
00153     return;
00154 
00155   if (! IgProf::initialize(&s_moduleid, 0, false))
00156     return;
00157 
00158   IgProf::disable(true);
00159   if (!opts)
00160   {
00161     IgProf::debug("FD: defaulting to total descriptor counting\n");
00162     s_count_used = 1;
00163   }
00164   else
00165   {
00166     if (s_count_used)
00167       IgProf::debug("FD: enabling usage counting\n");
00168     if (s_count_live)
00169       IgProf::debug("FD: enabling live counting\n");
00170   }
00171 
00172 
00173   IgHook::hook(doopen_hook_main.raw);
00174   IgHook::hook(doopen64_hook_main.raw);
00175   IgHook::hook(doclose_hook_main.raw);
00176   IgHook::hook(dodup_hook_main.raw);
00177   IgHook::hook(dodup2_hook_main.raw);
00178   IgHook::hook(dosocket_hook_main.raw);
00179   IgHook::hook(doaccept_hook_main.raw);
00180 #if __linux
00181   if (doopen_hook_main.raw.chain)   IgHook::hook(doopen_hook_libc.raw);
00182   if (doopen64_hook_main.raw.chain) IgHook::hook(doopen64_hook_libc.raw);
00183   if (doclose_hook_main.raw.chain)  IgHook::hook(doclose_hook_libc.raw);
00184   if (dodup_hook_main.raw.chain)    IgHook::hook(dodup_hook_libc.raw);
00185   if (dodup2_hook_main.raw.chain)   IgHook::hook(dodup2_hook_libc.raw);
00186   if (dosocket_hook_main.raw.chain) IgHook::hook(dosocket_hook_libc.raw);
00187   if (doaccept_hook_main.raw.chain) IgHook::hook(doaccept_hook_libc.raw);
00188 #endif
00189   IgProf::debug("File descriptor profiler enabled\n");
00190   IgProf::enable(true);
00191 }
00192 
00193 // -------------------------------------------------------------------
00194 // Trapped system calls.  Track live file descriptor usage.
00195 static int
00196 doopen(IgHook::SafeData<igprof_doopen_t> &hook, const char *fn, int flags, int mode)
00197 {
00198   bool enabled = IgProf::disable(false);
00199   int result = (*hook.chain)(fn, flags, mode);
00200   int err = errno;
00201 
00202   if (enabled && result != -1)
00203     add(result);
00204 
00205   errno = err;
00206   IgProf::enable(false);
00207   return result;
00208 }
00209 
00210 static int
00211 doopen64(IgHook::SafeData<igprof_doopen64_t> &hook, const char *fn, int flags, int mode)
00212 {
00213   bool enabled = IgProf::disable(false);
00214   int result = (*hook.chain)(fn, flags, mode);
00215   int err = errno;
00216 
00217   if (enabled && result != -1)
00218     add(result);
00219 
00220   errno = err;
00221   IgProf::enable(false);
00222   return result;
00223 }
00224 
00225 static int
00226 doclose(IgHook::SafeData<igprof_doclose_t> &hook, int fd)
00227 {
00228   IgProf::disable(false);
00229   int result = (*hook.chain)(fd);
00230   int err = errno;
00231 
00232   if (result != -1)
00233     remove(fd);
00234 
00235   errno = err;
00236   IgProf::enable(false);
00237   return result;
00238 }
00239 
00240 
00241 static int
00242 dodup(IgHook::SafeData<igprof_dodup_t> &hook, int fd)
00243 {
00244   bool enabled = IgProf::disable(false);
00245   int result = (*hook.chain)(fd);
00246   int err = errno;
00247 
00248   if (enabled && result != -1)
00249     add(result);
00250 
00251   errno = err;
00252   IgProf::enable(false);
00253   return result;
00254 }
00255 
00256 static int
00257 dodup2(IgHook::SafeData<igprof_dodup2_t> &hook, int fd, int newfd)
00258 {
00259   bool enabled = IgProf::disable(false);
00260   int result = (*hook.chain)(fd, newfd);
00261   int err = errno;
00262 
00263   if (result != -1)
00264   {
00265     remove(fd);
00266     if (enabled)
00267       add(newfd);
00268   }
00269 
00270   errno = err;
00271   IgProf::enable(false);
00272   return result;
00273 }
00274 
00275 static int
00276 dosocket(IgHook::SafeData<igprof_dosocket_t> &hook, int domain, int type, int proto)
00277 {
00278   bool enabled = IgProf::disable(false);
00279   int result = (*hook.chain)(domain, type, proto);
00280   int err = errno;
00281 
00282   if (enabled && result != -1)
00283     add(result);
00284 
00285   errno = err;
00286   IgProf::enable(false);
00287   return result;
00288 }
00289 
00290 static int
00291 doaccept(IgHook::SafeData<igprof_doaccept_t> &hook,
00292          int fd, struct sockaddr *addr, socklen_t *len)
00293 {
00294   bool enabled = IgProf::disable(false);
00295   int result = (*hook.chain)(fd, addr, len);
00296   int err = errno;
00297 
00298   if (enabled && result != -1)
00299     add(result);
00300 
00301   errno = err;
00302   IgProf::enable(false);
00303   return result;
00304 }
00305 
00306 // -------------------------------------------------------------------
00307 static bool autoboot = (initialize(), true);

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