I've asked this question on a TBB forum, but I'm hoping someone here might have some additional thoughts. I was debugging an issue we're seeing and noticed some strange behavior from tbb::concurrent_vector
.
The bottom line is that after a push_back()
call actually completes, the size()
of the concurrent_vector
does not reflect this. I've narrowed it down to be capacity related because if I capture capacity()
and size()
, size() == capacity() => true
which leads me to believe that size()
is returning the capacity and not the actual number of elements.
I have created a simple program that duplicates this issue, which triggers most often when the vector is empty. For simplicity, this program simply ASSERTs that size() != 0
immediately after a push_back()
call returns. I hope someone can please tell me if this is expected behavior or if its a bug.
#include <boost/thread.hpp>
#include <tbb/concurrent_vector.h>
typedef tbb::concurrent_vector<int> vec_type;
void invokePushBack(vec_type * vec)
{
for(int i = 0 ; i < 10 ; ++i)
{
vec_type::iterator it = vec->push_back(1);
assert(vec->size() != 0);
}
}
int main()
{
// note: the race condition doesn't always trigger,
// so we loop until it does.
while(true)
{
vec_type vec;
boost::thread_group tg;
for(int i = 0 ; i < 5 ; ++i)
tg.create_thread(boost::bind(invokePushBack, &vec));
tg.join_all();
}
}
According to their reference manual:
push_back() "Appends copy of value to the end of the vector."
and
size() returns "Number of elements in the vector. The result may include elements that are allocated but still under construction by concurrent calls to any of the growth methods (5.6.3)."
Based on this, I believe that size()
should at least reflect the push_back()
once push_back()
returns.