Intel(R) Threading Building Blocks Doxygen Documentation  version 4.2.3
observer_proxy.h
Go to the documentation of this file.
1 /*
2  Copyright (c) 2005-2019 Intel Corporation
3 
4  Licensed under the Apache License, Version 2.0 (the "License");
5  you may not use this file except in compliance with the License.
6  You may obtain a copy of the License at
7 
8  http://www.apache.org/licenses/LICENSE-2.0
9 
10  Unless required by applicable law or agreed to in writing, software
11  distributed under the License is distributed on an "AS IS" BASIS,
12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  See the License for the specific language governing permissions and
14  limitations under the License.
15 
16 
17 
18 
19 */
20 
21 #ifndef _TBB_observer_proxy_H
22 #define _TBB_observer_proxy_H
23 
24 #if __TBB_SCHEDULER_OBSERVER
25 
26 #include "scheduler_common.h" // to include task.h
28 #include "tbb/spin_rw_mutex.h"
29 #include "tbb/aligned_space.h"
30 
31 namespace tbb {
32 namespace internal {
33 
34 class observer_list {
35  friend class arena;
36 
37  // Mutex is wrapped with aligned_space to shut up warnings when its destructor
38  // is called while threads are still using it.
39  typedef aligned_space<spin_rw_mutex> my_mutex_type;
40 
42  observer_proxy* my_head;
43 
45  observer_proxy* my_tail;
46 
48  my_mutex_type my_mutex;
49 
51  arena* my_arena;
52 
54 
55  inline static void remove_ref_fast( observer_proxy*& p );
56 
58  void do_notify_entry_observers( observer_proxy*& last, bool worker );
59 
61  void do_notify_exit_observers( observer_proxy* last, bool worker );
62 
63 public:
64  observer_list () : my_head(NULL), my_tail(NULL) {}
65 
67 
68  void clear ();
69 
71  void insert ( observer_proxy* p );
72 
74  void remove ( observer_proxy* p );
75 
77 
78  void remove_ref( observer_proxy* p );
79 
81  typedef spin_rw_mutex::scoped_lock scoped_lock;
82 
84  spin_rw_mutex& mutex () { return my_mutex.begin()[0]; }
85 
86  bool empty () const { return my_head == NULL; }
87 
89 
91  inline void notify_entry_observers( observer_proxy*& last, bool worker );
92 
94  inline void notify_exit_observers( observer_proxy*& last, bool worker );
95 
97  bool ask_permission_to_leave();
98 }; // class observer_list
99 
101 
104 class observer_proxy {
105  friend class task_scheduler_observer_v3;
106  friend class observer_list;
108 
111  atomic<int> my_ref_count;
113  observer_list* my_list;
115 
116  observer_proxy* my_next;
118 
119  observer_proxy* my_prev;
121  task_scheduler_observer_v3* my_observer;
123  char my_version;
124 
125 #if __TBB_ARENA_OBSERVER || __TBB_SLEEP_PERMISSION
126  interface6::task_scheduler_observer* get_v6_observer();
127 #endif
128 #if __TBB_ARENA_OBSERVER
129  bool is_global(); //TODO: move them back inline when un-CPF'ing
130 #endif
131 
133  observer_proxy( task_scheduler_observer_v3& );
134 
135 #if TBB_USE_ASSERT
136  ~observer_proxy();
137 #endif /* TBB_USE_ASSERT */
138 
140  observer_proxy& operator = ( const observer_proxy& );
141 }; // class observer_proxy
142 
143 inline void observer_list::remove_ref_fast( observer_proxy*& p ) {
144  if( p->my_observer ) {
145  // Can decrement refcount quickly, as it cannot drop to zero while under the lock.
146  int r = --p->my_ref_count;
147  __TBB_ASSERT_EX( r, NULL );
148  p = NULL;
149  } else {
150  // Use slow form of refcount decrementing, after the lock is released.
151  }
152 }
153 
154 inline void observer_list::notify_entry_observers( observer_proxy*& last, bool worker ) {
155  if ( last == my_tail )
156  return;
157  do_notify_entry_observers( last, worker );
158 }
159 
160 inline void observer_list::notify_exit_observers( observer_proxy*& last, bool worker ) {
161  if ( !last )
162  return;
163  __TBB_ASSERT(is_alive((uintptr_t)last), NULL);
164  do_notify_exit_observers( last, worker );
165  __TBB_ASSERT(last, NULL);
166  poison_value(last);
167 }
168 
169 extern padded<observer_list> the_global_observer_list;
170 
171 } // namespace internal
172 } // namespace tbb
173 
174 #endif /* __TBB_SCHEDULER_OBSERVER */
175 
176 #endif /* _TBB_observer_proxy_H */
tbb::internal::task_scheduler_observer_v3 task_scheduler_observer
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:169
#define __TBB_ASSERT_EX(predicate, comment)
"Extended" version is useful to suppress warnings if a variable is only used with an assert ...
Definition: tbb_stddef.h:171
void const char const char int ITT_FORMAT __itt_group_sync p
#define poison_value(g)
auto last(Container &c) -> decltype(begin(c))
The graph class.
spin_rw_mutex_v3 spin_rw_mutex
Definition: spin_rw_mutex.h:37

Copyright © 2005-2019 Intel Corporation. All Rights Reserved.

Intel, Pentium, Intel Xeon, Itanium, Intel XScale and VTune are registered trademarks or trademarks of Intel Corporation or its subsidiaries in the United States and other countries.

* Other names and brands may be claimed as the property of others.