
> So the exact same syncronized code runs, but in an optimistic rather than pessimistic fashion.
I don't think that's the point. From what I've read, this offers an entirely different way of thinking about concurrency.
For example: consider that you have two operations, list_remove and list_insert, which by themselves are thread-safe. Traditionally, these can't easily be composed into a larger thread-safe operation. You'd have to write something like:
mutex_synchronize(**what**) {
item = list_remove(list1);
list_insert(list2, item);
}
The problem is that you have to consider every other flow in the program which might touch list1 and list2, and set up a mutex which they all honour. Forgot one and the program crashes in an occasional and infuriating way.
With STM, you write:
atomic {
item = list_remove(list1);
list_insert(list2, item);
}
and that's it. Concurrency no longer affects your entire program globally; it's defined locally to where it's needed. Amazing.
Of course, performance *is* related to this. Naively you could implement atomic() using a single global mutex, like the "BIG GIANT LOCK" that FreeBSD used to have, but that kills concurrency. So to get good concurrency the hard work is in having lots of little locks and making sure that they are all used correctly.
STM does this for you - you effectively get the finest-grained "lock" needed for your atomic operation.
It doesn't actually lock, but rolls back and retries if the transaction was stamped on by something else. In practice, retries seem to be needed only occasionally.
None of this stops you having to understand concurrency though. You still need to know which bits of code need to be wrapped in atomic(), and why.