Dear all,

The program below uses thread-safe static initialization to implement a 
singleton.
When analyzing this with Helgrind, a data race is reported between the 
initialization of "val" in the constructor (executed by thread 1) and the 
increment operation (executed by thread 2). This is expected, as Helgrind does 
not "understand" the synchronization generated by the compiler.

I'm looking for a way to get rid of the false positives in such cases, and 
experimented with annotations. I found that placing
    ANNOTATE_HAPPENS_AFTER(&inst);
    ANNOTATE_HAPPENS_BEFORE(&inst);
inside the getInstance() method (either in this order or reversed) makes the 
Helgrind warnings disappear.

Is this a valid approach? Are there possible side-effects? Could this "break" 
the analysis and lead to other data races going undetected?

Thanks,
Adriaan


#include <unistd.h>
#include <pthread.h>

class MySingleton {
public:
    MySingleton(int x) : val(x) {
        pthread_mutex_init(&lock, NULL);
    }
    static MySingleton *getInstance() {
        static MySingleton inst(0);
        //ANNOTATE_HAPPENS_AFTER(&inst);
        //ANNOTATE_HAPPENS_BEFORE(&inst);
        return &inst;
    }
    void increment() {
        pthread_mutex_lock(&lock);
        val++;
        pthread_mutex_unlock(&lock);
    };
private:
    pthread_mutex_t lock;
    int val;
};

void *thread_start(void *arg) {
    sleep(1);
    MySingleton::getInstance()->increment();
}

int main() {
    pthread_t a;
    pthread_create(&a, NULL, thread_start, NULL);
    MySingleton::getInstance();
    pthread_join(a, NULL);
}

------------------------------------------------------------------------------
_______________________________________________
Valgrind-users mailing list
Valgrind-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/valgrind-users

Reply via email to