From: Eric Bavier <bavier@cray.com>
To: "Ludovic Courtès" <ludo@gnu.org>
Cc: "guix-devel@gnu.org" <guix-devel@gnu.org>
Subject: Re: Disable gnulib's test-lock test in packages?
Date: Wed, 1 Nov 2017 18:56:18 +0000 [thread overview]
Message-ID: <CY4PR11MB1718E4EFD32B60529745CFEDB75F0@CY4PR11MB1718.namprd11.prod.outlook.com> (raw)
In-Reply-To: <8760ay2caa.fsf@gnu.org>
[-- Attachment #1.1: Type: text/plain, Size: 2330 bytes --]
Hello Ludo,
I ran the gnulib lock tests with the be95b17ae commit and the tests passed, then with the commit directly before and they failed; so I'm fairly confident.
Attached is an updated patch, which remove the *-gnulib-multi-core patches and disables the test on two more packages (augeas and gsasl). I was able to build most of the packages on gnulib's "users" list (https://git.savannah.gnu.org/gitweb/?p=gnulib.git;a=blob;f=users.txt;h=4ea176f2ef622b5c12843ba3d5aa35217c58502b;hb=HEAD) except for octave, because texlive-bin's luajit tests fail on this system.
Eric Bavier, Scientific Libraries, Cray Inc.
________________________________________
From: Ludovic Courtès <ludo@gnu.org>
Sent: Sunday, October 29, 2017 10:39
To: Eric Bavier
Cc: guix-devel@gnu.org
Subject: Re: Disable gnulib's test-lock test in packages?
Hi Eric,
Eric Bavier <bavier@cray.com> skribis:
> Several packages (libunistring, gettext, and libidn) in the guix bootstrap path hang on the "test-lock" test from gnulib while building on a aarch64 system I have access to. Some of them already have a patch applied that is supposed to fix the hang on system's with large core-counts, but it seems ineffective on my system. The findutils package is also affected, and there may be others, but I haven't discovered them yet.
>
> This commit in gnulib fixes the test-lock issue on my system, but doesn't help until our packages update their gnulib source:
> https://git.savannah.gnu.org/cgit/gnulib.git/commit/?id=be95b17ae933323cb757471f3d7c3f0617f9257e
>
> Not knowing any better, I created a dummy project to run the latest gnulib lock tests, attached for clarity.
So are you confident that the above commit fixes the issue?
As you might have seen, we already have
findutils-gnulib-multi-core.patch, gettext-gnulib-multi-core.patch, and
libunistring-gnulib-multi-core.patch, which turned out to be
insufficient to fix the problem.
> Until the updated lock module and tests make its way into these packages, I would like to ask if disabling these tests outright would be acceptable, similar to the attached patch. Thoughts?
Your patch looks like the safest approach; you can also remove
*gnulib-multi-core.patch while you’re at it. Then I think it’s OK for
‘core-updates’.
Thank you!
Ludo’.
[-- Attachment #1.2: Type: text/html, Size: 3348 bytes --]
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-gnu-Disable-gnulib-s-test-lock-test-in-packages.patch --]
[-- Type: text/x-patch; name="0001-gnu-Disable-gnulib-s-test-lock-test-in-packages.patch", Size: 38741 bytes --]
From 8e4988cf0da5bb170184a41822ff316e2e7f9c29 Mon Sep 17 00:00:00 2001
From: Eric Bavier <bavier@cray.com>
Date: Mon, 30 Oct 2017 11:23:46 -0500
Subject: [PATCH] gnu: Disable gnulib's test-lock test in packages.
* gnu/packages/base.scm (findutils)[source]: Disable test-lock.
* gnu/packages/gettext.scm (gettext-minimal)[source]: Ditto.
* gnu/packages/libidn.scm (libidn)[source]: Ditto.
* gnu/packages/libunistring.scm (libunistring)[source]: Ditto.
* gnu/packages/augeas.scm (augeas)[source]: Ditto.
* gnu/packages/gsasl.scm (gsasl)[source]: Ditto.
* gnu/packages/patches/findutils-gnulib-multi-core.patch,
gnu/packages/patches/gettext-gnulib-multi-core.patch,
gnu/packages/patches/gettext-multi-core.patch,
gnu/packages/patches/libunistring-gnulib-multi-core.patch: Delete patches.
* gnu/local.mk (DIST_PATCH_DATA): Remove them.
---
gnu/local.mk | 4 -
gnu/packages/augeas.scm | 13 +-
gnu/packages/base.scm | 17 +-
gnu/packages/gettext.scm | 19 +-
gnu/packages/gsasl.scm | 13 +-
gnu/packages/libidn.scm | 13 +-
gnu/packages/libunistring.scm | 15 +-
.../patches/findutils-gnulib-multi-core.patch | 294 ---------------------
.../patches/gettext-gnulib-multi-core.patch | 178 -------------
gnu/packages/patches/gettext-multi-core.patch | 185 -------------
.../patches/libunistring-gnulib-multi-core.patch | 178 -------------
11 files changed, 72 insertions(+), 857 deletions(-)
delete mode 100644 gnu/packages/patches/findutils-gnulib-multi-core.patch
delete mode 100644 gnu/packages/patches/gettext-gnulib-multi-core.patch
delete mode 100644 gnu/packages/patches/gettext-multi-core.patch
delete mode 100644 gnu/packages/patches/libunistring-gnulib-multi-core.patch
diff --git a/gnu/local.mk b/gnu/local.mk
index 90dc7ae..82aa9d9 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -618,7 +618,6 @@ dist_patch_DATA = \
%D%/packages/patches/fcgi-2.4.0-poll.patch \
%D%/packages/patches/file-CVE-2017-1000249.patch \
%D%/packages/patches/findutils-localstatedir.patch \
- %D%/packages/patches/findutils-gnulib-multi-core.patch \
%D%/packages/patches/findutils-test-xargs.patch \
%D%/packages/patches/flint-ldconfig.patch \
%D%/packages/patches/fltk-shared-lib-defines.patch \
@@ -650,8 +649,6 @@ dist_patch_DATA = \
%D%/packages/patches/gegl-CVE-2012-4433.patch \
%D%/packages/patches/gemma-intel-compat.patch \
%D%/packages/patches/geoclue-config.patch \
- %D%/packages/patches/gettext-multi-core.patch \
- %D%/packages/patches/gettext-gnulib-multi-core.patch \
%D%/packages/patches/ghc-dont-pass-linker-flags-via-response-files.patch \
%D%/packages/patches/ghostscript-CVE-2017-8291.patch \
%D%/packages/patches/ghostscript-no-header-id.patch \
@@ -817,7 +814,6 @@ dist_patch_DATA = \
%D%/packages/patches/libtirpc-CVE-2017-8779.patch \
%D%/packages/patches/libtorrent-rasterbar-boost-compat.patch \
%D%/packages/patches/libtool-skip-tests2.patch \
- %D%/packages/patches/libunistring-gnulib-multi-core.patch \
%D%/packages/patches/libusb-0.1-disable-tests.patch \
%D%/packages/patches/libusb-for-axoloti.patch \
%D%/packages/patches/libvirt-CVE-2017-1000256.patch \
diff --git a/gnu/packages/augeas.scm b/gnu/packages/augeas.scm
index 0771051..6939e41 100644
--- a/gnu/packages/augeas.scm
+++ b/gnu/packages/augeas.scm
@@ -1,6 +1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2016, 2017 Ricardo Wurmus <rekado@elephly.net>
;;; Copyright © 2017 Efraim Flashner <efraim@flashner.co.il>
+;;; Copyright © 2017 Eric Bavier <bavier@member.fsf.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -38,7 +39,17 @@
version ".tar.gz"))
(sha256
(base32
- "1yf93fqwav1zsl8dpyfkf0g11w05mmfckqy6qsjy5zkklnspbkv5"))))
+ "1yf93fqwav1zsl8dpyfkf0g11w05mmfckqy6qsjy5zkklnspbkv5"))
+ (modules '((guix build utils)))
+ (snippet
+ '(begin
+ ;; The gnulib test-lock test is prone to writer starvation
+ ;; with our glibc@2.25, which prefers readers, so disable it.
+ ;; The gnulib commit b20e8afb0b2 should fix this once
+ ;; incorporated here.
+ (substitute* "gnulib/tests/Makefile.in"
+ (("test-lock\\$\\(EXEEXT\\) ") ""))
+ #t))))
(build-system gnu-build-system)
;; Marked as "required" in augeas.pc
(propagated-inputs
diff --git a/gnu/packages/base.scm b/gnu/packages/base.scm
index 9cb628d..fb9423a 100644
--- a/gnu/packages/base.scm
+++ b/gnu/packages/base.scm
@@ -10,6 +10,7 @@
;;; Copyright © 2017 Rene Saavedra <rennes@openmailbox.org>
;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
;;; Copyright © 2017 Marius Bakke <mbakke@fastmail.com>
+;;; Copyright © 2017 Eric Bavier <bavier@member.fsf.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -263,11 +264,17 @@ interactive means to merge two files.")
"178nn4dl7wbcw499czikirnkniwnx36argdnqgz4ik9i6zvwkm6y"))
(patches (search-patches
"findutils-localstatedir.patch"
- "findutils-test-xargs.patch"
- ;; test-lock has performance issues on multi-core
- ;; machines, it hangs or takes a long time to complete.
- ;; This is a commit from gnulib to fix this issue.
- "findutils-gnulib-multi-core.patch"))))
+ "findutils-test-xargs.patch"))
+ (modules '((guix build utils)))
+ (snippet
+ '(begin
+ ;; The gnulib test-lock test is prone to writer starvation
+ ;; with our glibc@2.25, which prefers readers, so disable it.
+ ;; The gnulib commit b20e8afb0b2 should fix this once
+ ;; incorporated here.
+ (substitute* "tests/Makefile.in"
+ (("test-lock\\$\\(EXEEXT\\) ") ""))
+ #t))))
(build-system gnu-build-system)
(arguments
`(#:configure-flags (list
diff --git a/gnu/packages/gettext.scm b/gnu/packages/gettext.scm
index 76c01b1..51b772a 100644
--- a/gnu/packages/gettext.scm
+++ b/gnu/packages/gettext.scm
@@ -6,6 +6,7 @@
;;; Copyright © 2016 Alex Kost <alezost@gmail.com>
;;; Copyright © 2017 Marius Bakke <mbakke@fastmail.com>
;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
+;;; Copyright © 2017 Eric Bavier <bavier@member.fsf.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -47,12 +48,18 @@
(sha256
(base32
"0hsw28f9q9xaggjlsdp2qmbp2rbd1mp0njzan2ld9kiqwkq2m57z"))
- ;; test-lock has performance issues on multi-core machines,
- ;; it hangs or takes a long time to complete.
- ;; There is one commit in gettext and one commit
- ;; in gettext's embedded gnulib to fix this issue.
- (patches (search-patches "gettext-multi-core.patch"
- "gettext-gnulib-multi-core.patch"))))
+ (modules '((guix build utils)))
+ (snippet
+ '(begin
+ ;; The gnulib test-lock test is prone to writer starvation
+ ;; with our glibc@2.25, which prefers readers, so disable it.
+ ;; The gnulib commit b20e8afb0b2 should fix this once
+ ;; incorporated here.
+ (substitute* "gettext-runtime/tests/Makefile.in"
+ (("TESTS = test-lock\\$\\(EXEEXT\\)") "TESTS ="))
+ (substitute* "gettext-tools/gnulib-tests/Makefile.in"
+ (("test-lock\\$\\(EXEEXT\\) ") ""))
+ #t))))
(build-system gnu-build-system)
(outputs '("out"
"doc")) ;8 MiB of HTML
diff --git a/gnu/packages/gsasl.scm b/gnu/packages/gsasl.scm
index 727d0f0..3146f40 100644
--- a/gnu/packages/gsasl.scm
+++ b/gnu/packages/gsasl.scm
@@ -1,6 +1,7 @@
;;; GNU Guix --- Functional package management for GNU
;;; Copyright © 2012 Andreas Enge <andreas@enge.fr>
;;; Copyright © 2017 Ricardo Wurmus <rekado@elephly.net>
+;;; Copyright © 2017 Eric Bavier <bavier@member.fsf.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -81,7 +82,17 @@ the underlying security implementation.")
(uri (string-append "mirror://gnu/gsasl/gsasl-" version
".tar.gz"))
(sha256 (base32
- "1rci64cxvcfr8xcjpqc4inpfq7aw4snnsbf5xz7d30nhvv8n40ii"))))
+ "1rci64cxvcfr8xcjpqc4inpfq7aw4snnsbf5xz7d30nhvv8n40ii"))
+ (modules '((guix build utils)))
+ (snippet
+ '(begin
+ ;; The gnulib test-lock test is prone to writer starvation
+ ;; with our glibc@2.25, which prefers readers, so disable it.
+ ;; The gnulib commit b20e8afb0b2 should fix this once
+ ;; incorporated here.
+ (substitute* "tests/Makefile.in"
+ (("test-lock\\$\\(EXEEXT\\) ") ""))
+ #t))))
(build-system gnu-build-system)
(inputs `(("libidn" ,libidn)
("libntlm" ,libntlm)
diff --git a/gnu/packages/libidn.scm b/gnu/packages/libidn.scm
index dfb1be6..c318629 100644
--- a/gnu/packages/libidn.scm
+++ b/gnu/packages/libidn.scm
@@ -3,6 +3,7 @@
;;; Copyright © 2016, 2017 Efraim Flashner <efraim@flashner.co.il>
;;; Copyright © 2017 Marius Bakke <mbakke@fastmail.com>
;;; Copyright © 2017 Mark H Weaver <mhw@netris.org>
+;;; Copyright © 2017 Eric Bavier <bavier@member.fsf.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -38,7 +39,17 @@
".tar.gz"))
(sha256
(base32
- "068fjg2arlppjqqpzd714n1lf6gxkpac9v5yyvp1qwmv6nvam9s4"))))
+ "068fjg2arlppjqqpzd714n1lf6gxkpac9v5yyvp1qwmv6nvam9s4"))
+ (modules '((guix build utils)))
+ (snippet
+ '(begin
+ ;; The gnulib test-lock test is prone to writer starvation
+ ;; with our glibc@2.25, which prefers readers, so disable it.
+ ;; The gnulib commit b20e8afb0b2 should fix this once
+ ;; incorporated here.
+ (substitute* "lib/gltests/Makefile.in"
+ (("test-lock\\$\\(EXEEXT\\) ") ""))
+ #t))))
(build-system gnu-build-system)
;; FIXME: No Java and C# libraries are currently built.
(synopsis "Internationalized string processing library")
diff --git a/gnu/packages/libunistring.scm b/gnu/packages/libunistring.scm
index df02f68..bb7bc61 100644
--- a/gnu/packages/libunistring.scm
+++ b/gnu/packages/libunistring.scm
@@ -4,6 +4,7 @@
;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il>
;;; Copyright © 2016 Jan Nieuwenhuizen <janneke@gnu.org>
;;; Copyright © 2017 Mathieu Othacehe <m.othacehe@gmail.com>
+;;; Copyright © 2017 Eric Bavier <bavier@member.fsf.org>
;;;
;;; This file is part of GNU Guix.
;;;
@@ -40,10 +41,16 @@
(sha256
(base32
"15z76qrmrvkc3c6hfq2lzzqysgd21s682f2smycfab5g598n8drf"))
- ;; test-lock has performance issues on multi-core machines,
- ;; it hangs or takes a long time to complete.
- ;; This is a commit from gnulib to fix this issue.
- (patches (search-patches "libunistring-gnulib-multi-core.patch"))))
+ (modules '((guix build utils)))
+ (snippet
+ '(begin
+ ;; The gnulib test-lock test is prone to writer starvation
+ ;; with our glibc@2.25, which prefers readers, so disable it.
+ ;; The gnulib commit b20e8afb0b2 should fix this once
+ ;; incorporated here.
+ (substitute* "tests/Makefile.in"
+ (("test-lock\\$\\(EXEEXT\\) ") ""))
+ #t))))
(propagated-inputs (libiconv-if-needed))
(build-system gnu-build-system)
(arguments
diff --git a/gnu/packages/patches/findutils-gnulib-multi-core.patch b/gnu/packages/patches/findutils-gnulib-multi-core.patch
deleted file mode 100644
index 5a37f4f..0000000
--- a/gnu/packages/patches/findutils-gnulib-multi-core.patch
+++ /dev/null
@@ -1,294 +0,0 @@
-This patch fixes performance problems on multi-core machines
-as reported at <https://bugs.gnu.org/26441>.
-
-See commit 480d374e596a0ee3fed168ab42cd84c313ad3c89 in Gnulib
-by Bruno Haible <bruno@clisp.org>.
-
-diff --git a/tests/test-lock.c b/tests/test-lock.c
-index a992f64..fb18dee 100644
---- a/tests/test-lock.c
-+++ b/tests/test-lock.c
-@@ -1,5 +1,5 @@
- /* Test of locking in multithreaded situations.
-- Copyright (C) 2005, 2008-2015 Free Software Foundation, Inc.
-+ Copyright (C) 2005, 2008-2017 Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
-@@ -50,6 +50,28 @@
- Uncomment this to see if the operating system has a fair scheduler. */
- #define EXPLICIT_YIELD 1
-
-+/* Whether to use 'volatile' on some variables that communicate information
-+ between threads. If set to 0, a semaphore or a lock is used to protect
-+ these variables. If set to 1, 'volatile' is used; this is theoretically
-+ equivalent but can lead to much slower execution (e.g. 30x slower total
-+ run time on a 40-core machine), because 'volatile' does not imply any
-+ synchronization/communication between different CPUs. */
-+#define USE_VOLATILE 0
-+
-+#if USE_POSIX_THREADS && HAVE_SEMAPHORE_H
-+/* Whether to use a semaphore to communicate information between threads.
-+ If set to 0, a lock is used. If set to 1, a semaphore is used.
-+ Uncomment this to reduce the dependencies of this test. */
-+# define USE_SEMAPHORE 1
-+/* Mac OS X provides only named semaphores (sem_open); its facility for
-+ unnamed semaphores (sem_init) does not work. */
-+# if defined __APPLE__ && defined __MACH__
-+# define USE_NAMED_SEMAPHORE 1
-+# else
-+# define USE_UNNAMED_SEMAPHORE 1
-+# endif
-+#endif
-+
- /* Whether to print debugging messages. */
- #define ENABLE_DEBUGGING 0
-
-@@ -90,6 +112,12 @@
-
- #include "glthread/thread.h"
- #include "glthread/yield.h"
-+#if USE_SEMAPHORE
-+# include <errno.h>
-+# include <fcntl.h>
-+# include <semaphore.h>
-+# include <unistd.h>
-+#endif
-
- #if ENABLE_DEBUGGING
- # define dbgprintf printf
-@@ -103,6 +131,132 @@
- # define yield()
- #endif
-
-+#if USE_VOLATILE
-+struct atomic_int {
-+ volatile int value;
-+};
-+static void
-+init_atomic_int (struct atomic_int *ai)
-+{
-+}
-+static int
-+get_atomic_int_value (struct atomic_int *ai)
-+{
-+ return ai->value;
-+}
-+static void
-+set_atomic_int_value (struct atomic_int *ai, int new_value)
-+{
-+ ai->value = new_value;
-+}
-+#elif USE_SEMAPHORE
-+/* This atomic_int implementation can only support the values 0 and 1.
-+ It is initially 0 and can be set to 1 only once. */
-+# if USE_UNNAMED_SEMAPHORE
-+struct atomic_int {
-+ sem_t semaphore;
-+};
-+#define atomic_int_semaphore(ai) (&(ai)->semaphore)
-+static void
-+init_atomic_int (struct atomic_int *ai)
-+{
-+ sem_init (&ai->semaphore, 0, 0);
-+}
-+# endif
-+# if USE_NAMED_SEMAPHORE
-+struct atomic_int {
-+ sem_t *semaphore;
-+};
-+#define atomic_int_semaphore(ai) ((ai)->semaphore)
-+static void
-+init_atomic_int (struct atomic_int *ai)
-+{
-+ sem_t *s;
-+ unsigned int count;
-+ for (count = 0; ; count++)
-+ {
-+ char name[80];
-+ /* Use getpid() in the name, so that different processes running at the
-+ same time will not interfere. Use ai in the name, so that different
-+ atomic_int in the same process will not interfere. Use a count in
-+ the name, so that even in the (unlikely) case that a semaphore with
-+ the specified name already exists, we can try a different name. */
-+ sprintf (name, "test-lock-%lu-%p-%u",
-+ (unsigned long) getpid (), ai, count);
-+ s = sem_open (name, O_CREAT | O_EXCL, 0600, 0);
-+ if (s == SEM_FAILED)
-+ {
-+ if (errno == EEXIST)
-+ /* Retry with a different name. */
-+ continue;
-+ else
-+ {
-+ perror ("sem_open failed");
-+ abort ();
-+ }
-+ }
-+ else
-+ {
-+ /* Try not to leave a semaphore hanging around on the file system
-+ eternally, if we can avoid it. */
-+ sem_unlink (name);
-+ break;
-+ }
-+ }
-+ ai->semaphore = s;
-+}
-+# endif
-+static int
-+get_atomic_int_value (struct atomic_int *ai)
-+{
-+ if (sem_trywait (atomic_int_semaphore (ai)) == 0)
-+ {
-+ if (sem_post (atomic_int_semaphore (ai)))
-+ abort ();
-+ return 1;
-+ }
-+ else if (errno == EAGAIN)
-+ return 0;
-+ else
-+ abort ();
-+}
-+static void
-+set_atomic_int_value (struct atomic_int *ai, int new_value)
-+{
-+ if (new_value == 0)
-+ /* It's already initialized with 0. */
-+ return;
-+ /* To set the value 1: */
-+ if (sem_post (atomic_int_semaphore (ai)))
-+ abort ();
-+}
-+#else
-+struct atomic_int {
-+ gl_lock_define (, lock)
-+ int value;
-+};
-+static void
-+init_atomic_int (struct atomic_int *ai)
-+{
-+ gl_lock_init (ai->lock);
-+}
-+static int
-+get_atomic_int_value (struct atomic_int *ai)
-+{
-+ gl_lock_lock (ai->lock);
-+ int ret = ai->value;
-+ gl_lock_unlock (ai->lock);
-+ return ret;
-+}
-+static void
-+set_atomic_int_value (struct atomic_int *ai, int new_value)
-+{
-+ gl_lock_lock (ai->lock);
-+ ai->value = new_value;
-+ gl_lock_unlock (ai->lock);
-+}
-+#endif
-+
- #define ACCOUNT_COUNT 4
-
- static int account[ACCOUNT_COUNT];
-@@ -170,12 +324,12 @@ lock_mutator_thread (void *arg)
- return NULL;
- }
-
--static volatile int lock_checker_done;
-+static struct atomic_int lock_checker_done;
-
- static void *
- lock_checker_thread (void *arg)
- {
-- while (!lock_checker_done)
-+ while (get_atomic_int_value (&lock_checker_done) == 0)
- {
- dbgprintf ("Checker %p before check lock\n", gl_thread_self_pointer ());
- gl_lock_lock (my_lock);
-@@ -200,7 +354,8 @@ test_lock (void)
- /* Initialization. */
- for (i = 0; i < ACCOUNT_COUNT; i++)
- account[i] = 1000;
-- lock_checker_done = 0;
-+ init_atomic_int (&lock_checker_done);
-+ set_atomic_int_value (&lock_checker_done, 0);
-
- /* Spawn the threads. */
- checkerthread = gl_thread_create (lock_checker_thread, NULL);
-@@ -210,7 +365,7 @@ test_lock (void)
- /* Wait for the threads to terminate. */
- for (i = 0; i < THREAD_COUNT; i++)
- gl_thread_join (threads[i], NULL);
-- lock_checker_done = 1;
-+ set_atomic_int_value (&lock_checker_done, 1);
- gl_thread_join (checkerthread, NULL);
- check_accounts ();
- }
-@@ -254,12 +409,12 @@ rwlock_mutator_thread (void *arg)
- return NULL;
- }
-
--static volatile int rwlock_checker_done;
-+static struct atomic_int rwlock_checker_done;
-
- static void *
- rwlock_checker_thread (void *arg)
- {
-- while (!rwlock_checker_done)
-+ while (get_atomic_int_value (&rwlock_checker_done) == 0)
- {
- dbgprintf ("Checker %p before check rdlock\n", gl_thread_self_pointer ());
- gl_rwlock_rdlock (my_rwlock);
-@@ -284,7 +439,8 @@ test_rwlock (void)
- /* Initialization. */
- for (i = 0; i < ACCOUNT_COUNT; i++)
- account[i] = 1000;
-- rwlock_checker_done = 0;
-+ init_atomic_int (&rwlock_checker_done);
-+ set_atomic_int_value (&rwlock_checker_done, 0);
-
- /* Spawn the threads. */
- for (i = 0; i < THREAD_COUNT; i++)
-@@ -295,7 +451,7 @@ test_rwlock (void)
- /* Wait for the threads to terminate. */
- for (i = 0; i < THREAD_COUNT; i++)
- gl_thread_join (threads[i], NULL);
-- rwlock_checker_done = 1;
-+ set_atomic_int_value (&rwlock_checker_done, 1);
- for (i = 0; i < THREAD_COUNT; i++)
- gl_thread_join (checkerthreads[i], NULL);
- check_accounts ();
-@@ -356,12 +512,12 @@ reclock_mutator_thread (void *arg)
- return NULL;
- }
-
--static volatile int reclock_checker_done;
-+static struct atomic_int reclock_checker_done;
-
- static void *
- reclock_checker_thread (void *arg)
- {
-- while (!reclock_checker_done)
-+ while (get_atomic_int_value (&reclock_checker_done) == 0)
- {
- dbgprintf ("Checker %p before check lock\n", gl_thread_self_pointer ());
- gl_recursive_lock_lock (my_reclock);
-@@ -386,7 +542,8 @@ test_recursive_lock (void)
- /* Initialization. */
- for (i = 0; i < ACCOUNT_COUNT; i++)
- account[i] = 1000;
-- reclock_checker_done = 0;
-+ init_atomic_int (&reclock_checker_done);
-+ set_atomic_int_value (&reclock_checker_done, 0);
-
- /* Spawn the threads. */
- checkerthread = gl_thread_create (reclock_checker_thread, NULL);
-@@ -396,7 +553,7 @@ test_recursive_lock (void)
- /* Wait for the threads to terminate. */
- for (i = 0; i < THREAD_COUNT; i++)
- gl_thread_join (threads[i], NULL);
-- reclock_checker_done = 1;
-+ set_atomic_int_value (&reclock_checker_done, 1);
- gl_thread_join (checkerthread, NULL);
- check_accounts ();
- }
diff --git a/gnu/packages/patches/gettext-gnulib-multi-core.patch b/gnu/packages/patches/gettext-gnulib-multi-core.patch
deleted file mode 100644
index 5ccdbe4..0000000
--- a/gnu/packages/patches/gettext-gnulib-multi-core.patch
+++ /dev/null
@@ -1,178 +0,0 @@
-This patch fixes performance problems on multi-core machines
-as reported at <https://bugs.gnu.org/26441>.
-
-See commit 480d374e596a0ee3fed168ab42cd84c313ad3c89 in Gnulib
-by Bruno Haible <bruno@clisp.org>.
-
-diff --git a/gettext-tools/gnulib-tests/test-lock.c b/gettext-tools/gnulib-tests/test-lock.c
-index cb734b4e6..aa6de2739 100644
---- a/gettext-tools/gnulib-tests/test-lock.c
-+++ b/gettext-tools/gnulib-tests/test-lock.c
-@@ -50,6 +50,13 @@
- Uncomment this to see if the operating system has a fair scheduler. */
- #define EXPLICIT_YIELD 1
-
-+/* Whether to use 'volatile' on some variables that communicate information
-+ between threads. If set to 0, a lock is used to protect these variables.
-+ If set to 1, 'volatile' is used; this is theoretically equivalent but can
-+ lead to much slower execution (e.g. 30x slower total run time on a 40-core
-+ machine. */
-+#define USE_VOLATILE 0
-+
- /* Whether to print debugging messages. */
- #define ENABLE_DEBUGGING 0
-
-@@ -103,6 +110,51 @@
- # define yield()
- #endif
-
-+#if USE_VOLATILE
-+struct atomic_int {
-+ volatile int value;
-+};
-+static void
-+init_atomic_int (struct atomic_int *ai)
-+{
-+}
-+static int
-+get_atomic_int_value (struct atomic_int *ai)
-+{
-+ return ai->value;
-+}
-+static void
-+set_atomic_int_value (struct atomic_int *ai, int new_value)
-+{
-+ ai->value = new_value;
-+}
-+#else
-+struct atomic_int {
-+ gl_lock_define (, lock)
-+ int value;
-+};
-+static void
-+init_atomic_int (struct atomic_int *ai)
-+{
-+ gl_lock_init (ai->lock);
-+}
-+static int
-+get_atomic_int_value (struct atomic_int *ai)
-+{
-+ gl_lock_lock (ai->lock);
-+ int ret = ai->value;
-+ gl_lock_unlock (ai->lock);
-+ return ret;
-+}
-+static void
-+set_atomic_int_value (struct atomic_int *ai, int new_value)
-+{
-+ gl_lock_lock (ai->lock);
-+ ai->value = new_value;
-+ gl_lock_unlock (ai->lock);
-+}
-+#endif
-+
- #define ACCOUNT_COUNT 4
-
- static int account[ACCOUNT_COUNT];
-@@ -170,12 +222,12 @@ lock_mutator_thread (void *arg)
- return NULL;
- }
-
--static volatile int lock_checker_done;
-+static struct atomic_int lock_checker_done;
-
- static void *
- lock_checker_thread (void *arg)
- {
-- while (!lock_checker_done)
-+ while (get_atomic_int_value (&lock_checker_done) == 0)
- {
- dbgprintf ("Checker %p before check lock\n", gl_thread_self_pointer ());
- gl_lock_lock (my_lock);
-@@ -200,7 +252,8 @@ test_lock (void)
- /* Initialization. */
- for (i = 0; i < ACCOUNT_COUNT; i++)
- account[i] = 1000;
-- lock_checker_done = 0;
-+ init_atomic_int (&lock_checker_done);
-+ set_atomic_int_value (&lock_checker_done, 0);
-
- /* Spawn the threads. */
- checkerthread = gl_thread_create (lock_checker_thread, NULL);
-@@ -210,7 +263,7 @@ test_lock (void)
- /* Wait for the threads to terminate. */
- for (i = 0; i < THREAD_COUNT; i++)
- gl_thread_join (threads[i], NULL);
-- lock_checker_done = 1;
-+ set_atomic_int_value (&lock_checker_done, 1);
- gl_thread_join (checkerthread, NULL);
- check_accounts ();
- }
-@@ -254,12 +307,12 @@ rwlock_mutator_thread (void *arg)
- return NULL;
- }
-
--static volatile int rwlock_checker_done;
-+static struct atomic_int rwlock_checker_done;
-
- static void *
- rwlock_checker_thread (void *arg)
- {
-- while (!rwlock_checker_done)
-+ while (get_atomic_int_value (&rwlock_checker_done) == 0)
- {
- dbgprintf ("Checker %p before check rdlock\n", gl_thread_self_pointer ());
- gl_rwlock_rdlock (my_rwlock);
-@@ -284,7 +337,8 @@ test_rwlock (void)
- /* Initialization. */
- for (i = 0; i < ACCOUNT_COUNT; i++)
- account[i] = 1000;
-- rwlock_checker_done = 0;
-+ init_atomic_int (&rwlock_checker_done);
-+ set_atomic_int_value (&rwlock_checker_done, 0);
-
- /* Spawn the threads. */
- for (i = 0; i < THREAD_COUNT; i++)
-@@ -295,7 +349,7 @@ test_rwlock (void)
- /* Wait for the threads to terminate. */
- for (i = 0; i < THREAD_COUNT; i++)
- gl_thread_join (threads[i], NULL);
-- rwlock_checker_done = 1;
-+ set_atomic_int_value (&rwlock_checker_done, 1);
- for (i = 0; i < THREAD_COUNT; i++)
- gl_thread_join (checkerthreads[i], NULL);
- check_accounts ();
-@@ -356,12 +410,12 @@ reclock_mutator_thread (void *arg)
- return NULL;
- }
-
--static volatile int reclock_checker_done;
-+static struct atomic_int reclock_checker_done;
-
- static void *
- reclock_checker_thread (void *arg)
- {
-- while (!reclock_checker_done)
-+ while (get_atomic_int_value (&reclock_checker_done) == 0)
- {
- dbgprintf ("Checker %p before check lock\n", gl_thread_self_pointer ());
- gl_recursive_lock_lock (my_reclock);
-@@ -386,7 +440,8 @@ test_recursive_lock (void)
- /* Initialization. */
- for (i = 0; i < ACCOUNT_COUNT; i++)
- account[i] = 1000;
-- reclock_checker_done = 0;
-+ init_atomic_int (&reclock_checker_done);
-+ set_atomic_int_value (&reclock_checker_done, 0);
-
- /* Spawn the threads. */
- checkerthread = gl_thread_create (reclock_checker_thread, NULL);
-@@ -396,7 +451,7 @@ test_recursive_lock (void)
- /* Wait for the threads to terminate. */
- for (i = 0; i < THREAD_COUNT; i++)
- gl_thread_join (threads[i], NULL);
-- reclock_checker_done = 1;
-+ set_atomic_int_value (&reclock_checker_done, 1);
- gl_thread_join (checkerthread, NULL);
- check_accounts ();
- }
diff --git a/gnu/packages/patches/gettext-multi-core.patch b/gnu/packages/patches/gettext-multi-core.patch
deleted file mode 100644
index 31a378c..0000000
--- a/gnu/packages/patches/gettext-multi-core.patch
+++ /dev/null
@@ -1,185 +0,0 @@
-This patch fixes performance problems on multi-core machines
-as reported at <https://bugs.gnu.org/26441>.
-
-See commit 1afbcb06fded2a427b761dd1615b1e48e1e853cc in Gettext
-by Bruno Haible <bruno@clisp.org>.
-
-diff --git a/gettext-runtime/tests/test-lock.c b/gettext-runtime/tests/test-lock.c
-index d279d1d60..51cec3d6b 100644
---- a/gettext-runtime/tests/test-lock.c
-+++ b/gettext-runtime/tests/test-lock.c
-@@ -1,5 +1,5 @@
- /* Test of locking in multithreaded situations.
-- Copyright (C) 2005, 2008-2016 Free Software Foundation, Inc.
-+ Copyright (C) 2005, 2008-2017 Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
-@@ -50,6 +50,13 @@
- Uncomment this to see if the operating system has a fair scheduler. */
- #define EXPLICIT_YIELD 1
-
-+/* Whether to use 'volatile' on some variables that communicate information
-+ between threads. If set to 0, a lock is used to protect these variables.
-+ If set to 1, 'volatile' is used; this is theoretically equivalent but can
-+ lead to much slower execution (e.g. 30x slower total run time on a 40-core
-+ machine. */
-+#define USE_VOLATILE 0
-+
- /* Whether to print debugging messages. */
- #define ENABLE_DEBUGGING 0
-
-@@ -214,6 +221,51 @@ static inline void * gl_thread_self_pointer (void)
- # define yield()
- #endif
-
-+#if USE_VOLATILE
-+struct atomic_int {
-+ volatile int value;
-+};
-+static void
-+init_atomic_int (struct atomic_int *ai)
-+{
-+}
-+static int
-+get_atomic_int_value (struct atomic_int *ai)
-+{
-+ return ai->value;
-+}
-+static void
-+set_atomic_int_value (struct atomic_int *ai, int new_value)
-+{
-+ ai->value = new_value;
-+}
-+#else
-+struct atomic_int {
-+ gl_lock_define (, lock)
-+ int value;
-+};
-+static void
-+init_atomic_int (struct atomic_int *ai)
-+{
-+ gl_lock_init (ai->lock);
-+}
-+static int
-+get_atomic_int_value (struct atomic_int *ai)
-+{
-+ gl_lock_lock (ai->lock);
-+ int ret = ai->value;
-+ gl_lock_unlock (ai->lock);
-+ return ret;
-+}
-+static void
-+set_atomic_int_value (struct atomic_int *ai, int new_value)
-+{
-+ gl_lock_lock (ai->lock);
-+ ai->value = new_value;
-+ gl_lock_unlock (ai->lock);
-+}
-+#endif
-+
- #define ACCOUNT_COUNT 4
-
- static int account[ACCOUNT_COUNT];
-@@ -281,12 +333,12 @@ lock_mutator_thread (void *arg)
- return NULL;
- }
-
--static volatile int lock_checker_done;
-+static struct atomic_int lock_checker_done;
-
- static void *
- lock_checker_thread (void *arg)
- {
-- while (!lock_checker_done)
-+ while (get_atomic_int_value (&lock_checker_done) == 0)
- {
- dbgprintf ("Checker %p before check lock\n", gl_thread_self_pointer ());
- gl_lock_lock (my_lock);
-@@ -311,7 +363,8 @@ test_lock (void)
- /* Initialization. */
- for (i = 0; i < ACCOUNT_COUNT; i++)
- account[i] = 1000;
-- lock_checker_done = 0;
-+ init_atomic_int (&lock_checker_done);
-+ set_atomic_int_value (&lock_checker_done, 0);
-
- /* Spawn the threads. */
- checkerthread = gl_thread_create (lock_checker_thread, NULL);
-@@ -321,7 +374,7 @@ test_lock (void)
- /* Wait for the threads to terminate. */
- for (i = 0; i < THREAD_COUNT; i++)
- gl_thread_join (threads[i], NULL);
-- lock_checker_done = 1;
-+ set_atomic_int_value (&lock_checker_done, 1);
- gl_thread_join (checkerthread, NULL);
- check_accounts ();
- }
-@@ -365,12 +418,12 @@ rwlock_mutator_thread (void *arg)
- return NULL;
- }
-
--static volatile int rwlock_checker_done;
-+static struct atomic_int rwlock_checker_done;
-
- static void *
- rwlock_checker_thread (void *arg)
- {
-- while (!rwlock_checker_done)
-+ while (get_atomic_int_value (&rwlock_checker_done) == 0)
- {
- dbgprintf ("Checker %p before check rdlock\n", gl_thread_self_pointer ());
- gl_rwlock_rdlock (my_rwlock);
-@@ -395,7 +448,8 @@ test_rwlock (void)
- /* Initialization. */
- for (i = 0; i < ACCOUNT_COUNT; i++)
- account[i] = 1000;
-- rwlock_checker_done = 0;
-+ init_atomic_int (&rwlock_checker_done);
-+ set_atomic_int_value (&rwlock_checker_done, 0);
-
- /* Spawn the threads. */
- for (i = 0; i < THREAD_COUNT; i++)
-@@ -406,7 +460,7 @@ test_rwlock (void)
- /* Wait for the threads to terminate. */
- for (i = 0; i < THREAD_COUNT; i++)
- gl_thread_join (threads[i], NULL);
-- rwlock_checker_done = 1;
-+ set_atomic_int_value (&rwlock_checker_done, 1);
- for (i = 0; i < THREAD_COUNT; i++)
- gl_thread_join (checkerthreads[i], NULL);
- check_accounts ();
-@@ -467,12 +521,12 @@ reclock_mutator_thread (void *arg)
- return NULL;
- }
-
--static volatile int reclock_checker_done;
-+static struct atomic_int reclock_checker_done;
-
- static void *
- reclock_checker_thread (void *arg)
- {
-- while (!reclock_checker_done)
-+ while (get_atomic_int_value (&reclock_checker_done) == 0)
- {
- dbgprintf ("Checker %p before check lock\n", gl_thread_self_pointer ());
- gl_recursive_lock_lock (my_reclock);
-@@ -497,7 +551,8 @@ test_recursive_lock (void)
- /* Initialization. */
- for (i = 0; i < ACCOUNT_COUNT; i++)
- account[i] = 1000;
-- reclock_checker_done = 0;
-+ init_atomic_int (&reclock_checker_done);
-+ set_atomic_int_value (&reclock_checker_done, 0);
-
- /* Spawn the threads. */
- checkerthread = gl_thread_create (reclock_checker_thread, NULL);
-@@ -507,7 +562,7 @@ test_recursive_lock (void)
- /* Wait for the threads to terminate. */
- for (i = 0; i < THREAD_COUNT; i++)
- gl_thread_join (threads[i], NULL);
-- reclock_checker_done = 1;
-+ set_atomic_int_value (&reclock_checker_done, 1);
- gl_thread_join (checkerthread, NULL);
- check_accounts ();
- }
diff --git a/gnu/packages/patches/libunistring-gnulib-multi-core.patch b/gnu/packages/patches/libunistring-gnulib-multi-core.patch
deleted file mode 100644
index 709b20c..0000000
--- a/gnu/packages/patches/libunistring-gnulib-multi-core.patch
+++ /dev/null
@@ -1,178 +0,0 @@
-This patch fixes performance problems on multi-core machines
-as reported at <https://bugs.gnu.org/26441>.
-
-See commit 480d374e596a0ee3fed168ab42cd84c313ad3c89 in Gnulib
-by Bruno Haible <bruno@clisp.org>.
-
-diff --git a/tests/test-lock.c b/tests/test-lock.c
-index cb734b4e6..aa6de2739 100644
---- a/tests/test-lock.c
-+++ b/tests/test-lock.c
-@@ -50,6 +50,13 @@
- Uncomment this to see if the operating system has a fair scheduler. */
- #define EXPLICIT_YIELD 1
-
-+/* Whether to use 'volatile' on some variables that communicate information
-+ between threads. If set to 0, a lock is used to protect these variables.
-+ If set to 1, 'volatile' is used; this is theoretically equivalent but can
-+ lead to much slower execution (e.g. 30x slower total run time on a 40-core
-+ machine. */
-+#define USE_VOLATILE 0
-+
- /* Whether to print debugging messages. */
- #define ENABLE_DEBUGGING 0
-
-@@ -103,6 +110,51 @@
- # define yield()
- #endif
-
-+#if USE_VOLATILE
-+struct atomic_int {
-+ volatile int value;
-+};
-+static void
-+init_atomic_int (struct atomic_int *ai)
-+{
-+}
-+static int
-+get_atomic_int_value (struct atomic_int *ai)
-+{
-+ return ai->value;
-+}
-+static void
-+set_atomic_int_value (struct atomic_int *ai, int new_value)
-+{
-+ ai->value = new_value;
-+}
-+#else
-+struct atomic_int {
-+ gl_lock_define (, lock)
-+ int value;
-+};
-+static void
-+init_atomic_int (struct atomic_int *ai)
-+{
-+ gl_lock_init (ai->lock);
-+}
-+static int
-+get_atomic_int_value (struct atomic_int *ai)
-+{
-+ gl_lock_lock (ai->lock);
-+ int ret = ai->value;
-+ gl_lock_unlock (ai->lock);
-+ return ret;
-+}
-+static void
-+set_atomic_int_value (struct atomic_int *ai, int new_value)
-+{
-+ gl_lock_lock (ai->lock);
-+ ai->value = new_value;
-+ gl_lock_unlock (ai->lock);
-+}
-+#endif
-+
- #define ACCOUNT_COUNT 4
-
- static int account[ACCOUNT_COUNT];
-@@ -170,12 +222,12 @@ lock_mutator_thread (void *arg)
- return NULL;
- }
-
--static volatile int lock_checker_done;
-+static struct atomic_int lock_checker_done;
-
- static void *
- lock_checker_thread (void *arg)
- {
-- while (!lock_checker_done)
-+ while (get_atomic_int_value (&lock_checker_done) == 0)
- {
- dbgprintf ("Checker %p before check lock\n", gl_thread_self_pointer ());
- gl_lock_lock (my_lock);
-@@ -200,7 +252,8 @@ test_lock (void)
- /* Initialization. */
- for (i = 0; i < ACCOUNT_COUNT; i++)
- account[i] = 1000;
-- lock_checker_done = 0;
-+ init_atomic_int (&lock_checker_done);
-+ set_atomic_int_value (&lock_checker_done, 0);
-
- /* Spawn the threads. */
- checkerthread = gl_thread_create (lock_checker_thread, NULL);
-@@ -210,7 +263,7 @@ test_lock (void)
- /* Wait for the threads to terminate. */
- for (i = 0; i < THREAD_COUNT; i++)
- gl_thread_join (threads[i], NULL);
-- lock_checker_done = 1;
-+ set_atomic_int_value (&lock_checker_done, 1);
- gl_thread_join (checkerthread, NULL);
- check_accounts ();
- }
-@@ -254,12 +307,12 @@ rwlock_mutator_thread (void *arg)
- return NULL;
- }
-
--static volatile int rwlock_checker_done;
-+static struct atomic_int rwlock_checker_done;
-
- static void *
- rwlock_checker_thread (void *arg)
- {
-- while (!rwlock_checker_done)
-+ while (get_atomic_int_value (&rwlock_checker_done) == 0)
- {
- dbgprintf ("Checker %p before check rdlock\n", gl_thread_self_pointer ());
- gl_rwlock_rdlock (my_rwlock);
-@@ -284,7 +337,8 @@ test_rwlock (void)
- /* Initialization. */
- for (i = 0; i < ACCOUNT_COUNT; i++)
- account[i] = 1000;
-- rwlock_checker_done = 0;
-+ init_atomic_int (&rwlock_checker_done);
-+ set_atomic_int_value (&rwlock_checker_done, 0);
-
- /* Spawn the threads. */
- for (i = 0; i < THREAD_COUNT; i++)
-@@ -295,7 +349,7 @@ test_rwlock (void)
- /* Wait for the threads to terminate. */
- for (i = 0; i < THREAD_COUNT; i++)
- gl_thread_join (threads[i], NULL);
-- rwlock_checker_done = 1;
-+ set_atomic_int_value (&rwlock_checker_done, 1);
- for (i = 0; i < THREAD_COUNT; i++)
- gl_thread_join (checkerthreads[i], NULL);
- check_accounts ();
-@@ -356,12 +410,12 @@ reclock_mutator_thread (void *arg)
- return NULL;
- }
-
--static volatile int reclock_checker_done;
-+static struct atomic_int reclock_checker_done;
-
- static void *
- reclock_checker_thread (void *arg)
- {
-- while (!reclock_checker_done)
-+ while (get_atomic_int_value (&reclock_checker_done) == 0)
- {
- dbgprintf ("Checker %p before check lock\n", gl_thread_self_pointer ());
- gl_recursive_lock_lock (my_reclock);
-@@ -386,7 +440,8 @@ test_recursive_lock (void)
- /* Initialization. */
- for (i = 0; i < ACCOUNT_COUNT; i++)
- account[i] = 1000;
-- reclock_checker_done = 0;
-+ init_atomic_int (&reclock_checker_done);
-+ set_atomic_int_value (&reclock_checker_done, 0);
-
- /* Spawn the threads. */
- checkerthread = gl_thread_create (reclock_checker_thread, NULL);
-@@ -396,7 +451,7 @@ test_recursive_lock (void)
- /* Wait for the threads to terminate. */
- for (i = 0; i < THREAD_COUNT; i++)
- gl_thread_join (threads[i], NULL);
-- reclock_checker_done = 1;
-+ set_atomic_int_value (&reclock_checker_done, 1);
- gl_thread_join (checkerthread, NULL);
- check_accounts ();
- }
--
1.8.5.6
next prev parent reply other threads:[~2017-11-01 18:56 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-27 21:16 Disable gnulib's test-lock test in packages? Eric Bavier
2017-10-29 15:39 ` Ludovic Courtès
2017-11-01 18:56 ` Eric Bavier [this message]
2017-11-05 16:12 ` Ludovic Courtès
2017-11-07 4:45 ` Eric Bavier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://guix.gnu.org/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CY4PR11MB1718E4EFD32B60529745CFEDB75F0@CY4PR11MB1718.namprd11.prod.outlook.com \
--to=bavier@cray.com \
--cc=guix-devel@gnu.org \
--cc=ludo@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/guix.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).