I'm trying to use the tbb::flow (or pipeline/or task groups?) to cycle over a queue of "intervals": read a few top intervals, bisect each into A and B subintervals, check each half and possibly add them back into the queue; repeat.
The queue is actually a priority queue, managed separately. When an interval is being added, the queue reading access is locked and the right insertion point is found, possibly close to the top. So, I'd like to read the next top interval as late as possible, for example when at least 2 threads have become available to bisect-check it. That I think can be done with the "counting" continue_node.
The queue is regularly purged of low priority intervals. The length of the queue is going to converge to and fluctuate for a while around 0. I'm not sure how to exit the cycle then: say when the queue is empty at some moment I simply have nothing to send over the link explicitly, but how do I prevent the implicit message over the edge upon return from the body's operator()?? Other checking task could be adding intervals at the same time, so the queue may becomes non-empty again. It's when all the threads see the empty queue, the graph should exit. Can I use the graph::wait_for_all to wait for the "no activity" in the graph, that is, no explicit messages and no tasks running?
I'm thinking to use just 3 nodes as follows,
(function_node<continue_msg, interval> to read & bisect the top intervals)
--explicit try_put(A), try_put(B), or NO MESSAGE!?-->
(function_node<interval, continue_msg> to check&add, concurrency=nthreads)
( continue_node with T=2 )
repeat from the top
The flow can be started by populating the queue with nthreads/2 initial intervals and sending nthreads/2 continue_msgs to the first node to keep the the flow saturated.
This would be my first tbb::flow program, am I thinking in the correct terms? My main question then is the link between the two function_nodes above (correct node type?): can I have a full control over the edge messaging, to send either two half-intervals A&B, or NO MESSAGE if the queue is currently empty. If the other tasks send no messages over this edge, it should mean we're done and hopefully that's the time the wait_for_all to return?