Empty tasks

You might need a task that does not do anything but wait for its children to complete. The header file task.h defines class empty_task for this purpose. Example 9-10 shows its definition.

Example 9-10. empty_task

// Task that does nothing. Useful for synchronization.
class empty_task: public task {
    /*override*/ task* execute() {
        return NULL;
    }
};

A good example of empty_task in action shown in Example 9-11. It invokes parallel_for in the method start_for::execute(). The code there uses continuation-passing style. It creates two child tasks and uses an empty_task as the continuation when the child tasks complete. The top-level routine parallel_for waits on the root.

Example 9-11. empty_task usage from parallel_for

template<typename Range, typename Body>
task* start_for<Range,Body>::execute() {
  if( !my_range.is_divisible() ) {
   my_body( my_range );
   return NULL;
  } else {
   empty_task& c = *new(allocate_continuation()) empty_task;
   recycle_as_child_of(c);
   c.set_ref_count(2);
   start_for& b =
     *new(c.allocate_child()) start_for(Range(my_range,split()),my_body);
   c.spawn(b);
   return this; 
  }
}

Get Intel Threading Building Blocks now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.