On 09/18/12 08:55, Stefan Teleman wrote:
On Mon, Sep 17, 2012 at 11:17 AM, Liviu Nicoara <nikko...@hates.ms> wrote:
I hope you agree that this synchronization is sufficient for the facet
initialization and reading of facet data.
I have reduced the number of reported race conditions in
22.locale.numpunct.mt from 12440:
I am attaching a test program which, while 100% MT-safe, is flagged by the
Solaris thread analyzer. The test program contains, conceptually, the exact
same of shared variable access like the locale management code, the facet
management code and the facet data management code. This proves, if there was a
need, that the tool results are to be further analyzed and interpreted but not
taken at literal value.
The fix we are looking for is one which corrects the initial MT failure
observed in caching the facet data, as well as it preserves the unguarded reads
of facet data for performance reasons.
Thanks.
Liviu
http://s247136804.onlinehome.us/stdcxx-1056-SPARC-20120917/22.locale.numpunct.mt.nts.1.er.html/index.html
to 288:
http://s247136804.onlinehome.us/stdcxx-1056-20120918/22.locale.numpunct.mt.5.er.html/index.html
The changes are in the following files:
http://s247136804.onlinehome.us/stdcxx-1056-20120918/facet.cpp
http://s247136804.onlinehome.us/stdcxx-1056-20120918/punct.cpp
_numpunct.h looks like this:
http://s247136804.onlinehome.us/stdcxx-1056-20120918/_numpunct.h
With these changes, no races conditions are repoted for any of the
functions in std::numpunct<T>.
Still, there are 288 race conditions being reported in
__rw_locale::__rw_locale and in std::locale::_C_get_facet. We need to
identify the source and cause of these race conditions and correct
them as well.
This is not a complete solution to the problem, because we still have
to re-write the chunk of code I eliminated from facet.cpp. It is only
step one towards finding a real solution. But, at least for now, we
have pinpointed where the source of these race conditions is located,
and what causing it.
The test program was run as: ./22.locale.numpunct.mt --nthreads=8
--nloops=10000.
More to follow.
--Stefan
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#define MAX_THREADS 128
static long counter = 0, nloops = 10000000, nthreads = 16;
static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
extern "C" {
static void*
f (void* pv)
{
for (size_t i = 0; i < nloops; ++i) {
if (counter == 0) {
pthread_mutex_lock (&lock);
if (counter == 0)
++counter;
pthread_mutex_unlock (&lock);
}
else {
// counter value is safe to use here
}
}
printf ("%ld\n", counter);
return 0;
}
}
int
main (int argc, char** argv)
{
switch (argc) {
case 3:
nloops = atol (argv [2]);
case 2:
nthreads = atol (argv [1]);
break;
}
pthread_t tid [MAX_THREADS] = { 0 };
if (nthreads > MAX_THREADS)
nthreads = MAX_THREADS;
for (int i = 0; i < nthreads; ++i) {
if (pthread_create (tid + i, 0, f, 0))
exit (-1);
}
for (int i = 0; i < nthreads; ++i) {
if (tid [i])
pthread_join (tid [i], 0);
}
return 0;
}