- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have the latest version of TBB from github, it is not modified.
Windows version, x64, compiled with VS2017 using the tbb provided solution.
Most of the time when I boot my application it will crash on startup as one of the spawned threads attempts to set the MXCSR.
The error is access violation reading 0xFFFFFFFF.
I checked the dissassembly, and it is the instruction LDMXCSR that crashes.
At line 418 of custom_scheduler.h:
context_guard.set_ctx( __TBB_CONTEXT_ARG1(t->prefix().context) );
This invokes set_env: line 242 of msvc_ia32_common.h
Which calls __TBB_set_cpu_ctl_env
And crashes.
It does not crash every time, probably around 85% it crashes.
I "fixed" it by removing this line: context_guard.set_ctx( __TBB_CONTEXT_ARG1(t->prefix().context) );
And not setting the MXCSR
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
What TBB interfaces do you use? Do you use the enqueue interface?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I do use enqueue fairly heavily(most of my tasks use it over spawn)
Other stuff I use:
-spawn(very rarely)
-flow graph(but I think the crash happens before it comes online)
-lots of uses of spin_mutex/mutex/concurrent_queue/concurrent_vector
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
How do you allocate the tasks for enqueuing? What tbb::task_group_context they reference to? (My supposition is that tbb::task_group_context is destroyed before the enqueued task is finished).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Alex,
I tested it to see what was being enque'd prior to the crash, it shows two tasks, they both use the same code path.
TBB_Task<task_type>* t = new(tbb::task::allocate_root()) TBB_Task<task_type>(std::move(task));
tbb::task::enqueue(*t, tbb::priority_normal);
TBB_Task looks like this:
template <class Functor> class TBB_Task : public tbb::task {
Functor _Job;
tbb::task *execute() final{
math::disable_denormalized_floating_point();
_Job();
return nullptr;
}
public:
TBB_Task(Functor &&fxn) : _Job(std::move(fxn)) {}
};
(removing the call to disable_denormalized_floating_point doesn't change anything)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I am afraid about tbb::task::allocate_root() because it is uses the task_group_context of currently executing task. Do you call it inside some TBB algorithm?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi Alex,
I checked and yes both of them are being called within a call to tbb::parallel_invoke, they are nested within the same lambda, so they are launched serially when it is invoked.
I see what you are saying, it is using an expired context from parallel_invoke.
spawn does not suffer from this I take it?
(EDIT) nm spawn is worse and doesn't run at all
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You can use an explicit tbb::task_group_context with tbb::allocate_root to avoid implicit binding to the context of tbb::parallel_invoke. However, my concern is why do you need low level tasking (that has multiple hidden issues like that)? You may want to use task_group or flow graph if you need some sort of asynchronous tasking.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page