Hi!

On 2025-02-20T14:14:44+0000, Jonathan Wakely <jwak...@redhat.com> wrote:
> On Thu, 20 Feb 2025 at 14:08, Jonathan Wakely <jwak...@redhat.com> wrote:
>> On Thu, 20 Feb 2025 at 13:53, Thomas Schwinge <tschwi...@baylibre.com> wrote:
>> > On 2025-02-20T12:51:15+0000, Jonathan Wakely <jwak...@redhat.com> wrote:
>> > > On Thu, 20 Feb 2025 at 12:29, Thomas Schwinge <tschwi...@baylibre.com> 
>> > > wrote:
>> > >> I'm still working on libstdc++ support for GCC's GPU targets: GCN, 
>> > >> nvptx.
>> > >> These configurations are (in typical use) multi-threaded, and support
>> > >> mutexes etc., but they don't support dynamic spawning of threads etc.
>> > >> Therefore, re 'libgcc/gthr.h', they define '__GTHREADS' but *not*
>> > >> '__GTHREADS_CXX0X'.  (See 'libgcc/config/gcn/gthr-gcn.h'; nvptx still to
>> > >> be done, currently 'Thread model: single', very likely bogus...)
>> > >>
>> > >> Now, 'libstdc++-v3/acinclude.m4:GLIBCXX_CHECK_GTHREADS' does:
>> > >>
>> > >>     [...]
>> > >>       AC_MSG_CHECKING([for gthreads library])
>> > >>
>> > >>       AC_TRY_COMPILE([#include "gthr.h"],
>> > >>         [
>> > >>           #ifndef __GTHREADS_CXX0X
>> > >>           #error
>> > >>           #endif
>> > >>         ], [ac_has_gthreads=yes], [ac_has_gthreads=no])
>> > >>       else
>> > >>         ac_has_gthreads=no
>> > >>       fi
>> > >>
>> > >>       AC_MSG_RESULT([$ac_has_gthreads])
>> > >>
>> > >>       if test x"$ac_has_gthreads" = x"yes"; then
>> > >>         AC_DEFINE(_GLIBCXX_HAS_GTHREADS, 1,
>> > >>                   [Define if gthreads library is available.])
>> > >>     [...]
>> > >>
>> > >> That is, it defines '_GLIBCXX_HAS_GTHREADS' per '__GTHREADS_CXX0X'.
>> > >> Dependent on this '_GLIBCXX_HAS_GTHREADS',
>> > >> 'libstdc++-v3/include/bits/std_mutex.h' then enables 'class mutex'.  In
>> > >> other words, in the current GCN configuration ('__GTHREADS', but not
>> > >> '__GTHREADS_CXX0X'), 'class mutex' (and probably more) is not available,
>> > >> which leads to build issues (and presumably a lot of noise in the test
>> > >> suite).
>> > >
>> > > What are the build issues? There shouldn't be any, because we should
>> > > be checking _GLIBCXX_HAS_GTHREADS as needed.
>> >
>> > The build issue is 'libstdc++-v3/src/c++20/tzdb.cc', which checks
>> > '#if defined __GTHREADS' (which GCN defines), and then assumes that
>> > 'mutex' is available,
>>
>> Right, that's a bug (and not the first time I've done that).

Specifically:

    ../../../../../source-gcc/libstdc++-v3/src/c++20/tzdb.cc:687:9: error: 
‘mutex’ does not name a type; did you mean ‘minutes’? [-Wtemplate-body]
      687 |         mutex infos_mutex;
          |         ^~~~~
          |         minutes

>> > but that one via '_GLIBCXX_HAS_GTHREADS' is guarded
>> > on '__GTHREADS_CXX0X' (which GCN doesn't define).
>> >
>> > Now clearly 'std::chrono::tzdb' is not going to be used in offloaded code
>> > regions, but (a) famous last words..., and (b) I was more worried about
>> > the general case, where code (user code or libstdc++-internal) would see
>> > '!_GLIBCXX_HAS_GTHREADS', and from that deduce that locking for
>> > concurrent access etc. is not necessary.
>> >
>> > > And the testsuite should use dg-require-gthreads.
>> >
>> > > So instead of trying to make the C++11 thread library work without the
>> > > necessary gthreads support
>> >
>> > Right, we're not attempting to make 'std::thread::detach' work, for
>> > example.  But I was assuming that we could/had to make 'std::mutex'
>> > etc. work, so that algorithms in presence of "external parallelism" still
>> > do the appropriate locking etc.
>> >
>> > Like, when used within a GPU parallel kernel, 'std::chrono::tzdb' needs
>> > to 'mutex' its internal state, thus, guarding that on '__GTHREADS' would
>> > seem correct, even if '!__GTHREADS_CXX0X'?
>>
>> Yes. Elsewhere in the library we do that with __gnu_cxx::__mutex
>> instead of std::mutex.

So you're saying, for '__GTHREADS && !__GTHREADS_CXX0X' configurations,
libstdc++ internally still does locking (via '__GTHREADS' primitives),
just the user-facing 'std::mutex' etc. isn't available?

>> I think this should fix it:
>>
>> --- a/libstdc++-v3/src/c++20/tzdb.cc
>> +++ b/libstdc++-v3/src/c++20/tzdb.cc
>> @@ -48,6 +48,7 @@
>> #else
>> # define USE_ATOMIC_LIST_HEAD 0
>> # define USE_ATOMIC_SHARED_PTR 0
>> +# include <ext/concurrence.h>
>> #endif
>>
>> #if USE_ATOMIC_SHARED_PTR && ! USE_ATOMIC_LIST_HEAD
>> @@ -101,6 +102,8 @@ namespace std::chrono
>> #ifndef __GTHREADS
>>     // Dummy no-op mutex type for single-threaded targets.
>>     struct mutex { void lock() { } void unlock() { } };
>> +#elif ! defined _GLIBCXX_HAS_GHTREADS
>
> Oops, s/GHTR/GTHR/
>
>> +    using mutex = __gnu_cxx::__mutex;
>> #endif
>>     inline mutex& list_mutex()
>>     {

GCN has 'defined __GTHREADS && ATOMIC_POINTER_LOCK_FREE == 2', so we
have:

    #if defined __GTHREADS && ATOMIC_POINTER_LOCK_FREE == 2
    # define USE_ATOMIC_LIST_HEAD 1
    // TODO benchmark atomic<shared_ptr<>> vs mutex.
    # define USE_ATOMIC_SHARED_PTR 1

Maybe the attached
"Fix 'libstdc++-v3/src/c++20/tzdb.cc' build for '__GTHREADS && 
!__GTHREADS_CXX0X' configurations"?
Only GCN, nvptx build-tested so far.


Grüße
 Thomas


>> We could also enable std::mutex for the __GTHREADS && !
>> __GTHREADS_CXX0X case but that should probably wait for stage 1.
>>
>>
>>
>> >
>> > > maybe you just need to identify a handful
>> > > of bugs where we aren't checking the right macros in the libstdc++
>> > > sources?
>> > >
>> > >> Is '__GTHREADS != __GTHREADS_CXX0X' simply a configuration that 
>> > >> libstdc++
>> > >> so far has not attempted to support?  To make that work, do we need to
>> > >> consider '__GTHREADS' vs. '__GTHREADS_CXX0X' individually in libstdc++,
>> > >> for guarding the respective features?
>> >
>> > Another option for GCN, nvptx -- and maybe that's actually easiest: we
>> > define '__GTHREADS_CXX0X' in addition to '__GTHREADS', and implement the
>> > additional interfaces as "operation is not supported, -1 is returned"?
>> > That should make libstdc++ "happy" and give a consistent user experience
>> > (like, when the OS is out of resources)?
>> >
>> >
>> > Grüße
>> >  Thomas
>> >


>From 820e015494e25187c9a5ffbd69911ec6ce612789 Mon Sep 17 00:00:00 2001
From: Jonathan Wakely <jwak...@redhat.com>
Date: Thu, 20 Feb 2025 14:08:11 +0000
Subject: [PATCH] Fix 'libstdc++-v3/src/c++20/tzdb.cc' build for '__GTHREADS &&
 !__GTHREADS_CXX0X' configurations

	libstdc++-v3/
	* src/c++20/tzdb.cc [__GTHREADS && !__GTHREADS_CXX0X]: Use
	'__gnu_cxx::__mutex'.

Co-authored-by: Thomas Schwinge <tschwi...@baylibre.com>
---
 libstdc++-v3/src/c++20/tzdb.cc | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/libstdc++-v3/src/c++20/tzdb.cc b/libstdc++-v3/src/c++20/tzdb.cc
index 7e8cce7ce8c..70ba7b0ef53 100644
--- a/libstdc++-v3/src/c++20/tzdb.cc
+++ b/libstdc++-v3/src/c++20/tzdb.cc
@@ -35,6 +35,9 @@
 #include <atomic>     // atomic<T*>, atomic<int>
 #include <memory>     // atomic<shared_ptr<T>>
 #include <mutex>      // mutex
+#if defined __GTHREADS && ! defined _GLIBCXX_HAS_GHTREADS
+# include <ext/concurrence.h> // __gnu_cxx::__mutex
+#endif
 #include <filesystem> // filesystem::read_symlink
 
 #ifndef _AIX
@@ -97,11 +100,14 @@ namespace std::chrono
 {
   namespace
   {
-#if ! USE_ATOMIC_SHARED_PTR
 #ifndef __GTHREADS
     // Dummy no-op mutex type for single-threaded targets.
     struct mutex { void lock() { } void unlock() { } };
+#elif ! defined _GLIBCXX_HAS_GHTREADS
+    using mutex = __gnu_cxx::__mutex;
 #endif
+
+#if ! USE_ATOMIC_SHARED_PTR
     inline mutex& list_mutex()
     {
 #ifdef __GTHREAD_MUTEX_INIT
-- 
2.34.1

Reply via email to