Search code examples
gooptimizationconcurrency

In Golang what ensures calls to Mutex methods are not reordered relative to other statements?


As I understand upon reading Go Memory Model article, compiler is allowed to reorder statements, though such ability is subject to certain restrictions.

However I can't understand what restricts reordering of statements which include Mutex locking and unlocking, i.e.:

mu.RLock()
d := primes[i]
mu.RUnlock()

What ensures the second line is not reordered to the top? Is it about the phrase:

Not introducing data races also means not assuming that called functions always return or are free of synchronization operations.

i.e. simply relying on fact that Lock() is a function call (and I suppose, not inlined somehow) - or there is something different mechanism/logic?


Solution

  • Statements in a block are executed in source code order (ignoring the special case of the package block where dependencies control order). Optimizations must retain the side effects of this execution order.

    The specification does not specifically state that statements in a block are executed in source code order. Perhaps the authors thought it was so obvious that it does not need to be said.

    If the compiler cannot prove that i, primes or the backing of primes is only visible to the current goroutine, then compiler cannot reorder the statements without changing the side effects of the statements.