[1/6] Consolidate Linux sigprocmask implementation (BZ #22391)

Message ID 1509745249-11404-1-git-send-email-adhemerval.zanella@linaro.org
State New
Headers show
Series
  • [1/6] Consolidate Linux sigprocmask implementation (BZ #22391)
Related show

Commit Message

Adhemerval Zanella Nov. 3, 2017, 9:40 p.m.
This patch consolidates the sigprocmask Linux syscall implementation on
sysdeps/unix/sysv/linux/sigprocmask.c.  The changes are:

  1. For ia64, s390-64, sparc64, and x86_64 the default semantic for
     filter out SIGCANCEL and SIGSETXID is used.  Also the Linux pthread
     semantic is documented in the signal chapter.

  2. A new internal function to check for NPTL internal signals within a
     signal set is added (__nptl_has_internal_signal).  It is used to
     simplify the default sigprocmask.c implementation.

Checked on x86_64-linux-gnu.

	[BZ #22391]
	* manual/signal.texi: Add a note about internal pthread signals
	on Linux.
	* sysdeps/unix/sysv/linux/ia64/sigprocmask.c: Remove file.
	* sysdeps/unix/sysv/linux/s390/s390-64/sigprocmask.c: Likewise.
	* sysdeps/unix/sysv/linux/sparc/sparc64/sigprocmask.c: Likewise.
	* sysdeps/unix/sysv/linux/x86_64/sigprocmask.c: Likewise.
	* sysdeps/unix/sysv/linux/nptl-signals.h
	(__nptl_has_internal_signal): New function.
	* sysdeps/unix/sysv/linux/sigprocmask.c (__sigprocmask):
	Use __nptl_has_internal_signal and __nptl_clear_internal_signals
	function.

Signed-off-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Reported-by: Yury Norov <ynorov@caviumnetworks.com>
---
 ChangeLog                                          | 17 +++++++
 manual/signal.texi                                 |  5 ++
 sysdeps/unix/sysv/linux/alpha/sigprocmask.c        | 58 ----------------------
 sysdeps/unix/sysv/linux/ia64/sigprocmask.c         | 40 ---------------
 sysdeps/unix/sysv/linux/nptl-signals.h             |  6 +++
 sysdeps/unix/sysv/linux/s390/s390-64/sigprocmask.c | 38 --------------
 sysdeps/unix/sysv/linux/sigprocmask.c              | 23 +++------
 .../unix/sysv/linux/sparc/sparc64/sigprocmask.c    | 34 -------------
 sysdeps/unix/sysv/linux/x86_64/sigprocmask.c       | 39 ---------------
 9 files changed, 34 insertions(+), 226 deletions(-)
 delete mode 100644 sysdeps/unix/sysv/linux/alpha/sigprocmask.c
 delete mode 100644 sysdeps/unix/sysv/linux/ia64/sigprocmask.c
 delete mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/sigprocmask.c
 delete mode 100644 sysdeps/unix/sysv/linux/sparc/sparc64/sigprocmask.c
 delete mode 100644 sysdeps/unix/sysv/linux/x86_64/sigprocmask.c

Comments

Zack Weinberg Nov. 5, 2017, 10:46 p.m. | #1
On Fri, Nov 3, 2017 at 5:40 PM, Adhemerval Zanella
<adhemerval.zanella@linaro.org> wrote:
> This patch consolidates the sigprocmask Linux syscall implementation on
> sysdeps/unix/sysv/linux/sigprocmask.c

This looks like a virtuous change overall, but I don't know the code
well enough to singlehandedly review it.  I'd like to provide some
feedback on the manual change, though:

> +On Linux pthreads internally uses some signals to implement asynchronous
> +cancellation, effective ID synchronization for POSIX conformance, and
> +posix timer management.  These signals are filtered out on signal set
> +function manipulation.

This has grammar problems, and also, not all of the signal-set
functions filter the special signals.  For instance, sigfillset does,
but sigaddset doesn't (if I'm reading the code right, anyway).  And
this isn't even the right place to document this, because the main
reason why we need to document it is to explain why the kernel's idea
of the real-time signal range differs from what glibc exposes to
applications ... and the real-time signal range isn't documented at
all, *headdesk*.

So I suggest this _instead of_ the above change:

diff --git a/manual/signal.texi b/manual/signal.texi
index 9577ff091d..4f0ef59fb7 100644
--- a/manual/signal.texi
+++ b/manual/signal.texi
@@ -235,6 +235,7 @@ defined.  Since the signal numbers are allocated
consecutively,
 * Job Control Signals::         Signals used to support job control.
 * Operation Error Signals::     Used to report operational system errors.
 * Miscellaneous Signals::       Miscellaneous Signals.
+* Internally-Used Signals::     Signals used internally by the C library.
 * Signal Messages::             Printing a message describing a signal.
 @end menu

@@ -794,6 +795,26 @@ in @ref{Signaling Another Process}.
 The default action is to terminate the process.
 @end deftypevr

+@deftypevr Macro int SIGRTMIN
+@deftypevrx Macro int SIGRTMAX
+@standards{POSIX.1, signal.h}
+@cindex real-time signals
+The range of signal numbers @code{SIGRTMIN}, @code{SIGRTMIN+1},
+@dots{}, @code{SIGRTMAX} is also set aside for you to use any way you
+want.  In addition, these signals (and no others) are guaranteed to
+support @dfn{real-time} signal semantics, which unfortunately this
+manual does not yet document.
+
+Unlike all of the other signal number macros, @code{SIGRTMIN} and
+@code{SIGRTMAX} are not compile-time constants, because some operating
+systems make the number of real-time signals tunable on a
+per-installation or even per-process basis.  However, POSIX guarantees
+that there will be at least 8 signal numbers in this range.
+
+The default action for all signals in this range is to terminate the
+process.
+@end deftypevr
+
 @deftypevr Macro int SIGWINCH
 @standards{BSD, signal.h}
 Window size change.  This is generated on some systems (including GNU)
@@ -817,6 +838,22 @@ to print some status information about the system
and what the process
 is doing.  Otherwise the default is to do nothing.
 @end deftypevr

+@node Internally-Used Signals
+@subsection Internally-Used Signals
+@cindex internally used signals
+
+On some operating systems, @theglibc{} needs to use a few signals from
+the ``true'' real-time range internally, to implement thread
+cancellation, cross-thread effective ID synchronization, POSIX timer
+management, etc.  @Theglibc{} adjusts @code{SIGRTMIN} and
+@code{SIGRTMAX} to exclude these signals, and it also takes steps to
+prevent application code from altering their state: @code{sigprocmask}
+cannot block them and @code{sigaction} cannot redefine their handlers,
+for instance.  Therefore, most programs do not need to know or care
+about these signals.  We mainly document their existence for the sake
+of anyone who has ever wondered why there is a gap between the
+highest-numbered ``normal'' signal and @code{SIGRTMIN} on Linux.
+
 @node Signal Messages
 @subsection Signal Messages
 @cindex signal messages
Rical Jasan Nov. 6, 2017, 2:59 a.m. | #2
On 11/05/2017 02:46 PM, Zack Weinberg wrote:
> On Fri, Nov 3, 2017 at 5:40 PM, Adhemerval Zanella
> <adhemerval.zanella@linaro.org> wrote:
>> This patch consolidates the sigprocmask Linux syscall implementation on
>> sysdeps/unix/sysv/linux/sigprocmask.c
> 
> This looks like a virtuous change overall, but I don't know the code
> well enough to singlehandedly review it.  I'd like to provide some
> feedback on the manual change, though:
> 
>> +On Linux pthreads internally uses some signals to implement asynchronous
>> +cancellation, effective ID synchronization for POSIX conformance, and
>> +posix timer management.  These signals are filtered out on signal set
>> +function manipulation.
> 
> This has grammar problems, and also, not all of the signal-set
> functions filter the special signals.  For instance, sigfillset does,
> but sigaddset doesn't (if I'm reading the code right, anyway).  And
> this isn't even the right place to document this, because the main
> reason why we need to document it is to explain why the kernel's idea
> of the real-time signal range differs from what glibc exposes to
> applications ... and the real-time signal range isn't documented at
> all, *headdesk*.
> 
> So I suggest this _instead of_ the above change:
> 
> diff --git a/manual/signal.texi b/manual/signal.texi
> index 9577ff091d..4f0ef59fb7 100644
> --- a/manual/signal.texi
> +++ b/manual/signal.texi
> @@ -235,6 +235,7 @@ defined.  Since the signal numbers are allocated
> consecutively,
>  * Job Control Signals::         Signals used to support job control.
>  * Operation Error Signals::     Used to report operational system errors.
>  * Miscellaneous Signals::       Miscellaneous Signals.
> +* Internally-Used Signals::     Signals used internally by the C library.
>  * Signal Messages::             Printing a message describing a signal.
>  @end menu
> 
> @@ -794,6 +795,26 @@ in @ref{Signaling Another Process}.
>  The default action is to terminate the process.
>  @end deftypevr
> 
> +@deftypevr Macro int SIGRTMIN
> +@deftypevrx Macro int SIGRTMAX
> +@standards{POSIX.1, signal.h}
> +@cindex real-time signals
> +The range of signal numbers @code{SIGRTMIN}, @code{SIGRTMIN+1},
> +@dots{}, @code{SIGRTMAX} is also set aside for you to use any way you
> +want.  In addition, these signals (and no others) are guaranteed to
> +support @dfn{real-time} signal semantics, which unfortunately this
> +manual does not yet document.

I don't think we should say that at the end.  It will be wrong someday
(hopefully), without having to do anything to it.  It really just needs
a @pxref we don't have yet, so instead, say nothing, which will continue
to be correct both before and after real-time signal semantics are
documented, and after they are, the reference can be added to improve
the manual.

Maybe a bug report that real-time signal semantics aren't documented
would be a good place to both track the issue and keep a reminder to
update this paragraph.

> +
> +Unlike all of the other signal number macros, @code{SIGRTMIN} and
> +@code{SIGRTMAX} are not compile-time constants, because some operating
> +systems make the number of real-time signals tunable on a
> +per-installation or even per-process basis.  However, POSIX guarantees
> +that there will be at least 8 signal numbers in this range.
> +
> +The default action for all signals in this range is to terminate the
> +process.
> +@end deftypevr
> +
>  @deftypevr Macro int SIGWINCH
>  @standards{BSD, signal.h}
>  Window size change.  This is generated on some systems (including GNU)
> @@ -817,6 +838,22 @@ to print some status information about the system
> and what the process
>  is doing.  Otherwise the default is to do nothing.
>  @end deftypevr
> 
> +@node Internally-Used Signals
> +@subsection Internally-Used Signals
> +@cindex internally used signals
> +
> +On some operating systems, @theglibc{} needs to use a few signals from
> +the ``true'' real-time range internally, to implement thread
> +cancellation, cross-thread effective ID synchronization, POSIX timer
> +management, etc.  @Theglibc{} adjusts @code{SIGRTMIN} and
> +@code{SIGRTMAX} to exclude these signals, and it also takes steps to
> +prevent application code from altering their state: @code{sigprocmask}
> +cannot block them and @code{sigaction} cannot redefine their handlers,
> +for instance.  Therefore, most programs do not need to know or care
> +about these signals.  We mainly document their existence for the sake
> +of anyone who has ever wondered why there is a gap between the
> +highest-numbered ``normal'' signal and @code{SIGRTMIN} on Linux.
> +
>  @node Signal Messages
>  @subsection Signal Messages
>  @cindex signal messages

Otherwise, I like the direction you took this, especially since it slips
in documentation for some previously undocumented macros along with the
concept.

Rical
Adhemerval Zanella Nov. 6, 2017, 11:14 a.m. | #3
On 05/11/2017 20:46, Zack Weinberg wrote:
> On Fri, Nov 3, 2017 at 5:40 PM, Adhemerval Zanella
> <adhemerval.zanella@linaro.org> wrote:
>> This patch consolidates the sigprocmask Linux syscall implementation on
>> sysdeps/unix/sysv/linux/sigprocmask.c
> 
> This looks like a virtuous change overall, but I don't know the code
> well enough to singlehandedly review it.  I'd like to provide some
> feedback on the manual change, though:
> 
>> +On Linux pthreads internally uses some signals to implement asynchronous
>> +cancellation, effective ID synchronization for POSIX conformance, and
>> +posix timer management.  These signals are filtered out on signal set
>> +function manipulation.
> 
> This has grammar problems, and also, not all of the signal-set
> functions filter the special signals.  For instance, sigfillset does,
> but sigaddset doesn't (if I'm reading the code right, anyway).  And
> this isn't even the right place to document this, because the main
> reason why we need to document it is to explain why the kernel's idea
> of the real-time signal range differs from what glibc exposes to
> applications ... and the real-time signal range isn't documented at
> all, *headdesk*.

Indeed not all signal-set function filter the special signals and
the second part of this patchset is indeed to fix all the remaining
cases (tracked also by BZ#22391 [1], I might have forgot some
symbol on my bug report).

[1] https://sourceware.org/bugzilla/show_bug.cgi?id=22391

> 
> So I suggest this _instead of_ the above change:

This change looks reasonable.

> 
> diff --git a/manual/signal.texi b/manual/signal.texi
> index 9577ff091d..4f0ef59fb7 100644
> --- a/manual/signal.texi
> +++ b/manual/signal.texi
> @@ -235,6 +235,7 @@ defined.  Since the signal numbers are allocated
> consecutively,
>  * Job Control Signals::         Signals used to support job control.
>  * Operation Error Signals::     Used to report operational system errors.
>  * Miscellaneous Signals::       Miscellaneous Signals.
> +* Internally-Used Signals::     Signals used internally by the C library.
>  * Signal Messages::             Printing a message describing a signal.
>  @end menu
> 
> @@ -794,6 +795,26 @@ in @ref{Signaling Another Process}.
>  The default action is to terminate the process.
>  @end deftypevr
> 
> +@deftypevr Macro int SIGRTMIN
> +@deftypevrx Macro int SIGRTMAX
> +@standards{POSIX.1, signal.h}
> +@cindex real-time signals
> +The range of signal numbers @code{SIGRTMIN}, @code{SIGRTMIN+1},
> +@dots{}, @code{SIGRTMAX} is also set aside for you to use any way you
> +want.  In addition, these signals (and no others) are guaranteed to
> +support @dfn{real-time} signal semantics, which unfortunately this
> +manual does not yet document.

I think we can omit the last sentence "which unfortunately this
manual does not yet document.".

> +
> +Unlike all of the other signal number macros, @code{SIGRTMIN} and
> +@code{SIGRTMAX} are not compile-time constants, because some operating
> +systems make the number of real-time signals tunable on a
> +per-installation or even per-process basis.  However, POSIX guarantees
> +that there will be at least 8 signal numbers in this range.
> +
> +The default action for all signals in this range is to terminate the
> +process.
> +@end deftypevr
> +
>  @deftypevr Macro int SIGWINCH
>  @standards{BSD, signal.h}
>  Window size change.  This is generated on some systems (including GNU)
> @@ -817,6 +838,22 @@ to print some status information about the system
> and what the process
>  is doing.  Otherwise the default is to do nothing.
>  @end deftypevr
> 
> +@node Internally-Used Signals
> +@subsection Internally-Used Signals
> +@cindex internally used signals
> +
> +On some operating systems, @theglibc{} needs to use a few signals from
> +the ``true'' real-time range internally, to implement thread
> +cancellation, cross-thread effective ID synchronization, POSIX timer
> +management, etc.  @Theglibc{} adjusts @code{SIGRTMIN} and
> +@code{SIGRTMAX} to exclude these signals, and it also takes steps to
> +prevent application code from altering their state: @code{sigprocmask}
> +cannot block them and @code{sigaction} cannot redefine their handlers,
> +for instance.  Therefore, most programs do not need to know or care
> +about these signals.  We mainly document their existence for the sake
> +of anyone who has ever wondered why there is a gap between the
> +highest-numbered ``normal'' signal and @code{SIGRTMIN} on Linux.
> +
>  @node Signal Messages
>  @subsection Signal Messages
>  @cindex signal messages
> 

LGTM this addition, I will incorporate this on my next submission.
Adhemerval Zanella Nov. 6, 2017, 11:17 a.m. | #4
On 06/11/2017 00:59, Rical Jasan wrote:
> On 11/05/2017 02:46 PM, Zack Weinberg wrote:
>> On Fri, Nov 3, 2017 at 5:40 PM, Adhemerval Zanella
>> <adhemerval.zanella@linaro.org> wrote:
>>> This patch consolidates the sigprocmask Linux syscall implementation on
>>> sysdeps/unix/sysv/linux/sigprocmask.c
>>
>> This looks like a virtuous change overall, but I don't know the code
>> well enough to singlehandedly review it.  I'd like to provide some
>> feedback on the manual change, though:
>>
>>> +On Linux pthreads internally uses some signals to implement asynchronous
>>> +cancellation, effective ID synchronization for POSIX conformance, and
>>> +posix timer management.  These signals are filtered out on signal set
>>> +function manipulation.
>>
>> This has grammar problems, and also, not all of the signal-set
>> functions filter the special signals.  For instance, sigfillset does,
>> but sigaddset doesn't (if I'm reading the code right, anyway).  And
>> this isn't even the right place to document this, because the main
>> reason why we need to document it is to explain why the kernel's idea
>> of the real-time signal range differs from what glibc exposes to
>> applications ... and the real-time signal range isn't documented at
>> all, *headdesk*.
>>
>> So I suggest this _instead of_ the above change:
>>
>> diff --git a/manual/signal.texi b/manual/signal.texi
>> index 9577ff091d..4f0ef59fb7 100644
>> --- a/manual/signal.texi
>> +++ b/manual/signal.texi
>> @@ -235,6 +235,7 @@ defined.  Since the signal numbers are allocated
>> consecutively,
>>  * Job Control Signals::         Signals used to support job control.
>>  * Operation Error Signals::     Used to report operational system errors.
>>  * Miscellaneous Signals::       Miscellaneous Signals.
>> +* Internally-Used Signals::     Signals used internally by the C library.
>>  * Signal Messages::             Printing a message describing a signal.
>>  @end menu
>>
>> @@ -794,6 +795,26 @@ in @ref{Signaling Another Process}.
>>  The default action is to terminate the process.
>>  @end deftypevr
>>
>> +@deftypevr Macro int SIGRTMIN
>> +@deftypevrx Macro int SIGRTMAX
>> +@standards{POSIX.1, signal.h}
>> +@cindex real-time signals
>> +The range of signal numbers @code{SIGRTMIN}, @code{SIGRTMIN+1},
>> +@dots{}, @code{SIGRTMAX} is also set aside for you to use any way you
>> +want.  In addition, these signals (and no others) are guaranteed to
>> +support @dfn{real-time} signal semantics, which unfortunately this
>> +manual does not yet document.
> 
> I don't think we should say that at the end.  It will be wrong someday
> (hopefully), without having to do anything to it.  It really just needs
> a @pxref we don't have yet, so instead, say nothing, which will continue
> to be correct both before and after real-time signal semantics are
> documented, and after they are, the reference can be added to improve
> the manual.

So your suggestion is just remove this snippet?

> 
> Maybe a bug report that real-time signal semantics aren't documented
> would be a good place to both track the issue and keep a reminder to
> update this paragraph.

I will create a bug report for it.

> 
>> +
>> +Unlike all of the other signal number macros, @code{SIGRTMIN} and
>> +@code{SIGRTMAX} are not compile-time constants, because some operating
>> +systems make the number of real-time signals tunable on a
>> +per-installation or even per-process basis.  However, POSIX guarantees
>> +that there will be at least 8 signal numbers in this range.
>> +
>> +The default action for all signals in this range is to terminate the
>> +process.
>> +@end deftypevr
>> +
>>  @deftypevr Macro int SIGWINCH
>>  @standards{BSD, signal.h}
>>  Window size change.  This is generated on some systems (including GNU)
>> @@ -817,6 +838,22 @@ to print some status information about the system
>> and what the process
>>  is doing.  Otherwise the default is to do nothing.
>>  @end deftypevr
>>
>> +@node Internally-Used Signals
>> +@subsection Internally-Used Signals
>> +@cindex internally used signals
>> +
>> +On some operating systems, @theglibc{} needs to use a few signals from
>> +the ``true'' real-time range internally, to implement thread
>> +cancellation, cross-thread effective ID synchronization, POSIX timer
>> +management, etc.  @Theglibc{} adjusts @code{SIGRTMIN} and
>> +@code{SIGRTMAX} to exclude these signals, and it also takes steps to
>> +prevent application code from altering their state: @code{sigprocmask}
>> +cannot block them and @code{sigaction} cannot redefine their handlers,
>> +for instance.  Therefore, most programs do not need to know or care
>> +about these signals.  We mainly document their existence for the sake
>> +of anyone who has ever wondered why there is a gap between the
>> +highest-numbered ``normal'' signal and @code{SIGRTMIN} on Linux.
>> +
>>  @node Signal Messages
>>  @subsection Signal Messages
>>  @cindex signal messages
> 
> Otherwise, I like the direction you took this, especially since it slips
> in documentation for some previously undocumented macros along with the
> concept.
> 
> Rical
>
Zack Weinberg Nov. 6, 2017, 2 p.m. | #5
On Sun, Nov 5, 2017 at 9:59 PM, Rical Jasan <ricaljasan@pacific.net> wrote:
> On 11/05/2017 02:46 PM, Zack Weinberg wrote:
>> +@deftypevr Macro int SIGRTMIN
>> +@deftypevrx Macro int SIGRTMAX
>> +@standards{POSIX.1, signal.h}
>> +@cindex real-time signals
>> +The range of signal numbers @code{SIGRTMIN}, @code{SIGRTMIN+1},
>> +@dots{}, @code{SIGRTMAX} is also set aside for you to use any way you
>> +want.  In addition, these signals (and no others) are guaranteed to
>> +support @dfn{real-time} signal semantics, which unfortunately this
>> +manual does not yet document.
>
> I don't think we should say that at the end.  It will be wrong someday
> (hopefully), without having to do anything to it.  It really just needs
> a @pxref we don't have yet, so instead, say nothing, which will continue
> to be correct both before and after real-time signal semantics are
> documented, and after they are, the reference can be added to improve
> the manual.

I don't want to say nothing, because if we say nothing, it's an
undefined term and readers will be frustrated.  If we admit that this
is a gap in the manual, they'll still be frustrated but at least they
won't waste time searching for the missing piece.

> Maybe a bug report that real-time signal semantics aren't documented
> would be a good place to both track the issue and keep a reminder to
> update this paragraph.

Agree with this part.

zw

Patch

diff --git a/manual/signal.texi b/manual/signal.texi
index 9577ff0..46696af 100644
--- a/manual/signal.texi
+++ b/manual/signal.texi
@@ -2461,6 +2461,11 @@  well.  (In addition, it's not wise to put into your program an
 assumption that the system has no signals aside from the ones you know
 about.)
 
+On Linux pthreads internally uses some signals to implement asynchronous
+cancellation, effective ID synchronization for POSIX conformance, and
+posix timer management.  These signals are filtered out on signal set
+function manipulation.
+
 @deftypefun int sigemptyset (sigset_t *@var{set})
 @standards{POSIX.1, signal.h}
 @safety{@prelim{}@mtsafe{}@assafe{}@acsafe{}}
diff --git a/sysdeps/unix/sysv/linux/alpha/sigprocmask.c b/sysdeps/unix/sysv/linux/alpha/sigprocmask.c
deleted file mode 100644
index ebec70c..0000000
--- a/sysdeps/unix/sysv/linux/alpha/sigprocmask.c
+++ /dev/null
@@ -1,58 +0,0 @@ 
-/* Copyright (C) 1993-2017 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by David Mosberger (davidm@azstarnet.com).
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library.  If not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <errno.h>
-#include <sysdep.h>
-#include <signal.h>
-
-/* When there is kernel support for more than 64 signals, we'll have to
-   switch to a new system call convention here.  */
-
-int
-__sigprocmask (int how, const sigset_t *set, sigset_t *oset)
-{
-  unsigned long int setval;
-  long result;
-
-  if (set)
-    setval = set->__val[0];
-  else
-    {
-      setval = 0;
-      how = SIG_BLOCK;	/* ensure blocked mask doesn't get changed */
-    }
-
-  result = INLINE_SYSCALL (osf_sigprocmask, 2, how, setval);
-  if (result == -1)
-    /* If there are ever more than 63 signals, we need to recode this
-       in assembler since we wouldn't be able to distinguish a mask of
-       all 1s from -1, but for now, we're doing just fine... */
-    return result;
-
-  if (oset)
-    {
-      oset->__val[0] = result;
-      result = _SIGSET_NWORDS;
-      while (--result > 0)
-	oset->__val[result] = 0;
-    }
-  return 0;
-}
-
-libc_hidden_def (__sigprocmask)
-weak_alias (__sigprocmask, sigprocmask);
diff --git a/sysdeps/unix/sysv/linux/ia64/sigprocmask.c b/sysdeps/unix/sysv/linux/ia64/sigprocmask.c
deleted file mode 100644
index 920c5fd..0000000
--- a/sysdeps/unix/sysv/linux/ia64/sigprocmask.c
+++ /dev/null
@@ -1,40 +0,0 @@ 
-/* Copyright (C) 1997-2017 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Linux/IA64 specific sigprocmask
-   Written by Jes Sorensen, <Jes.Sorensen@cern.ch>, April 1999.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-/* Linux/ia64 only has rt signals, thus we do not even want to try falling
-   back to the old style signals as the default Linux handler does. */
-
-#include <errno.h>
-#include <signal.h>
-#include <unistd.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-/* Get and/or change the set of blocked signals.  */
-int
-__sigprocmask (int how, const sigset_t *set, sigset_t *oset)
-{
-
-  /* XXX The size argument hopefully will have to be changed to the
-     real size of the user-level sigset_t.  */
-  return INLINE_SYSCALL (rt_sigprocmask, 4, how, set, oset, _NSIG / 8);
-}
-libc_hidden_def (__sigprocmask)
-weak_alias (__sigprocmask, sigprocmask)
diff --git a/sysdeps/unix/sysv/linux/nptl-signals.h b/sysdeps/unix/sysv/linux/nptl-signals.h
index f30c597..6afd3fe 100644
--- a/sysdeps/unix/sysv/linux/nptl-signals.h
+++ b/sysdeps/unix/sysv/linux/nptl-signals.h
@@ -33,6 +33,12 @@ 
 #define SIGSETXID       (__SIGRTMIN + 1)
 
 
+static inline bool
+__nptl_has_internal_signal (const sigset_t *set)
+{
+  return __sigismember (set, SIGCANCEL) || __sigismember (set, SIGSETXID);
+}
+
 /* Return is sig is used internally.  */
 static inline int
 __nptl_is_internal_signal (int sig)
diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/sigprocmask.c b/sysdeps/unix/sysv/linux/s390/s390-64/sigprocmask.c
deleted file mode 100644
index a8010e7..0000000
--- a/sysdeps/unix/sysv/linux/s390/s390-64/sigprocmask.c
+++ /dev/null
@@ -1,38 +0,0 @@ 
-/* Copyright (C) 2001-2017 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-/* 64 bit Linux for S/390 only has rt signals, thus we do not even want to try
-   falling back to the old style signals as the default Linux handler does. */
-
-#include <errno.h>
-#include <signal.h>
-#include <unistd.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-/* Get and/or change the set of blocked signals.  */
-int
-__sigprocmask (int how, const sigset_t *set, sigset_t *oset)
-{
-
-  /* XXX The size argument hopefully will have to be changed to the
-     real size of the user-level sigset_t.  */
-  return INLINE_SYSCALL (rt_sigprocmask, 4, how, set, oset, _NSIG / 8);
-}
-libc_hidden_def (__sigprocmask)
-weak_alias (__sigprocmask, sigprocmask)
diff --git a/sysdeps/unix/sysv/linux/sigprocmask.c b/sysdeps/unix/sysv/linux/sigprocmask.c
index e776563..d14fc5c 100644
--- a/sysdeps/unix/sysv/linux/sigprocmask.c
+++ b/sysdeps/unix/sysv/linux/sigprocmask.c
@@ -1,4 +1,5 @@ 
-/* Copyright (C) 1997-2017 Free Software Foundation, Inc.
+/* Get and/or change the set of blocked signals.  Linux version.
+   Copyright (C) 1997-2017 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -17,34 +18,22 @@ 
 
 #include <errno.h>
 #include <signal.h>
-#include <string.h>  /* Needed for string function builtin redirection.  */
-#include <unistd.h>
+#include <nptl-signals.h>
 
-#include <sysdep.h>
-#include <sys/syscall.h>
 
-#include <nptl/pthreadP.h>              /* SIGCANCEL, SIGSETXID */
-
-
-/* Get and/or change the set of blocked signals.  */
 int
 __sigprocmask (int how, const sigset_t *set, sigset_t *oset)
 {
   sigset_t local_newmask;
 
-  /* The only thing we have to make sure here is that SIGCANCEL and
-     SIGSETXID are not blocked.  */
-  if (set != NULL
-      && (__builtin_expect (__sigismember (set, SIGCANCEL), 0)
-	  || __builtin_expect (__sigismember (set, SIGSETXID), 0)))
+  if (set != NULL && __glibc_unlikely (__nptl_has_internal_signal (set)))
     {
       local_newmask = *set;
-      __sigdelset (&local_newmask, SIGCANCEL);
-      __sigdelset (&local_newmask, SIGSETXID);
+      __nptl_clear_internal_signals (&local_newmask);
       set = &local_newmask;
     }
 
-  return INLINE_SYSCALL (rt_sigprocmask, 4, how, set, oset, _NSIG / 8);
+  return INLINE_SYSCALL_CALL (rt_sigprocmask, how, set, oset, _NSIG / 8);
 }
 libc_hidden_def (__sigprocmask)
 weak_alias (__sigprocmask, sigprocmask)
diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sigprocmask.c b/sysdeps/unix/sysv/linux/sparc/sparc64/sigprocmask.c
deleted file mode 100644
index ef7d7fe..0000000
--- a/sysdeps/unix/sysv/linux/sparc/sparc64/sigprocmask.c
+++ /dev/null
@@ -1,34 +0,0 @@ 
-/* Copyright (C) 1997-2017 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-#include <errno.h>
-#include <signal.h>
-#include <unistd.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-/* Get and/or change the set of blocked signals.  */
-int
-__sigprocmask (int how, const sigset_t *set, sigset_t *oset)
-{
-  /* XXX The size argument hopefully will have to be changed to the
-     real size of the user-level sigset_t.  */
-  return INLINE_SYSCALL (rt_sigprocmask, 4, how, set, oset, _NSIG / 8);
-}
-libc_hidden_def (__sigprocmask)
-weak_alias (__sigprocmask, sigprocmask)
diff --git a/sysdeps/unix/sysv/linux/x86_64/sigprocmask.c b/sysdeps/unix/sysv/linux/x86_64/sigprocmask.c
deleted file mode 100644
index 1610ddf..0000000
--- a/sysdeps/unix/sysv/linux/x86_64/sigprocmask.c
+++ /dev/null
@@ -1,39 +0,0 @@ 
-/* Copyright (C) 1997-2017 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Written by Jes Sorensen, <Jes.Sorensen@cern.ch>, April 1999.
-
-   The GNU C Library is free software; you can redistribute it and/or
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library 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
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, see
-   <http://www.gnu.org/licenses/>.  */
-
-/* Linux/x86_64 only has rt signals, thus we do not even want to try falling
-   back to the old style signals as the default Linux handler does. */
-
-#include <errno.h>
-#include <signal.h>
-#include <unistd.h>
-
-#include <sysdep.h>
-#include <sys/syscall.h>
-
-/* Get and/or change the set of blocked signals.  */
-int
-__sigprocmask (int how, const sigset_t *set, sigset_t *oset)
-{
-
-  /* XXX The size argument hopefully will have to be changed to the
-     real size of the user-level sigset_t.  */
-  return INLINE_SYSCALL (rt_sigprocmask, 4, how, set, oset, _NSIG / 8);
-}
-libc_hidden_def (__sigprocmask)
-weak_alias (__sigprocmask, sigprocmask)