MemoryTrace.h

Go to the documentation of this file.
00001 //# MemoryTrace.h: Memory usage tracing mechanism
00002 //# Copyright (C) 2015
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: Block.h 21120 2011-09-01 13:51:56Z gervandiepen $
00027 
00028 #ifndef CASA_MEMORYTRACE_H
00029 #define CASA_MEMORYTRACE_H
00030 
00031 #include <casacore/casa/aips.h>
00032 #include <casacore/casa/OS/Timer.h>
00033 #include <fstream>
00034 #include <string>
00035 
00036 namespace casacore { //# NAMESPACE CASACORE - BEGIN
00037 
00038   // <summary>memory usage tracing mechanism</summary>
00039   // <use visibility=export>
00040   //
00041   // <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
00042   // </reviewed>
00043   //
00044   // <synopsis>
00045   // The MemoryTrace class provides some means to trace the
00046   // memory usage of a program. It logs malloc and free messages in
00047   // a file which can be examined by the python script memorytrace.py.
00048   // <br>The tracing is done using hooks for malloc and free as explained
00049   // in 'man malloc_hook'.
00050   //
00051   // The tracing can be started and stopped at any time. On the first
00052   // start the trace file is created. The file can be closed at any time,
00053   // usually at the end of a program. Another start will recreate the file.
00054   //
00055   // The trace file consists of 3 types of lines:
00056   // <ul>
00057   //  <li> An allocation line like "a <address> <caller> <size>"
00058   //  <li> A deallocation line like "f <address> <caller>"
00059   //  <li> A line like "begin/end <name>" telling the script the beginning
00060   //   or end of a code block. It makes it possible to see how memory usage
00061   //   develops. Such lines can be inserted using the class MemoryTraceBlock.
00062   // </ul>
00063   // All lines start with the number of milliseconds since the start of
00064   // the program.
00065   // <p>
00066   // The script memorytrace.py can be used to interpret the log file and
00067   // to show the memory usage.
00068   // </synopsis>
00069 
00070   class MemoryTrace
00071   {
00072   public:
00073     // Start the tracing. Nothing is done if already started.
00074     // On the first time, it opens the trace file. The name of the
00075     // trace file can be given in the env.var. CASACORE_MEMORYTRACE.
00076     // If undefined, the name casacore_memorytrace.log will be used.
00077     static void start();
00078 
00079     // Stop the tracing.
00080     static void stop();
00081 
00082     // Open the trace file if not open yet.
00083     static void open();
00084 
00085     // Close the tracing output file.
00086     static void close();
00087 
00088     // Is tracing on?
00089     static Bool isOn()
00090       { return theirDoTrace; }
00091 
00092     // Is the tracing file opened?
00093     static Bool isOpen()
00094       { return theirFile.is_open(); }
00095 
00096     // Write a block line in the output file.
00097     static void writeBlock (const char* msg, const std::string& name);
00098     static void writeBlock (const char* msg, const char* name);
00099 
00100     // Write an alloc or free message.
00101     static std::ofstream& writeAlloc (const void* ptr, size_t);
00102     static std::ofstream& writeFree  (const void* ptr);
00103 
00104     // The hooks for malloc and free writing the trace messages.
00105     static void* mallocHook (size_t, const void* caller);
00106     static void freeHook (void*, const void* caller);
00107 
00108     // Make a string from a char* without tracing a possible malloc in
00109     // the string constructor.
00110     static std::string makeString (const char*);
00111 
00112   private:
00113     static Bool          theirDoTrace;
00114     static std::ofstream theirFile;
00115     static Timer         theirTimer;
00116     //# Variables to save original hooks.
00117     static void* (*theirOldMallocHook)(size_t, const void*);
00118     static void (*theirOldFreeHook)(void*, const void*);
00119   };
00120 
00121 
00122   // <summary> Class to write begin and end block message </summary>
00123   // <synopsis>
00124   // This class is meant to write memory trace messages indicating the
00125   // beginning and end of a code block. In this way it is known that the
00126   // (de)allocate messages between these messages belong to that code block.
00127   //
00128   // The constructor writes the begin message, while the destructor writes
00129   // the end message. Because the destructor is called automatically by the
00130   // compiler, the user does not have to worry about it; it will also
00131   // work fine in case of a premature exit from a function.
00132   //
00133   // It is possible to nest blocks as deeply as one likes.
00134   // </synopsis>
00135   class MemoryTraceBlock
00136   {
00137   public:
00138     // The constructor writes a block begin message.
00139     MemoryTraceBlock (const std::string& name);
00140     MemoryTraceBlock (const char* name);
00141     // The constructor writes a block end message.
00142     ~MemoryTraceBlock();
00143   private:
00144     std::string itsName;
00145   };
00146 
00147 } //# NAMESPACE CASACORE - END
00148 
00149 
00150 //# Trace memory (de)allocation.
00151 #define traceMemoryAlloc(ptr,size,msg)     \
00152   if (casacore::MemoryTrace::isOpen()) { \
00153     casacore::MemoryTrace::writeAlloc (ptr, size) << msg << std::endl; \
00154   }
00155 #define traceMemoryFree(ptr,msg)    \
00156   if (casacore::MemoryTrace::isOpen()) { \
00157     casacore::MemoryTrace::writeFree (ptr) << msg << std::endl;  \
00158   }
00159 
00160 #define traceMemoryBlockBegin(name)   \
00161   if (casacore::MemoryTrace::isOpen()) { \
00162     casacore::MemoryTrace::writeBlock(" begin ", name); \
00163   }
00164 #define traceMemoryBlockEnd(name)       \
00165   if (casacore::MemoryTrace::isOpen()) { \
00166     casacore::MemoryTrace::writeBlock(" end ", name); \
00167   }
00168 
00169 
00170 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on 31 Aug 2016 for casa by  doxygen 1.6.1