LWN.net Logo

Transactional memory for GCC 4.7.0

Transactional memory for GCC 4.7.0

Posted Nov 10, 2011 4:31 UTC (Thu) by quotemstr (subscriber, #45331)
Parent article: Transactional memory for GCC 4.7.0

While transactional memory is a neat feature, the particular model being proposed here could use some simplification. Consider this paragraph:

Note: A cancel-outer statement cancels only outer atomic transactions; the restrictions above imply that a cancel-outer statement cannot be executed when the outermost atomic transaction is not an outer atomic transaction. In contrast, an unannotated cancel statement can cancel an outer atomic transaction if it is the immediately enclosing atomic transaction
Why do we need separate outermost and atomic transactions? (The outer-most transaction isn't even necessarily an outermost transaction.) Why does "throw" commit a transaction by default, necessitating the creation of a separate cancel-and-throw operator? Why is there no retry provision built into the transaction? Why do we mix lexical and dynamic scope?

IMHO, it'd be better to simplify the whole thing and allow only simple operations and inline functions over simple operations inside transactions. Aren't most transactions, in practice, going to be of this variety anyway?


(Log in to post comments)

Transactional memory for GCC 4.7.0

Posted Nov 10, 2011 16:15 UTC (Thu) by tvld (subscriber, #59052) [Link]

Features for failure atomicity (cancel, cancel-outer, cancel-and-throw) require atomic transactions. A transaction marked as "outer" therefore must always be an atomic transaction. Nonetheless, failure atomicity is like an add-on, you don't have to use it or care about it if you don't need it (see the section at the end of the specification that explains the dependencies between features).

The reason why we restrict normal cancel to lexical scope and cancel-outer to specially marked transactions is that we do not want programmers guessing whether a call hidden somewhere in a larger transaction could cancel the transaction or not. Normal transactions give you exactly-once semantics, whereas transactions that can be canceled are at-most-once (while still being atomic of course).

If throw would cancel a transaction by default, we would change the semantics of existing code. So no, we don't want that.

"Retry provision": I'm not exactly sure which semantics you are referring to here (like what's been proposed by Harris et al.?). Note that you cannot busy-wait for some condition to change in a transaction, simply because it's supposed to be atomic and isolated.

Finally, we just don't know how people will use transactions. Sure, you often want to keep synchronizing regions small, but that will not be a good choice for some programmers or programs. So, from a specification perspective, "simplifying the whole thing" would mean to assume a given narrow use case and prevent other uses.

The current specification does not prevent you from using transactions in the simple form you mentioned, so if you want that, you can have it. Here's a simple recipe: Only use __transaction_atomic, and never call any functions in a different compilation unit. And that's it, no further annotations necessary (the specification allows compilers to automatically infer whether a function is transaction_safe, and this is what GCC does too).

Copyright © 2013, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds