17 #ifndef __TBB_parallel_scan_H 18 #define __TBB_parallel_scan_H 20 #define __TBB_parallel_scan_H_include_area 49 template<
typename Range,
typename Body>
67 new(
my_range.begin() ) Range(range_);
81 template<
typename Range,
typename Body>
94 sum_node(
const Range range_,
bool left_is_final_ ) :
135 template<
typename Range_,
typename Body_,
typename Partitioner_>
138 template<
typename Range_,
typename Body_>
144 template<
typename Range,
typename Body>
185 template<
typename Range,
typename Body,
typename Partitioner=simple_partitioner>
227 static void run(
const Range& range_, Body& body_,
const Partitioner& partitioner_ ) {
228 if( !range_.empty() ) {
237 temp_body->
my_body.reverse_join(body_);
245 body_.assign(temp_body->
my_body);
247 temp_body->destroy(*temp_body);
253 template<
typename Range,
typename Body,
typename Partitioner>
256 finish_pass1_type*
p = my_parent_sum ?
static_cast<finish_pass1_type*
>(
parent() ) : NULL;
260 bool treat_as_stolen = my_is_right_child && (is_stolen_task() || my_body!=
p->my_result.my_left_sum);
261 if( treat_as_stolen ) {
263 p->my_right_zombie = my_body =
new( allocate_root() )
final_sum_type(my_body->my_body);
266 task* next_task = NULL;
267 if( (my_is_right_child && !treat_as_stolen) || !my_range.is_divisible() || my_partition.should_execute_range(*
this) ) {
278 result =
new(allocate_additional_child_of(*my_parent_sum))
sum_node_type(my_range,my_is_final);
281 finish_pass1_type& c = *
new( allocate_continuation()) finish_pass1_type(*my_return_slot,my_sum,*result);
288 recycle_as_child_of(c);
292 my_return_slot = &result->
my_left;
293 my_is_right_child =
false;
295 my_parent_sum = result;
301 template<
typename Range,
typename Value,
typename Scan,
typename ReverseJoin>
320 template<
typename Tag>
362 template<
typename Range,
typename Body>
369 template<
typename Range,
typename Body>
376 template<
typename Range,
typename Body>
383 template<
typename Range,
typename Value,
typename Scan,
typename ReverseJoin>
384 Value
parallel_scan(
const Range& range,
const Value& identity,
const Scan& scan,
const ReverseJoin& reverse_join ) {
392 template<
typename Range,
typename Value,
typename Scan,
typename ReverseJoin>
401 template<
typename Range,
typename Value,
typename Scan,
typename ReverseJoin>
413 #undef __TBB_parallel_scan_H_include_area start_scan(sum_node_type *&return_slot_, const Range &range_, final_sum_type &body_, const Partitioner &partitioner_)
final_sum_type * my_left_sum
void set_ref_count(int count)
Set reference count.
final_sum_type **const my_sum
task * execute() __TBB_override
Should be overridden by derived classes.
final_sum_type * my_incoming
void assign(lambda_scan_body &b)
aligned_space< Range > my_range
Partitioner::partition_type my_partition
static bool is_final_scan()
final_sum< Range, Body > final_sum_type
static internal::allocate_root_proxy allocate_root()
Returns proxy for overloaded new that allocates a root task.
Performs final scan for a leaf.
final_sum_type * my_right_zombie
Dummy type that distinguishes splitting constructor from copy constructor.
void parallel_scan(const Range &range, Body &body)
Parallel prefix with default partitioner.
final_sum< Range, Body > final_sum_type
sum_node(const Range range_, bool left_is_final_)
const ReverseJoin & my_reverse_join
sum_node_type ** my_return_slot
#define __TBB_DEFAULT_PARTITIONER
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 ITT_FORMAT p void ITT_FORMAT p void size_t ITT_FORMAT d void ITT_FORMAT p const wchar_t ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s const char ITT_FORMAT s no args void ITT_FORMAT p size_t ITT_FORMAT d no args const wchar_t const wchar_t ITT_FORMAT s __itt_heap_function void size_t int ITT_FORMAT d __itt_heap_function void ITT_FORMAT p __itt_heap_function void void size_t int ITT_FORMAT d no args no args unsigned int ITT_FORMAT u const __itt_domain __itt_id ITT_FORMAT lu const __itt_domain __itt_id __itt_id parent
task * execute() __TBB_override
Should be overridden by derived classes.
sum_node< Range, Body > sum_node_type
static bool is_final_scan()
void recycle_as_child_of(task &new_parent)
Change this to be a child of new_parent.
task * execute() __TBB_override
Should be overridden by derived classes.
finish_scan(sum_node_type *&return_slot_, final_sum_type **sum_, sum_node_type &result_)
static void run(const Range &range_, Body &body_, const Partitioner &partitioner_)
void finish_construction(const Range &range_, Body *stuff_last_)
Base class for user-defined tasks.
sum_node< Range, Body > sum_node_type
Used to indicate that the final scan is being performed.
int ref_count() const
The internal reference count.
Base class for types that should not be assigned.
void const char const char int ITT_FORMAT __itt_group_sync p
final_sum< Range, Body > final_sum_type
sum_node_type * my_parent_sum
void recycle_as_continuation()
Change this to be a continuation of its former self.
Body * my_stuff_last
Where to put result of last subrange, or NULL if not last subrange.
Split work to be done in the scan.
Used to indicate that the initial scan is being performed.
const Value & identity_element
sum_node_type *& my_return_slot
sum_node_type & my_result
static void spawn_root_and_wait(task &root)
Spawn task allocated by allocate_root, wait for it to complete, and deallocate it.
lambda_scan_body(lambda_scan_body &b, split)
Initial task to split the work.
#define __TBB_ASSERT(predicate, comment)
No-op version of __TBB_ASSERT.
task * execute() __TBB_override
Should be overridden by derived classes.
void poison_pointer(T *__TBB_atomic &)
void reverse_join(lambda_scan_body &a)
task * create_child(const Range &range_, final_sum_type &f, sum_node *n, final_sum_type *incoming_, Body *stuff_last_)
void operator()(const Range &r, Tag tag)
lambda_scan_body(const Value &identity, const Scan &scan, const ReverseJoin &rev_join)