17 #ifndef __TBB__flow_graph_cache_impl_H 18 #define __TBB__flow_graph_cache_impl_H 20 #ifndef __TBB_flow_graph_H 21 #error Do not #include this internal file directly; use public TBB headers instead. 29 template<
typename T,
typename M=spin_mutex >
49 if ( &
s == &n )
return;
55 while( !
my_q.empty()) (
void)
my_q.pop();
56 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 57 my_built_predecessors.clear();
61 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 62 typedef edge_container<T> built_predecessors_type;
63 built_predecessors_type &built_predecessors() {
return my_built_predecessors; }
65 typedef typename edge_container<T>::edge_list_type predecessor_list_type;
66 void internal_add_built_predecessor( T &n ) {
68 my_built_predecessors.add_edge(n);
71 void internal_delete_built_predecessor( T &n ) {
73 my_built_predecessors.delete_edge(n);
76 void copy_predecessors( predecessor_list_type &v) {
78 my_built_predecessors.copy_edges(v);
81 size_t predecessor_count() {
83 return (
size_t)(my_built_predecessors.edge_count());
92 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 93 built_predecessors_type my_built_predecessors;
121 template<
typename T,
typename M=spin_mutex >
122 #if __TBB_PREVIEW_ASYNC_MSG 124 class predecessor_cache :
public node_cache< untyped_sender, M > {
127 #endif // __TBB_PREVIEW_ASYNC_MSG 131 #if __TBB_PREVIEW_ASYNC_MSG 137 #endif // __TBB_PREVIEW_ASYNC_MSG 158 msg = src->try_get( v );
163 src->register_successor( *
my_owner );
168 }
while ( msg ==
false );
181 src->register_successor( *
my_owner );
188 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 196 template<
typename T,
typename M=spin_mutex >
201 #if __TBB_PREVIEW_ASYNC_MSG 207 #endif // __TBB_PREVIEW_ASYNC_MSG 225 msg = reserved_src->try_reserve( v );
230 reserved_src->register_successor( *this->
my_owner );
234 this->
add( *reserved_src );
236 }
while ( msg ==
false );
243 reserved_src->try_release( );
250 reserved_src->try_consume( );
272 template<
typename T,
typename M=spin_rw_mutex >
279 #if __TBB_PREVIEW_ASYNC_MSG 287 #endif // __TBB_PREVIEW_ASYNC_MSG 289 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 290 edge_container<successor_type> my_built_successors;
297 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 298 typedef typename edge_container<successor_type>::edge_list_type successor_list_type;
300 edge_container<successor_type> &built_successors() {
return my_built_successors; }
303 typename mutex_type::scoped_lock l(
my_mutex,
true);
304 my_built_successors.add_edge( r );
308 typename mutex_type::scoped_lock l(
my_mutex,
true);
309 my_built_successors.delete_edge(r);
312 void copy_successors( successor_list_type &v) {
313 typename mutex_type::scoped_lock l(
my_mutex,
false);
314 my_built_successors.copy_edges(v);
317 size_t successor_count() {
318 typename mutex_type::scoped_lock l(
my_mutex,
false);
319 return my_built_successors.edge_count();
331 typename mutex_type::scoped_lock l(
my_mutex,
true);
332 my_successors.push_back( &r );
336 typename mutex_type::scoped_lock l(
my_mutex,
true);
337 for (
typename successors_type::iterator i = my_successors.begin();
338 i != my_successors.end(); ++i ) {
340 my_successors.erase(i);
347 typename mutex_type::scoped_lock l(
my_mutex,
false);
348 return my_successors.empty();
352 my_successors.clear();
353 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 354 my_built_successors.clear();
358 #if !__TBB_PREVIEW_ASYNC_MSG 359 virtual task * try_put_task(
const T &t ) = 0;
360 #endif // __TBB_PREVIEW_ASYNC_MSG 371 #if __TBB_PREVIEW_ASYNC_MSG 377 #endif // __TBB_PREVIEW_ASYNC_MSG 380 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 381 edge_container<successor_type> my_built_successors;
382 typedef edge_container<successor_type>::edge_list_type successor_list_type;
389 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 391 edge_container<successor_type> &built_successors() {
return my_built_successors; }
394 mutex_type::scoped_lock l(
my_mutex,
true);
395 my_built_successors.add_edge( r );
399 mutex_type::scoped_lock l(
my_mutex,
true);
400 my_built_successors.delete_edge(r);
403 void copy_successors( successor_list_type &v) {
404 mutex_type::scoped_lock l(
my_mutex,
false);
405 my_built_successors.copy_edges(v);
408 size_t successor_count() {
409 mutex_type::scoped_lock l(
my_mutex,
false);
410 return my_built_successors.edge_count();
422 mutex_type::scoped_lock l(
my_mutex,
true);
423 my_successors.push_back( &r );
424 if (
my_owner && r.is_continue_receiver() ) {
425 r.register_predecessor( *
my_owner );
430 mutex_type::scoped_lock l(
my_mutex,
true);
431 for ( successors_type::iterator i = my_successors.begin();
432 i != my_successors.end(); ++i ) {
438 my_successors.erase(i);
445 mutex_type::scoped_lock l(
my_mutex,
false);
446 return my_successors.empty();
450 my_successors.clear();
451 #if TBB_DEPRECATED_FLOW_NODE_EXTRACTION 452 my_built_successors.clear();
456 #if !__TBB_PREVIEW_ASYNC_MSG 457 virtual task * try_put_task(
const continue_msg &t ) = 0;
458 #endif // __TBB_PREVIEW_ASYNC_MSG 464 template<
typename T,
typename M=spin_rw_mutex>
474 #if __TBB_PREVIEW_ASYNC_MSG 476 task * try_put_task(
const X &t ) {
479 #endif // __TBB_PREVIEW_ASYNC_MSG 480 task * last_task = NULL;
481 bool upgraded =
true;
482 typename mutex_type::scoped_lock l(this->my_mutex, upgraded);
483 typename successors_type::iterator i = this->my_successors.begin();
484 while ( i != this->my_successors.end() ) {
485 task *new_task = (*i)->try_put_task(t);
487 graph& graph_ref = (*i)->graph_reference();
493 if ( (*i)->register_predecessor(*this->my_owner) ) {
495 l.upgrade_to_writer();
498 i = this->my_successors.erase(i);
511 template<
typename T,
typename M=spin_rw_mutex >
522 typename mutex_type::scoped_lock l(this->my_mutex,
false);
523 return this->my_successors.size();
526 #if __TBB_PREVIEW_ASYNC_MSG 528 task * try_put_task(
const X &t ) {
531 #endif // __TBB_PREVIEW_ASYNC_MSG 532 bool upgraded =
true;
533 typename mutex_type::scoped_lock l(this->my_mutex, upgraded);
534 typename successors_type::iterator i = this->my_successors.begin();
535 while ( i != this->my_successors.end() ) {
536 task *new_task = (*i)->try_put_task(t);
540 if ( (*i)->register_predecessor(*this->my_owner) ) {
542 l.upgrade_to_writer();
545 i = this->my_successors.erase(i);
558 #endif // __TBB__flow_graph_cache_impl_H void set_owner(successor_type *owner)
spin_rw_mutex_v3 spin_rw_mutex
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task * task
sender< T > predecessor_type
void remove_successor(successor_type &r)
void const char const char int ITT_FORMAT __itt_group_sync s
A node_cache maintains a std::queue of elements of type T. Each operation is protected by a lock.
reservable_predecessor_cache()
virtual ~successor_cache()
task * try_put_task(const T &t) __TBB_override
std::list< pointer_type > successors_type
bool get_item(output_type &v)
sender< output_type > predecessor_type
void set_owner(sender< continue_msg > *owner)
A cache of successors that are broadcast to.
Base class for types that should not be copied or assigned.
void register_successor(successor_type &r)
successor_type * my_owner
successors_type my_successors
An cache of predecessors that supports requests and reservations.
receiver< T > successor_type
task * try_put_task(const T &t) __TBB_override
successor_cache< T, M >::successors_type successors_type
A cache of predecessors that only supports try_get.
bool try_reserve(output_type &v)
size_type internal_size()
void remove_successor(successor_type &r)
void set_owner(owner_type *owner)
virtual ~successor_cache()
A cache of successors that are put in a round-robin fashion.
receiver< continue_msg > successor_type
An abstract cache of successors.
successor_cache< T, M >::successors_type successors_type
predecessor_type * reserved_src
successors_type my_successors
receiver< output_type > * pointer_type
sender< continue_msg > * my_owner
receiver< continue_msg > * pointer_type
receiver< T > successor_type
std::list< pointer_type > successors_type
void register_successor(successor_type &r)
void const char const char int ITT_FORMAT __itt_group_sync x void const char ITT_FORMAT __itt_group_sync s void ITT_FORMAT __itt_group_sync p void ITT_FORMAT p void ITT_FORMAT p no args __itt_suppress_mode_t unsigned int void size_t ITT_FORMAT d void ITT_FORMAT p void ITT_FORMAT p __itt_model_site __itt_model_site_instance ITT_FORMAT p __itt_model_task __itt_model_task_instance ITT_FORMAT p void * lock
static tbb::task * combine_tasks(graph &g, tbb::task *left, tbb::task *right)
sender< output_type > owner_type
receiver< output_type > successor_type