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>, 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.
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 
81  /// Return the parent of this task scope
82  const UT_TaskScope * getParent() const { return myParent; }
83 
84  /// Return the id of the assigned thread.
85  int getThreadId() const { return myThreadId; }
86 
87  /// Obtain the current task scope from thread local storage.
88  /// @note The return value is NULL if there is no current task scope.
89  // @{
90  static const UT_TaskScope * getCurrent(int thread)
91  {
92  return theTaskScope.getValueForThread(thread);
93  }
94  static const UT_TaskScope * getCurrent()
95  {
96  return getCurrent(SYSgetSTID());
97  }
98  // @}
99 
100  /// Obtain the current task scope from thread local storage, creating one
101  /// if there is none.
102  // @{
103  static const UT_TaskScope & getOrCreateCurrent(int thread)
104  {
105  const UT_TaskScope * &task = theTaskScope.getValueForThread(thread);
106 
107  if (task == NULL)
108  task = new UT_TaskScope(NULL, thread);
109  return *task;
110  }
112  {
113  return getOrCreateCurrent(SYSgetSTID());
114  }
115  // @}
116 
117  /// Obtain the root task scope from thread local storage, creating one
118  /// if there is none.
119  // @{
120  static const UT_TaskScope & getOrCreateRoot(int thread)
121  {
122  const UT_TaskScope * &task = theTaskScope.getValueForThread(thread);
123 
124  if (task == NULL)
125  task = new UT_TaskScope(NULL, thread);
126 
127  const UT_TaskScope *root = task;
128 
129  while (root->getParent())
130  root = root->getParent();
131  return *root;
132  }
133  static const UT_TaskScope & getOrCreateRoot()
134  {
135  return getOrCreateRoot(SYSgetSTID());
136  }
137  // @}
138 
139  /// Test if the given task scope is an ancestor of ours
140  bool isAncestor(const UT_TaskScope &parent) const
141  {
142  for (const UT_TaskScope *task = getParent();
143  task != NULL; task = task->getParent())
144  {
145  if (task == &parent)
146  return true;
147  }
148  return false;
149  }
150 
151 private:
152  const UT_TaskScope * myParent;
153  const UT_TaskScope * myOldTaskScope;
154  int myThreadId;
155  int myPerfMonEventId;
156 
157  typedef UT_ThreadSpecificValue<const UT_TaskScope *> ut_TaskScopeTLS;
158  static ut_TaskScopeTLS theTaskScope;
159 };
160 
161 #endif // __UT_TASKSCOPE_H_INCLUDED__
static const UT_TaskScope & getOrCreateCurrent()
Definition: UT_TaskScope.h:111
static const UT_TaskScope * getCurrent()
Definition: UT_TaskScope.h:94
UT_API void UTperformanceStopTaskScope(const UT_TaskScope *task_scope, int event_id)
static const UT_TaskScope * getCurrent(int thread)
Definition: UT_TaskScope.h:90
#define UT_API
Definition: UT_API.h:13
#define UT_TASKSCOPE_DBG(ZZ)
Definition: UT_TaskScope.h:27
int getThreadId() const
Return the id of the assigned thread.
Definition: UT_TaskScope.h:85
static const UT_TaskScope & getOrCreateRoot()
Definition: UT_TaskScope.h:133
const UT_TaskScope * getParent() const
Return the parent of this task scope.
Definition: UT_TaskScope.h:82
UT_TaskScope(const UT_TaskScope *parent, int thread)
Definition: UT_TaskScope.h:45
static const UT_TaskScope & getOrCreateRoot(int thread)
Definition: UT_TaskScope.h:120
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:140
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:103