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

concurrent_unordered_map crashes in parallel code (OpenMP)

Popov__Maxim
Beginner
474 Views
Hi!

The samplesource code to represent a bug:
[cpp]typedef tbb::concurrent_unordered_map< DWORD, int > tbb_cum_type;
tbb_cum_type tbb_cum;

int _tmain(int argc, _TCHAR* argv[])
{
	for(int i=0; i<100000; ++i) {
#pragma omp parallel num_threads(8)
		{
			int l = 0;
			for(int k=rand(); k>0; --k) {
				l += k;
			}

			DWORD dwThreadID = GetCurrentThreadId();
			tbb_cum[ dwThreadID ] = l;
		}

		tbb_cum.clear();
	}

	return 0;
}[/cpp]
It crashes both in release and debug builds. I'm using TBB 3.0 (tried different revisions), MSVS C++ compiler (2008 9.0.30729.1 SP).
Could you help me and find what is wrong?

Call stack is slightly different each time, but for example it is:

OpenMPtest2.exe!tbb::interface5::internal::flist_iterator<:INTERFACE5::INTERNAL::SPLIT_ORDERED_LIST><:PAIR>,tbb::tbb_allocator<:PAIR> > >,std::pair >::flist_iterator<:INTERFACE5::INTERNAL::SPLIT_ORDERED_LIST><:PAIR>,tbb::tbb_allocator<:PAIR> > >,std::pair >(const tbb::interface5::internal::flist_iterator<:INTERFACE5::INTERNAL::SPLIT_ORDERED_LIST><:PAIR>,tbb::tbb_allocator<:PAIR> > >,std::pair > & other={...}) Line 78 + 0xd bytes C++

OpenMPtest2.exe!tbb::interface5::internal::concurrent_unordered_base<:INTERFACE5::CONCURRENT_UNORDERED_MAP_TRAITS>,std::equal_to >,tbb::tbb_allocator<:PAIR> >,0> >::get_bucket(unsigned int bucket=0) Line 1315 + 0x1e bytes C++

OpenMPtest2.exe!tbb::interface5::internal::concurrent_unordered_base<:INTERFACE5::CONCURRENT_UNORDERED_MAP_TRAITS>,std::equal_to >,tbb::tbb_allocator<:PAIR> >,0> >::init_bucket(unsigned int bucket=4) Line 1273 C++

OpenMPtest2.exe!tbb::interface5::internal::concurrent_unordered_base<:INTERFACE5::CONCURRENT_UNORDERED_MAP_TRAITS>,std::equal_to >,tbb::tbb_allocator<:PAIR> >,0> >::internal_find(const unsigned long & key=10668) Line 1162 C++

OpenMPtest2.exe!tbb::interface5::internal::concurrent_unordered_base<:INTERFACE5::CONCURRENT_UNORDERED_MAP_TRAITS>,std::equal_to >,tbb::tbb_allocator<:PAIR> >,0> >::find(const unsigned long & key=10668) Line 900 + 0x10 bytes C++

OpenMPtest2.exe!tbb::interface5::concurrent_unordered_map,std::equal_to,tbb::tbb_allocator<:PAIR> > >::operator[](const unsigned long & key=10668) Line 194 C++

> OpenMPtest2.exe!wmain$omp$1() Line 74 + 0xe bytes C++

vcomp90.dll!_vcomp::ParallelRegion::HandlerThreadFunc(void * context=0x00403d80, unsigned long index=1) Line 293 + 0x3b bytes C++

vcomp90.dll!_vcomp::PersistentThreadFunc(void * pvContext=0x00000001) Line 215 C++

kernel32.dll!7d4dfe37()

0 Kudos
3 Replies
Alexey-Kukanov
Employee
474 Views
Thanks Maxim, we will take a look. At glance, there seems to be nothing wrong in your code. Can you please tell which TBB version you use?

Also if your goal is to have a container that keeps thread-specific data values (as the code suggests), let me recommend you to try tbb::enumerable_thread_specific or tbb::combinable classes.
0 Kudos
Popov__Maxim
Beginner
474 Views
Alexey, thank you for advice

Yes, I need a storage to hold some thread specific data (I'm using caching, which should work both in TBB and OpenMP threads). I will look at tbb::enumerable_thread_specific and tbb::combinable, thank you once more.

Regarding TBB version. I failed to find the exact version number in our commercial installation (it is 3.0.x for sure). But I tried version 3.0.5 with the same result (it also craches).

Best regards,
Maxim
0 Kudos
Anton_M_Intel
Employee
474 Views
Maxim, thanks for the report. There is a race in concurrent initialization code (call to init_bucket(0)) that is enabled by clear() method. It will be fixed in the next release.
0 Kudos
Reply