Added support for OpenMP barriers -- if libgomp.so has been built with debug information. More in general, added support for nested synchronization constructs.

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@7642 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/exp-drd/drd_thread.c b/exp-drd/drd_thread.c
index a47483a..c8ab570 100644
--- a/exp-drd/drd_thread.c
+++ b/exp-drd/drd_thread.c
@@ -63,6 +63,10 @@
    /// If true, indicates that there is a corresponding POSIX thread ID and
    /// a corresponding OS thread that is detached.
    Bool      detached_posix_thread;
+   /// Wether recording of memory accesses is active.
+   Bool      is_recording;
+   /// Nesting level of synchronization functions called by the client.
+   Int       synchr_nesting;
 } ThreadInfo;
 
 
@@ -154,6 +158,8 @@
          VG_(snprintf)(s_threadinfo[i].name, sizeof(s_threadinfo[i].name),
                        "thread %d", tid);
          s_threadinfo[i].name[sizeof(s_threadinfo[i].name) - 1] = 0;
+         s_threadinfo[i].is_recording  = True;
+         s_threadinfo[i].synchr_nesting = 0;
          if (s_threadinfo[i].first != 0)
             VG_(printf)("drd thread id = %d\n", i);
          tl_assert(s_threadinfo[i].first == 0);
@@ -330,6 +336,7 @@
 
    tl_assert(0 <= tid && tid < DRD_N_THREADS
              && tid != DRD_INVALID_THREADID);
+   tl_assert(s_threadinfo[tid].synchr_nesting == 0);
    for (sg = s_threadinfo[tid].last; sg; sg = sg_prev)
    {
       sg_prev = sg->prev;
@@ -471,6 +478,25 @@
    tl_assert(s_drd_running_tid != DRD_INVALID_THREADID);
 }
 
+int thread_enter_synchr(const DrdThreadId tid)
+{
+   tl_assert(IsValidDrdThreadId(tid));
+   return s_threadinfo[tid].synchr_nesting++;
+}
+
+int thread_leave_synchr(const DrdThreadId tid)
+{
+   tl_assert(IsValidDrdThreadId(tid));
+   tl_assert(s_threadinfo[tid].synchr_nesting >= 1);
+   return --s_threadinfo[tid].synchr_nesting;
+}
+
+int thread_get_synchr_nesting_count(const DrdThreadId tid)
+{
+   tl_assert(IsValidDrdThreadId(tid));
+   return s_threadinfo[tid].synchr_nesting;
+}
+
 /**
  * Return a pointer to the latest segment for the specified thread.
  */
@@ -720,6 +746,27 @@
    }
 }
 
+void thread_start_recording(const DrdThreadId tid)
+{
+   tl_assert(0 <= tid && tid < DRD_N_THREADS && tid != DRD_INVALID_THREADID);
+   tl_assert(! s_threadinfo[tid].is_recording);
+   s_threadinfo[tid].is_recording = True;
+}
+
+void thread_stop_recording(const DrdThreadId tid)
+{
+   tl_assert(0 <= tid && tid < DRD_N_THREADS && tid != DRD_INVALID_THREADID);
+   tl_assert(s_threadinfo[tid].is_recording);
+   s_threadinfo[tid].is_recording = False;
+}
+
+Bool thread_is_recording(const DrdThreadId tid)
+{
+   tl_assert(0 <= tid && tid < DRD_N_THREADS && tid != DRD_INVALID_THREADID);
+   return (s_threadinfo[tid].synchr_nesting == 0
+           && s_threadinfo[tid].is_recording);
+}
+
 void thread_print_all(void)
 {
    unsigned i;