Loading...
Searching...
No Matches
mallocTag.h
Go to the documentation of this file.
1//
2// Copyright 2016 Pixar
3//
4// Licensed under the Apache License, Version 2.0 (the "Apache License")
5// with the following modification; you may not use this file except in
6// compliance with the Apache License and the following modification to it:
7// Section 6. Trademarks. is deleted and replaced with:
8//
9// 6. Trademarks. This License does not grant permission to use the trade
10// names, trademarks, service marks, or product names of the Licensor
11// and its affiliates, except as required to comply with Section 4(c) of
12// the License and to reproduce the content of the NOTICE file.
13//
14// You may obtain a copy of the Apache License at
15//
16// http://www.apache.org/licenses/LICENSE-2.0
17//
18// Unless required by applicable law or agreed to in writing, software
19// distributed under the Apache License with the above modification is
20// distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
21// KIND, either express or implied. See the Apache License for the specific
22// language governing permissions and limitations under the Apache License.
23//
24#ifndef PXR_BASE_TF_MALLOC_TAG_H
25#define PXR_BASE_TF_MALLOC_TAG_H
26
27#include "pxr/pxr.h"
28#include "pxr/base/tf/api.h"
29
30#include <atomic>
31#include <cstdlib>
32#include <cstdint>
33#include <iosfwd>
34#include <string>
35#include <vector>
36
37PXR_NAMESPACE_OPEN_SCOPE
38
41
42struct Tf_MallocPathNode;
43
51public:
52 struct CallStackInfo;
53
60 struct CallTree {
80 struct PathNode {
81 size_t nBytes,
83 size_t nAllocations;
84 std::string siteName;
85 std::vector<PathNode>
87 };
88
97 struct CallSite {
98 std::string name;
99 size_t nBytes;
100 };
101
102 // Note: enum below must be kept in sync with tfmodule/mallocCallTree.h
103
106 TREE = 0,
108 BOTH
109 };
110
131 TF_API
133 size_t maxPrintedNodes = 100000) const;
134
140 TF_API
141 void Report(
142 std::ostream &out,
143 const std::string &rootName) const;
144
146 TF_API
147 void Report(
148 std::ostream &out) const;
149
151 std::vector<CallSite> callSites;
152
155
157 std::vector<CallStackInfo> capturedCallStacks;
158 };
159
164 {
166 std::vector<uintptr_t> stack;
167
170 size_t size;
171
175 };
176
188 TF_API static bool Initialize(std::string* errMsg);
189
194 static bool IsInitialized() {
195 return TfMallocTag::_isInitialized;
196 }
197
203 TF_API static size_t GetTotalBytes();
204
210 TF_API static size_t GetMaxTotalBytes();
211
224 TF_API static bool GetCallTree(CallTree* tree, bool skipRepeated = true);
225
226private:
227
228 struct _ThreadData;
229
230public:
231
255 class Auto {
256 public:
257 Auto(const Auto &) = delete;
258 Auto& operator=(const Auto &) = delete;
259
260 Auto(Auto &&) = delete;
261 Auto& operator=(Auto &&) = delete;
262
280 template <class Str, class... Strs>
281 explicit Auto(Str &&name1, Strs &&... nameN)
282 : _threadData(TfMallocTag::_Push(_CStr(std::forward<Str>(name1))))
283 , _nTags(_threadData
284 ? 1 + _PushImpl(std::forward<Strs>(nameN)...)
285 : 0) {}
286
297 inline void Release() {
298 while (_nTags--) {
299 TfMallocTag::_End(_threadData);
300 }
301 _threadData = nullptr;
302 }
303
309 inline ~Auto() {
310 Release();
311 }
312
313 private:
314
315 char const *_CStr(char const *cstr) const { return cstr; }
316 char const *_CStr(std::string const &str) const { return str.c_str(); }
317
318 template <class Str, class... Strs>
319 int _PushImpl(Str &&tag, Strs &&... rest) {
320 TfMallocTag::_Begin(_CStr(std::forward<Str>(tag)), _threadData);
321 return 1 + _PushImpl(std::forward<Strs>(rest)...);
322 }
323
324 int _PushImpl() {
325 // Recursion termination base-case.
326 return 0;
327 }
328
329 _ThreadData* _threadData;
330 int _nTags;
331
332 friend class TfMallocTag;
333 };
334
335 // A historical compatibility: before Auto could accept only one argument,
336 // so Auto2 existed to handle two arguments. Now Auto can accept any number
337 // of arguments, so Auto2 is just an alias for Auto.
338 using Auto2 = Auto;
339
349 static void Push(const std::string& name) {
350 _Push(name.c_str());
351 }
352
354 static void Push(const char* name) {
355 _Push(name);
356 }
357
363 static void Pop() {
364 if (TfMallocTag::_isInitialized) {
365 _End();
366 }
367 }
368
386 TF_API static void SetDebugMatchList(const std::string& matchList);
387
409 TF_API static void SetCapturedMallocStacksMatchList(const std::string& matchList);
410
416 TF_API static std::vector<std::vector<uintptr_t> > GetCapturedMallocStacks();
417
418private:
419 friend struct _TemporaryDisabler;
420
421 friend struct Tf_MallocGlobalData;
422
423 static bool _Initialize(std::string* errMsg);
424
425 static inline _ThreadData *_Push(char const *name) {
426 if (TfMallocTag::_isInitialized) {
427 return _Begin(name);
428 }
429 return nullptr;
430 }
431
432 TF_API static _ThreadData *_Begin(char const *name,
433 _ThreadData *threadData = nullptr);
434 TF_API static void _End(_ThreadData *threadData = nullptr);
435
436 static void* _MallocWrapper(size_t, const void*);
437 static void* _ReallocWrapper(void*, size_t, const void*);
438 static void* _MemalignWrapper(size_t, size_t, const void*);
439 static void _FreeWrapper(void*, const void*);
440
441 friend class TfMallocTag::Auto;
442 class Tls;
443 friend class TfMallocTag::Tls;
444 TF_API static std::atomic<bool> _isInitialized;
445};
446
449
452
486//
487PXR_NAMESPACE_CLOSE_SCOPE
488
489#define TF_MALLOC_TAG_NEW(name1, name2) \
490 /* this is for STL purposes */ \
491 inline void* operator new(::std::size_t, void* ptr) { \
492 return ptr; \
493 } \
494 \
495 inline void* operator new(::std::size_t s) { \
496 PXR_NS::TfAutoMallocTag tag(name1, name2); \
497 return malloc(s); \
498 } \
499 \
500 inline void* operator new[](::std::size_t s) { \
501 PXR_NS::TfAutoMallocTag tag(name1, name2); \
502 return malloc(s); \
503 } \
504 \
505 /* Required due to the placement-new override above. */ \
506 inline void operator delete(void* ptr, void* place) {} \
507 \
508 inline void operator delete(void* ptr, size_t) { \
509 free(ptr); \
510 } \
511 \
512 inline void operator delete[] (void* ptr, size_t) { \
513 free(ptr); \
514 } \
515
516#endif
Scoped (i.e.
Definition: mallocTag.h:255
Auto(Str &&name1, Strs &&... nameN)
Push one or more memory tags onto the local-call stack with names name1 ... nameN.
Definition: mallocTag.h:281
~Auto()
Pop a memory tag from the local-call stack.
Definition: mallocTag.h:309
void Release()
Pop the tag from the stack before it is destructed.
Definition: mallocTag.h:297
Top-down memory tagging system.
Definition: mallocTag.h:50
static void Push(const char *name)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition: mallocTag.h:354
static TF_API void SetDebugMatchList(const std::string &matchList)
Sets the tags to trap in the debugger.
size_t numAllocations
The number of allocations (always one unless stack frames have been combined to create unique stacks)...
Definition: mallocTag.h:174
static TF_API std::vector< std::vector< uintptr_t > > GetCapturedMallocStacks()
Returns the captured malloc stack traces for allocations billed to the malloc tags passed to SetCaptu...
static TF_API void SetCapturedMallocStacksMatchList(const std::string &matchList)
Sets the tags to trace.
static void Push(const std::string &name)
Manually push a tag onto the stack.
Definition: mallocTag.h:349
std::vector< uintptr_t > stack
The stack frame pointers.
Definition: mallocTag.h:166
size_t size
The amount of allocated memory (accumulated over all allocations sharing this call stack).
Definition: mallocTag.h:170
static TF_API size_t GetTotalBytes()
Return total number of allocated bytes.
static TF_API bool Initialize(std::string *errMsg)
Initialize the memory tagging system.
static bool IsInitialized()
Return true if the tagging system is active.
Definition: mallocTag.h:194
static void Pop()
Manually pop a tag from the stack.
Definition: mallocTag.h:363
static TF_API bool GetCallTree(CallTree *tree, bool skipRepeated=true)
Return a snapshot of memory usage.
static TF_API size_t GetMaxTotalBytes()
Return the maximum total number of bytes that have ever been allocated at one time.
This struct is used to represent a call stack taken for an allocation that was billed under a specifi...
Definition: mallocTag.h:164
STL namespace.
Summary data structure for malloc statistics.
Definition: mallocTag.h:60
std::vector< PathNode > children
Children nodes.
Definition: mallocTag.h:86
TF_API std::string GetPrettyPrintString(PrintSetting setting=BOTH, size_t maxPrintedNodes=100000) const
Return the malloc report string.
size_t nAllocations
The number of allocations for this node.
Definition: mallocTag.h:83
std::string siteName
Tag name.
Definition: mallocTag.h:84
std::vector< CallStackInfo > capturedCallStacks
The captured malloc stacks.
Definition: mallocTag.h:157
size_t nBytes
Allocated bytes by this or descendant nodes.
Definition: mallocTag.h:81
TF_API void Report(std::ostream &out) const
This is an overloaded member function, provided for convenience. It differs from the above function o...
size_t nBytesDirect
Allocated bytes (only for this node).
Definition: mallocTag.h:82
std::string name
Tag name.
Definition: mallocTag.h:98
PrintSetting
Specify which parts of the report to print.
Definition: mallocTag.h:105
@ BOTH
Print both tree and call sites.
Definition: mallocTag.h:108
@ TREE
Print the full call tree.
Definition: mallocTag.h:106
@ CALLSITES
Print just the call sites > 0.1%.
Definition: mallocTag.h:107
PathNode root
Root node of the call-site hierarchy.
Definition: mallocTag.h:154
TF_API void Report(std::ostream &out, const std::string &rootName) const
Generates a report to the ostream out.
std::vector< CallSite > callSites
All call sites.
Definition: mallocTag.h:151
Record of the bytes allocated under each different tag.
Definition: mallocTag.h:97
Node in the call tree structure.
Definition: mallocTag.h:80