24 #include <tbb/task_group.h>          
   25 #include <tbb/scalable_allocator.h>  
   30   namespace treeTraversal {
 
   35       template<
typename NODE, 
typename DATA, 
typename VISITOR_PRE, 
typename VISITOR_POST>
 
   39         const std::shared_ptr<NODE>& 
treeNode;
 
   40         std::shared_ptr<DATA> myData;
 
   41         VISITOR_PRE& visitorPre;
 
   42         VISITOR_POST& visitorPost;
 
   43         int problemSizeThreshold;
 
   48         mutable bool isPostOrderPhase;
 
   50         PreOrderTask(
const std::shared_ptr<NODE>& 
treeNode, 
const std::shared_ptr<DATA>& myData,
 
   51                      VISITOR_PRE& visitorPre, VISITOR_POST& visitorPost, 
int problemSizeThreshold,
 
   52                      tbb::task_group& tg, 
bool makeNewTasks = 
true)
 
   55               visitorPre(visitorPre),
 
   56               visitorPost(visitorPost),
 
   57               problemSizeThreshold(problemSizeThreshold),
 
   59               makeNewTasks(makeNewTasks),
 
   60               isPostOrderPhase(false) {}
 
   67             (void) visitorPost(
treeNode, *myData);
 
   75                 bool overThreshold = (
treeNode->problemSize() >= problemSizeThreshold);
 
   79                 for(
const std::shared_ptr<NODE>& child: 
treeNode->children)
 
   84                   std::shared_ptr<DATA> childData = std::allocate_shared<DATA>(
 
   85                       tbb::scalable_allocator<DATA>(), visitorPre(child, *myData));
 
   86                   ctg.run(PreOrderTask(child, childData, visitorPre, visitorPost,
 
   87                       problemSizeThreshold, ctg, overThreshold));
 
   92                 isPostOrderPhase = 
true;
 
   98                 (void) visitorPost(
treeNode, *myData);
 
  104               processNodeRecursively(
treeNode, *myData);
 
  109         void processNodeRecursively(
const std::shared_ptr<NODE>& node, DATA& myData)
 const 
  111           for(
const std::shared_ptr<NODE>& child: node->children)
 
  113             DATA childData = visitorPre(child, myData);
 
  114             processNodeRecursively(child, childData);
 
  118           (void) visitorPost(node, myData);
 
  123       template<
typename ROOTS, 
typename NODE, 
typename DATA, 
typename VISITOR_PRE, 
typename VISITOR_POST>
 
  129         VISITOR_PRE& visitorPre;
 
  130         VISITOR_POST& visitorPost;
 
  131         int problemSizeThreshold;
 
  133         RootTask(
const ROOTS& roots, DATA& myData, VISITOR_PRE& visitorPre, VISITOR_POST& visitorPost,
 
  134           int problemSizeThreshold, tbb::task_group& tg) :
 
  135           roots(roots), myData(myData), visitorPre(visitorPre), visitorPost(visitorPost),
 
  136           problemSizeThreshold(problemSizeThreshold), tg(tg) {}
 
  140           typedef PreOrderTask<NODE, DATA, VISITOR_PRE, VISITOR_POST> PreOrderTask;
 
  142           for(
const std::shared_ptr<NODE>& root: roots)
 
  144             std::shared_ptr<DATA> rootData = std::allocate_shared<DATA>(tbb::scalable_allocator<DATA>(), visitorPre(root, myData));
 
  145             tg.run(PreOrderTask(root, rootData, visitorPre, visitorPost, problemSizeThreshold, tg));
 
  150       template<
typename NODE, 
typename ROOTS, 
typename DATA, 
typename VISITOR_PRE, 
typename VISITOR_POST>
 
  151       void CreateRootTask(
const ROOTS& roots, DATA& rootData, VISITOR_PRE& visitorPre, VISITOR_POST& visitorPost, 
int problemSizeThreshold)
 
  153           typedef RootTask<ROOTS, NODE, DATA, VISITOR_PRE, VISITOR_POST> RootTask;
 
  155           tg.run_and_wait(RootTask(roots, rootData, visitorPre, visitorPost, problemSizeThreshold, tg));