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)


-- 

------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are 
consuming the most bandwidth. Provides multi-vendor support for NetFlow, 
J-Flow, sFlow and other flows. Make informed decisions using capacity 
planning reports. https://ad.doubleclick.net/ddm/clk/305295220;132659582;e
_______________________________________________
Valgrind-users mailing list
Valgrind-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/valgrind-users

Reply via email to