IBM Z and LinuxONE - Languages - Group home

The View form the C++ Standard meeting April 2013

By FANG LU posted Tue March 24, 2020 07:39 PM

  

Mood of the April C++ Std meeting in Bristol, plan to release C++14 Committee Draft (CD) and language feature set for C++14

Bristol is a terrific place. It is where much of the history of steam and iron occurred to change the world, although at the time people probably did not realize it. Isambard Kingdom Brunel had in the 19th century, revolutionized the way we travel, by bringing together steam engine to replace the paddlewheel along with iron to create an ocean going vessel that lasted far longer than any vessel at the time, the SS Great Britain. Just as it had a great many detractors who said it couldn’t be done, many people said a new Standard could not be created so quickly just after C++11. Well, The C++ Standard Committee is well on its way to changing the minds of those detractors.

This is because Bristol is also where the C++ Std will change the world in many ways. At this meeting, updates are being added to C++14 which will effectively be a new language standard on top of C++11. A new Committee Draft (CD) will be issued based on the cumulative work up to this meeting and it will be out for review. Our goal was to triage all features that can enter C++14. This means C++14 is more than just bug fixes and is unlike a Technical Corrigendum like TC1 which bridged C++ 1998 to C++2003. As such it will have additional features beyond defect fixes that has been deemed to be small enough in scope and solution but significant enough in annoyance that it should be fixed immediately post C++11.

To get an overview of the papers, please see the 4 blog (Part 1, 2, 3, 4) series by Jens from Meeting C++.

This may surprise a few but as already pointed out in my Portland C++ Std Trip report, it is the intention to issue a quick bug fix release, while addressing some of the minor features for C++14.

The tension it adds to this week’s workload was evident as many working groups had to prioritize likely C++14 items first, before C++17 items. The added tension is evident in the Mock Plenary session Friday afternoon which became officially the longest in my memory. It started at 1:30 pm and ended at 6:45 pm, exceeding the plenary session from the Fermi Lab meeting by almost half an hour.

Let me say what a Mock Plenary is. The afternoon before the real vote, we get together to run through a simulation of the vote to expose all the positions, and especially the controversies. This gives enough time to hash out the controversies without the time pressure of people having to catch flights. It also allows controversies to be fixed by the real vote or removed.

So this one, by my measure was both long and controversial. It definitely has its share of passionate fireworks. It was long because both Core and Library had a large number of motions, if not the most I have seen recently. As such, I will have to break up this trip report into several parts: Language, Library, Concurrency, and Transactional Memory. This is part of trying to catch the bus before it leaves as C++14 will go to CD ballot. After that, there is still a small chance to add something in the next C++ Standard meeting, but it will require a National Body comment on the CD ballot, or a serious defect. But after the Chicago meeting, this will likely go to a DIS (Draft International Standard) which takes a 5 month ballot and then a 2 month ballot to get to a Final Draft International Standard. Working backwards, this will put us in mid 2014 with some buffer zone, in case things goes wrong.

http://isocpp.org/std/iso-iec-jtc1-procedures

This means it actually prevented a large number of defect fixes to be processed because every chair was tasked with C++14 work before their normal load. I cannot reiterate all the votes as there will be an official paper in the post-meeting mailing.

By contrast the Saturday afternoon vote is almost quiet as we go through with any objection to unanimous consent on each motion. As such I will first comment on what I think are the more interesting features, some of which Herb has already blogged about. Many of these may have little or no controversy.

I will also comment on some of the more controversial ones covering those that were removed based on Friday’s Mock Vote and the remaining ones that did not have unanimous consent. Note that I am not the secretary and any actual vote results should be verified with the minutes, but I don’t think I am far off.

I also comment on the defeated or withdrawn proposals that resulted from the controversy in the Mock Plenary. In some of these cases, the proposal might still return because there is still time to add these proposal back if there is a National Body comment from the CD ballot.

Here are the new language extensions voted in and I will use the paper link number instead of feature description. Normally I would not, but since Jens blog has been using those links, and many people can access the Standard paper website, the paper number are generally well known anyway. But in many cases, the paper numbers approved are the core or library language paper developed at the meeting so is unknown on the website until the post-meeting mailing appears. These papers have no hot link as they are inaccessible to the public until the post-meeting mailing. In these cases, I will trace back to the website papers that motivated the wording change. I will also skip a few papers that are really minor language defect fixes.

  • N3472 (post-Portland) where Binary Literals is now accepted as core syntax using 0b/0B prefix as you would want. It is also in existing GCC/Clang extensions and is the same syntax in Java7, Python, and D. It looks like 0b10001111.
  • N3639, a continuation of N3497 runtime sized array as a language feature accepted. This is a consistent form of VLA for C++ using a runtime bound for an array. This is not C99 VLA which in some opinion is an abomination. This is VLA as it should have been. But because there were concerns that some part of N3638 may conflate with the library dynarray feature, it lead to this vote to become slightly controversial. Once it was clarified that the library issue does not depend on this, and that it is independent, this vote sailed through relatively unscathed.
  • N3638, a continuation of N3582: since we allowed lambdas to have return type deduction under special cases (such as whenever there is only a single actual executable statement), it seems to make sense that this be gifted back to normal functions. This is one of those symmetrical alignment that was missed during C++11 that becomes obvious afterwards. Now it is in C++14.
  • N3648 is really the wording developed from N3610 which will give us essentially move capture in lambdas. This is important for moving say, a unique_ptr into the lambda and defining new local variables in the lambda. This is in fact implemented by Jakko Jarvi from his original proposal for lambda.
  • N3653 is the core wording for N3605 and is another patch to increase symmetry. Aggregate types came into C++ as a C compatiblilty feature and had not changed much. Bjarne Stroustrup pointed out that aggregate initialization can't be used if a class has member-initializers. He provided the following example:

 

struct Univ {

   string name;

   int rank;

   string city = "unknown";

};

 

void t1()

{

   Univ u = {"Columbia",10};

   cout << u.name << ' ' << u.rank << ' ' << u.city << '\n';

}

 

 There is no reason why they can’t. So the rules were relaxed to allow member initialization in aggregate classes, using the same rules as in C++11.

  • N3667 is a core issue 1402 fix where we found implicitly defined move functions were too often deleted by our rules. This relaxes the rules.
  • N3652 describes the subset of N3597 selected for inclusion in C++14, relaxing a number of restrictions on constexpr functions. These changes all received overwhelmingly strong or unopposed support under review of the Evolution Working Group. It also incorporates Option 2 of N3598.about relaxing constraints on constexpr. This second part had a great deal of controversy. The first part is non-controversial:
  1. Allow declarations within constexpr functions, other than: static or thread_local variables
  2. uninitialized variables
  3. Allow if and switch statements (but not goto)
  4. Allow all looping statements: for (including range-based for), while, and do-while
  5. Allow mutation of objects whose lifetime began within the constant expression evaluation.

The second part is the removal of the implicit constness of constexpr non-static member function. This implicit constness creates problems for literal class types which desire to be usable both within constant expressions and outside them. This is about allowing more elaborate computations and making them implicitly const prevents mutation of data. This was controversial as some feel this is not really attacking the underlying problem. We can't bind a temporary to a non-const reference but one can call a non const member function on a temporary of class type. There is some ABI concerns with variable mutation and there is some chance this will require code change but the longer we wait for this fix, the more code there will be in the field. We also could have chosen to leave the issue and let the user deal with it with a const_cast, or add a qualifier like mutable to enable removal of the implicit constness. All these were mildly rejected, though not by much.

  • N3499 is about supporting digit separators and it is the prototypical bikeshed (meaning everyone have their personal favorite). THIS WAS NOT PASSED. The solution uses .. as a way to resolve ambiguity but in most cases will use a single underscore. C compatibility is possible with this solution. So if you have a suffix that can cause conflict, such as 100 with a 3d coordinate, then 100_3d is not possible and must be replaced with 100..3d. This was extremely controversial. We have looked at many alternatives and they are nicely listed in N3499 and all of them conflict in some way with some other language, or some tool, or parsing system. This solution was deemed to be the best we can get. But it is not intuitively satisfying as it is somewhat incomplete. But then the Standard is never about getting the best solution, the enemy of the good. The controversy arose because there is a large segment who prefer to have no solution at all, if we can’t have the best solution. Most of those who opposed do not have a solution either that can solve all the corner cases. In reality, digit separators is useful really only for writing very large numbers. I would argue this is a corner case where you are writing binary, octal, or very large decimals. Even time notations are better written as multiplication of seconds and minutes instead of the final product to make it clear where the value comes from without loss of efficiency because in many cases compiler would fold the result into a constant. My personal feeling? This is not a problem worth solving when we have spent more than a day with 20 experts’ time in total since 3 meetings ago. If the solution is obvious and simple, then it would be worth the time. There are far more interesting and useful problem to solve. You may feel differently.
  • N3664 is based on N3537 and is a small optimization where today we have one call for each allocation for each new and delete. Now optimizers are allowed to batch them. This is similar to copy elision already being permitted today.
  • N3651 is based on N3615 and is a proposal to support constexpr template variables. This replaces the use of static data members for parameterized constants, because these have annoyances of requiring duplicate declarations: once inside the class template, once outside the class template to provide the “real” definition in case the constants is odr-used. Herb provided one example from the paper. Here is another also from the paper using definitions of fundamental Pauli matrices (used in quantum mechanics):

 

struct matrix_constants {

  template<typename T>

     using pauli = hermitian_matrix<T, 2>;

  template<typename T>

     constexpr pauli<T> sigma1 = { { 0, 1 }, { 1, 0 } };

  template<typename T>

     constexpr pauli<T> sigma2 = { { 0, -1i }, { 1i, 0 } };

  template<typename T>

     constexpr pauli<T> sigma3 = { { 1, 0 }, { -1, 0 } };

};

  • N3649 is about generic lambdas and is based on N3559. This will replace the need to name the specific type of lambda parameter types by naming them as auto. It is probably one of the most requested feature after C++11. Some opposed this because there is concern that it should be delayed until we have a Concepts TS when constrained lambdas would also need to be specified. This example has been discussed extensively by Herb. Under the cover, a polymorphic lambda can essentially be modeled with a templated anonymous functor that looks likes this so it should be easily implementable.

[] ( auto p1, const auto& p2 ){f( p1, p2 ); }

// implemented as:

class __functor {

public:

 template<typename T1, typename T2>

 void operator()( T1 p1, const T2& p2 ) {

     f(p1, p2 );

  }

};

 

C++14 will also have the changes we made in Portland:

  • N3323, is a Proposal to Tweak Certain C++ Contextual Conversions in four distinct cases and cleans up the use cases.

as well as many defect fixes numbering into one hundred.

Library features, Technical Specification, Concurrency features, and Transactional Memory

Now I will deep dive onto the library feature additions for C++14. As with the language features, some of these originated from other subgroups. As before, I will not talk about minor bug fixes, but also talk about proposals that did not pass as they are often the most controversial.

  • N3545 is an incremental improvement to integral_constant by adding a constexpr operator()

member that returns the value of the template’s data member.

  • N3644 adds the ability for null forward iterator to be value initialized and compared as opposed to undefined as they are now.
  • N3668 is based on N3511 and N3608 and is another symmetry feature. We allow exchange on atomics and now non-atomics also have them.
  • N3658 is based on N3493 and is a proposal to add a type like
template<int...> struct index_sequence { };

so that an instantiation like index_sequence<0, 1, 2, 3> can be passed to a function template that deduces a parameter pack containing the integer sequence 0, 1, 2, 3.

  • N3670 is based on N3584 and proposes allowing tuples to be addressed by type as well as by numerical index such as:

tuple<string, string, int> t("foo", "bar", 7);

int i = get<int>(t); // i == 7

int j = get<2>(t); // Equivalent to the above: j == 7

string s = get<string>(t); // Compile-time error. Ambiguous

  • N3671 is based on N3607 propose adding overloads for std::equal, std::mismatch, and std::is_permutation to accept two ranges. When using these overloads, the caller does not need to separately check that the two ranges are of the same length. The authors illustrate this using std::equal. For example:

vector<int> v1 = { 1, 4 9 };

vector<int> v2 = { 1, 4, 9, 16, 25, 36, 49 };

vector<int> v3 = { 1, 2, 3, 4 };

assert(!equal(v1.begin(), v1.end(), v2.begin(), v2.end());

  • N3656 is based on N3588 and removed dangling memory allocations by adding a useful feature called make_unique which along with make_shared in C++11 means you no longer need to use new and delete, unless you are building low level memory routines. Herb already spoke extensively about the utility of this design in terms of completing C++ safety against dangling memory references.
  • N3642 is based on part 1 of N3531 and adds user-defined literal suffixes for several common facilities including time(h,min,s,ms,us,ns), and string (s) all under their own namespace. String turned out to be controversial as the proposed ‘s’ for string was disliked by some who prefer to reserve that facility for stringview. You see, string is a class in C++ and requires memory allocation and stringview is a new proposed feature that is already supported by several C++ library implementations as the true string, because it is a reference to the actual string. This argument is quite true. In the end, I still felt it was more natural when people think of strings to be associated with ‘s’ despite that it is not truly a string. When stringview does come along we can use something like ‘sv’ and I don’t feel there is any loss of generality. Note that there is no ambiguity with use of ‘s’ with time because the overloads for such an operator"" s() differ for these two usage scenarios, s can also be used for std::string.
  • N3660 is based on the remaining part of N3531 and adds the complex imaginary literal(i, il, i_f) double, long double and float respectively, as a user-defined literal suffix. It was WITHDRAWN before there was a vote on it.
  • N3665 is actually an outgrowth of concurrency proposal on synchronizing stream output characters in the presence of multithreading so that they would be sensible. This was NOT PASSED. It is an attempt to allow consistent string output in printf under a limited buffer size. There was a lot of concern this quick fix brought in at the 11th hour (there was no paper in the pre-meeting email) was disliked on a procedural basis by some, and by others with the concern that it constrained the design space. The supporting argument is that this inconsistency in string output was more serious because C++11 now has threading support. The counter argument is why fix it when it has been around for so long? Personally, I think we should have fixed it as it is a real problem, and most vendors introduce some kind of non-standard locking to ensure consistency.
  • N3654 is based on N3570 and is a proposal that is based on Boost.Component to fix the problem that C++ standard library stream I/O for strings that contain embedded spaces can produce unexpected results. For example,
std::stringstream ss;
std::string original = "foolish me";
std::string round_trip;

ss << original;
ss >> round_trip;

std::cout << original; // outputs: foolish me
std::cout << round_trip; // outputs: foolish

assert(original == round_trip); // assert will fire

The proposed quoted stream I/O manipulator places delimiters, defaulted to double-quote ("), around strings on output, and strips off the delimiters on input. This ensures strings with embedded white space round-trip as desired. For example,

std::stringstream ss;
std::string original = "foolish me";
std::string round_trip;

ss << quoted(original);
ss >> quoted(round_trip);

std::cout << original; // outputs: foolish me
std::cout << round_trip; // outputs: foolish me

assert(original == round_trip); // assert will not fire
  • N3645 is based on N3586 and is a proposal to address the issues that maps and sets are missing splice operation and that associative/unordered container are missing functions that allows you to extract elements. It DID NOT PASS due to concern about unordered multi set/map versions of these and there are current proposals for multi-threaded versions of these containers which may conflict.
  • N3657 is based on N3465 and is a proposal to add heterogeneous comparison look-up to associative containers.
  • N3672 is based on N3527 and is the proposal for optional which is a Boost feature. It is a Class template optional<T> that may or may not store a value of type T in its storage space. Its interface allows to query if a value of type T is currently stored, and if so, to access it. It was a 11th hour compromise that made it remove all relational operators and only support operator== and operator<. This has proven to be extremely controversial although the motion passed. But I expect a National Body comment with surface to rectify this.
  • N3669 is one of those consequential proposal of adding one feature N3652, the subset of N3597 with the removal of const from constexpr member functions which must be carried to the library. Although this was brought in only at the meeting. It is allowed to pass as it updates the library by adding const back now that constexpr has it removed implicitly.
  • N3655 is based on N3546 and proposes to augment C++11’s TransformationTraits with a number of template aliases whose use dramatically simplifies the traits’ most common applications.
  • N3662 is based on N3532 and is the library version of VLA called dynarray passed. It differs from the language VLA proposal in that it supports zero-sized arrays and can be looked at with decltype. However, both can be implemented on the stack or the heap such that the size is determined at runtime, but cannot change. It was passed amidst some minor concern with dependence and confusion on its relation with the VLA core language proposal.

In Kona, we also approved N3346 Terminolgy for Container Element Requirements while in Portland we approved 2 small papers and a large number of updates to adapt the C++11 library with constexpr.

  • N3421 is a proposal to make <functional>'s operator functors easier to use and more generic.
  • N3462 deals with the use of result_of in contexts where SFINAE is a consideration; i.e., in function signatures. result_of is intended to be a simple way to compute the result type of some callable when provided with arguments of specified types. It is a shorthand for a longer type computation using decltype and declval. However, there are cases where the use of result_of leads to a hard error whereas the equivalent use of decltype and declval would not. This happens in function signatures, when the direct use of decltype of an ill-formed call expression causes the function to be dropped due to SFINAE. The solution is make result_of SFINAE-friendly by conditioning the presence of the nested type typedef on whether the call expression is ill-formed or not.
  • N3302 Constexpr Library Additions: complex, v2
  • N3470 Constexpr Library Additions: containers, v2
  • N3469 Constexpr Library Additions: chrono, v3
  • N3471 Constexpr Library Additions: utilities, v3

 

Technical Specifications, Concurrency, and Transactional Memory

In this series that looks at C++14 content, we looked at features from Language and Library for C++14. Now we will look at Concurrency which is the other group that contributed features for C++14. In reality, some of the features from Language and Library also came from Concurrency.

Concurrency is the other major group that convened along with many small groups, needing to process all the smallish items for C++14. It came forward with 3 papers.

  • N3659 is based on N3568 and adds support for more complex forms of mutexes including shared mutex and upgradable mutex. This paper has been around since before C++11 but was postponed due to workload. It allows clients to easily code the well-known multiple readers/ single-writer locking pattern. However, only shared mutex was passed. It adds the following shared_mutex:
namespace std {

class shared_mutex
{
public:

shared_mutex();
~shared_mutex();

shared_mutex(const shared_mutex&) = delete;
shared_mutex& operator=(const shared_mutex&) = delete;

// Exclusive ownership

void lock(); // blocking
bool try_lock();
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
template <class Clock, class Duration>
bool
try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
void unlock();

// Shared ownership

void lock_shared(); // blocking
bool try_lock_shared();
template <class Rep, class Period>
bool
try_lock_shared_for(const chrono::duration<Rep, Period>& rel_time);
template <class Clock, class Duration>
bool
try_lock_shared_until(
const chrono::time_point<Clock, Duration>& abs_time);
void unlock_shared();
};

} // std

and shared_lock:

namespace std {

template <class Mutex>
class shared_lock
{
public:
typedef Mutex mutex_type;

// Shared locking

shared_lock() noexcept;
explicit shared_lock(mutex_type& m); // blocking
shared_lock(mutex_type& m, defer_lock_t) noexcept;
shared_lock(mutex_type& m, try_to_lock_t);
shared_lock(mutex_type& m, adopt_lock_t);
template <class Clock, class Duration>
shared_lock(mutex_type& m,
const chrono::time_point<Clock, Duration>& abs_time);
template <class Rep, class Period>
shared_lock(mutex_type& m,
const chrono::duration<Rep, Period>& rel_time);
~shared_lock();

shared_lock(shared_lock const&) = delete;
shared_lock& operator=(shared_lock const&) = delete;

shared_lock(shared_lock&& u) noexcept;
shared_lock& operator=(shared_lock&& u) noexcept;

void lock(); // blocking
bool try_lock();
template <class Rep, class Period>
bool try_lock_for(const chrono::duration<Rep, Period>& rel_time);
template <class Clock, class Duration>
bool
try_lock_until(const chrono::time_point<Clock, Duration>& abs_time);
void unlock();

// Setters

void swap(shared_lock& u) noexcept;
mutex_type* release() noexcept;

// Getters

bool owns_lock() const noexcept;
explicit operator bool () const noexcept;
mutex_type* mutex() const noexcept;

private:
mutex_type* pm; // exposition only
bool owns; // exposition only
};

template <class Mutex>
void swap(shared_lock<Mutex>& x, shared_lock<Mutex>& y) noexcept;

} // std

The upgradable mutex became contentious because there were some concerns about contentions in the implementation, so it was deferred.

  • N3636 is based on N3630, an update of part of N3451. It was NOT PASSED. It is an outcome of the Kona Compromise as it is trying to fix a potential problem in the std::future semantics model. Currently, it is not clear whether destructors for future blocks or not when it throws. This makes future hard to use in generic code because the destructor will sometimes block. You could say that throwing from destructor is not recommended anyway so this probably happens rarely. But there was a drive to define clearly whether they block, not block, or as they are now. Fearing to break code, the proposal worked out in committee supported all three solutions, but in particular invented a waiting_future returned by async() for the blocking case. Now code using async() with auto return type would continue to work while other code would break noisily. There is no implementation concern but the counter argument is that some objected this invention in the last minute. In general, the Kona Compromise was a devil’s bargain to have some advanced support for asynchronous feature given that there was not enough time in C++11 to enable more advanced abstractions. The result was async and future, which has been somewhat full of problematic corner cases. Since then, we have been fixing it and there is strong consensus in the group that we should stop doing that, and focus more time on more complete proposals such as Google executors and Microsoft then continuations.
  • N3637 is based on N3630, an update of part of N3451. It was NOT PASSED. It makes the thread destructor joining instead of terminate as it does now. This has the potential of making thread a proper RAII type and avoids inconsistency with async which also joins. This change may cause some dubious code to hang. It was defeated because there were some concerns that this behavior of thread destructor was a deliberate design decision. This too likely will be revisited.

After the C++14 features were triaged, we studied a number of future concurrency developments. Most of these are aiming for a Concurrency TS which will likely be put forward in the next meeting in Chicago. The current set of proposals can be roughly divided into several groups. There are the full-control tasking proposals which allow you to launch tasks asynchronously but give you all the controls a programmer would expect. These are the MS future.then continuations (N3558) with resumable functions (N3564) , and Google executors (N3562). Apple GCD also falls in this category. There are the groups that parallelize the C++ std library by adding parallel algorithms (N3554), and possibly concurrent containers but also some form of task management as a library facility. This is represented by a marriage of TTB, PPL and Nvidia Thrust’s. AMD’s Bolt also falls in this category. They enable throughput. There are the high level task language constructs that keep it simple and allow non-computer scientists to launch a parallel loop or task. These are the Cilk (N3557) and OpenMP (N3530) proposals. Vectorized loop (N3561) access from Intel also roughly falls along this line to enable a uniform way of accessing different vector units. I helped mostly with marrying OpenMP with Cilk and hope to have both semantics to enabled more close collaboration between the two groups. Even so, there is real question as to whether the language approach is superior to a pure library approach and this needs to be studied with actual usage examples. These two proposals were also passed to the C Committee and a Study Group has been formed. This will hopefully enable further compatibility with C. Even though OpenMP is about to release 4.0 with vast new support for accelerators, improved support for tasks, reductions amd affinity, much of that will not be in scope yet. For the merging purpose, we would mainly aim for loops, reductions and tasks as a first stage for merged syntax.

Three Technical Specifications were approved to move forward. They include Concepts-lite, Networking and Filesystems (N3505). I did not attend the Networking subgroup but they plan to issue a new TS every year. A document will be present in the post-meeting mailing. Filesystem did not meet but I have analyzed it extensively for IBM and feel it is a good document that has been in service as Boost.Filesystem for sometimes. It is designed around the posix filesystem notation, with specific support for Linux and Windows-style filesystems. Having spoken to the author, he is looking at improving it in future to support large enterprise scale filesystems, potentially GFS, or even 390 MVS.

I will talk a little about Concepts. N3580 is Concepts-lite is Concepts without separate checking, and the concept map feature. This significantly reduces the burden of implementation. It came out of what is called the Palo Alto Technical Report N3351, where Andrew Lumsdaine called a meeting with Bjarne Stroustrup, Alex Stepanov, Sean Parent and many from Indiana University to consolidate a way of moving forward after the removal of Concepts from C++11. Alex used a structure similar to his Elements of Programming book to design a Concepts for STL.

This resulted in far fewer concepts then the original removed Concepts proposal. This has been implemented in gcc and is shown to be useful for template prototype checking as expected and replaces the similar facility in D's static_if (N3613). Bjarne further showed a terse syntax for constrained lambdas which Herb had shown where there is no <> bracket in sight. But more importantly, to take over the world, it has to be fast. Early test results from GCC indicate it compiles faster with Concept-lite because it stops all the needless instantiation that would normally occur.

Two other possible Technical Specification for Concurrency, and Library Extension 2 were withdrawn without vote because they did not have paper, although they both have significant planned content and probably will be put forward in Chicago. The other possible TS for Chicago will be Transactional Memory.

 

I chaired the Transactional Memory SG5 group after giving a talk at ACCU on Transactional Memory progress to a room of over one hundred people. There were a lot of interest in Transactional Memory, including a genuine interest in participating in the design. Our group has been meeting regularly every 2 weeks since 2008 between Intel, IBM, Oracle, HP, and Redhat with many academic participation. We have developed a specification, which is now used as a base document and is part of the Intel C++ compiler, the GNU 4.7 C++ compiler. But this specification will likely be reduced for our first approach for standardization.

We continue to refine the semantics in this meeting. We had a 5 hour session which gathered feedback for design directions. In particular, Victor from Oracle presented N3589, a review of the specification as it stands today, the progress since Portland and the simple exception proposal. Tovald of Redhat presented his paper on advanced data escape mechanism N3592. A third paper N3591 on explicit cancellation was not discussed.

We had a large number of polls which helped us with design directions and obtained feedback that we should move quickly to submit standard wording for a simple specification for the 1st iteration TS. We aim to do that for Chicago. The poll results were as follow:

On relaxed TX name change: no consensus

on explicit cancellation: no

cancel on escaping exception: even, mixed

commit on escaping exception: weak yes, what does no mean here?

simple data escape: yes but is tied to cancel on escape

advanced data escape: clear no

atomic and relaxed: both yes

The current syntax contains the following support for 2 types of transaction statement.

  • Atomic transaction: The body of an atomic transaction appears to take effect atomically: no other thread sees any intermediate states of an atomic transaction, nor does the thread executing an atomic transaction see the effects of any operations of other threads interleaved between the steps within the transaction.

__transaction_atomic [[noexcept]] { <body> }

__transaction_atomic [[commit_on_escape]] { <body> }

__transaction_atomic [[cancel_on_escape]] { <body> }

  • Relaxed transaction: It is semantically equivalent to having a special mutex lock (one for the entire system) that is acquired before executing the body and released after the body is executed (unless the relaxed transaction statement is nested within another relaxed transaction, in which case the lock is not released until the end of the outermost relaxed transaction), and no atomic transaction appears to take effect while this special lock is held by any other thread.

__transaction_relaxed { <body> }

One of the key distinction between an atomic and a relaxed transaction is that any code may be executed within a relaxed transaction, but only transaction safe code may be executed within an atomic transaction.

I will say more on the design in future.

0 comments
5 views