1afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// Copyright 2014 Google Inc. All rights reserved.
2afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// https://developers.google.com/protocol-buffers/
3afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson//
4afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// Redistribution and use in source and binary forms, with or without
5afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// modification, are permitted provided that the following conditions are
6afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// met:
7afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson//
8afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson//     * Redistributions of source code must retain the above copyright
9afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// notice, this list of conditions and the following disclaimer.
10afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson//     * Redistributions in binary form must reproduce the above
11afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// copyright notice, this list of conditions and the following disclaimer
12afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// in the documentation and/or other materials provided with the
13afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// distribution.
14afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson//     * Neither the name of Google Inc. nor the names of its
15afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// contributors may be used to endorse or promote products derived from
16afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// this software without specific prior written permission.
17afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson//
18afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
30afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson// This file is an internal atomic implementation, use atomicops.h instead.
31afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
32afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson#ifndef GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_
33afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson#define GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_
34afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
35afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson#include <atomic.h>
36afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
37afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsonnamespace google {
38afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsonnamespace protobuf {
39afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsonnamespace internal {
40afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
41afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline Atomic32 NoBarrier_CompareAndSwap(volatile Atomic32* ptr,
42afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson                                         Atomic32 old_value,
43afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson                                         Atomic32 new_value) {
44afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  return (Atomic32)atomic_cas_32((volatile uint32_t*)ptr, (uint32_t)old_value, (uint32_t)new_value);
45afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
46afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
47afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline Atomic32 NoBarrier_AtomicExchange(volatile Atomic32* ptr,
48afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson                                         Atomic32 new_value) {
49afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  return (Atomic32)atomic_swap_32((volatile uint32_t*)ptr, (uint32_t)new_value);
50afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
51afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
52afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline Atomic32 NoBarrier_AtomicIncrement(volatile Atomic32* ptr,
53afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson                                          Atomic32 increment) {
54afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  return (Atomic32)atomic_add_32_nv((volatile uint32_t*)ptr, (uint32_t)increment);
55afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
56afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
57afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline void MemoryBarrier(void) {
58afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson	membar_producer();
59afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson	membar_consumer();
60afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
61afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
62afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline Atomic32 Barrier_AtomicIncrement(volatile Atomic32* ptr,
63afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson                                        Atomic32 increment) {
64afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  MemoryBarrier();
65afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  Atomic32 ret = NoBarrier_AtomicIncrement(ptr, increment);
66afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  MemoryBarrier();
67afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
68afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  return ret;
69afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
70afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
71afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline Atomic32 Acquire_CompareAndSwap(volatile Atomic32* ptr,
72afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson                                       Atomic32 old_value,
73afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson                                       Atomic32 new_value) {
74afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  Atomic32 ret = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
75afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  MemoryBarrier();
76afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
77afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  return ret;
78afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
79afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
80afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline Atomic32 Release_CompareAndSwap(volatile Atomic32* ptr,
81afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson                                       Atomic32 old_value,
82afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson                                       Atomic32 new_value) {
83afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  MemoryBarrier();
84afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
85afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
86afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
87afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline void NoBarrier_Store(volatile Atomic32* ptr, Atomic32 value) {
88afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  *ptr = value;
89afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
90afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
91afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline void Acquire_Store(volatile Atomic32* ptr, Atomic32 value) {
92afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  *ptr = value;
93afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  membar_producer();
94afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
95afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
96afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline void Release_Store(volatile Atomic32* ptr, Atomic32 value) {
97afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  membar_consumer();
98afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  *ptr = value;
99afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
100afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
101afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline Atomic32 NoBarrier_Load(volatile const Atomic32* ptr) {
102afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  return *ptr;
103afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
104afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
105afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline Atomic32 Acquire_Load(volatile const Atomic32* ptr) {
106afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  Atomic32 val = *ptr;
107afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  membar_consumer();
108afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  return val;
109afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
110afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
111afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline Atomic32 Release_Load(volatile const Atomic32* ptr) {
112afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  membar_producer();
113afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  return *ptr;
114afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
115afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
116afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson#ifdef GOOGLE_PROTOBUF_ARCH_64_BIT
117afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline Atomic64 NoBarrier_CompareAndSwap(volatile Atomic64* ptr,
118afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson                                         Atomic64 old_value,
119afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson                                         Atomic64 new_value) {
120afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  return atomic_cas_64((volatile uint64_t*)ptr, (uint64_t)old_value, (uint64_t)new_value);
121afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
122afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
123afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline Atomic64 NoBarrier_AtomicExchange(volatile Atomic64* ptr, Atomic64 new_value) {
124afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  return atomic_swap_64((volatile uint64_t*)ptr, (uint64_t)new_value);
125afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
126afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
127afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline Atomic64 NoBarrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment) {
128afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  return atomic_add_64_nv((volatile uint64_t*)ptr, increment);
129afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
130afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
131afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline Atomic64 Barrier_AtomicIncrement(volatile Atomic64* ptr, Atomic64 increment) {
132afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  MemoryBarrier();
133afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  Atomic64 ret = atomic_add_64_nv((volatile uint64_t*)ptr, increment);
134afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  MemoryBarrier();
135afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  return ret;
136afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
137afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
138afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline Atomic64 Acquire_CompareAndSwap(volatile Atomic64* ptr,
139afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson                                       Atomic64 old_value,
140afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson                                       Atomic64 new_value) {
141afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  Atomic64 ret = NoBarrier_CompareAndSwap(ptr, old_value, new_value);
142afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  MemoryBarrier();
143afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  return ret;
144afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
145afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
146afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline Atomic64 Release_CompareAndSwap(volatile Atomic64* ptr,
147afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson                                       Atomic64 old_value,
148afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson                                       Atomic64 new_value) {
149afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  MemoryBarrier();
150afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  return NoBarrier_CompareAndSwap(ptr, old_value, new_value);
151afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
152afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
153afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline void NoBarrier_Store(volatile Atomic64* ptr, Atomic64 value) {
154afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  *ptr = value;
155afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
156afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
157afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline void Acquire_Store(volatile Atomic64* ptr, Atomic64 value) {
158afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  *ptr = value;
159afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  membar_producer();
160afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
161afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
162afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline void Release_Store(volatile Atomic64* ptr, Atomic64 value) {
163afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  membar_consumer();
164afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  *ptr = value;
165afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
166afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
167afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline Atomic64 NoBarrier_Load(volatile const Atomic64* ptr) {
168afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  return *ptr;
169afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
170afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
171afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline Atomic64 Acquire_Load(volatile const Atomic64* ptr) {
172afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  Atomic64 ret = *ptr;
173afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  membar_consumer();
174afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  return ret;
175afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
176afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
177afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidsoninline Atomic64 Release_Load(volatile const Atomic64* ptr) {
178afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  membar_producer();
179afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson  return *ptr;
180afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}
181afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson#endif
182afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
183afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}  // namespace internal
184afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}  // namespace protobuf
185afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson}  // namespace google
186afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
187afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson#endif  // GOOGLE_PROTOBUF_ATOMICOPS_INTERNALS_SPARC_GCC_H_
188afb4b72037e3f13db208590fc782c4bc8e27f862Jeff Davidson
189