0023393: Improve usability of OSD_MAllocHook::CollectBySize
[occt.git] / src / OSD / OSD_MAllocHook.hxx
CommitLineData
b311480e 1// Created on: 2011-02-03
2// Created by: Mikhail SAZONOV
3// Copyright (c) 2011-2012 OPEN CASCADE SAS
4//
5// The content of this file is subject to the Open CASCADE Technology Public
6// License Version 6.5 (the "License"). You may not use the content of this file
7// except in compliance with the License. Please obtain a copy of the License
8// at http://www.opencascade.org and read it completely before using this file.
9//
10// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
11// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
12//
13// The Original Code and all software distributed under the License is
14// distributed on an "AS IS" basis, without warranty of any kind, and the
15// Initial Developer hereby disclaims all such warranties, including without
16// limitation, any warranties of merchantability, fitness for a particular
17// purpose or non-infringement. Please see the License for the specific terms
18// and conditions governing the rights and limitations under the License.
19
7af17f1e
MA
20
21#ifndef _OSD_MAllocHook_HeaderFile
22#define _OSD_MAllocHook_HeaderFile
23
24#include <Standard_TypeDef.hxx>
25#include <Standard_Mutex.hxx>
26#include <stdio.h>
27
28/**
29 * This class provides the possibility to set callback for memory
30 * allocation/deallocation.
31 * On MS Windows, it works only in Debug builds. It relies on the
32 * debug CRT function _CrtSetAllocHook (see MSDN for help).
33 */
34class OSD_MAllocHook
35{
36public:
37 /**
38 * Interface of a class that should handle allocation/deallocation events
39 */
40 class Callback
41 {
42 public:
43 //! Allocation event handler
44 /**
45 * It is called when allocation is done
46 * @param theSize
47 * the size of the memory block in bytes
48 * @param theRequestNum
49 * the allocation order number of the memory block
50 */
51 virtual void AllocEvent
52 (size_t theSize,
53 long theRequestNum) = 0;
54
55 //! Freeing event handler
56 /**
57 * It is called when the block is freed
58 * @param theData
59 * the pointer to the user data section of the memory block
60 * @param theSize
61 * the size of the memory block in bytes
62 * @param theRequestNum
63 * the allocation order number of the memory block
64 */
65 virtual void FreeEvent
66 (void* theData,
67 size_t theSize,
68 long theRequestNum) = 0;
69 };
70
71 /**
72 * Implementation of the handler that collects all events
73 * to the log file. It contains the method to generate the report
74 * from the log file.
75 */
76 class LogFileHandler: public Callback
77 {
78 public:
79 //! Constructor
80 Standard_EXPORT LogFileHandler();
81
82 //! Destructor
83 Standard_EXPORT ~LogFileHandler();
84
85 //! Create the file and start collecting events.
86 //! Return false if the file with the given name cannot be created.
87 Standard_EXPORT Standard_Boolean Open(const char* theFileName);
88
89 //! Close the file and stop collecting events
90 Standard_EXPORT void Close();
91
92 //! Make synthesized report on the given log file.
93 /**
94 * Generate an easy to use report in the
95 * new file with the given name, taking the given log file as input.
96 * If theIncludeAlive is true then
97 * include into the report the alive allocation numbers.
98 */
99 Standard_EXPORT static Standard_Boolean MakeReport
100 (const char* theLogFile,
101 const char* theOutFile,
102 const Standard_Boolean theIncludeAlive = Standard_False);
103
104 Standard_EXPORT virtual void AllocEvent(size_t, long);
105 Standard_EXPORT virtual void FreeEvent(void*, size_t, long);
106
107 private:
108 FILE* myLogFile;
109 Standard_Mutex myMutex;
110 size_t myBreakSize;
111 };
112
113 /**
114 * Implementation of the handler that collects numbers of
115 * allocations/deallocations for each block size directly in the memory.
116 */
117 class CollectBySize: public Callback
118 {
119 public:
120 //! Constructor
121 Standard_EXPORT CollectBySize();
122
123 //! Destructor
124 Standard_EXPORT ~CollectBySize();
125
126 //! Reset the buffer and start collecting events.
127 Standard_EXPORT void Reset();
128
129 //! Write report in the given file.
130 Standard_EXPORT Standard_Boolean MakeReport(const char* theOutFile);
131
132 Standard_EXPORT virtual void AllocEvent(size_t, long);
133 Standard_EXPORT virtual void FreeEvent(void*, size_t, long);
134
1cc1abe1 135 public:
7af17f1e
MA
136 struct Numbers
137 {
138 int nbAlloc;
139 int nbFree;
140 int nbLeftPeak;
141 Numbers() : nbAlloc(0), nbFree(0), nbLeftPeak(0) {}
142 };
1cc1abe1
RL
143
144 static const size_t myMaxAllocSize; //!< maximum tracked size
7af17f1e 145
1cc1abe1
RL
146 Standard_Mutex myMutex; //!< used for thread-safe access
147 Numbers* myArray; //!< indexed from 0 to myMaxAllocSize-1
148 ptrdiff_t myTotalLeftSize; //!< currently remained allocated size
149 size_t myTotalPeakSize; //!< maxium cumulative allocated size
7af17f1e
MA
150 size_t myBreakSize;
151 };
152
153 //! Set handler of allocation/deallocation events
154 /**
155 * You can pass here any implementation. For easy start, you can try
156 * with the predefined handler LogFileHandler, which static instance
157 * is returned by GetLogFileHandler().
158 * To clear the handler, pass NULL here.
159 */
160 Standard_EXPORT static void SetCallback
161 (Callback* theCB);
162
163 //! Get current handler of allocation/deallocation events
164 Standard_EXPORT static Callback* GetCallback();
165
166 //! Get static instance of LogFileHandler handler
167 Standard_EXPORT static LogFileHandler* GetLogFileHandler();
168
169 //! Get static instance of CollectBySize handler
170 Standard_EXPORT static CollectBySize* GetCollectBySize();
171};
172
173#endif /* _OSD_MAllocHook_HeaderFile */