|
From: Kirill F. <kir...@de...> - 2016-06-09 13:24:45
|
Hello, All!
How can I annotate source code (see below) to stop valgrind's DRD
tool complain about data race?
I think this source doesn't contain any data race, but DRD thinks
otherwise. This is because common synchronization primitives (like
mutexes) not used in this case. The code relies on possibility of CPU
to swap 's' pointer atomically.
See comments in source code below:
#include <pthread.h>
#include <unistd.h>
#include <signal.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <valgrind/drd.h>
pthread_t t1, t2;
struct S {
int x;
int y;
};
struct S *volatile s;
void *f1(void *arg)
{
ANNOTATE_BENIGN_RACE(&s, "");
(void)arg;
int n=0;
while (1) {
usleep(100000);
if (__sync_fetch_and_add(&s, 0) != 0) continue;
struct S *p=malloc(sizeof(struct S));
assert(p!=NULL);
p->x = ++n; // Conflicts with this line
p->y = ++n; // Conflicts with this line (see below)
p=__sync_lock_test_and_set(&s, p);
__sync_synchronize();
assert(p==NULL);
}
}
void *f2(void *arg)
{
ANNOTATE_BENIGN_RACE(&s, "");
(void)arg;
while (1) {
usleep(150000);
struct S *p=__sync_fetch_and_add(&s, 0);
if (p==NULL) continue;
volatile int z;
z=p->x; // Conflicting load (DRD complains on this lines)
z+=p->y; // Conflicting load
free(p);
__sync_lock_release(&s);
}
}
int main()
{
ANNOTATE_BENIGN_RACE(&s, "");
pthread_create(&t1, NULL, f1, NULL);
pthread_create(&t2, NULL, f2, NULL);
while (1) {
usleep(75000);
printf("%p\n", __sync_fetch_and_add(&s, 0));
}
return 0;
}
Valgrind output is follows:
...
==20829== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
...
==20829== Thread 3:
==20829== Conflicting load by thread 3 at 0x05c0a290 size 4
==20829== at 0x400AF1: f2 (testdrd.c:51)
==20829== by 0x4C3060B: vgDrd_thread_wrapper
(drd_pthread_intercepts.c:477)
==20829== by 0x4E4F453: start_thread (pthread_create.c:334)
==20829== Address 0x5c0a290 is at offset 0 from 0x5c0a290. Allocation
context:
==20829== at 0x4C2D02F: malloc (vg_replace_malloc.c:299)
==20829== by 0x4009EB: f1 (testdrd.c:29)
==20829== by 0x4C3060B: vgDrd_thread_wrapper
(drd_pthread_intercepts.c:477)
==20829== by 0x4E4F453: start_thread (pthread_create.c:334)
==20829== Other segment start (thread 2)
==20829== at 0x514DEA1: clone (in /lib/x86_64-linux-gnu/libc-2.22.so)
==20829== Other segment end (thread 2)
==20829== at 0x511D82D: ??? (in /lib/x86_64-linux-gnu/libc-2.22.so)
==20829== by 0x51473C3: usleep (in
/lib/x86_64-linux-gnu/libc-2.22.so)
==20829== by 0x4009CC: f1 (testdrd.c:26)
==20829== by 0x4C3060B: vgDrd_thread_wrapper
(drd_pthread_intercepts.c:477)
==20829== by 0x4E4F453: start_thread (pthread_create.c:334)
==20829== ==20829== Conflicting load by thread 3 at 0x05c0a294 size 4
==20829== at 0x400AFA: f2 (testdrd.c:52)
==20829== by 0x4C3060B: vgDrd_thread_wrapper
(drd_pthread_intercepts.c:477)
==20829== by 0x4E4F453: start_thread (pthread_create.c:334)
==20829== Address 0x5c0a294 is at offset 4 from 0x5c0a290. Allocation
context:
==20829== at 0x4C2D02F: malloc (vg_replace_malloc.c:299)
==20829== by 0x4009EB: f1 (testdrd.c:29)
==20829== by 0x4C3060B: vgDrd_thread_wrapper
(drd_pthread_intercepts.c:477)
==20829== by 0x4E4F453: start_thread (pthread_create.c:334)
==20829== Other segment start (thread 2)
==20829== at 0x514DEA1: clone (in /lib/x86_64-linux-gnu/libc-2.22.so)
==20829== Other segment end (thread 2)
==20829== at 0x511D82D: ??? (in /lib/x86_64-linux-gnu/libc-2.22.so)
==20829== by 0x51473C3: usleep (in
/lib/x86_64-linux-gnu/libc-2.22.so)
==20829== by 0x4009CC: f1 (testdrd.c:26)
==20829== by 0x4C3060B: vgDrd_thread_wrapper
(drd_pthread_intercepts.c:477)
==20829== by 0x4E4F453: start_thread (pthread_create.c:334)
--
|