[1/3] Do locking for __gcov_dump and __gcov_reset as well.

Message ID a3ceda7293e6e1f45d37356c322139bb01bcefac.1585901206.git.mliska@suse.cz
State New
Headers show
Series
  • __gcov_dump improvements
Related show

Commit Message

Martin Liška April 2, 2020, 2:47 p.m.
libgcc/ChangeLog:

2020-04-03  Martin Liska  <mliska@suse.cz>

	PR gcov-profile/93623
	* Makefile.in: Add _gcov_lock_unlock to LIBGCOV_INTERFACE.
	* libgcov-interface.c (ALIAS_void_fn): Remove.
	(__gcov_lock): New.
	(__gcov_unlock): New.
	(__gcov_flush): Use __gcov_lock and __gcov_unlock.
	(__gcov_reset): Likewise.
	(__gcov_dump): Likewise.
	* libgcov.h (__gcov_lock): New declaration.
	(__gcov_unlock): Likewise.
---
 libgcc/Makefile.in         |  3 +-
 libgcc/libgcov-interface.c | 59 ++++++++++++++++++++++++++++----------
 libgcc/libgcov.h           |  6 ++++
 3 files changed, 52 insertions(+), 16 deletions(-)

Patch

diff --git a/libgcc/Makefile.in b/libgcc/Makefile.in
index 851e7657d07..e6ed153abbc 100644
--- a/libgcc/Makefile.in
+++ b/libgcc/Makefile.in
@@ -906,7 +906,8 @@  LIBGCOV_PROFILER = _gcov_interval_profiler				\
 	_gcov_time_profiler
 LIBGCOV_INTERFACE = _gcov_dump _gcov_flush _gcov_fork			\
 	_gcov_execl _gcov_execlp					\
-	_gcov_execle _gcov_execv _gcov_execvp _gcov_execve _gcov_reset
+	_gcov_execle _gcov_execv _gcov_execvp _gcov_execve _gcov_reset  \
+	_gcov_lock_unlock
 LIBGCOV_DRIVER = _gcov
 
 libgcov-merge-objects = $(patsubst %,%$(objext),$(LIBGCOV_MERGE))
diff --git a/libgcc/libgcov-interface.c b/libgcc/libgcov-interface.c
index 048b9029ff3..a8054edba57 100644
--- a/libgcc/libgcov-interface.c
+++ b/libgcc/libgcov-interface.c
@@ -42,18 +42,9 @@  void __gcov_dump (void) {}
 
 #else
 
-/* Some functions we want to bind in this dynamic object, but have an
-   overridable global alias.  Unfortunately not all targets support
-   aliases, so we just have a forwarding function.  That'll be tail
-   called, so the cost is a single jump instruction.*/
-
-#define ALIAS_void_fn(src,dst) \
-  void dst (void)	    \
-  { src (); }
-
 extern __gthread_mutex_t __gcov_flush_mx ATTRIBUTE_HIDDEN;
 
-#ifdef L_gcov_flush
+#ifdef L_gcov_lock_unlock
 #ifdef __GTHREAD_MUTEX_INIT
 __gthread_mutex_t __gcov_flush_mx = __GTHREAD_MUTEX_INIT;
 #define init_mx_once()
@@ -74,6 +65,25 @@  init_mx_once (void)
 }
 #endif
 
+/* Lock critical section for __gcov_dump and __gcov_reset functions.  */
+
+void
+__gcov_lock (void)
+{
+  init_mx_once ();
+  __gthread_mutex_lock (&__gcov_flush_mx);
+}
+
+/* Unlock critical section for __gcov_dump and __gcov_reset functions.  */
+
+void
+__gcov_unlock (void)
+{
+  __gthread_mutex_unlock (&__gcov_flush_mx);
+}
+#endif
+
+#ifdef L_gcov_flush
 /* Called before fork or exec - write out profile information gathered so
    far and reset it to zero.  This avoids duplication or loss of the
    profile information gathered so far.  */
@@ -81,13 +91,12 @@  init_mx_once (void)
 void
 __gcov_flush (void)
 {
-  init_mx_once ();
-  __gthread_mutex_lock (&__gcov_flush_mx);
+  __gcov_lock ();
 
   __gcov_dump_int ();
   __gcov_reset_int ();
 
-  __gthread_mutex_unlock (&__gcov_flush_mx);
+  __gcov_unlock ();
 }
 
 #endif /* L_gcov_flush */
@@ -143,7 +152,17 @@  __gcov_reset_int (void)
     }
 }
 
-ALIAS_void_fn (__gcov_reset_int, __gcov_reset);
+/* Exported function __gcov_reset.  */
+
+void
+__gcov_reset (void)
+{
+  __gcov_lock ();
+
+  __gcov_reset_int ();
+
+  __gcov_unlock ();
+}
 
 #endif /* L_gcov_reset */
 
@@ -163,7 +182,17 @@  __gcov_dump_int (void)
     __gcov_dump_one (root);
 }
 
-ALIAS_void_fn (__gcov_dump_int, __gcov_dump);
+/* Exported function __gcov_dump.  */
+
+void
+__gcov_dump (void)
+{
+  __gcov_lock ();
+
+  __gcov_dump_int ();
+
+  __gcov_unlock ();
+}
 
 #endif /* L_gcov_dump */
 
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index 023293e05ec..104b80bdcbb 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -253,6 +253,12 @@  extern void __gcov_reset_int (void) ATTRIBUTE_HIDDEN;
 /* User function to enable early write of profile information so far.  */
 extern void __gcov_dump_int (void) ATTRIBUTE_HIDDEN;
 
+/* Lock critical section for __gcov_dump and __gcov_reset functions.  */
+extern void __gcov_lock (void) ATTRIBUTE_HIDDEN;
+
+/* Unlock critical section for __gcov_dump and __gcov_reset functions.  */
+extern void __gcov_unlock (void) ATTRIBUTE_HIDDEN;
+
 /* The merge function that just sums the counters.  */
 extern void __gcov_merge_add (gcov_type *, unsigned) ATTRIBUTE_HIDDEN;