Skip to content

Commit

Permalink
runtime: document philosophy behind runtime atomic usage
Browse files Browse the repository at this point in the history
Based on Dmitry Vyukov's comments in CL 65210.

Change-Id: I5dce7286b0d180cd43cad3aaf70f537fafcda588
Reviewed-on: https://go-review.googlesource.com/123275
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Rick Hudson <rlh@golang.org>
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
  • Loading branch information
aclements committed Jul 11, 2018
1 parent 631402f commit 9300d22
Showing 1 changed file with 41 additions and 0 deletions.
41 changes: 41 additions & 0 deletions src/runtime/HACKING.md
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,47 @@ In summary,
<tr><td>park</td><td>Y</td><td>N</td><td>N</td></tr>
</table>

Atomics
=======

The runtime uses its own atomics package at `runtime/internal/atomic`.
This corresponds to `sync/atomic`, but functions have different names
for historical reasons and there are a few additional functions needed
by the runtime.

In general, we think hard about the uses of atomics in the runtime and
try to avoid unnecessary atomic operations. If access to a variable is
sometimes protected by another synchronization mechanism, the
already-protected accesses generally don't need to be atomic. There
are several reasons for this:

1. Using non-atomic or atomic access where appropriate makes the code
more self-documenting. Atomic access to a variable implies there's
somewhere else that may concurrently access the variable.

2. Non-atomic access allows for automatic race detection. The runtime
doesn't currently have a race detector, but it may in the future.
Atomic access defeats the race detector, while non-atomic access
allows the race detector to check your assumptions.

3. Non-atomic access may improve performance.

Of course, any non-atomic access to a shared variable should be
documented to explain how that access is protected.

Some common patterns that mix atomic and non-atomic access are:

* Read-mostly variables where updates are protected by a lock. Within
the locked region, reads do not need to be atomic, but the write
does. Outside the locked region, reads need to be atomic.

* Reads that only happen during STW, where no writes can happen during
STW, do not need to be atomic.

That said, the advice from the Go memory model stands: "Don't be
[too] clever." The performance of the runtime matters, but its
robustness matters more.

Unmanaged memory
================

Expand Down

0 comments on commit 9300d22

Please sign in to comment.