Paolo Carlini wrote:
Paolo Carlini wrote:
I'm going to revert again the whole thing and wait for a different,
safe, approach, sorry.
In the short time frame, i.e., something solid for 4.4.0, I would
suggest two possible strategies:
1- Try to re-organize the new code in order to make possible using in
*few* selected places _GLIBCXX_ATOMIC_BUILTINS_4 to enable / disable
the new feature completely.
The necessary code changes for this are in the attached patch. Most of
the code doesn't need to be touched, because the added code doesn't
affect the non-exception_ptr case. The only thing that *needs* to change
is that the reference counting is removed from __gxx_exception_cleanup.
The reference count part of the __cxa_exception struct can stay - it's
simply unused, except for the initialization in __cxa_throw.
Of course, that additional field and the initialization can be ifdefed
out too, if you want.
The necessary configuration changes:
1) eh_ptr.cc must be excluded from compilation completely if the feature
is unavailable.
2) The test cases must be excluded from the test runs.
3) It needs to be remembered whether propagation was included in the
build. c++config needs to define _GLIBCXX_EXCEPTION_PTR_SUPPORTED on
platforms where it was. The issue here is that I don't know if
_GLIBCXX_ATOMIC_BUILTINS_4 keeps the value it had during the GCC build
when client programs get compiled, and the client would get weird errors
if it didn't. If it does, the new macro can simply be replaced.
I don't know how to do these configuration changes, so I couldn't
actually test my patch yet.
2- Learn from guard.cc. In that libsupc++ implementation file,
*certainly* atomic builtins are safely used, with fall-backs.
I'm afraid trying to learn something from that file is a futile exercise
for me. It's a chaos of ifdefs that I simply don't understand. It seems
to fall back to some global mutex for synchronization, which seems to be
implemented entirely inline. (The mutex is part of libstdc++, so if it
wasn't inline, you'd get the same link problems.)
Sebastian
Index: libsupc++/exception
===================================================================
--- libsupc++/exception (revision 139469)
+++ libsupc++/exception (working copy)
@@ -133,7 +133,8 @@
#pragma GCC visibility pop
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if defined(__GXX_EXPERIMENTAL_CXX0X__) && \
+ defined(_GLIBCXX_EXCEPTION_PTR_SUPPORTED)
#include <exception_ptr.h>
#endif
Index: libsupc++/eh_throw.cc
===================================================================
--- libsupc++/eh_throw.cc (revision 139469)
+++ libsupc++/eh_throw.cc (working copy)
@@ -46,13 +46,17 @@
if (code != _URC_FOREIGN_EXCEPTION_CAUGHT && code != _URC_NO_REASON)
__terminate (header->terminateHandler);
+#ifdef _GLIBCXX_ATOMIC_BUILTINS_4
if (__gnu_cxx::__exchange_and_add_dispatch (&header->referenceCount, -1) ==
0)
{
+#endif
if (header->exceptionDestructor)
header->exceptionDestructor (header + 1);
__cxa_free_exception (header + 1);
+#ifdef _GLIBCXX_ATOMIC_BUILTINS_4
}
+#endif
}
Index: libsupc++/eh_ptr.cc
===================================================================
--- libsupc++/eh_ptr.cc (revision 139469)
+++ libsupc++/eh_ptr.cc (working copy)
@@ -28,6 +28,10 @@
// the GNU General Public License.
#include <bits/c++config.h>
+
+// Prevent exception_ptr.h from erroring out
+#define _GLIBCXX_EXCEPTION_PTR_SUPPORTED 1
+
#include <exception>
#include <exception_ptr.h>
#include "unwind-cxx.h"
Index: libsupc++/exception_ptr.h
===================================================================
--- libsupc++/exception_ptr.h (revision 139469)
+++ libsupc++/exception_ptr.h (working copy)
@@ -38,6 +38,10 @@
#ifndef __EXCEPTION_PTR_H__
#define __EXCEPTION_PTR_H__
+#if !defined(_GLIBCXX_EXCEPTION_PTR_SUPPORTED)
+#error This platform does not support exception propagation.
+#endif
+
#pragma GCC visibility push(default)
#include <bits/c++config.h>