如何注释源代码(见下文)以阻止valgrind的DRD工具抱怨数据争用?
我认为这个来源并不包含任何数据竞争,但DRD认为不然。这是因为在这种情况下不使用常见的同步原语(如互斥)。代码依赖于CPU交换“' s”的可能性。原子指针。
请参阅以下来源中的评论。
#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
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;
}