[1/8] nptl: Add <thread_pointer.h> for defining __thread_pointer
Checks
Context |
Check |
Description |
dj/TryBot-apply_patch |
success
|
Patch applied to master at the time it was sent
|
Commit Message
<tls.h> already contains a definition that is quite similar,
but it is not consistent across architectures.
Only architectures for which rseq support is added are covered.
---
v2: As posted before.
sysdeps/nptl/thread_pointer.h | 28 ++++++++++++++++++++
sysdeps/powerpc/nptl/thread_pointer.h | 33 +++++++++++++++++++++++
sysdeps/x86/nptl/thread_pointer.h | 38 +++++++++++++++++++++++++++
3 files changed, 99 insertions(+)
create mode 100644 sysdeps/nptl/thread_pointer.h
create mode 100644 sysdeps/powerpc/nptl/thread_pointer.h
create mode 100644 sysdeps/x86/nptl/thread_pointer.h
Comments
The 12/07/2021 14:00, Florian Weimer via Libc-alpha wrote:
> <tls.h> already contains a definition that is quite similar,
> but it is not consistent across architectures.
>
> Only architectures for which rseq support is added are covered.
This looks ok.
It's an annoying gcc bug that __builtin_thread_pointer
does not work consistently across targets.
Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
> ---
> v2: As posted before.
>
> sysdeps/nptl/thread_pointer.h | 28 ++++++++++++++++++++
> sysdeps/powerpc/nptl/thread_pointer.h | 33 +++++++++++++++++++++++
> sysdeps/x86/nptl/thread_pointer.h | 38 +++++++++++++++++++++++++++
> 3 files changed, 99 insertions(+)
> create mode 100644 sysdeps/nptl/thread_pointer.h
> create mode 100644 sysdeps/powerpc/nptl/thread_pointer.h
> create mode 100644 sysdeps/x86/nptl/thread_pointer.h
>
> diff --git a/sysdeps/nptl/thread_pointer.h b/sysdeps/nptl/thread_pointer.h
> new file mode 100644
> index 0000000000..92f2f3093e
> --- /dev/null
> +++ b/sysdeps/nptl/thread_pointer.h
> @@ -0,0 +1,28 @@
> +/* __thread_pointer definition. Generic version.
> + Copyright (C) 2021 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
> + <https://www.gnu.org/licenses/>. */
> +
> +#ifndef _SYS_THREAD_POINTER_H
> +#define _SYS_THREAD_POINTER_H
> +
> +static inline void *
> +__thread_pointer (void)
> +{
> + return __builtin_thread_pointer ();
> +}
> +
> +#endif /* _SYS_THREAD_POINTER_H */
> diff --git a/sysdeps/powerpc/nptl/thread_pointer.h b/sysdeps/powerpc/nptl/thread_pointer.h
> new file mode 100644
> index 0000000000..8fd5ba671f
> --- /dev/null
> +++ b/sysdeps/powerpc/nptl/thread_pointer.h
> @@ -0,0 +1,33 @@
> +/* __thread_pointer definition. powerpc version.
> + Copyright (C) 2021 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
> + <https://www.gnu.org/licenses/>. */
> +
> +#ifndef _SYS_THREAD_POINTER_H
> +#define _SYS_THREAD_POINTER_H
> +
> +static inline void *
> +__thread_pointer (void)
> +{
> +#ifdef __powerpc64__
> + register void *__result asm ("r13");
> +#else
> + register void *__result asm ("r2");
> +#endif
> + return __result;
> +}
> +
> +#endif /* _SYS_THREAD_POINTER_H */
> diff --git a/sysdeps/x86/nptl/thread_pointer.h b/sysdeps/x86/nptl/thread_pointer.h
> new file mode 100644
> index 0000000000..6b71b6f7e1
> --- /dev/null
> +++ b/sysdeps/x86/nptl/thread_pointer.h
> @@ -0,0 +1,38 @@
> +/* __thread_pointer definition. x86 version.
> + Copyright (C) 2021 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
> + <https://www.gnu.org/licenses/>. */
> +
> +#ifndef _SYS_THREAD_POINTER_H
> +#define _SYS_THREAD_POINTER_H
> +
> +static inline void *
> +__thread_pointer (void)
> +{
> +#if __GNUC_PREREQ (11, 1)
> + return __builtin_thread_pointer ();
> +#else
> + void *__result;
> +# ifdef __x86_64__
> + __asm__ ("mov %%fs:0, %0" : "=r" (__result));
> +# else
> + __asm__ ("mov %%gs:0, %0" : "=r" (__result));
> +# endif
> + return __result;
> +#endif /* !GCC 11 */
> +}
> +
> +#endif /* _SYS_THREAD_POINTER_H */
> --
> 2.33.1
>
>
* Szabolcs Nagy:
> The 12/07/2021 14:00, Florian Weimer via Libc-alpha wrote:
>> <tls.h> already contains a definition that is quite similar,
>> but it is not consistent across architectures.
>>
>> Only architectures for which rseq support is added are covered.
>
> This looks ok.
>
> It's an annoying gcc bug that __builtin_thread_pointer
> does not work consistently across targets.
>
> Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
We don't need m68k for rseq, so I haven't added it, but I saw that
__thread_pointer is actually a system call there. Maybe that's why it's
not a universal GCC feature. Furthermore, for many ABIs, the thread
pointer is somewhat implicit. On x86, it took some discussion to figure
out that we actually have a canonical notion of a thread pointer. On
some other targets, the thread pointer is stored explicitly in a
(system) register, but it actually points to nowhere, so that local-exec
TLS access can make better use of immediate instruction operands.
It's also annoying that __has_builtin (__builtin_thread_pointer)
evaluates to true even for GCC targets where actually using
__builtin_thread_pointer () results in a compiler error.
In the future, we could install this as <sys/thread_pointer.h> if people
think it's useful (not just in an rseq context).
Thanks,
Florian
The 12/08/2021 18:55, Florian Weimer wrote:
> * Szabolcs Nagy:
> > The 12/07/2021 14:00, Florian Weimer via Libc-alpha wrote:
> >> <tls.h> already contains a definition that is quite similar,
> >> but it is not consistent across architectures.
> >>
> >> Only architectures for which rseq support is added are covered.
> >
> > This looks ok.
> >
> > It's an annoying gcc bug that __builtin_thread_pointer
> > does not work consistently across targets.
> >
> > Reviewed-by: Szabolcs Nagy <szabolcs.nagy@arm.com>
>
> We don't need m68k for rseq, so I haven't added it, but I saw that
> __thread_pointer is actually a system call there. Maybe that's why it's
> not a universal GCC feature. Furthermore, for many ABIs, the thread
> pointer is somewhat implicit. On x86, it took some discussion to figure
> out that we actually have a canonical notion of a thread pointer. On
> some other targets, the thread pointer is stored explicitly in a
> (system) register, but it actually points to nowhere, so that local-exec
> TLS access can make better use of immediate instruction operands.
i think local-exec tls access has to expose
some notion of thread pointer to the compiler
(from which a tls variable is at fixed offset).
whatever that notion is, __builtin_thread_pointer
can be defined based on that and if there is
nothing exposed then presumably tls access
relies on libc apis so __builtin_thread_pointer
can also rely on a libc api (or syscall).
tp is useful as a thread identifier and for fixed
offset tcb abis. (especially within libc and
compiler runtimes)
>
> It's also annoying that __has_builtin (__builtin_thread_pointer)
> evaluates to true even for GCC targets where actually using
> __builtin_thread_pointer () results in a compiler error.
>
> In the future, we could install this as <sys/thread_pointer.h> if people
> think it's useful (not just in an rseq context).
yeah, i would prefer gcc to be fixed.
new file mode 100644
@@ -0,0 +1,28 @@
+/* __thread_pointer definition. Generic version.
+ Copyright (C) 2021 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
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_THREAD_POINTER_H
+#define _SYS_THREAD_POINTER_H
+
+static inline void *
+__thread_pointer (void)
+{
+ return __builtin_thread_pointer ();
+}
+
+#endif /* _SYS_THREAD_POINTER_H */
new file mode 100644
@@ -0,0 +1,33 @@
+/* __thread_pointer definition. powerpc version.
+ Copyright (C) 2021 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
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_THREAD_POINTER_H
+#define _SYS_THREAD_POINTER_H
+
+static inline void *
+__thread_pointer (void)
+{
+#ifdef __powerpc64__
+ register void *__result asm ("r13");
+#else
+ register void *__result asm ("r2");
+#endif
+ return __result;
+}
+
+#endif /* _SYS_THREAD_POINTER_H */
new file mode 100644
@@ -0,0 +1,38 @@
+/* __thread_pointer definition. x86 version.
+ Copyright (C) 2021 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
+ <https://www.gnu.org/licenses/>. */
+
+#ifndef _SYS_THREAD_POINTER_H
+#define _SYS_THREAD_POINTER_H
+
+static inline void *
+__thread_pointer (void)
+{
+#if __GNUC_PREREQ (11, 1)
+ return __builtin_thread_pointer ();
+#else
+ void *__result;
+# ifdef __x86_64__
+ __asm__ ("mov %%fs:0, %0" : "=r" (__result));
+# else
+ __asm__ ("mov %%gs:0, %0" : "=r" (__result));
+# endif
+ return __result;
+#endif /* !GCC 11 */
+}
+
+#endif /* _SYS_THREAD_POINTER_H */