HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
UT_TaskScope.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: UT_TaskScope.h (UT Library, C++)
7  *
8  * COMMENTS:
9  *
10  */
11 
12 #ifndef __UT_TASKSCOPE_H_INCLUDED__
13 #define __UT_TASKSCOPE_H_INCLUDED__
14 
15 #include "UT_API.h"
16 #include "UT_Debug.h"
17 #include "UT_NonCopyable.h"
18 #include "UT_SmallObject.h"
19 #include "UT_Thread.h"
20 #include "UT_ThreadSpecificValue.h"
21 #include "UT_Performance.h"
22 
23 // Set the following line to #if 1 to enable debug message output
24 #if 0
25  #define UT_TASKSCOPE_DBG(ZZ) UT_DBGOUT(ZZ)
26 #else
27  #define UT_TASKSCOPE_DBG(ZZ)
28 #endif
29 
30 // Invalid Task ID
31 #define UT_INVALID_TASK_ID 0
32 
33 // Forward declarations
34 class UT_TaskScope;
35 template <typename T> class UT_ValArray;
36 
37 /// Array of UT_TaskScope pointers
39 
40 /// Scope object which defines a thread task, maintaining a parent-child
41 /// hierarchy.
42 class UT_API UT_TaskScope : public UT_SmallObject<UT_TaskScope>, UT_NonCopyable
43 {
44 public:
45  explicit UT_TaskScope(const UT_TaskScope *parent, int thread)
46  : myParent(parent)
47  {
48  myThreadId = thread;
49  myOldTaskScope = theTaskScope.getValueForThread(myThreadId);
50  theTaskScope.getValueForThread(myThreadId) = this;
51  UT_TASKSCOPE_DBG(("Task %p parent %p thread %d",
52  this, parent, myThreadId));
53 
54  // Notify the performance monitor that a threaded task has started.
56  myPerfMonEventId = UT_PERFMON_INVALID_ID;
57  if (perf->isRecordingThreadStats())
58  myPerfMonEventId = perf->startTaskScope(this);
59  }
60  explicit UT_TaskScope(const UT_TaskScope *parent)
61  : myParent(parent)
62  {
63  myThreadId = SYSgetSTID();
64  myOldTaskScope = theTaskScope.getValueForThread(myThreadId);
65  theTaskScope.getValueForThread(myThreadId) = this;
66  UT_TASKSCOPE_DBG(("Task %p parent %p thread %d",
67  this, parent, myThreadId));
68 
69  // Notify the performance monitor that a threaded task has started.
71  myPerfMonEventId = UT_PERFMON_INVALID_ID;
72  if (perf->isRecordingThreadStats())
73  myPerfMonEventId = perf->startTaskScope(this);
74  }
76  {
77  // Notify the performance monitor that a threaded task has ended.
78  if (myPerfMonEventId != UT_PERFMON_INVALID_ID)
79  UTgetPerformance()->stopTaskScope(this, myPerfMonEventId);
80 
81  theTaskScope.getValueForThread(SYSgetSTID()) = myOldTaskScope;
82  UT_TASKSCOPE_DBG(("Task %p parent %p ended", this, myParent));
83  }
84 
85  /// Return the parent of this task scope
86  const UT_TaskScope * getParent() const { return myParent; }
87 
88  /// Return the id of the assigned thread.
89  int getThreadId() const { return myThreadId; }
90 
91  /// Obtain the current task scope from thread local storage.
92  /// @note The return value is NULL if there is no current task scope.
93  // @{
94  static const UT_TaskScope * getCurrent(int thread)
95  {
96  return theTaskScope.getValueForThread(thread);
97  }
98  static const UT_TaskScope * getCurrent()
99  {
100  return getCurrent(SYSgetSTID());
101  }
102  // @}
103 
104  /// Obtain the current task scope from thread local storage, creating one
105  /// if there is none.
106  // @{
107  static const UT_TaskScope & getOrCreateCurrent(int thread)
108  {
109  const UT_TaskScope * &task = theTaskScope.getValueForThread(thread);
110 
111  if (task == NULL)
112  task = new UT_TaskScope(NULL, thread);
113  return *task;
114  }
116  {
117  return getOrCreateCurrent(SYSgetSTID());
118  }
119  // @}
120 
121  /// Obtain the root task scope from thread local storage, creating one
122  /// if there is none.
123  // @{
124  static const UT_TaskScope & getOrCreateRoot(int thread)
125  {
126  const UT_TaskScope * &task = theTaskScope.getValueForThread(thread);
127 
128  if (task == NULL)
129  task = new UT_TaskScope(NULL, thread);
130 
131  const UT_TaskScope *root = task;
132 
133  while (root->getParent())
134  root = root->getParent();
135  return *root;
136  }
137  static const UT_TaskScope & getOrCreateRoot()
138  {
139  return getOrCreateRoot(SYSgetSTID());
140  }
141  // @}
142 
143  /// Test if the given task scope is an ancestor of ours
144  bool isAncestor(const UT_TaskScope &parent) const
145  {
146  for (const UT_TaskScope *task = getParent();
147  task != NULL; task = task->getParent())
148  {
149  if (task == &parent)
150  return true;
151  }
152  return false;
153  }
154 
155 private:
156  const UT_TaskScope * myParent;
157  const UT_TaskScope * myOldTaskScope;
158  int myThreadId;
159  int myPerfMonEventId;
160 
161  typedef UT_ThreadSpecificValue<const UT_TaskScope *> ut_TaskScopeTLS;
162  static ut_TaskScopeTLS theTaskScope;
163 };
164 
165 #endif // __UT_TASKSCOPE_H_INCLUDED__
static const UT_TaskScope & getOrCreateCurrent()
Definition: UT_TaskScope.h:115
UT_API UT_Performance * UTgetPerformance(bool create=true)
static const UT_TaskScope * getCurrent()
Definition: UT_TaskScope.h:98
static const UT_TaskScope * getCurrent(int thread)
Definition: UT_TaskScope.h:94
#define UT_API
Definition: UT_API.h:12
#define UT_TASKSCOPE_DBG(ZZ)
Definition: UT_TaskScope.h:27
int getThreadId() const
Return the id of the assigned thread.
Definition: UT_TaskScope.h:89
static const UT_TaskScope & getOrCreateRoot()
Definition: UT_TaskScope.h:137
const UT_TaskScope * getParent() const
Return the parent of this task scope.
Definition: UT_TaskScope.h:86
UT_TaskScope(const UT_TaskScope *parent, int thread)
Definition: UT_TaskScope.h:45
#define UT_PERFMON_INVALID_ID
virtual int startTaskScope(const UT_TaskScope *task_scope)
static const UT_TaskScope & getOrCreateRoot(int thread)
Definition: UT_TaskScope.h:124
UT_ValArray< const UT_TaskScope * > UT_TaskScopePtrArray
Array of UT_TaskScope pointers.
Definition: UT_TaskScope.h:35
bool isAncestor(const UT_TaskScope &parent) const
Test if the given task scope is an ancestor of ours.
Definition: UT_TaskScope.h:144
SYS_API int SYSgetSTID()
virtual void stopTaskScope(const UT_TaskScope *task_scope, int event_id)
UT_TaskScope(const UT_TaskScope *parent)
Definition: UT_TaskScope.h:60
static const UT_TaskScope & getOrCreateCurrent(int thread)
Definition: UT_TaskScope.h:107
bool isRecordingThreadStats() const
Return true if Houdini is recording thread stats.