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 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_SCOPE_DESCRIPTION_H
25 #define PXR_BASE_TF_SCOPE_DESCRIPTION_H
26 
27 #include "pxr/pxr.h"
28 
31 #include "pxr/base/tf/api.h"
32 
33 #include <optional>
34 #include <vector>
35 #include <string>
36 
38 
39 /// \class TfScopeDescription
40 ///
41 /// This class is used to provide high-level descriptions about scopes of
42 /// execution that could possibly block, or to provide relevant information
43 /// about high-level action that would be useful in a crash report.
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 /// Macro that accepts either a single string, or printf-style arguments and
132 /// creates a scope description local variable with the resulting string.
133 #define TF_DESCRIBE_SCOPE(...) \
134  TfScopeDescription __scope_description__ \
135  (Tf_DescribeScopeFormat(__VA_ARGS__), TF_CALL_CONTEXT); \
136 
137 template <typename... Args>
138 inline std::string
139 Tf_DescribeScopeFormat(const char* fmt, Args&&... args) {
140  return TfStringPrintf(fmt, std::forward<Args>(args)...);
141 }
142 
143 // If there are no formatting arguments, the string can be forwarded to the
144 // scope description constructor. In C++17, consider if std::string_view could
145 // reduce the need for as many of these overloads
146 inline const char*
147 Tf_DescribeScopeFormat(const char* fmt) { return fmt; }
148 
149 inline std::string&&
150 Tf_DescribeScopeFormat(std::string&& fmt) { return std::move(fmt); }
151 
152 inline const std::string&
153 Tf_DescribeScopeFormat(const std::string& fmt) { return fmt; }
154 
156 
157 #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:40
TF_API ~TfScopeDescription()
GLsizei const GLchar *const * string
Definition: glcorearb.h:814
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:1432
TF_API std::vector< std::string > TfGetThisThreadScopeDescriptionStack()
#define PXR_NAMESPACE_CLOSE_SCOPE
Definition: pxr.h:91
**If you just want to fire and args
Definition: thread.h:609