*/
#define ANNOTATE_CONDVAR_SIGNAL(cv) do { } while(0)
+/**
+ * Tell DRD that the condition variable at address cv is about to be signaled.
+ */
+#define ANNOTATE_CONDVAR_SIGNAL_ALL(cv) do { } while(0)
+
/**
* Tell DRD that waiting on condition variable at address cv succeeded and that
* the memory operations performed after this annotation should be considered
*/
#define ANNOTATE_CONDVAR_WAIT(cv) do { } while(0)
+/**
+ * Tell DRD to consider the memory operations that happened before a mutex
+ * unlock event and after the subsequent mutex lock event on the same mutex as
+ * ordered. This is how DRD always behaves, so this macro has been defined
+ * such that it has no effect.
+ */
+#define ANNOTATE_PURE_HAPPENS_BEFORE_MUTEX(mtx) do { } while(0)
+
/** Deprecated -- don't use this annotation. */
#define ANNOTATE_MUTEX_IS_USED_AS_CONDVAR(mtx) do { } while(0)
*/
#define ANNOTATE_WRITERLOCK_RELEASED(rwlock) ANNOTATE_RWLOCK_RELEASED(rwlock, 1)
+/*
+ * Report that a barrier has been initialized with a given barrier count. The
+ * third argument specifies whether or not reinitialization is allowed, that
+ * is, whether or not it is allowed to call barrier_init() several times
+ * without calling barrier_destroy().
+ */
+#define ANNOTATE_BARRIER_INIT(barrier, count, reinitialization_allowed) \
+ DRDCL_(annotate_barrier_init)(barrier, count, reinitialization_allowed)
+
+/* Report that a barrier has been destroyed. */
+#define ANNOTATE_BARRIER_DESTROY(barrier) \
+ DRDCL_(annotate_barrier_destroy)(barrier)
+
+/* Report that the calling thread is about to start waiting for a barrier. */
+#define ANNOTATE_BARRIER_WAIT_BEFORE(barrier) \
+ DRDCL_(annotate_barrier_wait_before)(barrier)
+
+/* Report that the calling thread has just finished waiting for a barrier. */
+#define ANNOTATE_BARRIER_WAIT_AFTER(barrier) \
+ DRDCL_(annotate_barrier_wait_after)(barrier)
+
/**
* Tell DRD that a FIFO queue has been created. The abbreviation PCQ stands for
* <em>producer-consumer</em>.
#define ANNOTATE_BENIGN_RACE(addr, descr) \
DRDCL_(ignore_range)(addr, sizeof(*addr))
+/* Same as ANNOTATE_BENIGN_RACE(address, description), but applies to
+ the memory range [address, address+size). */
+#define ANNOTATE_BENIGN_RACE_SIZED(address, size, description) \
+ DRDCL_(ignore_range)(addr, size)
+
/** Tell DRD to ignore all reads performed by the current thread. */
#define ANNOTATE_IGNORE_READS_BEGIN() DRDCL_(set_record_loads)(0)
VG_USERREQ__DRD_SET_THREAD_NAME,
/* args: null-terminated character string. */
+ /* Tell DRD that a DRD annotation has not yet been implemented. */
+ VG_USERREQ__DRD_ANNOTATION_UNIMP,
+ /* args: Char*. */
+
/* Tell DRD that a user-defined reader-writer synchronization object
* has been created. */
VG_USERREQ__DRD_ANNOTATE_RWLOCK_CREATE
= VG_USERREQ_TOOL_BASE('H','G') + 256 + 18,
/* args: Addr, Int is_rw. */
- /* Tell DRD that an annotation has not yet been implemented. */
- VG_USERREQ__DRD_ANNOTATION_UNIMP
+ /* Tell DRD that a Helgrind annotation has not yet been implemented. */
+ VG_USERREQ__HELGRIND_ANNOTATION_UNIMP
= VG_USERREQ_TOOL_BASE('H','G') + 256 + 32,
/* args: Char*. */
rwlock, is_w, 0, 0, 0);
}
+static __inline__
+void DRDCL_(annotate_barrier_init)(const void* barrier, const unsigned count,
+ const int reinitialization_allowed)
+{
+ int res;
+ VALGRIND_DO_CLIENT_REQUEST(res, 0,
+ VG_USERREQ__DRD_ANNOTATION_UNIMP,
+ "ANNOTATE_BARRIER_INIT", 0, 0, 0, 0);
+}
+
+static __inline__
+void DRDCL_(annotate_barrier_destroy)(const void* barrier)
+{
+ int res;
+ VALGRIND_DO_CLIENT_REQUEST(res, 0,
+ VG_USERREQ__DRD_ANNOTATION_UNIMP,
+ "ANNOTATE_BARRIER_DESTROY", 0, 0, 0, 0);
+}
+
+static __inline__
+void DRDCL_(annotate_barrier_wait_before)(const void* barrier)
+{
+ int res;
+ VALGRIND_DO_CLIENT_REQUEST(res, 0,
+ VG_USERREQ__DRD_ANNOTATION_UNIMP,
+ "ANNOTATE_BARRIER_WAIT_BEFORE", 0, 0, 0, 0);
+}
+
+static __inline__
+void DRDCL_(annotate_barrier_wait_after)(const void* barrier)
+{
+ int res;
+ VALGRIND_DO_CLIENT_REQUEST(res, 0,
+ VG_USERREQ__DRD_ANNOTATION_UNIMP,
+ "ANNOTATE_BARRIER_WAIT_AFTER", 0, 0, 0, 0);
+}
+
+
+/**
+ * @addtogroup RaceDetectionAnnotations
+ */
+/*@{*/
+
+#ifdef __cplusplus
+/* ANNOTATE_UNPROTECTED_READ is the preferred way to annotate racy reads.
+
+ Instead of doing
+ ANNOTATE_IGNORE_READS_BEGIN();
+ ... = x;
+ ANNOTATE_IGNORE_READS_END();
+ one can use
+ ... = ANNOTATE_UNPROTECTED_READ(x); */
+template <typename T>
+inline T ANNOTATE_UNPROTECTED_READ(const volatile T& x) {
+ ANNOTATE_IGNORE_READS_BEGIN();
+ const T result = x;
+ ANNOTATE_IGNORE_READS_END();
+ return result;
+}
+/* Apply ANNOTATE_BENIGN_RACE_SIZED to a static variable. */
+#define ANNOTATE_BENIGN_RACE_STATIC(static_var, description) \
+ namespace { \
+ static class static_var##_annotator \
+ { \
+ public: \
+ static_var##_annotator() \
+ { \
+ ANNOTATE_BENIGN_RACE(&static_var, #static_var ": " description); \
+ } \
+ } the_##static_var##_annotator; \
+ }
+#endif
+
+/*@}*/
+
#endif /* __VALGRIND_DRD_H */
VG_(pp_ExeContext)(VG_(get_error_where)(e));
break;
}
- case UnimpClReq: {
+ case UnimpHgClReq: {
UnimpClReqInfo* uicr =(UnimpClReqInfo*)(VG_(get_error_extra)(e));
VG_(message)(Vg_UserMsg,
"The annotation macro %s has not yet been implemented in"
VG_(pp_ExeContext)(VG_(get_error_where)(e));
break;
}
+ case UnimpDrdClReq: {
+ UnimpClReqInfo* uicr =(UnimpClReqInfo*)(VG_(get_error_extra)(e));
+ VG_(message)(Vg_UserMsg,
+ "The annotation macro %s has not yet been implemented in"
+ " <valgrind/drd.h>\n",
+ uicr->descr);
+ VG_(pp_ExeContext)(VG_(get_error_where)(e));
+ break;
+ }
default:
VG_(message)(Vg_UserMsg,
"%s\n",
return sizeof(GenericErrInfo);
case InvalidThreadId:
return sizeof(InvalidThreadIdInfo);
- case UnimpClReq:
+ case UnimpHgClReq:
+ return sizeof(UnimpClReqInfo);
+ case UnimpDrdClReq:
return sizeof(UnimpClReqInfo);
default:
tl_assert(False);
skind = GenericErr;
else if (VG_(strcmp)(name, STR_InvalidThreadId) == 0)
skind = InvalidThreadId;
- else if (VG_(strcmp)(name, STR_UnimpClReq) == 0)
- skind = UnimpClReq;
+ else if (VG_(strcmp)(name, STR_UnimpHgClReq) == 0)
+ skind = UnimpHgClReq;
+ else if (VG_(strcmp)(name, STR_UnimpDrdClReq) == 0)
+ skind = UnimpDrdClReq;
else
return False;
case HoldtimeErr: return VGAPPEND(STR_, HoldtimeErr);
case GenericErr: return VGAPPEND(STR_, GenericErr);
case InvalidThreadId: return VGAPPEND(STR_, InvalidThreadId);
- case UnimpClReq: return VGAPPEND(STR_, UnimpClReq);
+ case UnimpHgClReq: return VGAPPEND(STR_, UnimpHgClReq);
+ case UnimpDrdClReq: return VGAPPEND(STR_, UnimpDrdClReq);
default:
tl_assert(0);
}