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 282 typedef untyped_sender owner_type;
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 typename mutex_type::scoped_lock l(
my_mutex,
true);
395 my_built_successors.add_edge( r );
399 typename mutex_type::scoped_lock l(
my_mutex,
true);
400 my_built_successors.delete_edge(r);
403 void copy_successors( successor_list_type &v) {
404 typename mutex_type::scoped_lock l(
my_mutex,
false);
405 my_built_successors.copy_edges(v);
408 size_t successor_count() {
409 typename mutex_type::scoped_lock l(
my_mutex,
false);
410 return my_built_successors.edge_count();
422 typename 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 typename 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 typename 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);
508 #if __TBB_PREVIEW_ASYNC_MSG 510 bool gather_successful_try_puts(
const X &t, task_list &tasks ) {
513 #endif // __TBB_PREVIEW_ASYNC_MSG 514 bool upgraded =
true;
515 bool is_at_least_one_put_successful =
false;
516 typename mutex_type::scoped_lock l(this->my_mutex, upgraded);
517 typename successors_type::iterator i = this->my_successors.begin();
518 while ( i != this->my_successors.end() ) {
519 task * new_task = (*i)->try_put_task(t);
523 tasks.push_back(*new_task);
525 is_at_least_one_put_successful =
true;
528 if ( (*i)->register_predecessor(*this->my_owner) ) {
530 l.upgrade_to_writer();
533 i = this->my_successors.erase(i);
539 return is_at_least_one_put_successful;
545 template<
typename T,
typename M=spin_rw_mutex >
556 typename mutex_type::scoped_lock l(this->my_mutex,
false);
557 return this->my_successors.size();
560 #if __TBB_PREVIEW_ASYNC_MSG 562 task * try_put_task(
const X &t ) {
565 #endif // __TBB_PREVIEW_ASYNC_MSG 566 bool upgraded =
true;
567 typename mutex_type::scoped_lock l(this->my_mutex, upgraded);
568 typename successors_type::iterator i = this->my_successors.begin();
569 while ( i != this->my_successors.end() ) {
570 task *new_task = (*i)->try_put_task(t);
574 if ( (*i)->register_predecessor(*this->my_owner) ) {
576 l.upgrade_to_writer();
579 i = this->my_successors.erase(i);
592 #endif // __TBB__flow_graph_cache_impl_H A cache of successors that are put in a round-robin fashion.
bool gather_successful_try_puts(const T &t, task_list &tasks)
sender< output_type > predecessor_type
sender< T > predecessor_type
successor_cache< T, M >::successors_type successors_type
virtual ~successor_cache()
void remove_successor(successor_type &r)
receiver< output_type > successor_type
reservable_predecessor_cache()
receiver< output_type > * pointer_type
sender< continue_msg > * my_owner
task * try_put_task(const T &t) __TBB_override
successor_type * my_owner
bool get_item(output_type &v)
An abstract cache of successors.
A node_cache maintains a std::queue of elements of type T. Each operation is protected by a lock.
successors_type my_successors
receiver< T > successor_type
successors_type my_successors
void remove_successor(successor_type &r)
receiver< continue_msg > successor_type
A cache of successors that are broadcast to.
task * try_put_task(const T &t) __TBB_override
bool try_reserve(output_type &v)
receiver< continue_msg > * pointer_type
static tbb::task *const SUCCESSFULLY_ENQUEUED
receiver< T > successor_type
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
void register_successor(successor_type &r)
Base class for types that should not be copied or assigned.
successor_cache< T, M >::successors_type successors_type
std::list< pointer_type > successors_type
void const char const char int ITT_FORMAT __itt_group_sync s
An cache of predecessors that supports requests and reservations.
size_type internal_size()
std::list< pointer_type > successors_type
void set_owner(owner_type *owner)
virtual ~successor_cache()
void set_owner(successor_type *owner)
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)
A cache of predecessors that only supports try_get.
void register_successor(successor_type &r)
void set_owner(sender< continue_msg > *owner)
predecessor_type * reserved_src