Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.
2412 Discussions

std::condition_variable.wait() causes busy wait?

mgmt1969
Beginner
580 Views
Hello,

I am finding on Windows Vista with Microsoft Visual Studio that a call to std::condition_variable.wait() causes a busy wait. This is as if the wait() function was internally executing a for (;;) {} loop until the condition is met instead of putting the calling thread to sleep and being awakened by a change in the variable value.

I have found this with the Intel Thread Profiler, part of Intel's VTune 9.1. To be honest, I am not sure if this is a real issue or if it is just an error of the Thread Profiler in registering the state of the calling thread.
Has anyone found a similar behaviour?

If anyone wishes to test this issue, they can use the following code excerpt, which exercises the condition_variable.wait() function.

Cheers,
manuel

#include
#include

#include
#include

#include

using namespace std;
using namespace tbb;

int my_barrier;
mutex my_mutex;
condition_variable my_cond;

struct CountTask : public task
{
CountTask(unsigned int time) : m_time(time) {}
virtual task* execute()
{
Sleep(1000*m_time);
{
lock_guard lock(my_mutex);
printf("Got into thread %d\\n", my_barrier--);
my_cond.notify_one();
}
// Causes all available threads to fill up by spinning
while (true);
return 0;
}
unsigned int m_time;
};

int main() {
int n = task_scheduler_init::default_num_threads();
printf("n=%d\\n",n);
task_scheduler_init tbbinit( n+1 );
my_barrier = n;
for (int i = 0; i < n; ++i)
task::enqueue(*new (task::allocate_root()) CountTask(i));
{
unique_lock lock(my_mutex);
while (my_barrier > 0)
my_cond.wait(lock);
}
printf("done\\n");
return 0;
}

0 Kudos
1 Reply
Alexey_K_Intel3
Employee
580 Views

I have inspected your example withtask manager, and did not observe busy waiting.

I think the reason of your observation is that Thread Profiler (or at least the version you have) does not recognize Windows API for condition variables that was introduced in Vista. TBB checks the version of OS kernel, and uses these API functions if available.

Thread Profiler is not developedanymore, and will soon be superceded by a new tool thatis now in Beta. You might also try Locks & Waits mode of Intel Parallel Amplifier; it does not show thread activity on a timeline, but tells how much time threads were waiting. And, Windows Performance Monitor (perfmon) should also help to observe CPU (in)activity.

Reply