Re: C++ Threads, what's the status quo?
Jeff Koftinoff wrote:
With that code, the compiler is STILL permitted to re-order main() to
be:
int main()
{
count++;
StMutex lockMe( &gMutex );
}
There are no guarantees, since the compiler knows that StMutex does not
modify count. Even if you try to 'hide' the definition of StMutex, even
if it involves a kernel trap/syscall/etc - there is nothing in the c++
standard that forbids this optimization - and yes, this kind of
optimization is important to be able to have for non-mutex classes. So
how does the compiler know that this class is very special and is a
'multi-threaded sequence point'?
No, the compiler may possibly eliminate count++ (in some cases), but it
is not allowed to execute it before StMutex's constructor executes.
After all, there is a sequence point between the two statements:
"At certain specified points in the execution sequence called sequence
points, all side effects of previous evaluations shall be complete and
no side effects of subsequent evaluations shall have taken
place."[?1.9/7]
The above rule applies only to "actual code generated." The compiler is
not obligiated to generate code for every statement - statements that
have no effect on the observable state of the program can be
eliminated. But otherwise, unless the statement is eliminated, then it
must execute as ?1.9/7 requires - that is, in a specific order
relative to the program's other statements. Otherwise, if the compiler
could reorder sequence poitnts at will, it would not be possible to
write single-threaded C++ programs and be sure that they would run
correctly.
So either the program executes the statements in their current order or
it skips one or more of them. So for which ones does the compiler have
to generate code? The compiler is not allowed to optimize away StMutex.
Furthermore, since StMutex's constructor calls pthread_mutex_lock() - a
call which may or may not result in observable side effects, and its
destructor calls pthread_mutex_unlock() (which may or may not depend on
count's current value), the compiler must generate code for all three
statements that will execute in the order specified by the program.
Any solutions require compiler language extensions to force the
optimizer to not be so tricky. These compiler language extensions are
not portable. To properly support threads in C++, the C++ language
definition must standardize these kinds of things. It is not trivial,
and it is discouraging to see how much code is multi-threaded 'hanging
by a thread, working by accident' because the compiler did not do a
specific optimization - yet...
The C++ Standard does make guarantees. Those guarantees may not have
been formulated with multi-threaded operation in mind, but that does
not mean that they are useless in a multi-threaded environment either.
Greg
--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]