Commit | Line | Data |
---|---|---|
b311480e | 1 | // Created on: 2011-02-03 |
2 | // Created by: Mikhail SAZONOV | |
973c2be1 | 3 | // Copyright (c) 2011-2014 OPEN CASCADE SAS |
b311480e | 4 | // |
973c2be1 | 5 | // This file is part of Open CASCADE Technology software library. |
b311480e | 6 | // |
d5f74e42 | 7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published | |
973c2be1 | 9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT | |
11 | // distribution for complete text of the license and disclaimer of any warranty. | |
b311480e | 12 | // |
973c2be1 | 13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. | |
7af17f1e MA |
15 | |
16 | #ifndef _OSD_MAllocHook_HeaderFile | |
17 | #define _OSD_MAllocHook_HeaderFile | |
18 | ||
19 | #include <Standard_TypeDef.hxx> | |
20 | #include <Standard_Mutex.hxx> | |
21 | #include <stdio.h> | |
64531d9c | 22 | #include <fstream> |
7af17f1e MA |
23 | |
24 | /** | |
25 | * This class provides the possibility to set callback for memory | |
26 | * allocation/deallocation. | |
27 | * On MS Windows, it works only in Debug builds. It relies on the | |
28 | * debug CRT function _CrtSetAllocHook (see MSDN for help). | |
29 | */ | |
30 | class OSD_MAllocHook | |
31 | { | |
32 | public: | |
33 | /** | |
34 | * Interface of a class that should handle allocation/deallocation events | |
35 | */ | |
36 | class Callback | |
37 | { | |
38 | public: | |
39 | //! Allocation event handler | |
40 | /** | |
41 | * It is called when allocation is done | |
42 | * @param theSize | |
43 | * the size of the memory block in bytes | |
44 | * @param theRequestNum | |
45 | * the allocation order number of the memory block | |
46 | */ | |
47 | virtual void AllocEvent | |
48 | (size_t theSize, | |
49 | long theRequestNum) = 0; | |
50 | ||
51 | //! Freeing event handler | |
52 | /** | |
53 | * It is called when the block is freed | |
54 | * @param theData | |
55 | * the pointer to the user data section of the memory block | |
56 | * @param theSize | |
57 | * the size of the memory block in bytes | |
58 | * @param theRequestNum | |
59 | * the allocation order number of the memory block | |
60 | */ | |
61 | virtual void FreeEvent | |
62 | (void* theData, | |
63 | size_t theSize, | |
64 | long theRequestNum) = 0; | |
65 | }; | |
66 | ||
67 | /** | |
68 | * Implementation of the handler that collects all events | |
69 | * to the log file. It contains the method to generate the report | |
70 | * from the log file. | |
71 | */ | |
72 | class LogFileHandler: public Callback | |
73 | { | |
74 | public: | |
75 | //! Constructor | |
76 | Standard_EXPORT LogFileHandler(); | |
77 | ||
78 | //! Destructor | |
79 | Standard_EXPORT ~LogFileHandler(); | |
80 | ||
81 | //! Create the file and start collecting events. | |
82 | //! Return false if the file with the given name cannot be created. | |
83 | Standard_EXPORT Standard_Boolean Open(const char* theFileName); | |
84 | ||
85 | //! Close the file and stop collecting events | |
86 | Standard_EXPORT void Close(); | |
87 | ||
88 | //! Make synthesized report on the given log file. | |
89 | /** | |
90 | * Generate an easy to use report in the | |
91 | * new file with the given name, taking the given log file as input. | |
92 | * If theIncludeAlive is true then | |
93 | * include into the report the alive allocation numbers. | |
94 | */ | |
95 | Standard_EXPORT static Standard_Boolean MakeReport | |
96 | (const char* theLogFile, | |
97 | const char* theOutFile, | |
98 | const Standard_Boolean theIncludeAlive = Standard_False); | |
99 | ||
100 | Standard_EXPORT virtual void AllocEvent(size_t, long); | |
101 | Standard_EXPORT virtual void FreeEvent(void*, size_t, long); | |
102 | ||
103 | private: | |
64531d9c | 104 | std::ofstream myLogFile; |
7af17f1e MA |
105 | Standard_Mutex myMutex; |
106 | size_t myBreakSize; | |
107 | }; | |
108 | ||
109 | /** | |
110 | * Implementation of the handler that collects numbers of | |
111 | * allocations/deallocations for each block size directly in the memory. | |
112 | */ | |
113 | class CollectBySize: public Callback | |
114 | { | |
115 | public: | |
116 | //! Constructor | |
117 | Standard_EXPORT CollectBySize(); | |
118 | ||
119 | //! Destructor | |
120 | Standard_EXPORT ~CollectBySize(); | |
121 | ||
122 | //! Reset the buffer and start collecting events. | |
123 | Standard_EXPORT void Reset(); | |
124 | ||
125 | //! Write report in the given file. | |
126 | Standard_EXPORT Standard_Boolean MakeReport(const char* theOutFile); | |
127 | ||
128 | Standard_EXPORT virtual void AllocEvent(size_t, long); | |
129 | Standard_EXPORT virtual void FreeEvent(void*, size_t, long); | |
130 | ||
1cc1abe1 | 131 | public: |
7af17f1e MA |
132 | struct Numbers |
133 | { | |
134 | int nbAlloc; | |
135 | int nbFree; | |
136 | int nbLeftPeak; | |
137 | Numbers() : nbAlloc(0), nbFree(0), nbLeftPeak(0) {} | |
138 | }; | |
1cc1abe1 RL |
139 | |
140 | static const size_t myMaxAllocSize; //!< maximum tracked size | |
7af17f1e | 141 | |
1cc1abe1 RL |
142 | Standard_Mutex myMutex; //!< used for thread-safe access |
143 | Numbers* myArray; //!< indexed from 0 to myMaxAllocSize-1 | |
144 | ptrdiff_t myTotalLeftSize; //!< currently remained allocated size | |
145 | size_t myTotalPeakSize; //!< maxium cumulative allocated size | |
941a7a24 | 146 | size_t myBreakSize; //!< user defined allocation size to debug (see place_for_breakpoint()) |
147 | size_t myBreakPeak; //!< user defined peak size limit to debug | |
7af17f1e MA |
148 | }; |
149 | ||
150 | //! Set handler of allocation/deallocation events | |
151 | /** | |
152 | * You can pass here any implementation. For easy start, you can try | |
153 | * with the predefined handler LogFileHandler, which static instance | |
154 | * is returned by GetLogFileHandler(). | |
155 | * To clear the handler, pass NULL here. | |
156 | */ | |
157 | Standard_EXPORT static void SetCallback | |
158 | (Callback* theCB); | |
159 | ||
160 | //! Get current handler of allocation/deallocation events | |
161 | Standard_EXPORT static Callback* GetCallback(); | |
162 | ||
163 | //! Get static instance of LogFileHandler handler | |
164 | Standard_EXPORT static LogFileHandler* GetLogFileHandler(); | |
165 | ||
166 | //! Get static instance of CollectBySize handler | |
167 | Standard_EXPORT static CollectBySize* GetCollectBySize(); | |
168 | }; | |
169 | ||
170 | #endif /* _OSD_MAllocHook_HeaderFile */ |