- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[cpp] // Set up initial function list gen_tasks for (bool simulating = true; simulating; ) { parallel_for( blocked_range(0, genTaskCount), [=] (const blocked_range &r) { for (size_t i = r.begin(); i != r.end(); ++i) { gen_task(gen_task.data); } } // Accumulate next tasks into gen_task list. Step the generation // and test for termination }[/cpp]
Basically, you build a list of tasks to execute and then launch a set of workers to process the current generation's list. They each may generate outputs and schedule tasks for the next generation; presumably each of these tasks can operate independently and safely in a a threaded environment. The comment at the loop would be expanded to code to rebuild the gen_task array with new task pointers and new data, adjusting the next gen's genTaskCount as appropriate. Implementation details can be worked out but I'd probably first try an enumerable thread specific collection for registering the next-gen task-data pairs (each work thread can collect these without interfering with other workers), then migrate the details from the thread local structures to gen_task during the generation change.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[cpp]void do_job(){ while(1){ x = obtain_global_variable_safely(); std::cout << "Value is:" << x << std::endl; leave(); } }[/cpp]
I cannot change the API, it is written long ago. I thought of 4 possible solutions:
- Open inline assembler, save registers and stack. That would be quite messy and unportable. Actually, the current version does something like this, but resorts to services of external package to this job in a portable way. However, needless to say, it segfaults if I use it in MT context.
- Create threads (may be pthreads/tbb_threads/Boost.Thread), then wait on some condition variable. Here, I don't know, could it interfere with the task scheduler? Would there be too much overhead? Anyway, I have to save stack and registers, so context-switch overhead is probably inevitable, are there other kinds of overhead?
- I guess, if I could wait inside the task on a condition variable, but somehow, take the task out of the scheduler for the wait period, it could be the best. Is that possible?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Are there constraints to guarantee that multiple, simultaneoususer functions play nice with each other?
Some of the declared constraints would be hard to implement in any environment; in particular the need to be able to place the leave() call in the midst of a instruction sequence so that the semanticsare to call the head of the function when initially scheduled, but then to treat the leave() call as a coroutine breakfrom whichexecution resumesthe next time the function is scheduled sounds like it would require some special sauce in the scheduler to handle context preservation and coroutining. Every leave() call imposes a place where a stack context would need to be preserved. Management of these contexts could get real hairy in a general case.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[cpp]class user_class{ channel_t ch_in; channel_t ch_out; channel_t ch_err; void user_function(){ int x = 5; while(!ch_in.try_read()){ int z = 20; leave(); ch_out.write(x*60+z); if(global_get_stop_flag()) break; } if(global_stop_not_allowed()) ch_err.write(-1); }[/cpp]Assume global_* do not pose a problem here.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Can't you just increment task's ref_count and then call wait_for_all() to block the task, and then, when you want to resume it, decrement it from other thread?
Daniel
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page