Value SerialSumTree( TreeNode* root ) { Value result = root->value; if( root->left ) result += SerialSumTree(root->left); if( root->right ) result += SerialSumTree(root->right); return result; }
tbb::task* execute() { tbb::task* next = NULL; if( !is_continuation ) { if( root->node_count<1000 ) { *sum = SerialSumTree(root); } else { // Create tasks before spawning any of them. tbb::task* a = NULL; tbb::task* b = NULL; if( root->left ) a = new( allocate_child() ) OptimizedSumTask(root->left,&x); if( root->right ) b = new( allocate_child() ) OptimizedSumTask(root->right,&y); recycle_as_continuation(); is_continuation = true; set_ref_count( (a!=NULL)+(b!=NULL) ); if( a ) { if( b ) spawn(*b); } else a = b; next = a; } } else { *sum = root->value; if( root->left ) *sum += x; if( root->right ) *sum += y; } return next; }
task* execute() { if( root->node_count<1000 ) { *sum = SerialSumTree(root); } else { Value x, y; int count = 1; tbb::task_list list; if( root->left ) { ++count; list.push_back( *new( allocate_child() ) SimpleSumTask(root->left,&x) ); } if( root->right ) { ++count; list.push_back( *new( allocate_child() ) SimpleSumTask(root->right,&y) ); } // Argument to set_ref_count is one more than size of the list, // because spawn_and_wait_for_all expects an augmented ref_count. set_ref_count(count); spawn_and_wait_for_all(list); *sum = root->value; if( root->left ) *sum += x; if( root->right ) *sum += y; } return NULL; }