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.

: handler_busy(false) { pending_operations = NULL; }
tbb::interface6::internal::aggregator_generic::pending_operations
atomic< operation_type * > pending_operations
An atomically updated list (aka mailbox) of pending operations.
Definition: _aggregator_impl.h:104
tbb::interface6::internal::aggregator_generic::handler_busy
uintptr_t handler_busy
Controls thread access to handle_operations.
Definition: _aggregator_impl.h:106

## 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.

{
operation_type *res;
// op->status should be read before inserting the operation into the
// aggregator waitlist since it can become invalid after executing a
// handler (if the operation has 'short' life time.)
const uintptr_t status = op->status;
// ITT note: &(op->status) tag is used to cover accesses to this op node. This
// thread has created the operation, and now releases it so that the handler
// thread may handle the associated operation w/o triggering a race condition;
// thus this tag will be acquired just before the operation is handled in the
// handle_operations functor.
call_itt_notify(releasing, &(op->status));
// insert the operation in the queue.
do {
// Tools may flag the following line as a race; it is a false positive:
// This is an atomic read; we don't provide itt_hide_load_word for atomics
op->next = res = pending_operations; // NOT A RACE
} while (pending_operations.compare_and_swap(op, res) != res);
if (!res) { // first in the list; handle the operations.
// ITT note: &pending_operations tag covers access to the handler_busy flag,
// which this waiting handler thread will try to set before entering
// handle_operations.
call_itt_notify(acquired, &pending_operations);
start_handle_operations(handle_operations);
// The operation with 'short' life time can already be destroyed.
if (long_life_time)
__TBB_ASSERT(op->status, NULL);
}
// not first; wait for op to be ready.
else if (!status) { // operation is blocking here.
__TBB_ASSERT(long_life_time, "Waiting for an operation object that might be destroyed during processing.");
call_itt_notify(prepare, &(op->status));
spin_wait_while_eq(op->status, uintptr_t(0));
itt_load_word_with_acquire(op->status);
}
}
__TBB_ASSERT
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
Definition: tbb_stddef.h:165
tbb::internal::acquired
@ acquired
Definition: tbb_profiling.h:129
tbb::internal::releasing
@ releasing
Definition: tbb_profiling.h:129
tbb::internal::prepare
@ prepare
Definition: tbb_profiling.h:129
tbb::internal::itt_load_word_with_acquire
T itt_load_word_with_acquire(const tbb::atomic< T > &src)
Definition: tbb_profiling.h:168
tbb::internal::call_itt_notify
void call_itt_notify(notify_type, void *)
Definition: tbb_profiling.h:276
tbb::internal::spin_wait_while_eq
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:394
tbb::interface6::internal::aggregator_generic::start_handle_operations
void start_handle_operations(handler_type &handle_operations)
Trigger the handling of operations when the handler is free.
Definition: _aggregator_impl.h:110

References __TBB_ASSERT, tbb::internal::acquired, tbb::internal::call_itt_notify(), tbb::internal::itt_load_word_with_acquire(), tbb::internal::prepare, tbb::internal::releasing, and tbb::internal::spin_wait_while_eq().

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

Here is the call graph for this function:
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 | ) |

inline private

Trigger the handling of operations when the handler is free.

Definition at line 110 of file _aggregator_impl.h.

{
operation_type *op_list;
// ITT note: &handler_busy tag covers access to pending_operations as it is passed
// between active and waiting handlers. Below, the waiting handler waits until
// the active handler releases, and the waiting handler acquires &handler_busy as
// it becomes the active_handler. The release point is at the end of this
// function, when all operations in pending_operations have been handled by the
// owner of this aggregator.
call_itt_notify(prepare, &handler_busy);
// get the handler_busy:
// only one thread can possibly spin here at a time
spin_wait_until_eq(handler_busy, uintptr_t(0));
call_itt_notify(acquired, &handler_busy);
// acquire fence not necessary here due to causality rule and surrounding atomics
__TBB_store_with_release(handler_busy, uintptr_t(1));
// ITT note: &pending_operations tag covers access to the handler_busy flag
// itself. Capturing the state of the pending_operations signifies that
// handler_busy has been set and a new active handler will now process that list's
// operations.
call_itt_notify(releasing, &pending_operations);
// grab pending_operations
op_list = pending_operations.fetch_and_store(NULL);
// handle all the operations
handle_operations(op_list);
// release the handler
itt_store_word_with_release(handler_busy, uintptr_t(0));
}
tbb::internal::spin_wait_until_eq
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:402
tbb::internal::itt_store_word_with_release
void itt_store_word_with_release(tbb::atomic< T > &dst, U src)
Definition: tbb_profiling.h:157
tbb::internal::__TBB_store_with_release
void __TBB_store_with_release(volatile T &location, V value)
Definition: tbb_machine.h:716

References tbb::internal::__TBB_store_with_release(), tbb::internal::acquired, tbb::internal::call_itt_notify(), tbb::internal::itt_store_word_with_release(), tbb::internal::prepare, tbb::internal::releasing, and tbb::internal::spin_wait_until_eq().

Here is the call graph for this function:

## 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:

- _aggregator_impl.h

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.