]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Addition of helgrind client request VALGRIND_HG_GNAT_DEPENDENT_MASTER_JOIN
authorPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Mon, 28 Nov 2016 18:16:27 +0000 (18:16 +0000)
committerPhilippe Waroquiers <philippe.waroquiers@skynet.be>
Mon, 28 Nov 2016 18:16:27 +0000 (18:16 +0000)
See helgrind.h for description

git-svn-id: svn://svn.valgrind.org/valgrind/trunk@16158

NEWS
helgrind/helgrind.h
helgrind/hg_main.c

diff --git a/NEWS b/NEWS
index 25f94a9426faa09e38d44bfac7f0d1a5aa6c5f5c..3ff733d3b1ea07ed33d417561106389667309177 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -47,6 +47,8 @@ X86/MacOSX 10.11/12, AMD64/MacOSX 10.11/12 and TILEGX/Linux.
 
   - Support for --xtree-memory and 'xtmemory [<filename>]>'.
 
+  - addition of client request VALGRIND_HG_GNAT_DEPENDENT_MASTER_JOIN,
+    useful for Ada gnat compiled applications.
 
 * ==================== OTHER CHANGES ====================
 
index d194c4473d61a78973e880a1ed9361b2f6853afb..f560a4db91d7b5d9180f9b31ad845a9ddd0d69cd 100644 (file)
@@ -133,7 +133,8 @@ typedef
       _VG_USERREQ__HG_PTHREAD_COND_SIGNAL_POST,   /* pth_cond_t* */
       _VG_USERREQ__HG_PTHREAD_COND_BROADCAST_POST,/* pth_cond_t* */
       _VG_USERREQ__HG_RTLD_BIND_GUARD,            /* int flags */
-      _VG_USERREQ__HG_RTLD_BIND_CLEAR             /* int flags */
+      _VG_USERREQ__HG_RTLD_BIND_CLEAR,            /* int flags */
+      _VG_USERREQ__HG_GNAT_DEPENDENT_MASTER_JOIN  /* void*d, void*m */
    } Vg_TCheckClientRequest;
 
 
@@ -424,6 +425,37 @@ typedef
       _res;                                                  \
    }))
 
+/* End-user request for Ada applications compiled with GNAT.
+   Helgrind understands the Ada concept of Ada task dependencies and
+   terminations. See Ada Reference Manual section 9.3 "Task Dependence 
+   - Termination of Tasks".
+   However, in some cases, the master of (terminated) tasks completes
+   only when the application exits. An example of this is dynamically
+   allocated tasks with an access type defined at Library Level.
+   By default, the state of such tasks in Helgrind will be 'exited but
+   join not done yet'. Many tasks in such a state are however causing
+   Helgrind CPU and memory to increase significantly.
+   VALGRIND_HG_GNAT_DEPENDENT_MASTER_JOIN can be used to indicate
+   to Helgrind that a not yet completed master has however already
+   'seen' the termination of a dependent : this is conceptually the
+   same as a pthread_join and causes the cleanup of the dependent
+   as done by Helgrind when a master completes.
+   This allows to avoid the overhead in helgrind caused by such tasks.
+   A typical usage for a master to indicate it has done conceptually a join
+   with a dependent task before the master completes is:
+      while not Dep_Task'Terminated loop
+         ... do whatever to wait for Dep_Task termination.
+      end loop;
+      VALGRIND_HG_GNAT_DEPENDENT_MASTER_JOIN
+        (Dep_Task'Identity,
+         Ada.Task_Identification.Current_Task);
+    Note that VALGRIND_HG_GNAT_DEPENDENT_MASTER_JOIN should be a binding
+    to a C function built with the below macro. */
+#define VALGRIND_HG_GNAT_DEPENDENT_MASTER_JOIN(_qzz_dep, _qzz_master) \
+   DO_CREQ_v_WW(_VG_USERREQ__HG_GNAT_DEPENDENT_MASTER_JOIN,           \
+                void*,(_qzz_dep),                                     \
+                void*,(_qzz_master))
+
 /*----------------------------------------------------------------*/
 /*---                                                          ---*/
 /*--- ThreadSanitizer-compatible requests                      ---*/
index 8a75a84b466b7da6c38898ea0445a25c46980998..a0724d1b5152792da26950c14da27cf74f7afbe6 100644 (file)
@@ -4883,7 +4883,7 @@ typedef
       Word  master_level; // level of dependency between master and dependent
       Thread* hg_dependent; // helgrind Thread* for dependent task.
    }
-   GNAT_dmml;
+   GNAT_dmml; // (d)ependent (m)aster (m)aster_(l)evel.
 static XArray* gnat_dmmls;   /* of GNAT_dmml */
 static void gnat_dmmls_INIT (void)
 {
@@ -5107,6 +5107,41 @@ Bool hg_handle_client_request ( ThreadId tid, UWord* args, UWord* ret)
             *ret = -1;
          break;
 
+      /* This thread (tid) (a master) is informing us that it has
+         seen the termination of a dependent task, and that this should
+         be considered as a join between master and dependent. */
+      case _VG_USERREQ__HG_GNAT_DEPENDENT_MASTER_JOIN: {
+         Word n;
+         const Thread *stayer = map_threads_maybe_lookup( tid );
+         const void *dependent = (void*)args[1];
+         const void *master = (void*)args[2];
+
+         if (0)
+         VG_(printf)("HG_GNAT_DEPENDENT_MASTER_JOIN (tid %d): "
+                     "self_id = %p Thread* = %p dependent %p\n",
+                     (Int)tid, master, stayer, dependent);
+
+         gnat_dmmls_INIT();
+         /* Similar loop as for master completed hook below, but stops at
+            the first matching occurence, only comparing master and
+            dependent. */
+         for (n = VG_(sizeXA) (gnat_dmmls) - 1; n >= 0; n--) {
+            GNAT_dmml *dmml = (GNAT_dmml*) VG_(indexXA)(gnat_dmmls, n);
+            if (dmml->master == master
+                && dmml->dependent == dependent) {
+               if (0)
+               VG_(printf)("quitter %p dependency to stayer %p (join)\n",
+                           dmml->hg_dependent->hbthr,  stayer->hbthr);
+               tl_assert(dmml->hg_dependent->hbthr != stayer->hbthr);
+               generate_quitter_stayer_dependence (dmml->hg_dependent->hbthr,
+                                                   stayer->hbthr);
+               VG_(removeIndexXA) (gnat_dmmls, n);
+               break;
+            }
+         }
+         break;
+      }
+
       /* --- --- Client requests for Helgrind's use only --- --- */
 
       /* Some thread is telling us its pthread_t value.  Record the