>From db6c51cb278392aee178a3e836f37e0f2a7b1990 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Sat, 8 Aug 2020 19:47:28 +0200 Subject: [PATCH 1/4] New module 'thread-optim'. * lib/thread-optim.h: New file. * modules/thread-optim: New file. * doc/multithread.texi (Multithreading Optimizations): New section. --- ChangeLog | 7 ++++++ doc/multithread.texi | 47 ++++++++++++++++++++++++++++++++++++++++ lib/thread-optim.h | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++ modules/thread-optim | 21 ++++++++++++++++++ 4 files changed, 135 insertions(+) create mode 100644 lib/thread-optim.h create mode 100644 modules/thread-optim diff --git a/ChangeLog b/ChangeLog index 73e2056..ee9b6ce 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2020-08-08 Bruno Haible + + New module 'thread-optim'. + * lib/thread-optim.h: New file. + * modules/thread-optim: New file. + * doc/multithread.texi (Multithreading Optimizations): New section. + 2020-08-07 Paul Eggert doc: more updates for glibc 2.32 diff --git a/doc/multithread.texi b/doc/multithread.texi index b600517..022a6cb 100644 --- a/doc/multithread.texi +++ b/doc/multithread.texi @@ -60,6 +60,7 @@ Nevertheless, they need to use mutexes/locks in many cases. * POSIX multithreading:: * ISO C multithreading:: * Gnulib multithreading:: +* Multithreading Optimizations:: @end menu @node Multithreading APIs @@ -216,3 +217,49 @@ native Windows platforms (mingw and MSVC). ISO C multithreading API. However, @code{--enable-threads=posix} is always a better choice. @end itemize + +@node Multithreading Optimizations +@section Optimizations of multithreaded code + +Despite all the optimizations of multithreading primitives that have been +implemented over the years --- from +@url{https://en.wikipedia.org/wiki/Compare-and-swap, +atomic operations in hardware}, +over @url{https://en.wikipedia.org/wiki/Futex, futexes} and +@url{https://www.efficios.com/blog/2019/02/08/linux-restartable-sequences/, +restartable sequences} +in the Linux kernel, to lock elision +@url{https://lwn.net/Articles/534758/, [1]} +@url{https://www.gnu.org/software/libc/manual/html_node/Elision-Tunables.html, +[2]}) +--- single-threaded programs can still profit performance-wise from the +assertion that they are single-threaded. + +Gnulib defines four facilities that help optimizing for the single-threaded +case. + +@itemize @bullet +@item +The Gnulib multithreading API, when used on glibc @leq{} 2.32 and *BSD systems, +uses weak symbols to detect whether the program is linked with +@code{libpthread}. If not, the program has no way to create additional +threads and must therefore be single-threaded. This optimization applies +to all the Gnulib multithreading API (locks, thread-local storage, and more). +@item +The @code{thread-optim} module, on glibc @geq{} 2.32 systems, allows your code +to skip locking between threads (regardless which of the three multithreading +APIs you use). You need extra code for this: include the +@code{"thread-optim.h"} header file, and use the macros @code{IF_MT_DECL} +and @code{IF_MT}. +@item +The @code{unlocked-io} module is applicable only if all the programs in your +package are single-threaded. It optimizes the operations on @code{FILE} +streams. You need extra code for this: include the @code{"unlocked-io.h"} +header file. Some Gnulib modules that do operations on @code{FILE} streams +have these preparations already included. +@item +You may define the C macro @code{GNULIB_WCHAR_SINGLE}, if all the programs in +your package are single-threaded and won't change the locale after it has +been initialized. This macro optimizes the functions @code{mbrtowc} and +@code{wcwidth}. +@end itemize diff --git a/lib/thread-optim.h b/lib/thread-optim.h new file mode 100644 index 0000000..8040d53 --- /dev/null +++ b/lib/thread-optim.h @@ -0,0 +1,60 @@ +/* Optimization of multithreaded code. + + Copyright (C) 2020 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 + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +/* Written by Bruno Haible , 2020. */ + +#ifndef _THREAD_OPTIM_H +#define _THREAD_OPTIM_H + +/* This file defines a way to optimize multithreaded code for the single-thread + case, based on the variable '__libc_single_threaded', defined in + glibc >= 2.32. */ + +/* Typical use: In a block or function, use + + IF_MT_DECL; + ... + IF_MT + if (pthread_mutex_lock (&lock)) abort (); + ... + IF_MT + if (pthread_mutex_unlock (&lock)) abort (); + + The macro IF_MT_DECL establishes local variables for use by IF_MT. + + IF_MT STATEMENT executes STATEMENT in the multithreaded cases, and skips it + in the single-threaded case. + + The code between IF_MT_DECL and IF_MT must not create threads or invoke + functions that may indirectly create threads (e.g. 'dlopen' may, indirectly + through C++ initializers of global variables in the shared library being + opened, create threads). + + The lock here is meant to synchronize threads in the same process. The + same optimization cannot be applied to locks that synchronize different + processes (e.g. through shared memory mappings). */ + +#if HAVE_SYS_SINGLE_THREADED_H /* glibc >= 2.32 */ +# include +# define IF_MT_DECL char optimize_for_single_thread = __libc_single_threaded +# define IF_MT if (optimize_for_single_thread) +#else +# define IF_MT_DECL (void *)0 +# define IF_MT +#endif + +#endif /* _THREAD_OPTIM_H */ diff --git a/modules/thread-optim b/modules/thread-optim new file mode 100644 index 0000000..caf4518 --- /dev/null +++ b/modules/thread-optim @@ -0,0 +1,21 @@ +Description: +Optimization of multithreaded code. + +Files: +lib/thread-optim.h + +Depends-on: + +configure.ac: +AC_CHECK_HEADERS([sys/single_threaded.h]) + +Makefile.am: + +Include: +"thread-optim.h" + +License: +LGPLv2+ + +Maintainer: +all -- 2.7.4