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:
+ */