Home ⌂Doc Index ◂Up ▴
Intel(R) Threading Building Blocks Doxygen Documentation  version 4.2.3
tbb::interface6::internal::aggregator_generic< operation_type > Class Template Reference

Aggregator base class. More...

#include <_aggregator_impl.h>

Inheritance diagram for tbb::interface6::internal::aggregator_generic< operation_type >:
Collaboration diagram for tbb::interface6::internal::aggregator_generic< operation_type >:

Public Member Functions

 aggregator_generic ()
 
template<typename handler_type >
void execute (operation_type *op, handler_type &handle_operations, bool long_life_time=true)
 Execute an operation. More...
 

Private Member Functions

template<typename handler_type >
void start_handle_operations (handler_type &handle_operations)
 Trigger the handling of operations when the handler is free. More...
 

Private Attributes

atomic< operation_type * > pending_operations
 An atomically updated list (aka mailbox) of pending operations. More...
 
uintptr_t handler_busy
 Controls thread access to handle_operations. More...
 

Detailed Description

template<typename operation_type>
class tbb::interface6::internal::aggregator_generic< operation_type >

Aggregator base class.

An aggregator for collecting operations coming from multiple sources and executing them serially on a single thread. operation_type must be derived from aggregated_operation. The parameter handler_type is a functor that will be passed the list of operations and is expected to handle each operation appropriately, setting the status of each operation to non-zero.

Definition at line 49 of file _aggregator_impl.h.

Constructor & Destructor Documentation

◆ aggregator_generic()

template<typename operation_type>
tbb::interface6::internal::aggregator_generic< operation_type >::aggregator_generic ( )
inline

Definition at line 51 of file _aggregator_impl.h.

51 : handler_busy(false) { pending_operations = NULL; }
uintptr_t handler_busy
Controls thread access to handle_operations.
atomic< operation_type * > pending_operations
An atomically updated list (aka mailbox) of pending operations.

Member Function Documentation

◆ execute()

template<typename operation_type>
template<typename handler_type >
void tbb::interface6::internal::aggregator_generic< operation_type >::execute ( operation_type *  op,
handler_type &  handle_operations,
bool  long_life_time = true 
)
inline

Execute an operation.

Places an operation into the waitlist (pending_operations), and either handles the list, or waits for the operation to complete, or returns. The long_life_time parameter specifies the life time of the given operation object. Operations with long_life_time == true may be accessed after execution. A "short" life time operation (long_life_time == false) can be destroyed during execution, and so any access to it after it was put into the waitlist, including status check, is invalid. As a consequence, waiting for completion of such operation causes undefined behavior.

Definition at line 64 of file _aggregator_impl.h.

64  {
65  operation_type *res;
66  // op->status should be read before inserting the operation into the
67  // aggregator waitlist since it can become invalid after executing a
68  // handler (if the operation has 'short' life time.)
69  const uintptr_t status = op->status;
70 
71  // ITT note: &(op->status) tag is used to cover accesses to this op node. This
72  // thread has created the operation, and now releases it so that the handler
73  // thread may handle the associated operation w/o triggering a race condition;
74  // thus this tag will be acquired just before the operation is handled in the
75  // handle_operations functor.
76  call_itt_notify(releasing, &(op->status));
77  // insert the operation in the queue.
78  do {
79  // Tools may flag the following line as a race; it is a false positive:
80  // This is an atomic read; we don't provide itt_hide_load_word for atomics
81  op->next = res = pending_operations; // NOT A RACE
82  } while (pending_operations.compare_and_swap(op, res) != res);
83  if (!res) { // first in the list; handle the operations.
84  // ITT note: &pending_operations tag covers access to the handler_busy flag,
85  // which this waiting handler thread will try to set before entering
86  // handle_operations.
88  start_handle_operations(handle_operations);
89  // The operation with 'short' life time can already be destroyed.
90  if (long_life_time)
91  __TBB_ASSERT(op->status, NULL);
92  }
93  // not first; wait for op to be ready.
94  else if (!status) { // operation is blocking here.
95  __TBB_ASSERT(long_life_time, "Waiting for an operation object that might be destroyed during processing.");
96  call_itt_notify(prepare, &(op->status));
97  spin_wait_while_eq(op->status, uintptr_t(0));
98  itt_load_word_with_acquire(op->status);
99  }
100  }
void call_itt_notify(notify_type, void *)
void spin_wait_while_eq(const volatile T &location, U value)
Spin WHILE the value of the variable is equal to a given value.
Definition: tbb_machine.h:391
void start_handle_operations(handler_type &handle_operations)
Trigger the handling of operations when the handler is free.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:165
T itt_load_word_with_acquire(const tbb::atomic< T > &src)
atomic< operation_type * > pending_operations
An atomically updated list (aka mailbox) of pending operations.

Referenced by tbb::interface6::internal::aggregator< tbb::interface6::internal::aggregating_functor, internal::function_input_base::operation_type >::execute().

Here is the caller graph for this function:

◆ start_handle_operations()

template<typename operation_type>
template<typename handler_type >
void tbb::interface6::internal::aggregator_generic< operation_type >::start_handle_operations ( handler_type &  handle_operations)
inlineprivate

Trigger the handling of operations when the handler is free.

Definition at line 110 of file _aggregator_impl.h.

110  {
111  operation_type *op_list;
112 
113  // ITT note: &handler_busy tag covers access to pending_operations as it is passed
114  // between active and waiting handlers. Below, the waiting handler waits until
115  // the active handler releases, and the waiting handler acquires &handler_busy as
116  // it becomes the active_handler. The release point is at the end of this
117  // function, when all operations in pending_operations have been handled by the
118  // owner of this aggregator.
120  // get the handler_busy:
121  // only one thread can possibly spin here at a time
122  spin_wait_until_eq(handler_busy, uintptr_t(0));
124  // acquire fence not necessary here due to causality rule and surrounding atomics
125  __TBB_store_with_release(handler_busy, uintptr_t(1));
126 
127  // ITT note: &pending_operations tag covers access to the handler_busy flag
128  // itself. Capturing the state of the pending_operations signifies that
129  // handler_busy has been set and a new active handler will now process that list's
130  // operations.
132  // grab pending_operations
133  op_list = pending_operations.fetch_and_store(NULL);
134 
135  // handle all the operations
136  handle_operations(op_list);
137 
138  // release the handler
140  }
void call_itt_notify(notify_type, void *)
void itt_store_word_with_release(tbb::atomic< T > &dst, U src)
void spin_wait_until_eq(const volatile T &location, const U value)
Spin UNTIL the value of the variable is equal to a given value.
Definition: tbb_machine.h:399
void __TBB_store_with_release(volatile T &location, V value)
Definition: tbb_machine.h:713
uintptr_t handler_busy
Controls thread access to handle_operations.
atomic< operation_type * > pending_operations
An atomically updated list (aka mailbox) of pending operations.

Member Data Documentation

◆ handler_busy

template<typename operation_type>
uintptr_t tbb::interface6::internal::aggregator_generic< operation_type >::handler_busy
private

Controls thread access to handle_operations.

Definition at line 106 of file _aggregator_impl.h.

◆ pending_operations

template<typename operation_type>
atomic<operation_type *> tbb::interface6::internal::aggregator_generic< operation_type >::pending_operations
private

An atomically updated list (aka mailbox) of pending operations.

Definition at line 104 of file _aggregator_impl.h.


The documentation for this class was generated from the following file:

Copyright © 2005-2020 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.