1448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.org/*
2448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.org * Copyright 2014 Google Inc.
3448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.org *
4448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.org * Use of this source code is governed by a BSD-style license that can be
5448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.org * found in the LICENSE file.
6448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.org */
7448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.org
8448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.org#ifndef SkBarriers_arm_DEFINED
9448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.org#define SkBarriers_arm_DEFINED
10448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.org
11448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.orgstatic inline void sk_compiler_barrier() { asm volatile("" : : : "memory"); }
12448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.org
13448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.orgtemplate <typename T>
14448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.orgT sk_acquire_load(T* ptr) {
15448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.org    T val = *ptr;
16448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.org    __sync_synchronize();  // Issue a full barrier, which is an overkill acquire barrier.
17448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.org    return val;
18448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.org}
19448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.org
20448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.orgtemplate <typename T>
21654a9c20acb2e34b7836139615c29dc09fa0fb9cmtkleinT sk_consume_load(T* ptr) {
22654a9c20acb2e34b7836139615c29dc09fa0fb9cmtklein    T val = *ptr;
23654a9c20acb2e34b7836139615c29dc09fa0fb9cmtklein    // Unlike acquire, consume loads (data-dependent loads) are guaranteed not to reorder on ARM.
24654a9c20acb2e34b7836139615c29dc09fa0fb9cmtklein    // No memory barrier is needed, so we just use a compiler barrier.
25654a9c20acb2e34b7836139615c29dc09fa0fb9cmtklein    // C.f. http://preshing.com/20140709/the-purpose-of-memory_order_consume-in-cpp11/
26654a9c20acb2e34b7836139615c29dc09fa0fb9cmtklein    sk_compiler_barrier();
27654a9c20acb2e34b7836139615c29dc09fa0fb9cmtklein    return val;
28654a9c20acb2e34b7836139615c29dc09fa0fb9cmtklein}
29654a9c20acb2e34b7836139615c29dc09fa0fb9cmtklein
30654a9c20acb2e34b7836139615c29dc09fa0fb9cmtkleintemplate <typename T>
31448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.orgvoid sk_release_store(T* ptr, T val) {
32448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.org    __sync_synchronize();  // Issue a full barrier, which is an overkill release barrier.
33448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.org    *ptr = val;
34448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.org}
35448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.org
36448e2a3b3935d91e7bf84dc5b0367b92d2e2a518commit-bot@chromium.org#endif//SkBarriers_x86_DEFINED
37