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

Basis question

renorm
Beginner
105 Views
Does concurrent wringing the same value to the primitive variable needs to be synchronized?
[cpp]bool updated_flag = false; // indicates that the data was updated

/* Any thread which modifies the data must set
   updated_flag = true
*/

/* Later, after reaching the serial section, check the value of updated_flag.
   updated_flag == true indicates, that the data was modified.
*/[/cpp]
Either all threads write the same value into updated_flag or all threads leave updated_flag unchanged. I could replace updated_flag with an atomic variable, but don't want to do it unless there is a need.
0 Kudos
7 Replies
RafSchietekat
Black Belt
105 Views
If I understand the scenario correctly you can probably get away with it, for a boolean anyway, but why not just do the right thing?
Dmitry_Vyukov
Valued Contributor I
105 Views
Quoting renorm
Does concurrent wringing the same value to the primitive variable needs to be synchronized?

From POSIX point of view - yes.
From Win32 point of view - most likely yes.
From C99/C++03 point of view - it's not specified, so usually one of the above.
From C1x/C++0x point of view - yes.


renorm
Beginner
105 Views
The right thing is to use atomic. But an atomic variable has no constructor. It is inconvenient, sometimes. For example, this doesn't work.
[cpp]struct A {
    static tbb::atomic flag_;
};

tbb::atomic A::flag_ = true;[/cpp]
Dmitry_Vyukov
Valued Contributor I
105 Views
Global objects are zero initialized. So just call your flag not_flag_.
ARCH_R_Intel
Employee
105 Views
By the way, the reason that atomic has no constructors is that in examples like renorm's, there's no way to ensure that dynamic initialization of flag_ occurs before the first access. By not having any constructors, we enable the use of the zero initialization trick.

Of course with C++0x, we could use the constexpr feature to fix the problem. Though then code is likely to use C++0x atomics anyway.

If timing of dynamic initialization is not an issue, a work-around is to subclass atomic with a class that has the desired constructor. Though in practice I use Dmitriy's suggestion of naming things so that zero initialization works.

- Arch

renorm
Beginner
105 Views
I will use Dmitriy's suggestion as well. Thanks.
Dmitry_Vyukov
Valued Contributor I
105 Views
By the way, the reason that atomic has no constructors is that in examples like renorm's, there's no way to ensure that dynamic initialization of flag_ occurs before the first access. By not having any constructors, we enable the use of the zero initialization trick.

Of course with C++0x, we could use the constexpr feature to fix the problem. Though then code is likely to use C++0x atomics anyway.

If timing of dynamic initialization is not an issue, a work-around is to subclass atomic with a class that has the desired constructor. Though in practice I use Dmitriy's suggestion of naming things so that zero initialization works.


There is another possibility (which is sometimes applied to things like atomics and mutexes). Create basic_atomic class which is a POD type. Not that handy to use, but can be initialized to any value.

Reply