This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

State of support for the ISO C++ Transactional Memory TS and remanining work


Hi,

I'd like to summarize the current state of support for the TM TS, and
outline the current plan for the work that remains to complete the
support.

I'm aware we're at the end of stage 1, but I'm confident we can still
finish this work and hope to include it in GCC 6 because:
(1) most of the support is already in GCC, and we have a big head start
in the space of TM so it would be unfortunate to not waste that by not
delivering support for the TM TS,
(2) this is a TS and support for it is considered experimental,
(3) most of the affected code is in libitm or the compiler's TM passes,
which has to be enabled explicitly by the user.

Currently, we have complete support for the syntax and all necessary
instrumentation except the exception handling bits listed below.  libitm
has a good set of STM and HTM-based algorithms.


What is missing on the compiler side is essentially a change of how we
support atomic_noexcept and atomic_cancel, in particular exception
handling.  Instead of just using a finally block as done currently, the
compiler need to build a catch clause so that it can actively intercept
exceptions that escape an atomic_noexcept or atomic_cancel.  For
atomic_noexcept, the compiler needs to include a call to abort() in the
catch clause.


For atomic_cancel, it needs to call ITM_commitTransactionEH in the catch
clause, and use NULL as exception argument.  This can then be used by
libitm to look at the currently being handled exception and (a) check
whether the type support transaction cancellation as specified by the TS
and (b) pick out the allocations that belong to this exception and roll
back everything else before rethrowing this exception.

For (a), it's probably best to place this check into libstdc++
(specifically, libsupc++ I suppose) because support for transaction
cancellation is a property that library parts of the standard (or the
TS) require, and that has to match the implementation in libstdc++.
Attached is a patch by Jason that implements this check.  This adds one
symbol, which should be okay we hope.

For (b), our plan is to track the additional allocations that happen
when during construction of the exception types that support
cancellation (eg, creating the what() string for logic_error).  There
are several ways to do that, one of that being that we create custom
transactional clones of those constructors that tell libitm that either
such a constructor is currently running or explicitly list the
allocations that have been made by the constructor; eventually, we would
always (copy) construct into memory returned by cxa_allocate_exception,
which then makes available the necessary undo information when such an
exception is handled in libitm.


The other big piece of missing support is making sure that the functions
that are specified in the TS as transaction_safe are indeed that.  I
believe we do not need to actually add such annotations to any libstdc++
functions that are already transaction-safe and completely defined in
headers -- those functions are implicitly transaction-safe, and we can
thus let the compiler isntrument them at the point of use inside of a
transaction.

If a supposedly transaction-safe function is not defined in a header,
we'd need a transaction_safe annotation at the declaration.  Jason has
implemented the TM TS feature test macro, so we can only add the
annotation if the user has enabled support for the TM TS in the
respective compilation process.
We also need ensure that there is a transaction clode of the function.
This will add symbols to libstdc++, but these all have their own special
prefix in the mangled name.  I'd like to get feedback on how to best
trigger the insturmentation and make it a part of a libstdc++ build.
(If that would show to be too problematic, we could still fall back to
writing transacitonal clones manually.)
For the clones of the constructors of the types that support
cancellation, I suppose manually written clones might be easier than
automatic instrumentation.

I've not yet created tests for the full list of functions specified as
transaction-safe in the TS, but my understanding is that this list was
created after someone from the ISO C++ TM study group looked at libstdc
++'s implementation and investigated which functions might be feasible
to be declared transaction-safe in it.

I'm looking forward to your feedback.

Thanks,

Torvald
// -*- C++ -*- GNU C++ atomic_cancel support.
// Copyright (C) 2015 Free Software Foundation, Inc.
//
// This file is part of GCC.
//
// GCC is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3, or (at your option)
// any later version.
//
// GCC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

#include <bits/c++config.h>
#include <cstdlib>
#include <cxxabi.h>
#include <exception>
#include <stdexcept>
#include <new>
#include <typeinfo>
#include <string.h>

bool
__cxxabiv1::__cxa_exception_supports_tx_cancel()
{
  const std::type_info *tinfo = __cxa_current_exception_type();
  if (!dynamic_cast <const __class_type_info*>(tinfo))
    // All scalar types support transaction cancellation.
    return true;

  // But only specific classes support tx cancel.
  const char *name = tinfo->name();

  // First check for std::
  if (name[0] != 'S' || name[1] != 't')
    return false;
  name += 2;

  const char txe[] = "12tx_exceptionI";
  if (!strncmp (name, txe, strlen(txe))
      || !strcmp (name, "8bad_cast")
      || !strcmp (name, "9bad_alloc")
      || !strcmp (name, "10bad_typeid")
      || !strcmp (name, "11logic_error")
      || !strcmp (name, "11range_error")
      || !strcmp (name, "12domain_error")
      || !strcmp (name, "12length_error")
      || !strcmp (name, "12out_of_range")
      || !strcmp (name, "13bad_exception")
      || !strcmp (name, "13runtime_error")
      || !strcmp (name, "14overflow_error")
      || !strcmp (name, "15underflow_error")
      || !strcmp (name, "16invalid_argument")
      || !strcmp (name, "20bad_array_new_length"))
    return true;

  return false;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]