HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
EXPR_Lock.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: EXPR_Lock.h (EXPR Library, C++)
7  *
8  * COMMENTS: This header allows us to enable/disable locking when evaluating
9  * parameters and hscript expressions.
10  */
11 
12 #ifndef __EXPR_LOCK_H_INCLUDED__
13 #define __EXPR_LOCK_H_INCLUDED__
14 
15 #include "EXPR_API.h"
16 
17 #include <UT/UT_LockUtil.h>
18 #include <UT/UT_TaskLock.h>
19 #include <UT/UT_TBBSpinLock.h>
20 #include <SYS/SYS_AtomicInt.h>
21 #include <SYS/SYS_Types.h>
22 
23 // Modify this to enable/disable parm expr locking
24 #define EXPR_LOCKS 1
25 
26 #if H_BUILD_PARALLEL_COOK_MODE
27 class EXPR_API EXPR_StaticLock : private UT_TaskLock
28 {
29 public:
30 
31  /// Performs the functor F while inside this lock scope in UT_TaskArena.
32  /// This method allows the optimization that if we're calling this while
33  /// the lock is already held in the same task scope, then we can avoid
34  /// creating an unnecessary task arena.
35  template <typename F>
36  void
37  lockedExecute(const F &functor)
38  {
39  theStaticCounter.add(1);
40 
41  if (theIsDisabled)
42  {
43  functor();
44  }
45  else
46  {
47  bool was_first = false;
48  (void) UT_TaskLock::lock(was_first);
49  if (!was_first)
50  {
51  functor();
52  }
53  else
54  {
55  UT_TaskArena arena;
56  arena.execute(functor);
57  }
59  }
60  }
61 
62  /// Performs the functor F while inside this lock scope in UT_TaskArena.
63  /// This method allows the optimization that if we're calling this while
64  /// the lock is already held in the same task scope, then we can avoid
65  /// creating an unnecessary task arena.
66  template <typename F>
67  void
68  lockedExecute(const F &functor, UT_TaskArena &arena)
69  {
70  theStaticCounter.add(1);
71 
72  if (theIsDisabled)
73  {
74  functor();
75  }
76  else
77  {
78  bool was_first = false;
79  (void) UT_TaskLock::lock(was_first);
80  if (!was_first)
81  {
82  functor();
83  }
84  else
85  {
86  arena.execute(functor);
87  }
89  }
90  }
91 
92  /// Performs the functor F while inside this lock scope OUTSIDE an arena.
93  /// @note Only do this if you know functor will never spawn tasks!
94  template <typename F>
95  void
96  lockedExecuteWithoutArena(const F &functor)
97  {
98  theStaticCounter.add(1);
99 
100  if (theIsDisabled)
101  {
102  functor();
103  }
104  else
105  {
107  functor();
109  }
110  }
111 
112  using UT_TaskLock::hasLock;
113 
114  static SYS_AtomicCounter theStaticCounter;
115  static bool theIsDisabled;
116 };
117 #else
119 #endif
120 
121 #if EXPR_LOCKS
124 #else
125  typedef UT_NullLock EXPR_Lock;
127 #endif
128 
130 
131 /// The global evaluation lock is a global mutex for protecting any
132 /// non-threadsafe evaluation (both expressions and node) code. This is
133 /// necessary to guard against code that might access global objects.
135 
136 #endif // __EXPR_LOCK_H_INCLUDED__
EXPR_StaticLock EXPR_GlobalStaticLock
Definition: EXPR_Lock.h:123
void execute(F &functor)
Definition: UT_TaskArena.h:60
void
Definition: png.h:1083
UT_TBBSpinLock EXPR_Lock
Definition: EXPR_Lock.h:122
EXPR_Lock::Scope EXPR_AutoLock
Definition: EXPR_Lock.h:129
bool hasLock()
Definition: UT_TaskLock.h:266
UT_TaskLockWithArena EXPR_StaticLock
Definition: EXPR_Lock.h:118
UT_TaskLock that avoids deadlocks when used with TBB task scheduling.
Definition: UT_TaskLock.h:293
void unlock()
Definition: UT_TaskLock.h:261
EXPR_API EXPR_GlobalStaticLock & ev_GlobalEvalLock()
#define EXPR_API
Definition: EXPR_API.h:10