diff mbox series

Add parallelism support to gcov for MinGW platforms

Message ID 1781936.tdWV9SEqCh@fomalhaut
State New
Headers show
Series Add parallelism support to gcov for MinGW platforms | expand

Commit Message

Eric Botcazou April 29, 2021, 9:43 a.m. UTC
Hi,

if you attempt a profiled bootstrap on the MinGW platforms with -jN, N > 1,
it miserably fails because of profile mismatches all over the place, the
reason being that gcov has no support for parallelism on these platforms.

The attached patch adds it and, therefore, makes it possible to do a profiled
bootstrap with -jN, N > 1, on these platforms.

Tested on x86-64/Linux, x86-64/Windows and x86/Windows, OK for the mainline?


2021-04-29  Eric Botcazou  <ebotcazou@adacore.com>

libgcc/
	* libgcc/libgcov.h: For the target, define GCOV_LOCKED_WITH_LOCKING if
	__MSVCRT__ and, for the host, define it if HOST_HAS_LK_LOCK.
	* libgcov-driver.c: Add include directives if GCOV_LOCKED_WITH_LOCKING.
gcc/
	* configure.ac: Check for the presence of sys/locking.h header and for
	whether _LK_LOCK is supported by _locking.
	* configure: Regenerate.
	* config.in: Likewise.
	* gcov-io.h: Define GCOV_LOCKED_WITH_LOCKING if HOST_HAS_LK_LOCK.
	* gcov-io.c (gcov_open): Add support for GCOV_LOCKED_WITH_LOCKING.
	* system.h: Include <sys/locking.h> if HAVE_SYS_LOCKING_H.

Comments

Richard Biener April 29, 2021, 12:28 p.m. UTC | #1
On Thu, Apr 29, 2021 at 1:20 PM Eric Botcazou <botcazou@adacore.com> wrote:
>
> Hi,
>
> if you attempt a profiled bootstrap on the MinGW platforms with -jN, N > 1,
> it miserably fails because of profile mismatches all over the place, the
> reason being that gcov has no support for parallelism on these platforms.
>
> The attached patch adds it and, therefore, makes it possible to do a profiled
> bootstrap with -jN, N > 1, on these platforms.
>
> Tested on x86-64/Linux, x86-64/Windows and x86/Windows, OK for the mainline?

OK.

Thanks,
Richard.

>
> 2021-04-29  Eric Botcazou  <ebotcazou@adacore.com>
>
> libgcc/
>         * libgcc/libgcov.h: For the target, define GCOV_LOCKED_WITH_LOCKING if
>         __MSVCRT__ and, for the host, define it if HOST_HAS_LK_LOCK.
>         * libgcov-driver.c: Add include directives if GCOV_LOCKED_WITH_LOCKING.
> gcc/
>         * configure.ac: Check for the presence of sys/locking.h header and for
>         whether _LK_LOCK is supported by _locking.
>         * configure: Regenerate.
>         * config.in: Likewise.
>         * gcov-io.h: Define GCOV_LOCKED_WITH_LOCKING if HOST_HAS_LK_LOCK.
>         * gcov-io.c (gcov_open): Add support for GCOV_LOCKED_WITH_LOCKING.
>         * system.h: Include <sys/locking.h> if HAVE_SYS_LOCKING_H.
>
> --
> Eric Botcazou
diff mbox series

Patch

diff --git a/gcc/configure.ac b/gcc/configure.ac
index 22305e37071..e9ba2af548a 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -1257,7 +1257,7 @@  AC_HEADER_SYS_WAIT
 AC_HEADER_TIOCGWINSZ
 AC_CHECK_HEADERS(limits.h stddef.h string.h strings.h stdlib.h time.h iconv.h \
 		 fcntl.h ftw.h unistd.h sys/file.h sys/time.h sys/mman.h \
-		 sys/resource.h sys/param.h sys/times.h sys/stat.h \
+		 sys/resource.h sys/param.h sys/times.h sys/stat.h sys/locking.h \
 		 direct.h malloc.h langinfo.h ldfcn.h locale.h wchar.h)
 
 # Check for thread headers.
@@ -1711,6 +1711,19 @@  if test $ac_cv_af_inet6 = yes; then
   [Define if AF_INET6 supported.])
 fi
 
+# Check if _LK_LOCK is supported by _locking
+AC_CACHE_CHECK(for _LK_LOCK, ac_cv_lk_lock, [
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[
+#include <io.h>
+#include <sys/locking.h>]], [[
+  int fd;
+  return _locking (fd, _LK_LOCK, 0);]])],
+[ac_cv_lk_lock=yes],[ac_cv_lk_lock=no])])
+if test $ac_cv_lk_lock = yes; then
+  AC_DEFINE(HOST_HAS_LK_LOCK, 1,
+  [Define if _LK_LOC supported by _locking.])
+fi
+
 # Restore CFLAGS, CXXFLAGS from before the gcc_AC_NEED_DECLARATIONS tests.
 CFLAGS="$saved_CFLAGS"
 CXXFLAGS="$saved_CXXFLAGS"
diff --git a/gcc/gcov-io.c b/gcc/gcov-io.c
index 80c9082a649..21ca3949c41 100644
--- a/gcc/gcov-io.c
+++ b/gcc/gcov-io.c
@@ -137,6 +137,8 @@  gcov_open (const char *name, int mode)
   s_flock.l_start = 0;
   s_flock.l_len = 0; /* Until EOF.  */
   s_flock.l_pid = getpid ();
+#elif GCOV_LOCKED_WITH_LOCKING
+  int fd;
 #endif
 
   gcov_nonruntime_assert (!gcov_var.file);
@@ -170,6 +172,34 @@  gcov_open (const char *name, int mode)
 
   gcov_var.file = fdopen (fd, (mode > 0) ? "rb" : "r+b");
 
+  if (!gcov_var.file)
+    {
+      close (fd);
+      return 0;
+    }
+#elif GCOV_LOCKED_WITH_LOCKING
+  if (mode > 0)
+    {
+      /* pass mode (ignored) for compatibility */
+      fd = open (name, O_RDONLY | O_BINARY, S_IRUSR | S_IWUSR);
+    }
+  else
+     {
+       /* Truncate if force new mode.  */
+       fd = open (name, O_RDWR | O_BINARY | O_CREAT | (mode < 0 ? O_TRUNC : 0),
+		  0666);
+    }
+  if (fd < 0)
+    return 0;
+
+  if (_locking (fd, _LK_LOCK, LONG_MAX) < 0)
+    {
+      close (fd);
+      return 0;
+    }
+
+  gcov_var.file = fdopen (fd, (mode > 0) ? "rb" : "r+b");
+
   if (!gcov_var.file)
     {
       close (fd);
diff --git a/gcc/gcov-io.h b/gcc/gcov-io.h
index 75f16a274c7..c9958f450d3 100644
--- a/gcc/gcov-io.h
+++ b/gcc/gcov-io.h
@@ -202,6 +202,12 @@  typedef uint64_t gcov_type_unsigned;
 #define GCOV_LOCKED 0
 #endif
 
+#if defined (HOST_HAS_LK_LOCK)
+#define GCOV_LOCKED_WITH_LOCKING 1
+#else
+#define GCOV_LOCKED_WITH_LOCKING 0
+#endif
+
 #define ATTRIBUTE_HIDDEN
 
 #endif /* !IN_LIBGCOV */
diff --git a/gcc/system.h b/gcc/system.h
index a3f5948aaee..6416c4e033e 100644
--- a/gcc/system.h
+++ b/gcc/system.h
@@ -360,6 +360,10 @@  extern int errno;
 # endif
 #endif
 
+#ifdef HAVE_SYS_LOCKING_H
+# include <sys/locking.h>
+#endif
+
 #ifndef SEEK_SET
 # define SEEK_SET 0
 # define SEEK_CUR 1
diff --git a/libgcc/libgcov-driver.c b/libgcc/libgcov-driver.c
index a1338b6e525..faa2df44715 100644
--- a/libgcc/libgcov-driver.c
+++ b/libgcc/libgcov-driver.c
@@ -36,10 +36,15 @@  void __gcov_init (struct gcov_info *p __attribute__ ((unused))) {}
 #else /* inhibit_libc */
 
 #include <string.h>
+
 #if GCOV_LOCKED
 #include <fcntl.h>
 #include <errno.h>
 #include <sys/stat.h>
+#elif GCOV_LOCKED_WITH_LOCKING
+#include <fcntl.h>
+#include <sys/locking.h>
+#include <sys/stat.h>
 #endif
 
 #if HAVE_SYS_MMAN_H
diff --git a/libgcc/libgcov.h b/libgcc/libgcov.h
index 7b0d367ec52..8d323db0538 100644
--- a/libgcc/libgcov.h
+++ b/libgcc/libgcov.h
@@ -89,6 +89,12 @@  typedef unsigned gcov_type_unsigned __attribute__ ((mode (QI)));
 #define GCOV_LOCKED 0
 #endif
 
+#if defined (__MSVCRT__)
+#define GCOV_LOCKED_WITH_LOCKING 1
+#else
+#define GCOV_LOCKED_WITH_LOCKING 0
+#endif
+
 #ifndef GCOV_SUPPORTS_ATOMIC
 /* Detect whether target can support atomic update of profilers.  */
 #if __SIZEOF_LONG_LONG__ == 4 && __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4
@@ -133,12 +139,19 @@  typedef unsigned gcov_type_unsigned __attribute__ ((mode (QI)));
 typedef unsigned gcov_unsigned_t;
 typedef unsigned gcov_position_t;
 /* gcov_type is typedef'd elsewhere for the compiler */
+
 #if defined (HOST_HAS_F_SETLKW)
 #define GCOV_LOCKED 1
 #else
 #define GCOV_LOCKED 0
 #endif
 
+#if defined (HOST_HAS_LK_LOCK)
+#define GCOV_LOCKED_WITH_LOCKING 1
+#else
+#define GCOV_LOCKED_WITH_LOCKING 0
+#endif
+
 /* Some Macros specific to gcov-tool.  */
 
 #define L_gcov 1