HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
scopeDescription.h
Go to the documentation of this file.
1 //
2 // Copyright 2016 Pixar
3 //
4 // Licensed under the terms set forth in the LICENSE.txt file available at
5 // https://openusd.org/license.
6 //
7 #ifndef PXR_BASE_TF_SCOPE_DESCRIPTION_H
8 #define PXR_BASE_TF_SCOPE_DESCRIPTION_H
9 
10 #include "pxr/pxr.h"
11 
14 #include "pxr/base/tf/api.h"
15 
16 #include <optional>
17 #include <vector>
18 #include <string>
19 
21 
22 /// \file tf/scopeDescription.h
23 
24 /// \class TfScopeDescription
25 ///
26 /// This class is used to provide high-level descriptions about scopes of
27 /// execution that could possibly block, or to provide relevant information
28 /// about high-level action that would be useful in a crash report.
29 ///
30 /// The TF_DESCRIBE_SCOPE() macro provides a convenient way to annotate a
31 /// given scope:
32 ///
33 /// \code
34 /// void OpenManyFiles() {
35 /// TF_DESCRIBE_SCOPE("Opening many files");
36 ///
37 /// for (auto path : manyPaths) {
38 /// TF_DESCRIBE_SCOPE("Opening file: %s", path.c_str());
39 ///
40 /// // do potentially expensive file operations ...
41 /// }
42 /// }
43 /// \endcode
44 ///
45 /// This class is reasonably fast to use, especially if the message strings are
46 /// not dynamically created, however it should not be used in very highly
47 /// performance sensitive contexts. The cost to push & pop is essentially a TLS
48 /// lookup plus a couple of atomic operations.
50 {
51  TfScopeDescription() = delete;
52  TfScopeDescription(TfScopeDescription const &) = delete;
53  TfScopeDescription &operator=(TfScopeDescription const &) = delete;
54 public:
55  /// Construct with a description. Push \a description on the stack of
56  /// descriptions for this thread. Caller guarantees that the string
57  /// \p description lives at least as long as this TfScopeDescription object.
58  TF_API explicit
59  TfScopeDescription(std::string const &description,
60  TfCallContext const &context = TfCallContext());
61 
62  /// Construct with a description. Push \a description on the stack of
63  /// descriptions for this thread. This object adopts ownership of the
64  /// rvalue \p description.
65  TF_API explicit
66  TfScopeDescription(std::string &&description,
67  TfCallContext const &context = TfCallContext());
68 
69  /// Construct with a description. Push \a description on the stack of
70  /// descriptions for this thread. Caller guarantees that the string
71  /// \p description lives at least as long as this TfScopeDescription object.
72  TF_API explicit
73  TfScopeDescription(char const *description,
74  TfCallContext const &context = TfCallContext());
75 
76  /// Destructor.
77  /// Pop the description stack in this thread.
79 
80  /// Replace the description stack entry for this scope description. Caller
81  /// guarantees that the string \p description lives at least as long as this
82  /// TfScopeDescription object.
83  TF_API void SetDescription(std::string const &description);
84 
85  /// Replace the description stack entry for this scope description. This
86  /// object adopts ownership of the rvalue \p description.
87  TF_API void SetDescription(std::string &&description);
88 
89  /// Replace the description stack entry for this scope description. Caller
90  /// guarantees that the string \p description lives at least as long as this
91  /// TfScopeDescription object.
92  TF_API void SetDescription(char const *description);
93 
94 private:
95  friend inline TfScopeDescription *
96  Tf_GetPreviousScopeDescription(TfScopeDescription *d) {
97  return d->_prev;
98  }
99  friend inline char const *
100  Tf_GetScopeDescriptionText(TfScopeDescription *d) {
101  return d->_description;
102  }
103  friend inline TfCallContext const &
104  Tf_GetScopeDescriptionContext(TfScopeDescription *d) {
105  return d->_context;
106  }
107 
108  inline void _Push();
109  inline void _Pop() const;
110 
111  std::optional<std::string> _ownedString;
112  char const *_description;
113  TfCallContext _context;
114  void *_localStack;
115  TfScopeDescription *_prev; // link to parent scope.
116 };
117 
118 /// Return a copy of the current description stack for the "main" thread as
119 /// identified by ArchGetMainThreadId() as a vector of strings. The most
120 /// recently pushed description is at back(), and the least recently pushed
121 /// description is at front().
122 TF_API std::vector<std::string>
124 
125 /// Return a copy of the current description stack for the current thread of
126 /// execution as a vector of strings. The most recently pushed description is
127 /// at back(), and the least recently pushed description is at front().
128 TF_API std::vector<std::string>
130 
131 /// Convenience macro for annotating the current scope with a description.
132 /// This macro accepts either a single string, or printf-style arguments and
133 /// creates a scope description local variable with the resulting string.
134 ///
135 /// \hideinitializer
136 #define TF_DESCRIBE_SCOPE(...) \
137  TfScopeDescription __scope_description__ \
138  (Tf_DescribeScopeFormat(__VA_ARGS__), TF_CALL_CONTEXT); \
139 
140 template <typename... Args>
141 inline std::string
142 Tf_DescribeScopeFormat(const char* fmt, Args&&... args) {
143  return TfStringPrintf(fmt, std::forward<Args>(args)...);
144 }
145 
146 // If there are no formatting arguments, the string can be forwarded to the
147 // scope description constructor. In C++17, consider if std::string_view could
148 // reduce the need for as many of these overloads
149 inline const char*
150 Tf_DescribeScopeFormat(const char* fmt) { return fmt; }
151 
152 inline std::string&&
153 Tf_DescribeScopeFormat(std::string&& fmt) { return std::move(fmt); }
154 
155 inline const std::string&
156 Tf_DescribeScopeFormat(const std::string& fmt) { return fmt; }
157 
159 
160 #endif // PXR_BASE_TF_SCOPE_DESCRIPTION_H
TF_API std::string TfStringPrintf(const char *fmt,...)
TF_API void SetDescription(std::string const &description)
friend TfScopeDescription * Tf_GetPreviousScopeDescription(TfScopeDescription *d)
#define TF_API
Definition: api.h:23
TF_API ~TfScopeDescription()
friend TfCallContext const & Tf_GetScopeDescriptionContext(TfScopeDescription *d)
TF_API std::vector< std::string > TfGetCurrentScopeDescriptionStack()
friend char const * Tf_GetScopeDescriptionText(TfScopeDescription *d)
std::string Tf_DescribeScopeFormat(const char *fmt, Args &&...args)
PXR_NAMESPACE_CLOSE_SCOPE PXR_NAMESPACE_OPEN_SCOPE
Definition: path.h:1425
TF_API std::vector< std::string > TfGetThisThreadScopeDescriptionStack()
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:74
**If you just want to fire and args
Definition: thread.h:618