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;
}

Reply via email to