void TreeRepository::appendNode(TreeNode* rawNode) { TreeNodePtr bnode(rawNode); TreeNodePtr node(new CachedTreeNode(bnode)); if (!this->getNode(node->getUid())) { // TODO need a more detailed change policy: invalidate only when parent/childe // structure is changed. // connect(node.get(), &TreeNode::changed, this, &TreeRepository::invalidated); connect(node.get(), &TreeNode::changed, this, &TreeRepository::onChanged); mNodes.push_back(node); } }
void TestSimpleSuccessorArc(const char *name) { tbb::flow::graph g; { REMARK("Join<%s> successor test ", name); tbb::flow::join_node<tbb::flow::tuple<int>, JNODE_TYPE> qj(g); tbb::flow::broadcast_node<tbb::flow::tuple<int> > bnode(g); tbb::flow::make_edge(qj, bnode); ASSERT(!qj.my_successors.empty(),"successor missing after linking"); g.reset(); ASSERT(!qj.my_successors.empty(),"successor missing after reset()"); g.reset(tbb::flow::rf_clear_edges); ASSERT(qj.my_successors.empty(), "successors not removed after reset(rf_clear_edges)"); } }
void TestSimpleSuccessorArc(const char *name) { tbb::flow::graph g; { //tbb::flow::join_node<tbb::flow::tuple<int>, tbb::flow::queueing> qj(g); REMARK("Join<%s> successor test ", name); tbb::flow::join_node<tbb::flow::tuple<int>, JNODE_TYPE> qj(g); tbb::flow::broadcast_node<tbb::flow::tuple<int> > bnode(g); tbb::flow::make_edge(qj, bnode); ASSERT(!qj.my_successors.empty(),"successor missing after linking"); g.reset(); ASSERT(!qj.my_successors.empty(),"successor missing after reset()"); #if TBB_PREVIEW_FLOW_GRAPH_FEATURES g.reset(tbb::flow::rf_extract); ASSERT(qj.my_successors.empty(), "successors not removed after reset(rf_extract)"); #endif } }
void TestSimpleSuccessorArc<tbb::flow::tag_matching>(const char *name) { tbb::flow::graph g; { REMARK("Join<%s> successor test ", name); typedef tbb::flow::tuple<int,int> my_tuple; tbb::flow::join_node<my_tuple, tbb::flow::tag_matching> qj(g, tag_func<int>(1), tag_func<int>(1) ); tbb::flow::broadcast_node<my_tuple > bnode(g); tbb::flow::make_edge(qj, bnode); ASSERT(!qj.my_successors.empty(),"successor missing after linking"); g.reset(); ASSERT(!qj.my_successors.empty(),"successor missing after reset()"); g.reset(tbb::flow::rf_clear_edges); ASSERT(qj.my_successors.empty(), "successors not removed after reset(rf_clear_edges)"); } }
// sequencer_node behaves like a queueing node, but requires a different constructor. void TestSequencerNode() { tbb::flow::graph g; tbb::flow::sequencer_node<int> bnode(g, seq_body()); REMARK("Testing sequencer_node:"); tbb::flow::function_node<int> fnode(g, tbb::flow::serial, serial_fn_body<int>(serial_fn_state0)); REMARK("Testing sequencer_node:"); serial_fn_state0 = 0; // reset to waiting state. REMARK(" make_edge"); tbb::flow::make_edge(bnode, fnode); ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after make_edge"); REMARK(" try_put"); bnode.try_put(0); // will forward to the fnode BACKOFF_WAIT( serial_fn_state0 == 0, "timeout waiting for function_node"); // wait for the function_node to fire up ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after forwarding message"); serial_fn_state0 = 0; g.wait_for_all(); REMARK(" remove_edge"); tbb::flow::remove_edge(bnode, fnode); ASSERT(bnode.my_successors.empty(), "buffering node has a successor after remove_edge"); tbb::flow::join_node<tbb::flow::tuple<int,int>,tbb::flow::reserving> jnode(g); tbb::flow::make_edge(bnode, tbb::flow::input_port<0>(jnode)); // will spawn a task g.wait_for_all(); ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after attaching to join"); REMARK(" reverse"); bnode.try_put(3); // the edge should reverse g.wait_for_all(); ASSERT(bnode.my_successors.empty(), "buffering node has a successor after reserving"); REMARK(" reset()"); g.wait_for_all(); g.reset(); // should be in forward direction again ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after reset()"); #if TBB_PREVIEW_FLOW_GRAPH_FEATURES REMARK(" remove_edge"); g.reset(tbb::flow::rf_extract); // should be in forward direction again ASSERT(bnode.my_successors.empty(), "buffering node has a successor after reset(rf_extract)"); ASSERT(fnode.my_predecessors.empty(), "buffering node reversed after reset(rf_extract)"); #endif REMARK(" done\n"); g.wait_for_all(); }
int main(int argc, char *argv[], char *envp[]) { char line[256]; char ch; char *pwd; int i; cmd_ptr *cmdptr = NULL; pwd = malloc(sizeof(char) * 1024); jlist = jobs_init(); //signal(SIGCHLD, SIG_DFL); signal(SIGINT, SIG_IGN); signal(SIGTERM, SIG_IGN); signal(SIGQUIT, SIG_IGN); signal(SIGTSTP, SIG_IGN); signal(SIGSTOP, SIG_IGN); for (;;) { struct task *newtask; struct tnode *nodelist; strcpy(pwd, getenv("PWD")); printf("[CSC3150 shell:%s]$", pwd); line[0] = 0; i = 0; while ((ch = getchar()) != '\n') line[i++] = ch; line[i] = 0; if (line[0] == 0) continue; //temp=malloc(sizeof(char)*(strlen(line)+1)); //strcpy(temp,line); if (!firstck(line)) { printf("Error: invalid input command line\n"); continue; } //printf("Error\n"); cmdptr = malloc(sizeof(cmd_ptr)); initialize2(cmdptr); newtask = malloc(sizeof(struct task)); newtask->cmd = malloc(sizeof(char) * (strlen(line) + 1)); strcpy(newtask->cmd, line); jlist->job[jlist->n++] = newtask; if (start_chk(line) == 2) { nodelist = bnode(line); exec1(nodelist); continue; } if (start_chk(line) == 3) getcmd3(line, cmdptr); else if (start_chk(line) == 4) getcmd4(line, cmdptr); else if (start_chk(line) == 5) getcmd5(line, cmdptr); else if (start_chk(line) == 6) getcmd6(line, cmdptr); else if (start_chk(line) == 7) getcmd7(line, cmdptr); else if (start_chk(line) == 8) getcmd8(line, cmdptr); else { printf("Error: invalid input command line\n"); continue; } nodelist = newnode(cmdptr); newtask->tids = execute(nodelist, NULL, NULL); if (newtask->tids != NULL) { jlist->job[jlist->n] = newtask; jlist->n++; } lwait(newtask->tids); } return 0; }
/*! Build the BVH, given an input data set * - Handling our own stack is quite a bit faster than the recursive style. * - Each build stack entry's parent field eventually stores the offset * to the parent of that node. Before that is finally computed, it will * equal exactly three other values. (These are the magic values Untouched, * Untouched-1, and TouchedTwice). * - The partition here was also slightly faster than std::partition. */ void BVH::build() { BVHBuildEntry todo[128]; uint32_t stackptr = 0; const uint32_t Untouched = 0xffffffff; const uint32_t TouchedTwice = 0xfffffffd; // Push the root todo[stackptr].start = 0; todo[stackptr].end = build_prims->size(); todo[stackptr].parent = 0xfffffffc; stackptr++; BVHFlatNode node; std::vector<BVHFlatNode> buildnodes; buildnodes.reserve(build_prims->size()*2); while(stackptr > 0) { // Pop the next item off of the stack BVHBuildEntry &bnode( todo[--stackptr] ); uint32_t start = bnode.start; uint32_t end = bnode.end; uint32_t nPrims = end - start; nNodes++; node.start = start; node.nPrims = nPrims; node.rightOffset = Untouched; // Calculate the bounding box for this node BBox bb( (*build_prims)[start]->getBBox()); BBox bc( (*build_prims)[start]->getCentroid()); for(uint32_t p = start+1; p < end; ++p) { bb.expandToInclude( (*build_prims)[p]->getBBox()); bc.expandToInclude( (*build_prims)[p]->getCentroid()); } node.bbox = bb; // If the number of primitives at this point is less than the leaf // size, then this will become a leaf. (Signified by rightOffset == 0) if(nPrims <= leafSize) { node.rightOffset = 0; nLeafs++; } buildnodes.push_back(node); // Child touches parent... // Special case: Don't do this for the root. if(bnode.parent != 0xfffffffc) { buildnodes[bnode.parent].rightOffset --; // When this is the second touch, this is the right child. // The right child sets up the offset for the flat tree. if( buildnodes[bnode.parent].rightOffset == TouchedTwice ) { buildnodes[bnode.parent].rightOffset = nNodes - 1 - bnode.parent; } } // If this is a leaf, no need to subdivide. if(node.rightOffset == 0) continue; // Set the split dimensions uint32_t split_dim = bc.maxDimension(); // Split on the center of the longest axis float split_coord = .5f * (bc.min[split_dim] + bc.max[split_dim]); // Partition the list of objects on this split uint32_t mid = start; for(uint32_t i=start;i<end;++i) { if( (*build_prims)[i]->getCentroid()[split_dim] < split_coord ) { std::swap( (*build_prims)[i], (*build_prims)[mid] ); ++mid; } } // If we get a bad split, just choose the center... if(mid == start || mid == end) { mid = start + (end-start)/2; } // Push right child todo[stackptr].start = mid; todo[stackptr].end = end; todo[stackptr].parent = nNodes-1; stackptr++; // Push left child todo[stackptr].start = start; todo[stackptr].end = mid; todo[stackptr].parent = nNodes-1; stackptr++; } // Copy the temp node data to a flat array flatTree = new BVHFlatNode[nNodes]; for(uint32_t n=0; n<nNodes; ++n) flatTree[n] = buildnodes[n]; }
void TestBufferingNode(const char * name) { tbb::flow::graph g; B bnode(g); tbb::flow::function_node<int,int,tbb::flow::rejecting> fnode(g, tbb::flow::serial, serial_fn_body<int>(serial_fn_state0)); REMARK("Testing %s:", name); for(int icnt = 0; icnt < 2; icnt++) { bool reverse_edge = (icnt & 0x2) != 0; serial_fn_state0 = 0; // reset to waiting state. REMARK(" make_edge"); tbb::flow::make_edge(bnode, fnode); ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after make_edge"); REMARK(" try_put"); bnode.try_put(1); // will forward to the fnode BACKOFF_WAIT(serial_fn_state0 == 0, "Timed out waiting for first put"); if(reverse_edge) { REMARK(" try_put2"); bnode.try_put(2); // will reverse the edge // cannot do a wait_for_all here; the function_node is still executing BACKOFF_WAIT(!bnode.my_successors.empty(), "Timed out waiting after 2nd put"); // at this point the only task running is the one for the function_node. ASSERT(bnode.my_successors.empty(), "successor not removed"); } else { ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after forwarding message"); } serial_fn_state0 = 0; // release the function_node. if(reverse_edge) { // have to do a second release because the function_node will get the 2nd item BACKOFF_WAIT( serial_fn_state0 == 0, "Timed out waiting after 2nd put"); serial_fn_state0 = 0; // release the function_node. } g.wait_for_all(); REMARK(" remove_edge"); tbb::flow::remove_edge(bnode, fnode); ASSERT(bnode.my_successors.empty(), "buffering node has a successor after remove_edge"); } tbb::flow::join_node<tbb::flow::tuple<int,int>,tbb::flow::reserving> jnode(g); tbb::flow::make_edge(bnode, tbb::flow::input_port<0>(jnode)); // will spawn a task g.wait_for_all(); ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after attaching to join"); REMARK(" reverse"); bnode.try_put(1); // the edge should reverse g.wait_for_all(); ASSERT(bnode.my_successors.empty(), "buffering node has a successor after reserving"); REMARK(" reset()"); g.wait_for_all(); g.reset(); // should be in forward direction again ASSERT(!bnode.my_successors.empty(), "buffering node has no successor after reset()"); REMARK(" remove_edge"); g.reset(tbb::flow::rf_clear_edges); ASSERT(bnode.my_successors.empty(), "buffering node has a successor after reset(rf_clear_edges)"); tbb::flow::make_edge(bnode, tbb::flow::input_port<0>(jnode)); // add edge again // reverse edge by adding to buffer. bnode.try_put(1); // the edge should reverse g.wait_for_all(); ASSERT(bnode.my_successors.empty(), "buffering node has a successor after reserving"); REMARK(" remove_edge(reversed)"); g.reset(tbb::flow::rf_clear_edges); ASSERT(bnode.my_successors.empty(), "buffering node has no successor after reset()"); ASSERT(tbb::flow::input_port<0>(jnode).my_predecessors.empty(), "predecessor not reset"); REMARK(" done\n"); g.wait_for_all(); }