This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: libstdc++/7445: poor performance of std::locale::classic() inmulti-threaded applications


Andrew Pollard wrote:
>   The recent checkin to libstdc++--v3/src/locale.cc that went into V3.2 (and
> the trunk) isn't really correct - it probably works, but there is a problem
> if two threads call the method at the same time.

Egads.  That would be a regression... there was a similar locale
thread bug in the past.  Does the regression test suite catch
this yet?
- Dan

p.s. here's a test I used to detect the earlier locale thread bug.
Don't remember where it came from.

strtest.cpp:

/* Program to demonstrate bug in thread safety of stringstream in gcc 3.0.
 * Usage: strtest [ threads [ iterations ] ]
 * Takes number of concurrent threads to run and number of iterations per
 * thread as arguments.
 *
 * Crash history:
 * on a 1GHz x86, strtest 30 30000 lasted about 12s, 13s, 20s, and 43s before segv,
 * but often runs several minutes until manually terminated.
 *
 * on a 200MHz ppc405, strtest 20 10000 lasted about 9s for two runs,
 * but often runs several minutes until manually terminated.
 */
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sstream>

size_t num_threads = 4;
long num_iterations = 10000;

extern "C" {
    static void *threadFunc(void *);
}

int main(int argc, char * argv[])
{
    pthread_t *threads;
    time_t tprogstart;

    if (argc > 1) {
        num_threads = atoi(argv[1]);
    }
    if (argc > 2) {
        num_iterations = atoi(argv[2]);
    }
    printf("Using %d concurrent threads for %ld iterations each.\n", num_threads
, num_iterations);
    threads = (pthread_t *)malloc(num_threads * sizeof(pthread_t));

#if !defined(__linux__)
    thr_setconcurrency(num_threads);
#endif

    tprogstart = time(NULL);
    for (long round=0;;round++) {
        printf("Round %ld: ", round); fflush(stdout);
        for (size_t i = 0; i < num_threads; ++i) {
            pthread_create(&(threads[i]), 0, threadFunc, 0);
            write(fileno(stdout), "c", 1);  // Thread created
        }

        for (size_t i = 0; i < num_threads; ++i) {
            pthread_join(threads[i], 0);
            write(fileno(stdout), "j", 1);  // Thread joined
        }
        printf(" %lds.\n", time(NULL) - tprogstart); fflush(stdout);
    }

    pthread_exit(0);

    return (0);
}

extern "C" {
    static void *threadFunc(void*)
    {
        for (long i = 0; i < num_iterations; ++i) {
            std::stringstream str;
        }
        write(fileno(stdout), "d", 1);  // Done with set of iterations

        pthread_exit(0);

        return(0);
    }
}


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]