DRD_(rwlock_pre_unlock)(arg[1], user_rwlock);
break;
+ case VG_USERREQ__SET_PTHREAD_COND_INITIALIZER:
+ DRD_(pthread_cond_initializer) = (Addr)arg[1];
+ DRD_(pthread_cond_initializer_size) = arg[2];
+ break;
+
case VG_USERREQ__DRD_START_NEW_SEGMENT:
DRD_(thread_new_segment)(DRD_(PtThreadIdToDrdThreadId)(arg[1]));
break;
* source files.
*/
enum {
+ /* Declare the address and size of a variable with value
+ * PTHREAD_COND_INITIALIZER.
+ */
+ VG_USERREQ__SET_PTHREAD_COND_INITIALIZER = VG_USERREQ_TOOL_BASE('D', 'r'),
+ /* args: address, size. */
+
/* To ask the drd tool to start a new segment in the specified thread. */
- VG_USERREQ__DRD_START_NEW_SEGMENT = VG_USERREQ_TOOL_BASE('D', 'r'),
+ VG_USERREQ__DRD_START_NEW_SEGMENT,
/* args: POSIX thread ID. */
/* Tell drd the pthread_t of the running thread. */
#include "drd_mutex.h"
#include "pub_tool_errormgr.h" /* VG_(maybe_record_error)() */
#include "pub_tool_libcassert.h" /* tl_assert() */
+#include "pub_tool_libcbase.h" /* VG_(memcmp)() */
#include "pub_tool_libcprint.h" /* VG_(printf)() */
#include "pub_tool_machine.h" /* VG_(get_IP)() */
#include "pub_tool_threadstate.h" /* VG_(get_running_tid)() */
static Bool DRD_(s_trace_cond);
+/* Global variables. */
+
+Addr DRD_(pthread_cond_initializer);
+int DRD_(pthread_cond_initializer_size);
+
+
/* Function definitions. */
void DRD_(cond_set_report_signal_unlocked)(const Bool r)
cond);
}
- if (!p)
+ tl_assert(DRD_(pthread_cond_initializer));
+ if (!p && VG_(memcmp)((void*)cond, (void*)DRD_(pthread_cond_initializer),
+ DRD_(pthread_cond_initializer_size)) != 0)
{
not_initialized(cond);
return;
}
+ if (!p)
+ p = cond_get_or_allocate(cond);
+
cond_signal(DRD_(thread_get_running_tid)(), p);
}
}
p = DRD_(cond_get)(cond);
- if (!p)
+ tl_assert(DRD_(pthread_cond_initializer));
+ if (!p && VG_(memcmp)((void*)cond, (void*)DRD_(pthread_cond_initializer),
+ DRD_(pthread_cond_initializer_size)) != 0)
{
not_initialized(cond);
return;
}
+ if (!p)
+ p = cond_get_or_allocate(cond);
+
cond_signal(DRD_(thread_get_running_tid)(), p);
}
struct cond_info;
+/* Variable declarations. */
+
+extern Addr DRD_(pthread_cond_initializer);
+extern int DRD_(pthread_cond_initializer_size);
+
+
/* Function declarations. */
void DRD_(cond_set_report_signal_unlocked)(const Bool r);
static void DRD_(init)(void) __attribute__((constructor));
static void DRD_(check_threading_library)(void);
static void DRD_(set_main_thread_state)(void);
+static void DRD_(set_pthread_cond_initializer)(void);
/* Function definitions. */
{
DRD_(check_threading_library)();
DRD_(set_main_thread_state)();
+ DRD_(set_pthread_cond_initializer)();
}
/**
// Make sure that DRD knows about the main thread's POSIX thread ID.
VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREADID,
pthread_self(), 0, 0, 0, 0);
+}
+
+/** Tell DRD which value PTHREAD_COND_INITIALIZER has. */
+static void DRD_(set_pthread_cond_initializer)(void)
+{
+ int res;
+ static pthread_cond_t pthread_cond_initializer = PTHREAD_COND_INITIALIZER;
+
+ // Make sure that DRD knows about the main thread's POSIX thread ID.
+ VALGRIND_DO_CLIENT_REQUEST(res, -1, VG_USERREQ__SET_PTHREAD_COND_INITIALIZER,
+ &pthread_cond_initializer,
+ sizeof(pthread_cond_initializer),
+ 0, 0, 0);
}