Is it a good idea to use atomic operations in setter and getter methods?

154 views
Skip to first unread message

T L

unread,
Jul 18, 2019, 11:35:31 AM7/18/19
to golang-nuts
For example:

type Page struct {
    views uint32
}

func (page *Page) SetViews(n uint32) {
    atomic.StoreUint32(&page.views, n)
}

func (page *Page) Views() uint32 {
    return atomic.LoadUint32(&page.views)
}

Keith Randall and Ian Lance Taylor said that atomic.Load is a memory_order_acquire
and atomic.Store is memory_order_release, so there is no memory order guarantees
between the following two calls, I think:

atomic.StoreUint32(&page.views, n)
atomic.LoadUint32(&page.views)

In other words, the load result might not reflect the latest value of page.views.

On the contrary, the memory order between the following two calls
is guaranteed to be as their order shown in code.

atomic.LoadUint32(&page.views)
atomic.StoreUint32(&page.views, n)

Is my understanding right?


Ian Lance Taylor

unread,
Jul 18, 2019, 1:01:27 PM7/18/19
to T L, golang-nuts
On Thu, Jul 18, 2019 at 8:35 AM T L <tapi...@gmail.com> wrote:
>
> For example:
>
> type Page struct {
> views uint32
> }
>
> func (page *Page) SetViews(n uint32) {
> atomic.StoreUint32(&page.views, n)
> }
>
> func (page *Page) Views() uint32 {
> return atomic.LoadUint32(&page.views)
> }
>
> Keith Randall and Ian Lance Taylor said that atomic.Load is a memory_order_acquire
> and atomic.Store is memory_order_release, so there is no memory order guarantees
> between the following two calls, I think:
>
> atomic.StoreUint32(&page.views, n)
> atomic.LoadUint32(&page.views)
>
> In other words, the load result might not reflect the latest value of page.views.

In these kinds of discussions it's hard to know what "latest value"
means. But in general an atomic load will see any atomic store that
preceded it in absolute time. The difference between load-acquire and
sequentially-consistent-load is not with the atomic value itself; it's
with all other memory accesses. The LoadUint32 will see the
StoreUint32, but it may not see any other non-atomic memory stores
done before the StoreUint32.


> On the contrary, the memory order between the following two calls
> is guaranteed to be as their order shown in code.
>
> atomic.LoadUint32(&page.views)
> atomic.StoreUint32(&page.views, n)
>
> Is my understanding right?

So, per above, not quite.

And that said, see the more recent discussion on
https://golang.org/issue/5045, in which Russ argues that we should use
sequential consistency anyhow.

Ian

T L

unread,
Jul 18, 2019, 7:14:16 PM7/18/19
to golang-nuts
Thanks, Ian. I get it now.
Reply all
Reply to author
Forward
0 new messages