Recycling the parent as a child
This style is useful when the child inherits much of its state from a parent and the continuation does not need the parent’s state. The child must have the parent’s type. In Example 9-6, C is the type of the continuation, and it must derive from the class task. If C does nothing but wait for all children to complete, C can be the class empty_task.
Example 9-6. Recycling parent as a child
task* T::execute() {
if( not recursing any further ) {
...
return NULL;
} else {
set_ref_count(k);
// Construct continuation
C& c = allocate_continuation();
// Recycle self as first child
task& tk = new( c.allocate_child() ) T(…); tk.spawn();
task& tk-1 = new( c.allocate_child() ) T(…); tk-1.spawn();
...
task& t2 = new( c.allocate_child() ) T(…); t2.spawn();
// task t1 is our recycled self.
recycle_as_child_of(c);
... update fields of *this to state subproblem to be solved by t1
return this;
}
}Here are the key points of the pattern:
The call to
set_ref_countuseskas its argument. There is no extra 1, as there is in blocking style.Each child task except for
t1is allocated byc.allocate_child. It is critical to usec.allocate_childand not(*this).allocate_child;otherwise, the task graph will be wrong.Task
t1is recycled from the parent, and hence gets the parent’s state without performing copy operations. Do not forget to update the state to represent a child subproblem; otherwise, infinite recursion will occur.
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access