From 2d853e8b44e1717532e91a76410b2cdfcad7c73d Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Mon, 15 Jul 2019 02:41:02 +0200 Subject: [PATCH] pthread-spin: New module. * lib/pthread.in.h (pthread_spin_init, pthread_spin_destroy, pthread_spin_lock, pthread_spin_trylock, pthread_spin_unlock): Remove inline definitions. * lib/pthread-spin.c: New file. * m4/pthread-spin.m4: New file. * modules/pthread-spin: New file. * doc/posix-functions/pthread_spin_init.texi: Mention the new module. * doc/posix-functions/pthread_spin_lock.texi: Likewise. * doc/posix-functions/pthread_spin_trylock.texi: Likewise. * doc/posix-functions/pthread_spin_unlock.texi: Likewise. * doc/posix-functions/pthread_spin_destroy.texi: Likewise. --- ChangeLog | 15 ++ doc/posix-functions/pthread_spin_destroy.texi | 10 +- doc/posix-functions/pthread_spin_init.texi | 10 +- doc/posix-functions/pthread_spin_lock.texi | 10 +- doc/posix-functions/pthread_spin_trylock.texi | 10 +- doc/posix-functions/pthread_spin_unlock.texi | 10 +- lib/pthread-spin.c | 182 ++++++++++++++++++ lib/pthread.in.h | 43 ----- m4/pthread-spin.m4 | 30 +++ modules/pthread-spin | 31 +++ 10 files changed, 288 insertions(+), 63 deletions(-) create mode 100644 lib/pthread-spin.c create mode 100644 m4/pthread-spin.m4 create mode 100644 modules/pthread-spin diff --git a/ChangeLog b/ChangeLog index e3acb25dbd..ebe77e15c2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2019-07-14 Bruno Haible + + pthread-spin: New module. + * lib/pthread.in.h (pthread_spin_init, pthread_spin_destroy, + pthread_spin_lock, pthread_spin_trylock, pthread_spin_unlock): Remove + inline definitions. + * lib/pthread-spin.c: New file. + * m4/pthread-spin.m4: New file. + * modules/pthread-spin: New file. + * doc/posix-functions/pthread_spin_init.texi: Mention the new module. + * doc/posix-functions/pthread_spin_lock.texi: Likewise. + * doc/posix-functions/pthread_spin_trylock.texi: Likewise. + * doc/posix-functions/pthread_spin_unlock.texi: Likewise. + * doc/posix-functions/pthread_spin_destroy.texi: Likewise. + 2019-07-14 Bruno Haible pthread-tss: New module. diff --git a/doc/posix-functions/pthread_spin_destroy.texi b/doc/posix-functions/pthread_spin_destroy.texi index bb34331941..c9a671327c 100644 --- a/doc/posix-functions/pthread_spin_destroy.texi +++ b/doc/posix-functions/pthread_spin_destroy.texi @@ -4,15 +4,17 @@ POSIX specification:@* @url{http://www.opengroup.org/onlinepubs/9699919799/functions/pthread_spin_destroy.html} -Gnulib module: --- +Gnulib module: pthread-spin Portability problems fixed by Gnulib: @itemize +@item +This function is missing on some platforms: +Mac OS X 10.5, FreeBSD 5.2.1, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 9, Cygwin 1.7.9, mingw, MSVC 14, Android 6.0. +But the provided replacement is just a dummy on some of these platforms: +Minix 3.1.8. @end itemize Portability problems not fixed by Gnulib: @itemize -@item -This function is missing on some platforms: -Mac OS X 10.5, FreeBSD 5.2.1, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 9, Cygwin 1.7.9, mingw, MSVC 14, Android 6.0. @end itemize diff --git a/doc/posix-functions/pthread_spin_init.texi b/doc/posix-functions/pthread_spin_init.texi index cf1f95f772..fc511da214 100644 --- a/doc/posix-functions/pthread_spin_init.texi +++ b/doc/posix-functions/pthread_spin_init.texi @@ -4,15 +4,17 @@ POSIX specification:@* @url{http://www.opengroup.org/onlinepubs/9699919799/functions/pthread_spin_init.html} -Gnulib module: --- +Gnulib module: pthread-spin Portability problems fixed by Gnulib: @itemize +@item +This function is missing on some platforms: +Mac OS X 10.5, FreeBSD 5.2.1, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 9, Cygwin 1.7.9, mingw, MSVC 14, Android 6.0. +But the provided replacement is just a dummy on some of these platforms: +Minix 3.1.8. @end itemize Portability problems not fixed by Gnulib: @itemize -@item -This function is missing on some platforms: -Mac OS X 10.5, FreeBSD 5.2.1, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 9, Cygwin 1.7.9, mingw, MSVC 14, Android 6.0. @end itemize diff --git a/doc/posix-functions/pthread_spin_lock.texi b/doc/posix-functions/pthread_spin_lock.texi index bbec5a3dac..c5a8087ab8 100644 --- a/doc/posix-functions/pthread_spin_lock.texi +++ b/doc/posix-functions/pthread_spin_lock.texi @@ -4,15 +4,17 @@ POSIX specification:@* @url{http://www.opengroup.org/onlinepubs/9699919799/functions/pthread_spin_lock.html} -Gnulib module: --- +Gnulib module: pthread-spin Portability problems fixed by Gnulib: @itemize +@item +This function is missing on some platforms: +Mac OS X 10.5, FreeBSD 5.2.1, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 9, Cygwin 1.7.9, mingw, MSVC 14, Android 6.0. +But the provided replacement is just a dummy on some of these platforms: +Minix 3.1.8. @end itemize Portability problems not fixed by Gnulib: @itemize -@item -This function is missing on some platforms: -Mac OS X 10.5, FreeBSD 5.2.1, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 9, Cygwin 1.7.9, mingw, MSVC 14, Android 6.0. @end itemize diff --git a/doc/posix-functions/pthread_spin_trylock.texi b/doc/posix-functions/pthread_spin_trylock.texi index 8dcb7934d6..75b0ff24d2 100644 --- a/doc/posix-functions/pthread_spin_trylock.texi +++ b/doc/posix-functions/pthread_spin_trylock.texi @@ -4,15 +4,17 @@ POSIX specification:@* @url{http://www.opengroup.org/onlinepubs/9699919799/functions/pthread_spin_trylock.html} -Gnulib module: --- +Gnulib module: pthread-spin Portability problems fixed by Gnulib: @itemize +@item +This function is missing on some platforms: +Mac OS X 10.5, FreeBSD 5.2.1, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 9, Cygwin 1.7.9, mingw, MSVC 14, Android 6.0. +But the provided replacement is just a dummy on some of these platforms: +Minix 3.1.8. @end itemize Portability problems not fixed by Gnulib: @itemize -@item -This function is missing on some platforms: -Mac OS X 10.5, FreeBSD 5.2.1, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 9, Cygwin 1.7.9, mingw, MSVC 14, Android 6.0. @end itemize diff --git a/doc/posix-functions/pthread_spin_unlock.texi b/doc/posix-functions/pthread_spin_unlock.texi index 9ee936a051..e243fd48bd 100644 --- a/doc/posix-functions/pthread_spin_unlock.texi +++ b/doc/posix-functions/pthread_spin_unlock.texi @@ -4,15 +4,17 @@ POSIX specification:@* @url{http://www.opengroup.org/onlinepubs/9699919799/functions/pthread_spin_unlock.html} -Gnulib module: --- +Gnulib module: pthread-spin Portability problems fixed by Gnulib: @itemize +@item +This function is missing on some platforms: +Mac OS X 10.5, FreeBSD 5.2.1, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 9, Cygwin 1.7.9, mingw, MSVC 14, Android 6.0. +But the provided replacement is just a dummy on some of these platforms: +Minix 3.1.8. @end itemize Portability problems not fixed by Gnulib: @itemize -@item -This function is missing on some platforms: -Mac OS X 10.5, FreeBSD 5.2.1, OpenBSD 3.8, Minix 3.1.8, AIX 5.1, HP-UX 11, IRIX 6.5, Solaris 9, Cygwin 1.7.9, mingw, MSVC 14, Android 6.0. @end itemize diff --git a/lib/pthread-spin.c b/lib/pthread-spin.c new file mode 100644 index 0000000000..0b3410937a --- /dev/null +++ b/lib/pthread-spin.c @@ -0,0 +1,182 @@ +/* POSIX spin locks. + Copyright (C) 2010-2019 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 2, 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 Paul Eggert, 2010, and Bruno Haible , 2019. */ + +#include + +/* Specification. */ +#include + +#if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS +# include "windows-spin.h" +#endif + +#if (defined _WIN32 && ! defined __CYGWIN__) && USE_WINDOWS_THREADS +/* Use Windows threads. */ + +int +pthread_spin_init (pthread_spinlock_t *lock, + int shared_across_processes _GL_UNUSED) +{ + glwthread_spin_init (lock); + return 0; +} + +int +pthread_spin_lock (pthread_spinlock_t *lock) +{ + return glwthread_spin_lock (lock); +} + +int +pthread_spin_trylock (pthread_spinlock_t *lock) +{ + return glwthread_spin_trylock (lock); +} + +int +pthread_spin_unlock (pthread_spinlock_t *lock) +{ + return glwthread_spin_unlock (lock); +} + +int +pthread_spin_destroy (pthread_spinlock_t *lock) +{ + return glwthread_spin_destroy (lock); +} + +#elif HAVE_PTHREAD_H +/* Provide workarounds for POSIX threads. */ + +/* We don't use the C11 (available in GCC >= 4.9) because it would + require to link with -latomic. */ + +# if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7) +/* Use GCC built-ins (available in GCC >= 4.7) that operate on the first byte + of the lock. + Documentation: + */ + +int +pthread_spin_init (pthread_spinlock_t *lock, + int shared_across_processes _GL_UNUSED) +{ + __atomic_clear (lock, __ATOMIC_SEQ_CST); + return 0; +} + +int +pthread_spin_lock (pthread_spinlock_t *lock) +{ + while (__atomic_test_and_set (lock, __ATOMIC_SEQ_CST)) + ; + return 0; +} + +int +pthread_spin_trylock (pthread_spinlock_t *lock) +{ + if (__atomic_test_and_set (lock, __ATOMIC_SEQ_CST)) + return EBUSY; + return 0; +} + +int +pthread_spin_unlock (pthread_spinlock_t *lock) +{ + __atomic_clear (lock, __ATOMIC_SEQ_CST); + return 0; +} + +int +pthread_spin_destroy (pthread_spinlock_t *lock) +{ + return 0; +} + +# else +/* Emulate a spin lock through a mutex. */ + +int +pthread_spin_init (pthread_spinlock_t *lock, + int shared_across_processes _GL_UNUSED) +{ + return pthread_mutex_init (lock, NULL); +} + +int +pthread_spin_lock (pthread_spinlock_t *lock) +{ + return pthread_mutex_lock (lock); +} + +int +pthread_spin_trylock (pthread_spinlock_t *lock) +{ + return pthread_mutex_trylock (lock); +} + +int +pthread_spin_unlock (pthread_spinlock_t *lock) +{ + return pthread_mutex_unlock (lock); +} + +int +pthread_spin_destroy (pthread_spinlock_t *lock) +{ + return pthread_mutex_destroy (lock); +} + +# endif + +#else +/* Provide a dummy implementation for single-threaded applications. */ + +int +pthread_spin_init (pthread_spinlock_t *lock _GL_UNUSED, + int shared_across_processes _GL_UNUSED) +{ + return 0; +} + +int +pthread_spin_lock (pthread_spinlock_t *lock _GL_UNUSED) +{ + return 0; +} + +int +pthread_spin_trylock (pthread_spinlock_t *lock _GL_UNUSED) +{ + return 0; +} + +int +pthread_spin_unlock (pthread_spinlock_t *lock _GL_UNUSED) +{ + return 0; +} + +int +pthread_spin_destroy (pthread_spinlock_t *lock _GL_UNUSED) +{ + return 0; +} + +#endif diff --git a/lib/pthread.in.h b/lib/pthread.in.h index 514b77745b..d0f3ad8bda 100644 --- a/lib/pthread.in.h +++ b/lib/pthread.in.h @@ -362,49 +362,6 @@ typedef unsigned int pthread_barrierattr_t; #endif -#if ! @HAVE_PTHREAD_SPINLOCK_T@ - -# if @GNULIB_PTHREAD@ - -# if !GNULIB_defined_pthread_spinlock_functions - -_GL_PTHREAD_INLINE int -pthread_spin_init (pthread_spinlock_t *lock, int pshared) -{ - return pthread_mutex_init (lock, NULL); -} - -_GL_PTHREAD_INLINE int -pthread_spin_destroy (pthread_spinlock_t *lock) -{ - return pthread_mutex_destroy (lock); -} - -_GL_PTHREAD_INLINE int -pthread_spin_lock (pthread_spinlock_t *lock) -{ - return pthread_mutex_lock (lock); -} - -_GL_PTHREAD_INLINE int -pthread_spin_trylock (pthread_spinlock_t *lock) -{ - return pthread_mutex_trylock (lock); -} - -_GL_PTHREAD_INLINE int -pthread_spin_unlock (pthread_spinlock_t *lock) -{ - return pthread_mutex_unlock (lock); -} - -# define GNULIB_defined_pthread_spinlock_functions 1 -# endif - -# endif - -#endif - /* =========== Thread functions =========== */ #if @GNULIB_PTHREAD_THREAD@ diff --git a/m4/pthread-spin.m4 b/m4/pthread-spin.m4 new file mode 100644 index 0000000000..9352d5a53a --- /dev/null +++ b/m4/pthread-spin.m4 @@ -0,0 +1,30 @@ +# pthread-spin.m4 serial 1 +dnl Copyright (C) 2019 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_PTHREAD_SPIN], +[ + AC_REQUIRE([gl_PTHREAD_H]) + AC_REQUIRE([AC_CANONICAL_HOST]) + + if { case "$host_os" in mingw*) true;; *) false;; esac; } \ + && test $gl_threads_api = windows; then + dnl Choose function names that don't conflict with the mingw-w64 winpthreads + dnl library. + REPLACE_PTHREAD_SPIN_INIT=1 + REPLACE_PTHREAD_SPIN_LOCK=1 + REPLACE_PTHREAD_SPIN_TRYLOCK=1 + REPLACE_PTHREAD_SPIN_UNLOCK=1 + REPLACE_PTHREAD_SPIN_DESTROY=1 + else + if test $HAVE_PTHREAD_H = 0; then + HAVE_PTHREAD_SPIN_INIT=0 + HAVE_PTHREAD_SPIN_LOCK=0 + HAVE_PTHREAD_SPIN_TRYLOCK=0 + HAVE_PTHREAD_SPIN_UNLOCK=0 + HAVE_PTHREAD_SPIN_DESTROY=0 + fi + fi +]) diff --git a/modules/pthread-spin b/modules/pthread-spin new file mode 100644 index 0000000000..a58b9f7ce8 --- /dev/null +++ b/modules/pthread-spin @@ -0,0 +1,31 @@ +Description: +POSIX spin locks. + +Files: +lib/pthread-spin.c +m4/pthread-spin.m4 + +Depends-on: +pthread-h +windows-spin [test $gl_threads_api = windows] + +configure.ac: +gl_PTHREAD_SPIN +if test $HAVE_PTHREAD_SPIN_INIT = 0 || test $REPLACE_PTHREAD_SPIN_INIT = 1; then + AC_LIBOBJ([pthread-spin]) +fi +gl_PTHREAD_MODULE_INDICATOR([pthread-spin]) + +Makefile.am: + +Include: + + +Link: +$(LIBMULTITHREAD) + +License: +LGPLv2+ + +Maintainer: +all -- 2.39.5