casacore
Loading...
Searching...
No Matches
MemoryTrace.h
Go to the documentation of this file.
1// # MemoryTrace.h: Memory usage tracing mechanism
2// # Copyright (C) 2015
3// # Associated Universities, Inc. Washington DC, USA.
4// #
5// # This library is free software; you can redistribute it and/or modify it
6// # under the terms of the GNU Library General Public License as published by
7// # the Free Software Foundation; either version 2 of the License, or (at your
8// # option) any later version.
9// #
10// # This library is distributed in the hope that it will be useful, but WITHOUT
11// # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12// # FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13// # License for more details.
14// #
15// # You should have received a copy of the GNU Library General Public License
16// # along with this library; if not, write to the Free Software Foundation,
17// # Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
18// #
19// # Correspondence concerning AIPS++ should be addressed as follows:
20// # Internet email: casa-feedback@nrao.edu.
21// # Postal address: AIPS++ Project Office
22// # National Radio Astronomy Observatory
23// # 520 Edgemont Road
24// # Charlottesville, VA 22903-2475 USA
25
26#ifndef CASA_MEMORYTRACE_H
27#define CASA_MEMORYTRACE_H
28
29#include <casacore/casa/aips.h>
30#include <casacore/casa/OS/Timer.h>
31#include <fstream>
32#include <string>
33
34namespace casacore { // # NAMESPACE CASACORE - BEGIN
35
36// <summary>memory usage tracing mechanism</summary>
37// <use visibility=export>
38//
39// <reviewed reviewer="UNKNOWN" date="before2004/08/25" tests="" demos="">
40// </reviewed>
41//
42// <synopsis>
43// The MemoryTrace class provides some means to trace the
44// memory usage of a program. It logs malloc and free messages in
45// a file which can be examined by the python script memorytrace.py.
46// <br>The tracing is done using hooks for malloc and free as explained
47// in 'man malloc_hook'.
48//
49// The tracing can be started and stopped at any time. On the first
50// start the trace file is created. The file can be closed at any time,
51// usually at the end of a program. Another start will recreate the file.
52//
53// The trace file consists of 3 types of lines:
54// <ul>
55// <li> An allocation line like "a <address> <caller> <size>"
56// <li> A deallocation line like "f <address> <caller>"
57// <li> A line like "begin/end <name>" telling the script the beginning
58// or end of a code block. It makes it possible to see how memory usage
59// develops. Such lines can be inserted using the class MemoryTraceBlock.
60// </ul>
61// All lines start with the number of milliseconds since the start of
62// the program.
63// <p>
64// The script memorytrace.py can be used to interpret the log file and
65// to show the memory usage.
66// </synopsis>
67
69 public:
70 // Start the tracing. Nothing is done if already started.
71 // On the first time, it opens the trace file. The name of the
72 // trace file can be given in the env.var. CASACORE_MEMORYTRACE.
73 // If undefined, the name casacore_memorytrace.log will be used.
74 static void start();
75
76 // Stop the tracing.
77 static void stop();
78
79 // Open the trace file if not open yet.
80 static void open();
81
82 // Close the tracing output file.
83 static void close();
84
85 // Is tracing on?
86 static Bool isOn() { return theirDoTrace; }
87
88 // Is the tracing file opened?
89 static Bool isOpen() { return theirFile.is_open(); }
90
91 // Write a block line in the output file.
92 static void writeBlock(const char* msg, const std::string& name);
93 static void writeBlock(const char* msg, const char* name);
94
95 // Write an alloc or free message.
96 static std::ofstream& writeAlloc(const void* ptr, size_t);
97 static std::ofstream& writeFree(const void* ptr);
98
99 // The hooks for malloc and free writing the trace messages.
100 static void* mallocHook(size_t, const void* caller);
101 static void freeHook(void*, const void* caller);
102
103 // Make a string from a char* without tracing a possible malloc in
104 // the string constructor.
105 static std::string makeString(const char*);
106
107 private:
109 static std::ofstream theirFile;
111 // # Variables to save original hooks.
112 static void* (*theirOldMallocHook)(size_t, const void*);
113 static void (*theirOldFreeHook)(void*, const void*);
114};
115
116// <summary> Class to write begin and end block message </summary>
117// <synopsis>
118// This class is meant to write memory trace messages indicating the
119// beginning and end of a code block. In this way it is known that the
120// (de)allocate messages between these messages belong to that code block.
121//
122// The constructor writes the begin message, while the destructor writes
123// the end message. Because the destructor is called automatically by the
124// compiler, the user does not have to worry about it; it will also
125// work fine in case of a premature exit from a function.
126//
127// It is possible to nest blocks as deeply as one likes.
128// </synopsis>
130 public:
131 // The constructor writes a block begin message.
132 MemoryTraceBlock(const std::string& name);
133 MemoryTraceBlock(const char* name);
134 // The constructor writes a block end message.
136
137 private:
138 std::string itsName;
139};
140
141} // namespace casacore
142
143// # Trace memory (de)allocation.
144#define traceMemoryAlloc(ptr, size, msg) \
145 if (casacore::MemoryTrace::isOpen()) { \
146 casacore::MemoryTrace::writeAlloc(ptr, size) << msg << std::endl; \
147 }
148#define traceMemoryFree(ptr, msg) \
149 if (casacore::MemoryTrace::isOpen()) { \
150 casacore::MemoryTrace::writeFree(ptr) << msg << std::endl; \
151 }
152
153#define traceMemoryBlockBegin(name) \
154 if (casacore::MemoryTrace::isOpen()) { \
155 casacore::MemoryTrace::writeBlock(" begin ", name); \
156 }
157#define traceMemoryBlockEnd(name) \
158 if (casacore::MemoryTrace::isOpen()) { \
159 casacore::MemoryTrace::writeBlock(" end ", name); \
160 }
161
162#endif
~MemoryTraceBlock()
The constructor writes a block end message.
MemoryTraceBlock(const char *name)
MemoryTraceBlock(const std::string &name)
The constructor writes a block begin message.
static void open()
Open the trace file if not open yet.
static Bool isOn()
Is tracing on?
Definition MemoryTrace.h:86
static std::ofstream & writeFree(const void *ptr)
static Bool theirDoTrace
static std::string makeString(const char *)
Make a string from a char* without tracing a possible malloc in the string constructor.
static std::ofstream theirFile
static Bool isOpen()
Is the tracing file opened?
Definition MemoryTrace.h:89
static void(* theirOldFreeHook)(void *, const void *)
static std::ofstream & writeAlloc(const void *ptr, size_t)
Write an alloc or free message.
static void writeBlock(const char *msg, const std::string &name)
Write a block line in the output file.
static Timer theirTimer
static void writeBlock(const char *msg, const char *name)
static void * mallocHook(size_t, const void *caller)
The hooks for malloc and free writing the trace messages.
static void close()
Close the tracing output file.
static void freeHook(void *, const void *caller)
static void start()
Start the tracing.
static void stop()
Stop the tracing.
For temporary backward namespace compatibility, use casa as alias for casacore.
Definition mainpage.dox:28
String name() const
Return the name of the field.
bool Bool
Define the standard types used by Casacore.
Definition aipstype.h:40