pthreadpool: add helgrind magic to PTHREAD_TEVENT_JOB_THREAD_FENCE_*()
authorStefan Metzmacher <metze@samba.org>
Thu, 21 Jun 2018 10:43:08 +0000 (12:43 +0200)
committerRalph Boehme <slow@samba.org>
Tue, 24 Jul 2018 15:38:27 +0000 (17:38 +0200)
This avoids the expected helgrind/drd warnings on the job states which
are protected by the thread fence.

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
lib/pthreadpool/pthreadpool_tevent.c

index fbf9c0e..821d13b 100644 (file)
 #include "lib/util/dlinklist.h"
 #include "lib/util/attr.h"
 
+/*
+ * We try to give some hints to helgrind/drd
+ *
+ * Note ANNOTATE_BENIGN_RACE_SIZED(address, size, describtion)
+ * takes an memory address range that ignored by helgrind/drd
+ * 'description' is just ignored...
+ *
+ *
+ * Note that ANNOTATE_HAPPENS_*(unique_uintptr)
+ * just takes a DWORD/(void *) as unique key
+ * for the barrier.
+ */
+#ifdef HAVE_VALGRIND_HELGRIND_H
+#include <valgrind/helgrind.h>
+#endif
+#ifndef ANNOTATE_BENIGN_RACE_SIZED
+#define ANNOTATE_BENIGN_RACE_SIZED(address, size, describtion)
+#endif
+#ifndef ANNOTATE_HAPPENS_BEFORE
+#define ANNOTATE_HAPPENS_BEFORE(unique_uintptr)
+#endif
+#ifndef ANNOTATE_HAPPENS_AFTER
+#define ANNOTATE_HAPPENS_AFTER(unique_uintptr)
+#endif
+#ifndef ANNOTATE_HAPPENS_BEFORE_FORGET_ALL
+#define ANNOTATE_HAPPENS_BEFORE_FORGET_ALL(unique_uintptr)
+#endif
+
 #define PTHREAD_TEVENT_JOB_THREAD_FENCE_INIT(__job) do { \
        _UNUSED_ const struct pthreadpool_tevent_job *__j = __job; \
+       ANNOTATE_BENIGN_RACE_SIZED(&__j->needs_fence, \
+                                  sizeof(__j->needs_fence), \
+                                  "race by design, protected by fence"); \
 } while(0);
 
 #ifdef WITH_PTHREADPOOL
 
 #define PTHREAD_TEVENT_JOB_THREAD_FENCE(__job) do { \
        _UNUSED_ const struct pthreadpool_tevent_job *__j = __job; \
+       ANNOTATE_HAPPENS_BEFORE(&__job->needs_fence); \
        __PTHREAD_TEVENT_JOB_THREAD_FENCE(memory_order_seq_cst); \
+       ANNOTATE_HAPPENS_AFTER(&__job->needs_fence); \
 } while(0);
 
 #define PTHREAD_TEVENT_JOB_THREAD_FENCE_FINI(__job) do { \
        _UNUSED_ const struct pthreadpool_tevent_job *__j = __job; \
+       ANNOTATE_HAPPENS_BEFORE_FORGET_ALL(&__job->needs_fence); \
 } while(0);
 
 struct pthreadpool_tevent_job_state;