From d39f7dc8d558ca31a661b02d08ff090ce65e6652 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Tue, 5 May 2020 16:15:45 +0200 Subject: [PATCH] Do locking for __gcov_dump and __gcov_reset as well. 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/ChangeLog | 13 +++++++++ libgcc/Makefile.in | 3 +- libgcc/libgcov-interface.c | 59 ++++++++++++++++++++++++++++---------- libgcc/libgcov.h | 6 ++++ 4 files changed, 65 insertions(+), 16 deletions(-) diff --git a/libgcc/ChangeLog b/libgcc/ChangeLog index 02b36d3a380..fbf2bd1c98f 100644 --- a/libgcc/ChangeLog +++ b/libgcc/ChangeLog @@ -1,3 +1,16 @@ +2020-05-05 Martin Liska + + 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. + 2020-05-01 Uroš Bizjak * config/i386/sfp-exceptions.c (__math_force_eval): New define. 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; -- 2.30.2