C++ - Transactional memory: exact meaning of atomic_commit?

Viewed 23

Context:

I was reading the Transactional memory reference.

Some info are really unclear to me. I run the code below in godbolt and I have a sense of what should happen but I want some confirmation or explanation of what is really expected to happen, not what I think should happen.

In the atomic_commit case:

If an exception is thrown, the transaction is committed normally.

That line raises some questions:

auto f() -> std::optional<int> {
    static int i = 0;

    std::optional<int> p;
    atomic_commit {  

        //some memory ops happen here
        ++i;
        throw std::runtime_error("I decide to fail here, for some reason");
        

        p = i;
        return p;  // commit transaction
    }

    return std::nullopt;
}

int main() {
  for (int retries = 0 ; retries < 10 ; ++retries) {
    try {
        auto r = f();
        if (r) {
            std::cout << r.value() << std::endl;
        } else {
            std::cout << "nope" << std::endl;
        }
    } catch (...) {
        //handle the exception and maybe retry.
    }
  }
}

Question:

  • What happens exactly to the already registered data ? Is it taken back?

  • If two threads try to write at the same address, and the first one failed to do so, what happens to the second? is the data corrupted?

  • In the case no exception is thrown, and two threads try to write in the same address, what happens exactly?

As an added info, I mostly use the latest gcc.

Other thoughts:

On the other hand, the atomic_cancel seems to have an interesting behavior:

the values of all memory locations in the program that were modified by side effects of the operations of the atomic block are restored to the values they had at the time the start of the atomic block was executed, and the exception continues stack unwinding as usual

That would mean that all the data is copied first (may be faster than a lock). It is the most natural behavior to me, except for the part that calling std::abort is quite rude.

But it doesn't matter, it is not always implemented anyway(gcc..).

Thanks

0 Answers
Related