On Tue, Oct 01, 2024 at 12:36:21PM +0200, Jakub Jelinek wrote:
> On Tue, Oct 01, 2024 at 11:10:03AM +0100, Jonathan Wakely wrote:
> > Let's use an inline variable. A function-local static requires
> > __cxa_guard_acquire, which (for some targets, including the ones
> > affected by this change) uses __gthread_active_p which will
> > recursively re-enter the variable's initialization.
> > 
> > So something like:
> > 
> > #pragma GCC diagnostic push
> > #pragma GCC diagnostic ignored "-Wc++17-extensions"
> > inline volatile int __gthread_active = -1;
> > #pragma GCC diagnostic pop
> 
> Note, only for #ifdef __cplusplus, for C there is no such thing as inline
> variables and in that case it should use
> static volatile int __ghtread_active = -1;
> instead.
> 
>       Jakub
> 

So something like this maybe; bootstrapped and regtested on
x86_64-pc-linux-gnu and aarch64-unknown-linux-gnu, OK for trunk?

Or maybe it would be clearer to do the #ifdef __cplusplus here locally
rather than introducing a new __GTHREAD_VAR macro?

-- >8 --

Subject: [PATCH] libgcc: Use inline variable instead of function-local static

To support C++ ODR rules but remain compatible with C, I had initially
changed these variables to be function-local statics rather than global
internal-linkage decls.

However, both GCC and Clang support using namespace-scope 'inline'
variables even in pre-C++17 (with a warning), so let's simplify and do
that instead.  For C we instead revert back to using an internal-linkage
variable.

        PR c++/115126

libgcc/ChangeLog:

        * gthr-posix.h (__GTHREAD_VAR): New macro.
        (__gthread_active): Be a possibly-inline variable instead of a
        function.  Ignore any resultant diagnostics.
        (__gthread_trigger): __gthread_active is now a variable.
        (__gthread_active_p): Likewise.

Signed-off-by: Nathaniel Shead <nathanielosh...@gmail.com>
---
 libgcc/gthr-posix.h | 39 +++++++++++++++++++--------------------
 1 file changed, 19 insertions(+), 20 deletions(-)

diff --git a/libgcc/gthr-posix.h b/libgcc/gthr-posix.h
index 478bcf4cee6..b24992a539f 100644
--- a/libgcc/gthr-posix.h
+++ b/libgcc/gthr-posix.h
@@ -55,8 +55,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If 
not, see
 
 #ifdef __cplusplus
 # define __GTHREAD_INLINE inline __GTHREAD_ALWAYS_INLINE
+# define __GTHREAD_VAR inline
 #else
 # define __GTHREAD_INLINE static inline
+# define __GTHREAD_VAR static
 #endif
 
 typedef pthread_t __gthread_t;
@@ -198,18 +200,16 @@ __gthrw(pthread_setschedparam)
 #if defined(__FreeBSD__) || (defined(__sun) && defined(__svr4__))
 
 #pragma GCC visibility push(hidden)
-__GTHREAD_INLINE volatile int *
-__gthread_active (void)
-{
-  static volatile int __gthread_active_var = -1;
-  return &__gthread_active_var;
-}
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wc++17-extensions"
+__GTHREAD_VAR volatile int * __gthread_active = -1;
+#pragma GCC diagnostic pop
 #pragma GCC visibility pop
 
 __GTHREAD_INLINE void
 __gthread_trigger (void)
 {
-  *__gthread_active () = 1;
+  *__gthread_active = 1;
 }
 
 #pragma GCC visibility push(hidden)
@@ -220,7 +220,7 @@ __gthread_active_p (void)
   static pthread_once_t __gthread_active_once = PTHREAD_ONCE_INIT;
 
   /* Avoid reading __gthread_active twice on the main code path.  */
-  int __gthread_active_latest_value = *__gthread_active ();
+  int __gthread_active_latest_value = *__gthread_active;
 
   /* This test is not protected to avoid taking a lock on the main code
      path so every update of __gthread_active in a threaded program must
@@ -237,10 +237,10 @@ __gthread_active_p (void)
        }
 
       /* Make sure we'll never enter this block again.  */
-      if (*__gthread_active () < 0)
-       *__gthread_active () = 0;
+      if (*__gthread_active < 0)
+       *__gthread_active = 0;
 
-      __gthread_active_latest_value = *__gthread_active ();
+      __gthread_active_latest_value = *__gthread_active;
     }
 
   return __gthread_active_latest_value != 0;
@@ -315,26 +315,24 @@ __gthread_active_p (void)
 #if defined(__hppa__) && defined(__hpux__)
 
 #pragma GCC visibility push(hidden)
-__GTHREAD_INLINE volatile int *
-__gthread_active (void)
-{
-  static volatile int __gthread_active_var = -1;
-  return &__gthread_active_var;
-}
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wc++17-extensions"
+__GTHREAD_VAR volatile int * __gthread_active = -1;
+#pragma GCC diagnostic pop
 #pragma GCC visibility pop
 
 __GTHREAD_INLINE int
 __gthread_active_p (void)
 {
   /* Avoid reading __gthread_active twice on the main code path.  */
-  int __gthread_active_latest_value = *__gthread_active ();
+  int __gthread_active_latest_value = *__gthread_active;
   size_t __s;
 
   if (__builtin_expect (__gthread_active_latest_value < 0, 0))
     {
       pthread_default_stacksize_np (0, &__s);
-      *__gthread_active () = __s ? 1 : 0;
-      __gthread_active_latest_value = *__gthread_active ();
+      *__gthread_active = __s ? 1 : 0;
+      __gthread_active_latest_value = *__gthread_active;
     }
 
   return __gthread_active_latest_value != 0;
@@ -980,6 +978,7 @@ __gthread_rwlock_unlock (__gthread_rwlock_t *__rwlock)
 
 #endif /* _LIBOBJC */
 
+#undef __GTHREAD_VAR
 #undef __GTHREAD_INLINE
 #undef __GTHREAD_ALWAYS_INLINE
 
-- 
2.46.0

Reply via email to