Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner
12 Views

How to put a task in a queue but defer its execution?

Hello,

Anybody has an idea how to submit a task to a tbb scheduler, but prevent it from being executed until some further programmer-defined event (like func. call or something)?

Thanks
0 Kudos
9 Replies
Highlighted
12 Views

You may allocate a task in advance and keep it for a while, but when you "submit", i.e. spawn() or enqueue() a task becomes available for execution and nothing can be done about it. So either you should not spawn a task until it is ready, or you make the task check its readiness inside execute() method, and recycle itself for later re-spawning. Whichever is better/more convenient, may depend on other restrictions/design forces.
0 Kudos
Highlighted
Valued Contributor I
12 Views

Quoting 05522541
Anybody has an idea how to submit a task to a tbb scheduler, but prevent it from being executed until some further programmer-defined event (like func. call or something)?

That's completely senseless. Why you ever need that? It's like asking for how can I call a function and not call it at the same time.

0 Kudos
Highlighted
Valued Contributor I
12 Views

If you submit a task to a scheduler you want it to be executed ASAP. If you do not want it to be executed ASAP do not submit it to a scheduler.
0 Kudos
Highlighted
Beginner
12 Views

I have a somewhat similar problem. I am trying to do the following.
When execute method starts I first try to get a lock and if I can I do my things, release and exit.
If I cannot get a lock I want to recycle _this_/create identical task, put it back in queue and exit.

My problem is that the new/recycled task executes next rather than be put on the end of the queue.
It gets called multiple times while another task processes the region, this is exactly what I was trying to avoid. At the same time there are tasks in the queue that could process other regions.

Any idea what I do wrong? Are there any way to put the task explicitly on the end of the queue?


I could maintain my own FIFO queue and manually schedule tasks, but that is something I don't want to do for several reasons.



This is simplified code (creates identical task and spawns it):

task* RefineTask::execute ()
{
int h = region->hold.compare_and_swap(1, 0);
if (!h) { // success
processRegion(region);

// release
region->hold = 0;

} else { // region is being processed
// return this back to the queue
task &p = *parent();
RefineTask &t = *new(task::allocate_additional_child_of(p)) RefineTask(region);
p.spawn(t);
}

return NULL;
}

0 Kudos
Highlighted
Black Belt
12 Views

If you want to poll, dedicate a tbb_thread to it. An upcoming TBB release will provide a global task queue (FIFO) in addition to the normally LIFO scheduling of locally spawned tasks (stealing is from the other side of the deque), so you could get away with this, but it still seems like abuse to me: why not choose between waiting to get the lock (if you expect short waits) or using a condition variable (if you expect long waits)?
0 Kudos
Highlighted
Beginner
12 Views

I expect long waits but contentions should seldom happen. I would like to use tbb because tasks paradigm align nicely with my algorithm but I am not sure how I can use condition variable with it. Do you mean pthread_cond_t because I cannot find anything similar to condition in tbb?
0 Kudos
Highlighted
Black Belt
12 Views

Generally speaking, don't involve TBB until you'redone waiting the way you already know.

0 Kudos
Highlighted
Employee
12 Views

The latest open-source release of TBB has an implementation of std::condition_variable. It's in include/tbb/compat/condition_variable .

Though blocking a thread for a long time hurts the efficiency of the task paradigm. If using tasking, it might be better to use a pattern that defers execution of the task instead of blocking the thread, which of course was your original question.

Our new TBB Design Patterns document has some relevant patterns. To get it now, go to http://www.threadingbuildingblocks.org/ver.php?fid=151, and look for Design_Patterns.pdf . Chapters 8-10 may be relevant to your problem. Even though chapter 8 is called "GUI Thread", it is worth reading first because chapters 9 and 10 build upon the example there. The patterns in those chapter rely upon the new task::enqueue functionality in the latest open source release.

0 Kudos
Highlighted
Beginner
12 Views

Thank you, it seems task::enqueue is a good quick solution for my case. I want a task execution postponed but can live if it is not. Glancing over patterns it looks like I might want to implement something similar to serilizer next.

Also, I cannot enqueue a task I am recycling, can I?
0 Kudos