|
From: Julian S. <js...@ac...> - 2010-01-28 17:31:06
|
On Thursday 28 January 2010, Julian Seward wrote:
> > Yeaaa.
> > Still, I want a unit test were the current implementation hides a race.
> > W/o a unittest, how do we test that the new implementation is correct (or
> > at least better)?
>
> Fair enough.
>
> Something like this [...]
Demo program using libpthread is below.
Helgrind(trunk) says
==15851== Possible data race during write of size 4 at 0x601060 by thread #4
==15851== at 0x4007D8: actions_b1 (pthb_reuse_race.c:34)
==15851== by 0x4C29752: mythread_wrapper (hg_intercepts.c:202)
==15851== by 0x4E3403F: start_thread (in /lib64/libpthread-2.8.so)
==15851== by 0x511C08C: clone (in /lib64/libc-2.8.so)
==15851== This conflicts with a previous write of size 4 by thread #2
==15851== at 0x400812: actions_a1 (pthb_reuse_race.c:19)
==15851== by 0x4C29752: mythread_wrapper (hg_intercepts.c:202)
==15851== by 0x4E3403F: start_thread (in /lib64/libpthread-2.8.so)
==15851== by 0x511C08C: clone (in /lib64/libc-2.8.so)
DRD(trunk) doesn't say anything.
TSan also doesn't say anything.
J
#define _GNU_SOURCE
#include <assert.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
/* Shared location, accessed by A1 (or A2) and B1 (or B2) */
int L;
/* The barrier, size 2 */
pthread_barrier_t B;
// A1/A2: write L, then wait for barrier, then sleep
void* actions_a1 ( void* v ) {
L = 1;
pthread_barrier_wait(&B);
sleep(1);
return NULL;
}
void* actions_a2 ( void* v ) {
pthread_barrier_wait(&B);
sleep(1);
return NULL;
}
// B1/B2: sleep, wait for barrier, then write L
void* actions_b1 ( void* v ) {
sleep(1);
pthread_barrier_wait(&B);
L = 1;
return NULL;
}
void* actions_b2 ( void* v ) {
sleep(1);
pthread_barrier_wait(&B);
return NULL;
}
int main ( void )
{
pthread_t a1, a2, b1, b2;
pthread_barrier_init(&B, NULL, 2);
pthread_create(&a1, NULL, actions_a1, NULL);
pthread_create(&a2, NULL, actions_a2, NULL);
pthread_create(&b1, NULL, actions_b1, NULL);
pthread_create(&b2, NULL, actions_b2, NULL);
pthread_join(a1, NULL);
pthread_join(a2, NULL);
pthread_join(b1, NULL);
pthread_join(b2, NULL);
return 0;
}
|