HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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_PerformanceThread.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>
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.
55  // It will return -1 if we don't need to be recording thread stats.
56  myPerfMonEventId = UTperformanceStartTaskScope(this);
57  }
58  explicit UT_TaskScope(const UT_TaskScope *parent)
59  : myParent(parent)
60  {
61  myThreadId = SYSgetSTID();
62  myOldTaskScope = theTaskScope.getValueForThread(myThreadId);
63  theTaskScope.getValueForThread(myThreadId) = this;
64  UT_TASKSCOPE_DBG(("Task %p parent %p thread %d",
65  this, parent, myThreadId));
66 
67  // Notify the performance monitor that a threaded task has started.
68  // It will return -1 if we don't need to be recording thread stats.
69  myPerfMonEventId = UTperformanceStartTaskScope(this);
70  }
72  {
73  // Notify the performance monitor that a threaded task has ended.
74  if (myPerfMonEventId >= 0)
75  UTperformanceStopTaskScope(this, myPerfMonEventId);
76 
77  theTaskScope.getValueForThread(SYSgetSTID()) = myOldTaskScope;
78  UT_TASKSCOPE_DBG(("Task %p parent %p ended", this, myParent));
79  }
80 
82 
83  /// Return the parent of this task scope
84  const UT_TaskScope * getParent() const { return myParent; }
85 
86  /// Return the id of the assigned thread.
87  int getThreadId() const { return myThreadId; }
88 
89  /// Obtain the current task scope from thread local storage.
90  /// @note The return value is NULL if there is no current task scope.
91  // @{
92  static const UT_TaskScope * getCurrent(int thread)
93  {
94  return theTaskScope.getValueForThread(thread);
95  }
96  static const UT_TaskScope * getCurrent()
97  {
98  return getCurrent(SYSgetSTID());
99  }
100  // @}
101 
102  /// Obtain the current task scope from thread local storage, creating one
103  /// if there is none.
104  // @{
106  {
107  const UT_TaskScope * &task = theTaskScope.getValueForThread(thread);
108 
109  if (task == NULL)
110  task = new UT_TaskScope(NULL, thread);
111  return *task;
112  }
114  {
115  return getOrCreateCurrent(SYSgetSTID());
116  }
117  // @}
118 
119  /// Obtain the root task scope from thread local storage, creating one
120  /// if there is none.
121  // @{
122  static const UT_TaskScope & getOrCreateRoot(int thread)
123  {
124  const UT_TaskScope * &task = theTaskScope.getValueForThread(thread);
125 
126  if (task == NULL)
127  task = new UT_TaskScope(NULL, thread);
128 
129  const UT_TaskScope *root = task;
130 
131  while (root->getParent())
132  root = root->getParent();
133  return *root;
134  }
135  static const UT_TaskScope & getOrCreateRoot()
136  {
137  return getOrCreateRoot(SYSgetSTID());
138  }
139  // @}
140 
141  /// Test if the given task scope is an ancestor of ours
142  bool isAncestor(const UT_TaskScope &parent) const
143  {
144  for (const UT_TaskScope *task = getParent();
145  task != NULL; task = task->getParent())
146  {
147  if (task == &parent)
148  return true;
149  }
150  return false;
151  }
152 
153 private:
154  const UT_TaskScope * myParent;
155  const UT_TaskScope * myOldTaskScope;
156  int myThreadId;
157  int myPerfMonEventId;
158 
159  typedef UT_ThreadSpecificValue<const UT_TaskScope *> ut_TaskScopeTLS;
160  static ut_TaskScopeTLS theTaskScope;
161 };
162 
163 #endif // __UT_TASKSCOPE_H_INCLUDED__
static const UT_TaskScope & getOrCreateCurrent()
Definition: UT_TaskScope.h:113
static const UT_TaskScope * getCurrent()
Definition: UT_TaskScope.h:96
UT_API void UTperformanceStopTaskScope(const UT_TaskScope *task_scope, int event_id)
static const UT_TaskScope * getCurrent(int thread)
Definition: UT_TaskScope.h:92
#define UT_API
Definition: UT_API.h:14
GU_API GA_Offset getParent(const GU_Detail *gdp, const GA_Offset &node)
#define UT_TASKSCOPE_DBG(ZZ)
Definition: UT_TaskScope.h:27
int getThreadId() const
Return the id of the assigned thread.
Definition: UT_TaskScope.h:87
static const UT_TaskScope & getOrCreateRoot()
Definition: UT_TaskScope.h:135
const UT_TaskScope * getParent() const
Return the parent of this task scope.
Definition: UT_TaskScope.h:84
UT_TaskScope(const UT_TaskScope *parent, int thread)
Definition: UT_TaskScope.h:45
#define UT_NON_COPYABLE(CLASS)
Define deleted copy constructor and assignment operator inside a class.
static const UT_TaskScope & getOrCreateRoot(int thread)
Definition: UT_TaskScope.h:122
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:142
**Note that the tasks the is the thread number *for the or if it s being executed by a non pool thread(this *can happen in cases where the whole pool is occupied and the calling *thread contributes to running the work load).**Thread pool.Have fun
SYS_API int SYSgetSTID()
UT_API int UTperformanceStartTaskScope(const UT_TaskScope *task_scope)
UT_TaskScope(const UT_TaskScope *parent)
Definition: UT_TaskScope.h:58
static const UT_TaskScope & getOrCreateCurrent(int thread)
Definition: UT_TaskScope.h:105