[PATCH v2] libstdc++: Make certain exceptions transaction_safe.

Jonathan Wakely jwakely@redhat.com
Thu Jan 14 17:58:00 GMT 2016


On 07/01/16 17:47 +0100, Torvald Riegel wrote:
>The attached patch makes some exceptions transaction-safe, as require by
>the Transactional Memory TS.  I believe I addressed all feedback for the
>previous version of this patch (in particular, there are now more safety
>checks for preconditions for this implementation (eg, that the new
>allocator is used), all exceptions declared by the TM TS are now
>supported (with the exception of tx_exception -- should I add that in a
>follow-up patch?)

Yes, that can be a separate patch, as it's adding a new type rather
than modifying the existing ones to add this TM magic.

>Thus, the patch adds txnal clones as required.  They are new exported
>symbols, but not visible to nontransactional code.  The only changes to
>headers is transaction_safe[_dynamic] annotations where required by the
>TS, and a few friend declarations.  The annotations are only enabled if
>a user compiles with -fgnu-tm.  IOW, the changes are pretty much
>invisible when not using the TM TS.

Thanks for adding all the clear comments as well. I'm sure we'll all
be grateful for those when we come to look back at the code.

>There are also commented-out calls to _ITM_setAssociatedException in the
>code, which exist to show how we plan to support transaction
>cancellation through exceptions (which needs some more libitm support
>and bugfixes on the compiler side).
>
>Tested on x86_64-linux and x86-linux.
>
>OK?

Yes, with some minor formatting changes noted below.

>@@ -129,12 +129,16 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>     logic_error& operator=(const logic_error&) _GLIBCXX_USE_NOEXCEPT;
> #endif
> 
>-    virtual ~logic_error() _GLIBCXX_USE_NOEXCEPT;
>+    virtual ~logic_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
> 
>     /** Returns a C-style character string describing the general cause of
>      *  the current error (the same string passed to the ctor).  */
>     virtual const char* 
>-    what() const _GLIBCXX_USE_NOEXCEPT;
>+    what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;

A blank line here please.

>+# ifdef _GLIBCXX_TM_TS_INTERNAL
>+    friend void*
>+    ::_txnal_logic_error_get_msg(void* e);
>+# endif
>   };
> 
>   /** Thrown by the library, or by you, to report domain errors (domain in


>@@ -208,21 +212,25 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
>     runtime_error& operator=(const runtime_error&) _GLIBCXX_USE_NOEXCEPT;
> #endif
> 
>-    virtual ~runtime_error() _GLIBCXX_USE_NOEXCEPT;
>+    virtual ~runtime_error() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
> 
>     /** Returns a C-style character string describing the general cause of
>      *  the current error (the same string passed to the ctor).  */
>     virtual const char* 
>-    what() const _GLIBCXX_USE_NOEXCEPT;
>+    what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;

And here.

>+# ifdef _GLIBCXX_TM_TS_INTERNAL
>+    friend void*
>+    ::_txnal_runtime_error_get_msg(void* e);
>+# endif
>   };
> 
>   /** Thrown to indicate range errors in internal computations.  */
>   class range_error : public runtime_error 
>   {
>   public:
>-    explicit range_error(const string& __arg);
>+    explicit range_error(const string& __arg) _GLIBCXX_TXN_SAFE;
> #if __cplusplus >= 201103L
>-    explicit range_error(const char*);
>+    explicit range_error(const char*) _GLIBCXX_TXN_SAFE;
> #endif
>     virtual ~range_error() _GLIBCXX_USE_NOEXCEPT;
>   };


>diff --git a/libstdc++-v3/libsupc++/exception b/libstdc++-v3/libsupc++/exception
>index 01dd9c2..8b8935d 100644
>--- a/libstdc++-v3/libsupc++/exception
>+++ b/libstdc++-v3/libsupc++/exception
>@@ -61,11 +61,12 @@ namespace std
>   {
>   public:
>     exception() _GLIBCXX_USE_NOEXCEPT { }
>-    virtual ~exception() _GLIBCXX_USE_NOEXCEPT;
>+    virtual ~exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
> 
>     /** Returns a C-style character string describing the general cause
>      *  of the current error.  */
>-    virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
>+    virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN
>+	_GLIBCXX_USE_NOEXCEPT;
>   };

Please break this line after the return type, i.e.

    virtual const char*
    what() const _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;

>   /** If an %exception is thrown which is not listed in a function's
>@@ -77,10 +78,11 @@ namespace std
> 
>     // This declaration is not useless:
>     // http://gcc.gnu.org/onlinedocs/gcc-3.0.2/gcc_6.html#SEC118
>-    virtual ~bad_exception() _GLIBCXX_USE_NOEXCEPT;
>+    virtual ~bad_exception() _GLIBCXX_TXN_SAFE_DYN _GLIBCXX_USE_NOEXCEPT;
> 
>     // See comment in eh_exception.cc.
>-    virtual const char* what() const _GLIBCXX_USE_NOEXCEPT;
>+    virtual const char* what() const _GLIBCXX_TXN_SAFE_DYN
>+	_GLIBCXX_USE_NOEXCEPT;

Same here.



More information about the Libstdc++ mailing list