Bug 64735 - std::future broken on armel
Summary: std::future broken on armel
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libstdc++ (show other bugs)
Version: 4.9.2
: P3 normal
Target Milestone: 7.0
Assignee: Jonathan Wakely
URL:
Keywords:
: 58938 (view as bug list)
Depends on:
Blocks:
 
Reported: 2015-01-22 21:21 UTC by Bastiaan Jacques
Modified: 2021-07-22 21:29 UTC (History)
4 users (show)

See Also:
Host:
Target: arm
Build:
Known to work:
Known to fail: 4.9.0, 4.9.1, 4.9.2, 5.0
Last reconfirmed: 2015-01-23 00:00:00


Attachments
Not yet fully tested patch for std::future fix (1.89 KB, patch)
2016-11-05 22:07 UTC, Pauli
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Bastiaan Jacques 2015-01-22 21:21:36 UTC
$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/armv5tel-unknown-linux-gnueabi/4.9.2/lto-wrapper
Target: armv5tel-unknown-linux-gnueabi
Configured with: /build/gcc/src/gcc-4.9-20141224/configure --prefix=/usr --libdir=/usr/lib --libexecdir=/usr/lib --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=https://github.com/archlinuxarm/PKGBUILDs/issues --enable-languages=c,c++,fortran,go,lto,objc,obj-c++ --enable-shared --enable-threads=posix --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-clocale=gnu --disable-libstdcxx-pch --disable-libssp --enable-gnu-unique-object --enable-linker-build-id --enable-cloog-backend=isl --enable-lto --enable-plugin --enable-install-libiberty --with-linker-hash-style=gnu --disable-multilib --disable-werror --enable-checking=release --host=armv5tel-unknown-linux-gnueabi --build=armv5tel-unknown-linux-gnueabi --with-arch=armv5te --with-float=soft
Thread model: posix
gcc version 4.9.2 20141224 (prerelease) (GCC) 

Test case from https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=727621 :

#include <future>

int main()
{
        std::future<bool> fb = std::async([]{ return false; });
        return 0;
}

yields:

future.cc: In function ‘int main()’:
future.cc:5:27: error: variable ‘std::future<bool> fb’ has initializer but incomplete type
         std::future<bool> fb = std::async([]{ return false; });
                           ^
future.cc:5:62: error: invalid use of incomplete type ‘class std::future<bool>’
         std::future<bool> fb = std::async([]{ return false; });
                                                              ^
In file included from future.cc:1:0:
/usr/include/c++/4.9.2/future:114:11: error: declaration of ‘class std::future<bool>’
     class future;
           ^
/usr/include/c++/4.9.2/future: At global scope:
/usr/include/c++/4.9.2/future:176:5: error: ‘std::future<typename std::result_of<_Functor(_ArgTypes ...)>::type> std::async(_Fn&&, _Args&& ...) [with _Fn = main()::<lambda()>; _Args = {}; typename std::result_of<_Functor(_ArgTypes ...)>::type = bool]’, declared using local type ‘main()::<lambda()>’, is used but never defined [-fpermissive]
     async(_Fn&& __fn, _Args&&... __args);
     ^
Comment 1 Ramana Radhakrishnan 2015-01-23 10:01:35 UTC
Confirmed with -march=armv5te on all platforms. The only thing I can think of off the top of my head that is different for armv5te compared to armv7-a is that on armv5te we end up going through the kernel helper function for all atomic and sync type operations, there is no inlining and maybe that's what is broken in some sense here. 

Would help for some comments from a libstdc++ / C++ person.
Comment 2 Jonathan Wakely 2015-01-23 10:04:57 UTC
I think this is expected, the std:future type and std::async function are declared unconditionally, but the definitions are guarded by:

#if defined(_GLIBCXX_HAS_GTHREADS) && defined(_GLIBCXX_USE_C99_STDINT_TR1) \
  && (ATOMIC_INT_LOCK_FREE > 1)

If your target doesn't meet those conditions then you don't get to use std::future
Comment 3 Jonathan Wakely 2015-01-23 10:05:38 UTC
i.e. it's not broken, it's missing, and that's by design.
Comment 4 Ramana Radhakrishnan 2015-01-23 10:25:40 UTC
(In reply to Jonathan Wakely from comment #3)
> i.e. it's not broken, it's missing, and that's by design.

Right so if I parse that correctly, it boils down to implementation of atomics with calls to kernel helper function vs the lack of it IIUC. Not really a libstdc++ issue but more of an issue with the way in which atomics are implemented on arch's that don't have the actual instruction support but are implemented through kernel helper functions.

It appears as though this breaks quite a few packages on older versions of the architecture so that's interesting.

Ramana
Comment 5 Bastiaan Jacques 2015-01-23 12:33:15 UTC
(In reply to Jonathan Wakely from comment #3)
> i.e. it's not broken, it's missing, and that's by design.

So is it the intention of the GCC developers that program writers targeting such platforms simply avoid these facilities and use std::thread/mutex instead?
Comment 6 Jonathan Wakely 2015-01-23 15:50:56 UTC
(In reply to Bastiaan Jacques from comment #5)
> (In reply to Jonathan Wakely from comment #3)
> > i.e. it's not broken, it's missing, and that's by design.
> 
> So is it the intention of the GCC developers that program writers targeting
> such platforms simply avoid these facilities and use std::thread/mutex
> instead?

Or they could contribute an implementation that works for their target.

The intention of the developers is that the feature should work correctly, and if that isn't possible with the current implementation for some target, then the feature should be disabled on that target. And that's what you see.
Comment 7 Pauli 2016-11-05 22:07:58 UTC
Created attachment 39971 [details]
Not yet fully tested patch for std::future fix

I'm currently in process fixing this bug. But I have to delay running tests and other verification for tomorrow. The patch is compile tested on Debian armel vm.
Comment 8 Jonathan Wakely 2016-11-07 22:27:00 UTC
The patch is a pessimization for non-armv5 targets, we don't want to change the targets that already work correctly. I'll look at a better way to do it (maybe encapsulating the ref-count more neatly) this week.
Comment 9 Pauli 2016-11-09 10:43:02 UTC
atomicity.h uses exactly same builtins if _GLIBCXX_ATOMIC_BUILTINS is set 1. Difference include check for __gthread_active_p check and annotations for race detector. Annotations are empty macros in default build. Same code is uses for all other atomic operations in libstdc++.

I'm finally having an working armv5te build from gcc-6-branch. I'm currently waiting the second unit test run to complete. If there is no unexpected failures from futures or exceptions I fill submit the complete patch later today.
Comment 10 Matthias Klose 2016-11-12 09:46:03 UTC
> I'm finally having an working armv5te build

is this supposed to work for armv4t as well?
Comment 11 Jonathan Wakely 2017-01-04 10:55:31 UTC
Author: redi
Date: Wed Jan  4 10:54:59 2017
New Revision: 244051

URL: https://gcc.gnu.org/viewcvs?rev=244051&root=gcc&view=rev
Log:
Support exception propagation without lock-free atomic int

2017-01-04  Pauli Nieminen  <suokkos@gmail.com>
	    Jonathan Wakely  <jwakely@redhat.com>

	PR libstdc++/64735
	* acinclude.m4 (GLIBCXX_CHECK_EXCEPTION_PTR_SYMVER): Define.
	* config.h.in: Regenerate.
	* config/abi/pre/gnu.ver [HAVE_EXCEPTION_PTR_SINCE_GCC46]
	(GLIBCXX_3.4.15, GLIBCXX_3.4.21, CXXABI_1.3.3, CXXABI_1.3.5): Make
	exports for exception_ptr, nested_exception, and future conditional.
	[HAVE_EXCEPTION_PTR_SINCE_GCC46] (GLIBCXX_3.4.23, CXXABI_1.3.11): Add
	exports for exception_ptr, nested_exception, and future conditional.
	* configure: Regenerate.
	* configure.ac: Use GLIBCXX_CHECK_EXCEPTION_PTR_SYMVER.
	* include/std/future: Remove check for ATOMIC_INT_LOCK_FREE
	* libsupc++/eh_atomics.h: New file for internal use only.
	(__eh_atomic_inc, __eh_atomic_dec): New.
	* libsupc++/eh_ptr.cc (exception_ptr::_M_addref)
	(exception_ptr::_M_release) (__gxx_dependent_exception_cleanup)
	(rethrow_exception): Use eh_atomics.h reference counting helpers.
	* libsupc++/eh_throw.cc (__gxx_exception_cleanup): Likewise.
	* libsupc++/eh_tm.cc (free_any_cxa_exception): Likewise.
	* libsupc++/exception: Remove check for ATOMIC_INT_LOCK_FREE.
	* libsupc++/exception_ptr.h: Likewise.
	* libsupc++/guard.cc: Include header for ATOMIC_INT_LOCK_FREE macro.
	* libsupc++/nested_exception.cc: Remove check for
	ATOMIC_INT_LOCK_FREE.
	* libsupc++/nested_exception.h: Likewise.
	* src/c++11/future.cc: Likewise.
	* testsuite/18_support/exception_ptr/*: Remove atomic builtins checks.
	* testsuite/18_support/nested_exception/*: Likewise.
	* testsuite/30_threads/async/*: Likewise.
	* testsuite/30_threads/future/*: Likewise.
	* testsuite/30_threads/headers/future/types_std_c++0x.cc: Likewise.
	* testsuite/30_threads/packaged_task/*: Likewise.
	* testsuite/30_threads/promise/*: Likewise.
	* testsuite/30_threads/shared_future/*: Likewise.

Added:
    trunk/libstdc++-v3/libsupc++/eh_atomics.h
Modified:
    trunk/libstdc++-v3/ChangeLog
    trunk/libstdc++-v3/acinclude.m4
    trunk/libstdc++-v3/config.h.in
    trunk/libstdc++-v3/config/abi/pre/gnu.ver
    trunk/libstdc++-v3/configure
    trunk/libstdc++-v3/configure.ac
    trunk/libstdc++-v3/include/std/future
    trunk/libstdc++-v3/libsupc++/eh_ptr.cc
    trunk/libstdc++-v3/libsupc++/eh_throw.cc
    trunk/libstdc++-v3/libsupc++/eh_tm.cc
    trunk/libstdc++-v3/libsupc++/exception
    trunk/libstdc++-v3/libsupc++/exception_ptr.h
    trunk/libstdc++-v3/libsupc++/guard.cc
    trunk/libstdc++-v3/libsupc++/nested_exception.cc
    trunk/libstdc++-v3/libsupc++/nested_exception.h
    trunk/libstdc++-v3/src/c++11/future.cc
    trunk/libstdc++-v3/testsuite/18_support/exception_ptr/40296.cc
    trunk/libstdc++-v3/testsuite/18_support/exception_ptr/60612-terminate.cc
    trunk/libstdc++-v3/testsuite/18_support/exception_ptr/60612-unexpected.cc
    trunk/libstdc++-v3/testsuite/18_support/exception_ptr/62258.cc
    trunk/libstdc++-v3/testsuite/18_support/exception_ptr/64241.cc
    trunk/libstdc++-v3/testsuite/18_support/exception_ptr/current_exception.cc
    trunk/libstdc++-v3/testsuite/18_support/exception_ptr/lifespan.cc
    trunk/libstdc++-v3/testsuite/18_support/exception_ptr/make_exception_ptr.cc
    trunk/libstdc++-v3/testsuite/18_support/exception_ptr/make_exception_ptr_2.cc
    trunk/libstdc++-v3/testsuite/18_support/exception_ptr/move.cc
    trunk/libstdc++-v3/testsuite/18_support/exception_ptr/requirements.cc
    trunk/libstdc++-v3/testsuite/18_support/exception_ptr/requirements_neg.cc
    trunk/libstdc++-v3/testsuite/18_support/exception_ptr/rethrow_exception.cc
    trunk/libstdc++-v3/testsuite/18_support/nested_exception/51438.cc
    trunk/libstdc++-v3/testsuite/18_support/nested_exception/62154.cc
    trunk/libstdc++-v3/testsuite/18_support/nested_exception/68139.cc
    trunk/libstdc++-v3/testsuite/18_support/nested_exception/cons.cc
    trunk/libstdc++-v3/testsuite/18_support/nested_exception/nested_ptr.cc
    trunk/libstdc++-v3/testsuite/18_support/nested_exception/rethrow_if_nested.cc
    trunk/libstdc++-v3/testsuite/18_support/nested_exception/rethrow_nested.cc
    trunk/libstdc++-v3/testsuite/18_support/nested_exception/throw_with_nested.cc
    trunk/libstdc++-v3/testsuite/30_threads/async/42819.cc
    trunk/libstdc++-v3/testsuite/30_threads/async/49668.cc
    trunk/libstdc++-v3/testsuite/30_threads/async/54297.cc
    trunk/libstdc++-v3/testsuite/30_threads/async/any.cc
    trunk/libstdc++-v3/testsuite/30_threads/async/async.cc
    trunk/libstdc++-v3/testsuite/30_threads/async/except.cc
    trunk/libstdc++-v3/testsuite/30_threads/async/forced_unwind.cc
    trunk/libstdc++-v3/testsuite/30_threads/async/launch.cc
    trunk/libstdc++-v3/testsuite/30_threads/async/lwg2021.cc
    trunk/libstdc++-v3/testsuite/30_threads/async/sync.cc
    trunk/libstdc++-v3/testsuite/30_threads/future/cons/assign_neg.cc
    trunk/libstdc++-v3/testsuite/30_threads/future/cons/constexpr.cc
    trunk/libstdc++-v3/testsuite/30_threads/future/cons/copy_neg.cc
    trunk/libstdc++-v3/testsuite/30_threads/future/cons/default.cc
    trunk/libstdc++-v3/testsuite/30_threads/future/cons/move.cc
    trunk/libstdc++-v3/testsuite/30_threads/future/cons/move_assign.cc
    trunk/libstdc++-v3/testsuite/30_threads/future/members/45133.cc
    trunk/libstdc++-v3/testsuite/30_threads/future/members/get.cc
    trunk/libstdc++-v3/testsuite/30_threads/future/members/get2.cc
    trunk/libstdc++-v3/testsuite/30_threads/future/members/share.cc
    trunk/libstdc++-v3/testsuite/30_threads/future/members/valid.cc
    trunk/libstdc++-v3/testsuite/30_threads/future/members/wait.cc
    trunk/libstdc++-v3/testsuite/30_threads/future/members/wait_for.cc
    trunk/libstdc++-v3/testsuite/30_threads/future/members/wait_until.cc
    trunk/libstdc++-v3/testsuite/30_threads/future/requirements/explicit_instantiation.cc
    trunk/libstdc++-v3/testsuite/30_threads/headers/future/types_std_c++0x.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/49668.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/60564.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/1.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/2.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/3.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/56492.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/alloc.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/alloc2.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/alloc_min.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/assign_neg.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/copy_neg.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/move.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/cons/move_assign.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/forced_unwind.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/at_thread_exit.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/get_future.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/get_future2.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke2.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke3.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke4.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/invoke5.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/reset.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/reset2.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/swap.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/members/valid.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/requirements/explicit_instantiation.cc
    trunk/libstdc++-v3/testsuite/30_threads/packaged_task/uses_allocator.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/60966.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/69106.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/cons/1.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/cons/alloc.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/cons/alloc2.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/cons/alloc_min.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/cons/assign_neg.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/cons/copy_neg.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/cons/move.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/cons/move_assign.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/members/at_thread_exit.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/members/get_future.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/members/get_future2.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/members/set_exception.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/members/set_exception2.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/members/set_value.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/members/set_value2.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/members/set_value3.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/members/swap.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/requirements/explicit_instantiation.cc
    trunk/libstdc++-v3/testsuite/30_threads/promise/uses_allocator.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/cons/assign.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/cons/constexpr.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/cons/copy.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/cons/default.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/cons/move.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/cons/move_assign.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/members/45133.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/members/get.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/members/get2.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/members/valid.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/members/wait.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/members/wait_for.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/members/wait_until.cc
    trunk/libstdc++-v3/testsuite/30_threads/shared_future/requirements/explicit_instantiation.cc
Comment 12 Jonathan Wakely 2017-01-04 10:57:25 UTC
This is fixed on trunk now, without pessimizing targets that already support exception propagation.
Comment 13 Jonathan Wakely 2017-01-18 17:25:16 UTC
*** Bug 58938 has been marked as a duplicate of this bug. ***
Comment 14 GCC Commits 2021-04-15 16:10:22 UTC
The master branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:6c0c7fc6236470a533675cd3cd1ebb1cc3dd112c

commit r11-8198-g6c0c7fc6236470a533675cd3cd1ebb1cc3dd112c
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Apr 14 20:48:54 2021 +0100

    libstdc++: Move atomic functions to libsupc++ [PR 96657]
    
    The changes for PR libstdc++/64735 mean that libsupc++ function might
    now depend on the __exchange_and_add and __atomic_add functions defined
    in config/cpu/*/atomicity.h which is not compiled into libsupc++. This
    causes a link failure for some targets when trying to use libsupc++
    without the rest of libstdc++.
    
    This patch simply moves the definitions of those functions into
    libsupc++ so that they are available there.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/96657
            * libsupc++/Makefile.am: Add atomicity.cc here.
            * src/c++98/Makefile.am: Remove it from here.
            * libsupc++/Makefile.in: Regenerate.
            * src/c++98/Makefile.in: Regenerate.
            * testsuite/18_support/exception_ptr/96657.cc: New test.
Comment 15 GCC Commits 2021-07-22 17:05:14 UTC
The releases/gcc-10 branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:f2074277aa3ce0848429e34d6149ba26ff3b708e

commit r10-9997-gf2074277aa3ce0848429e34d6149ba26ff3b708e
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Apr 14 20:48:54 2021 +0100

    libstdc++: Move atomic functions to libsupc++ [PR 96657]
    
    The changes for PR libstdc++/64735 mean that libsupc++ function might
    now depend on the __exchange_and_add and __atomic_add functions defined
    in config/cpu/*/atomicity.h which is not compiled into libsupc++. This
    causes a link failure for some targets when trying to use libsupc++
    without the rest of libstdc++.
    
    This patch simply moves the definitions of those functions into
    libsupc++ so that they are available there.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/96657
            * libsupc++/Makefile.am: Add atomicity.cc here.
            * src/c++98/Makefile.am: Remove it from here.
            * libsupc++/Makefile.in: Regenerate.
            * src/c++98/Makefile.in: Regenerate.
            * testsuite/18_support/exception_ptr/96657.cc: New test.
    
    (cherry picked from commit 6c0c7fc6236470a533675cd3cd1ebb1cc3dd112c)
Comment 16 GCC Commits 2021-07-22 21:29:08 UTC
The releases/gcc-9 branch has been updated by Jonathan Wakely <redi@gcc.gnu.org>:

https://gcc.gnu.org/g:ba5e10a8c84f56bb2838adb6d1cc9b74741ac4f1

commit r9-9640-gba5e10a8c84f56bb2838adb6d1cc9b74741ac4f1
Author: Jonathan Wakely <jwakely@redhat.com>
Date:   Wed Apr 14 20:48:54 2021 +0100

    libstdc++: Move atomic functions to libsupc++ [PR 96657]
    
    The changes for PR libstdc++/64735 mean that libsupc++ function might
    now depend on the __exchange_and_add and __atomic_add functions defined
    in config/cpu/*/atomicity.h which is not compiled into libsupc++. This
    causes a link failure for some targets when trying to use libsupc++
    without the rest of libstdc++.
    
    This patch simply moves the definitions of those functions into
    libsupc++ so that they are available there.
    
    libstdc++-v3/ChangeLog:
    
            PR libstdc++/96657
            * libsupc++/Makefile.am: Add atomicity.cc here.
            * src/c++98/Makefile.am: Remove it from here.
            * libsupc++/Makefile.in: Regenerate.
            * src/c++98/Makefile.in: Regenerate.
            * testsuite/18_support/exception_ptr/96657.cc: New test.
    
    (cherry picked from commit 6c0c7fc6236470a533675cd3cd1ebb1cc3dd112c)