Intel® oneAPI Threading Building Blocks
Ask questions and share information about adding parallelism to your applications when using this threading library.
This community is designed for sharing of public information. Please do not share Intel or third-party confidential information here.

concurrent_vector push_back segfault


I'm working on parallelizing some open source code (SystemC) that is using std::vector
After replacing it with tbb::concurrent_vector, segfault occurs (deterministically, not a race condition).

Details follow.

System info (output of 'make info' of tbb):
OS: linux

I could not copy my Makefile here, simply because SystemC is a rather big project, using automake, etc. but I've already build it with some tbb constructs succesfully.

::tbb::concurrent_vector m_delta_events;

According to the eclipse call hierarchy command & gdb, the first time the member is accessed is in the following code:
sc_simcontext::add_delta_event( sc_event* e )
m_delta_events.push_back( e );
return ( m_delta_events.size() - 1 );

e is not null, however *e is not initialized.

The backtrace:
#0 0xb7796bdd in __TBB_machine_load_store::load_with_acquire (location=@0x6c) at ../../include/tbb/machine/linux_ia32.h:181
#1 0xb7796c05 in __TBB_machine_load_with_acquire (location=@0x6c) at ../../include/tbb/machine/linux_ia32.h:210
#2 0xb7797558 in tbb::internal::concurrent_vector_base_v3::helper::acquire_segment (v=@0x809e098, index=27, element_size=4, owner=false) at ../../src/tbb/concurrent_vector.cpp:117
#3 0xb77960a7 in tbb::internal::concurrent_vector_base_v3::internal_push_back (this=0x809e098, element_size=4, index=@0xbfcdabe0) at ../../src/tbb/concurrent_vector.cpp:422
#4 0x0804bdeb in tbb::concurrent_vector<:SC_EVENT> >::push_back (this=0x809e094, item=@0xbfcdac24) at /tmp/sdaniele/local/tbb30_20100310oss/include/tbb/concurrent_vector.h:660
#5 0x0804beb4 in sc_core::sc_simcontext::add_delta_event (this=0x809e058, e=0xbfcdad60) at /tmp/sdaniele/trunk/code/current/systemc-2.2.0/include/sysc/kernel/sc_simcontext.h:509
#6 0x08066e8f in sc_core::sc_event::notify_internal (this=0xbfcdad60, t=@0xbfcdad44) at ../../../../src/sysc/kernel/sc_event.h:244
#7 0x0806c87b in sc_clock (this=0xbfcdace8, name_=0x80839b3 "Clock_1", period_v_=1, period_tu_=sc_core::SC_MS, duty_cycle_=0.5) at ../../../../src/sysc/communication/sc_clock.cpp:152
#8 0x0804a6f1 in sc_main (argc=6, argv=0xbfcdaf84) at main.cpp:51
#9 0x0805362e in sc_elab_and_sim (argc=6, argv=0xbfcdaf84) at ../../../../src/sysc/kernel/sc_main_main.cpp:99
#10 0x08052e38 in main (argc=6, argv=0xbfcdaf84) at ../../../../src/sysc/kernel/sc_main.cpp:70

Thanks in advance,

Daniel Krikun
0 Kudos
1 Reply
Hi, it is hard to say why segfault happens without at least top-level scheme of how/where/when concurrent_vector is used, created, and destroyed. I guess some serial (not-thread-safe) method is used simultaneously with concurrent push_back(). It can be clear()/destruction, swap(), assign, and etc.

I also noticed another problem in your code:
m_delta_events.push_back( e );
return ( m_delta_events.size() - 1 );
It is not guaranteed that size() will return index of previously executed push_back(). 1) They are not synchronized. 2) size()-1 can return an index less than an index of the most recent inserted element (see why).
If you need an index of the element inserted by this push_back(), please use iterator returned by the call. E.g. index=my.push_back()-my.begin();
And if index would be used to access the element later, you might want to optimize out unnecessary address calculation in operator [] by using that iterator (or pointer) directly.