Ami Tavory Ami Tavory - 1 year ago 53
C++ Question

Generic Components Friendly To Software Transactional Memory

Say we write some new class which can be used concurrently or not. Obviously, we don't want to have locks on everything on the chance that they will be called concurrently. One way to address this is through parameterizing by mixins specifying locking:

template<class Locking>
struct foo : private Locking {
void bar() {
// Do something.

and instantiating
with a class that actually locks for the multithreading case, and with a class that does no-ops for the other case (hopefully, the compiler will even optimize away the calls).

Now suppose I'd like to do this with software-transactional memory instead of locking. Looking at N3919 (or the gcc precursor), the idea is different. There are no calls such as



Instead there are function specifiers like

void bar() transaction_safe;

and block specifiers like

transaction { /* body */ }

with strict rules of the latter calling the former, and nothing that looks like it can be used by mixins.

How can this be done(without involving the preprocessor)? Note also that one of the main benefits of STM is composability, but there seems no way to get the instantiation to reflect that
is transactionable.

Answer Source

In a similar way, with lambda, it seems you may do something like:

template<class Transaction>
struct foo {
    void bar() {
        Transaction::run([](){ /* Do something. */ });

with the 2 implementations

template<typename F>
void TransactionNone::run(F f) { f(); }


template<typename F>
void TransactionReal::run(F f) { transaction{ f(); } }

For attributes,

A function is transaction-safe if it is not transaction-unsafe.

So it seems you may omit that keyword, and let the compiler/linker do that job.