1bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Protocol Buffers - Google's data interchange format
2bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Copyright 2013 Google Inc.  All rights reserved.
3bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// http://code.google.com/p/protobuf/
4bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch//
5bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Redistribution and use in source and binary forms, with or without
6bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// modification, are permitted provided that the following conditions are
7bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// met:
8bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch//
9bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch//     * Redistributions of source code must retain the above copyright
10bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// notice, this list of conditions and the following disclaimer.
11bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch//     * Redistributions in binary form must reproduce the above
12bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// copyright notice, this list of conditions and the following disclaimer
13bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// in the documentation and/or other materials provided with the
14bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// distribution.
15bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch//     * Neither the name of Google Inc. nor the names of its
16bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// contributors may be used to endorse or promote products derived from
17bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// this software without specific prior written permission.
18bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch//
19bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
31bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// This file is an internal atomic implementation for compiler-based
32bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// ThreadSanitizer (http://clang.llvm.org/docs/ThreadSanitizer.html).
33bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch// Use atomicops.h instead.
34bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
35bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_TSAN_H_
36bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_TSAN_H_
37bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
38bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#define ATOMICOPS_COMPILER_BARRIER() __asm__ __volatile__("" : : : "memory")
39bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <sanitizer/tsan_interface_atomic.h>
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
42bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochnamespace google {
43bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochnamespace protobuf {
44bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochnamespace internal {
45bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
46bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32 *ptr,
47bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                         Atomic32 old_value,
48bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                         Atomic32 new_value) {
49bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  Atomic32 cmp = old_value;
50bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  __tsan_atomic32_compare_exchange_strong(ptr, &cmp, new_value,
51bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      __tsan_memory_order_relaxed, __tsan_memory_order_relaxed);
52bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return cmp;
53bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
54bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
55bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32 *ptr,
56bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                         Atomic32 new_value) {
57bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return __tsan_atomic32_exchange(ptr, new_value,
58bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      __tsan_memory_order_relaxed);
59bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
60bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
61bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline Atomic32 Acquire_AtomicExchange(volatile Atomic32 *ptr,
62bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                       Atomic32 new_value) {
63bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return __tsan_atomic32_exchange(ptr, new_value,
64bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      __tsan_memory_order_acquire);
65bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
66bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
67bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline Atomic32 Release_AtomicExchange(volatile Atomic32 *ptr,
68bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                       Atomic32 new_value) {
69bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return __tsan_atomic32_exchange(ptr, new_value,
70bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      __tsan_memory_order_release);
71bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
72bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
73bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32 *ptr,
74bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                          Atomic32 increment) {
75bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return increment + __tsan_atomic32_fetch_add(ptr, increment,
76bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      __tsan_memory_order_relaxed);
77bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
78bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
79bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline Atomic32 Barrier_AtomicIncrement(volatile Atomic32 *ptr,
80bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                        Atomic32 increment) {
81bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return increment + __tsan_atomic32_fetch_add(ptr, increment,
82bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      __tsan_memory_order_acq_rel);
83bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
84bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
85bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline Atomic32 Acquire_CompareAndSwap(volatile Atomic32 *ptr,
86bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                       Atomic32 old_value,
87bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                       Atomic32 new_value) {
88bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  Atomic32 cmp = old_value;
89bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  __tsan_atomic32_compare_exchange_strong(ptr, &cmp, new_value,
90bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      __tsan_memory_order_acquire, __tsan_memory_order_acquire);
91bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return cmp;
92bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
93bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
94bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline Atomic32 Release_CompareAndSwap(volatile Atomic32 *ptr,
95bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                       Atomic32 old_value,
96bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                       Atomic32 new_value) {
97bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  Atomic32 cmp = old_value;
98bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  __tsan_atomic32_compare_exchange_strong(ptr, &cmp, new_value,
99bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      __tsan_memory_order_release, __tsan_memory_order_relaxed);
100bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return cmp;
101bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
102bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
103bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline void NoBarrier_Store(volatile Atomic32 *ptr, Atomic32 value) {
104bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  __tsan_atomic32_store(ptr, value, __tsan_memory_order_relaxed);
105bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
106bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
107bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline void Acquire_Store(volatile Atomic32 *ptr, Atomic32 value) {
108bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  __tsan_atomic32_store(ptr, value, __tsan_memory_order_relaxed);
109bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
110bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
111bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
112bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline void Release_Store(volatile Atomic32 *ptr, Atomic32 value) {
113bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  __tsan_atomic32_store(ptr, value, __tsan_memory_order_release);
114bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
115bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
116bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline Atomic32 NoBarrier_Load(volatile const Atomic32 *ptr) {
117bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return __tsan_atomic32_load(ptr, __tsan_memory_order_relaxed);
118bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
119bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
120bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline Atomic32 Acquire_Load(volatile const Atomic32 *ptr) {
121bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return __tsan_atomic32_load(ptr, __tsan_memory_order_acquire);
122bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
123bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
124bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline Atomic32 Release_Load(volatile const Atomic32 *ptr) {
125bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
126bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return __tsan_atomic32_load(ptr, __tsan_memory_order_relaxed);
127bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
128bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
129bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64 *ptr,
130bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                         Atomic64 old_value,
131bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                         Atomic64 new_value) {
132bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  Atomic64 cmp = old_value;
133bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  __tsan_atomic64_compare_exchange_strong(ptr, &cmp, new_value,
134bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      __tsan_memory_order_relaxed, __tsan_memory_order_relaxed);
135bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return cmp;
136bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
137bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
138bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64 *ptr,
139bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                         Atomic64 new_value) {
140bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return __tsan_atomic64_exchange(ptr, new_value, __tsan_memory_order_relaxed);
141bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
142bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
143bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline Atomic64 Acquire_AtomicExchange(volatile Atomic64 *ptr,
144bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                       Atomic64 new_value) {
145bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return __tsan_atomic64_exchange(ptr, new_value, __tsan_memory_order_acquire);
146bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
147bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
148bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline Atomic64 Release_AtomicExchange(volatile Atomic64 *ptr,
149bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                       Atomic64 new_value) {
150bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return __tsan_atomic64_exchange(ptr, new_value, __tsan_memory_order_release);
151bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
152bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
153bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64 *ptr,
154bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                          Atomic64 increment) {
155bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return increment + __tsan_atomic64_fetch_add(ptr, increment,
156bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      __tsan_memory_order_relaxed);
157bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
158bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
159bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline Atomic64 Barrier_AtomicIncrement(volatile Atomic64 *ptr,
160bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                        Atomic64 increment) {
161bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return increment + __tsan_atomic64_fetch_add(ptr, increment,
162bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      __tsan_memory_order_acq_rel);
163bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
164bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
165bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline void NoBarrier_Store(volatile Atomic64 *ptr, Atomic64 value) {
166bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  __tsan_atomic64_store(ptr, value, __tsan_memory_order_relaxed);
167bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
168bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
169bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline void Acquire_Store(volatile Atomic64 *ptr, Atomic64 value) {
170bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  __tsan_atomic64_store(ptr, value, __tsan_memory_order_relaxed);
171bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
172bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
173bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
174bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline void Release_Store(volatile Atomic64 *ptr, Atomic64 value) {
175bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  __tsan_atomic64_store(ptr, value, __tsan_memory_order_release);
176bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
177bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
178bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline Atomic64 NoBarrier_Load(volatile const Atomic64 *ptr) {
179bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return __tsan_atomic64_load(ptr, __tsan_memory_order_relaxed);
180bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
181bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
182bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline Atomic64 Acquire_Load(volatile const Atomic64 *ptr) {
183bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return __tsan_atomic64_load(ptr, __tsan_memory_order_acquire);
184bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
185bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
186bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline Atomic64 Release_Load(volatile const Atomic64 *ptr) {
187bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
188bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return __tsan_atomic64_load(ptr, __tsan_memory_order_relaxed);
189bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
190bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
191bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline Atomic64 Acquire_CompareAndSwap(volatile Atomic64 *ptr,
192bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                       Atomic64 old_value,
193bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                       Atomic64 new_value) {
194bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  Atomic64 cmp = old_value;
195bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  __tsan_atomic64_compare_exchange_strong(ptr, &cmp, new_value,
196bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      __tsan_memory_order_acquire, __tsan_memory_order_acquire);
197bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return cmp;
198bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
199bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
200bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline Atomic64 Release_CompareAndSwap(volatile Atomic64 *ptr,
201bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                       Atomic64 old_value,
202bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch                                       Atomic64 new_value) {
203bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  Atomic64 cmp = old_value;
204bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  __tsan_atomic64_compare_exchange_strong(ptr, &cmp, new_value,
205bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch      __tsan_memory_order_release, __tsan_memory_order_relaxed);
206bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  return cmp;
207bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
208bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
209bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdochinline void MemoryBarrier() {
210bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch  __tsan_atomic_thread_fence(__tsan_memory_order_seq_cst);
211bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}
212bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
213bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}  // namespace internal
214bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}  // namespace protobuf
215bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch}  // namespace google
216bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
217bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#undef ATOMICOPS_COMPILER_BARRIER
218bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch
219bb1529ce867d8845a77ec7cdf3e3003ef1771a40Ben Murdoch#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_TSAN_H_
220