The whole point of using std::atomic
and not mutexes is to get:
- higher performance for multithread code (no contention between readers);
- smaller change of performance when heavy contention occurs (a retry on failed RMW is less drastic than losing the rest of time slice because a thread holding the mutex is ready to run but not running);
- the ability to communicate with signal handlers.
When the atomicity of the operation is "emulated" with a table of mutexes:
- The performance will at best be as good as a user mutex, for the case where exactly one modifying operation is needed; when multiple operations are used in sequence, multiple locking/unlocking operation will need to occur, making the code less efficient.
- Performance will be no more predictable than with an explicit user mutex.
- Such "emulated" atomicity cannot be used with code that blocks other code (e.g. a signal handler).
So why was such poor emulation of atomic CPU operations found worthwhile? What's the use case of the non-lock-free fallback mechanism in std::atomic
?