On 09/17/12 11:44, Stefan Teleman wrote:
On Mon, Sep 17, 2012 at 11:38 AM, Wojciech Meyer <wojciech.me...@arm.com> wrote:
so which compilers do fail? You know, some of them might use the same
component.
Intel Compiler/Thread Analyzer on Linux, SunPro Compiler/Thread
Analyzer on Linux and Solaris (Intel and SPARC). All three of them
show the same exact problems.
The Intel Compilers and the SunPro Compilers have nothing in common
with each other.
FWIW, I would like to offer a simple explanation for the similar results you
are seeing with the two thread analyzers. In the first experiment the analyzer
sees unguarded reads of _C_impdata, _C_impsize, et al., whereas in the second
experiment both reads and writes are covered under the umbrella of the `class'
mutex guard which is locked on each public interface call.
Just for the record, the unguarded reads are deliberate and they enhance the
performance of access to the facet POD data. They are there under the
assumption that MT read accesses are safe as long as the writes are properly
guarded.
However, after more careful thought, I think there is a problem there even
though we don't have an objective proof for it, yet.
The writes are not atomic and they function just like DCII, being subject to
both compiler reordering and out of order execution. E.g., it is assumed that
the writes to the _C_impsize and _C_impdata members occur in the program order,
which would make unguarded reads/tests of _C_impsize safe. This is what the
facet initialization and access code does, conceptually:
if (_C_impsize) {
// already initialized, use data
}
else {
// initialize
mutex.lock ();
_C_impdata = get_data_from_database ();
_C_impsize = get_data_size ();
mutex.unlock ();
}
The mutex lock and unlock operations introduce memory barriers but they are not
guaranteeing the order in which the two writes occur. If the writes would occur
in the exact program order, unguarded reads and tests of _C_impsize would be
safe. Unfortunately, a thread may see the _C_impsize variable being updated
before the _C_impdata.
Martin?
Thanks,
Liviu