Add DRD as an experimental tool. Bart Van Assche is the maintainer.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@7211 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/exp-drd/drd_clientreq.c b/exp-drd/drd_clientreq.c
new file mode 100644
index 0000000..194d31f
--- /dev/null
+++ b/exp-drd/drd_clientreq.c
@@ -0,0 +1,175 @@
+#include "drd_clientreq.h"
+#include "drd_cond.h"
+#include "drd_mutex.h"
+#include "drd_suppression.h" // drd_start_suppression()
+#include "drd_thread.h"
+#include "drd_track.h"
+#include "pthread_object_size.h"
+#include "pub_core_tooliface.h" // VG_TRACK()
+#include "pub_tool_basics.h" // Bool
+#include "pub_tool_libcassert.h"
+#include "pub_tool_libcassert.h" // tl_assert()
+#include "pub_tool_libcprint.h" // VG_(message)()
+#include "pub_tool_machine.h" // VG_(get_SP)()
+#include "pub_tool_threadstate.h"
+#include "pub_tool_tooliface.h" // VG_(needs_...)()
+
+
+static void drd_spin_init_or_unlock(const Addr spinlock, const SizeT size)
+{
+ struct mutex_info* mutex_p = mutex_get(spinlock);
+ if (mutex_p)
+ {
+ mutex_unlock(spinlock);
+ }
+ else
+ {
+ mutex_init(spinlock, size);
+ }
+}
+
+static void drd_pre_cond_wait(const Addr cond, const Addr mutex)
+{
+ mutex_unlock(mutex);
+ cond_pre_wait(cond, mutex);
+}
+
+static void drd_post_cond_wait(const Addr cond, const Addr mutex)
+{
+ cond_post_wait(cond);
+ mutex_lock(mutex, PTHREAD_MUTEX_SIZE);
+}
+
+static void drd_pre_cond_signal(const Addr cond)
+{
+ cond_pre_signal(cond);
+}
+
+static void drd_pre_cond_broadcast(const Addr cond)
+{
+ cond_pre_broadcast(cond);
+}
+
+static Bool drd_handle_client_request(ThreadId tid, UWord* arg, UWord* ret)
+{
+ UWord result = 0;
+
+ switch (arg[0])
+ {
+ case VG_USERREQ__GET_THREAD_SELF:
+ result = tid;
+ break;
+
+ case VG_USERREQ__SET_THREAD_NAME:
+ thread_set_name_fmt(VgThreadIdToDrdThreadId(VG_(get_running_tid)()),
+ (char*)arg[1], arg[2]);
+ break;
+
+ case VG_USERREQ__DRD_START_SUPPRESSION:
+ drd_start_suppression(arg[1], arg[1] + arg[2], "client");
+ break;
+
+ case VG_USERREQ__DRD_FINISH_SUPPRESSION:
+ drd_finish_suppression(arg[1], arg[1] + arg[2]);
+ break;
+
+ case VG_USERREQ__DRD_SUPPRESS_CURRENT_STACK:
+ thread_set_stack_startup(thread_get_running_tid(),
+ VG_(get_SP)(VG_(get_running_tid)()));
+ break;
+
+ case VG_USERREQ__DRD_START_NEW_SEGMENT:
+ thread_new_segment(PtThreadIdToDrdThreadId(arg[1]));
+ break;
+
+ case VG_USERREQ__DRD_START_RECORDING:
+ thread_start_recording(PtThreadIdToDrdThreadId(arg[1]));
+ break;
+
+ case VG_USERREQ__DRD_STOP_RECORDING:
+ thread_stop_recording(PtThreadIdToDrdThreadId(arg[1]));
+ break;
+
+ case VG_USERREQ__SET_PTHREADID:
+ thread_set_pthreadid(thread_get_running_tid(), arg[1]);
+ break;
+
+ case VG_USERREQ__SET_JOINABLE:
+ thread_set_joinable(PtThreadIdToDrdThreadId(arg[1]), (Bool)arg[2]);
+ break;
+
+ case VG_USERREQ__POST_THREAD_JOIN:
+ tl_assert(arg[1]);
+ drd_post_thread_join(thread_get_running_tid(),
+ PtThreadIdToDrdThreadId(arg[1]));
+ break;
+
+ case VG_USERREQ__PRE_MUTEX_INIT:
+ drd_pre_mutex_init(arg[1], arg[2]);
+ break;
+
+ case VG_USERREQ__POST_MUTEX_DESTROY:
+ drd_post_mutex_destroy(arg[1], arg[2]);
+ break;
+
+ case VG_USERREQ__PRE_PTHREAD_MUTEX_LOCK:
+ drd_pre_mutex_lock(thread_get_running_tid(), arg[1], arg[2]);
+ break;
+
+ case VG_USERREQ__POST_PTHREAD_MUTEX_LOCK:
+ drd_post_mutex_lock(thread_get_running_tid(), arg[1], arg[2]);
+ break;
+
+ case VG_USERREQ__PRE_PTHREAD_MUTEX_UNLOCK:
+ drd_pre_mutex_unlock(thread_get_running_tid(), arg[1]);
+ break;
+
+ case VG_USERREQ__SPIN_INIT_OR_UNLOCK:
+ drd_spin_init_or_unlock(arg[1], arg[2]);
+ break;
+
+ case VG_USERREQ__POST_PTHREAD_COND_INIT:
+ drd_post_cond_init(arg[1], arg[2]);
+ break;
+
+ case VG_USERREQ__PRE_PTHREAD_COND_DESTROY:
+ drd_pre_cond_destroy(arg[1], arg[2]);
+ break;
+
+ case VG_USERREQ__PRE_PTHREAD_COND_WAIT:
+ drd_pre_cond_wait(arg[1], arg[2]);
+ break;
+
+ case VG_USERREQ__POST_PTHREAD_COND_WAIT:
+ drd_post_cond_wait(arg[1], arg[2]);
+ break;
+
+ case VG_USERREQ__PRE_PTHREAD_COND_SIGNAL:
+ drd_pre_cond_signal(arg[1]);
+ break;
+
+ case VG_USERREQ__PRE_PTHREAD_COND_BROADCAST:
+ drd_pre_cond_broadcast(arg[1]);
+ break;
+
+ default:
+ VG_(message)(Vg_DebugMsg, "Unrecognized client request 0x%lx 0x%lx",
+ arg[0], arg[1]);
+ tl_assert(0);
+ return False;
+ }
+
+ *ret = result;
+ return True;
+}
+
+void drd_clientreq_init(void)
+{
+ VG_(needs_client_requests)(drd_handle_client_request);
+}
+
+/*
+ * Local variables:
+ * c-basic-offset: 3
+ * End:
+ */