blob: f9d3e253edb0e7fc6fc62b6b37ae3a36357dc8c8 [file] [log] [blame]
Duane Sand09604112012-05-24 17:40:21 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#ifndef ANDROID_CUTILS_ATOMIC_MIPS_H
18#define ANDROID_CUTILS_ATOMIC_MIPS_H
19
20#include <stdint.h>
21
Ben Cheng5206d592012-12-07 10:54:09 -080022#ifndef ANDROID_ATOMIC_INLINE
23#define ANDROID_ATOMIC_INLINE inline __attribute__((always_inline))
24#endif
25
26extern ANDROID_ATOMIC_INLINE void android_compiler_barrier(void)
Duane Sand09604112012-05-24 17:40:21 -070027{
28 __asm__ __volatile__ ("" : : : "memory");
29}
30
31#if ANDROID_SMP == 0
Ben Cheng5206d592012-12-07 10:54:09 -080032extern ANDROID_ATOMIC_INLINE void android_memory_barrier(void)
Duane Sand09604112012-05-24 17:40:21 -070033{
34 android_compiler_barrier();
35}
Ben Cheng5206d592012-12-07 10:54:09 -080036extern ANDROID_ATOMIC_INLINE void android_memory_store_barrier(void)
Duane Sand09604112012-05-24 17:40:21 -070037{
38 android_compiler_barrier();
39}
40#else
Ben Cheng5206d592012-12-07 10:54:09 -080041extern ANDROID_ATOMIC_INLINE void android_memory_barrier(void)
Duane Sand09604112012-05-24 17:40:21 -070042{
43 __asm__ __volatile__ ("sync" : : : "memory");
44}
Ben Cheng5206d592012-12-07 10:54:09 -080045extern ANDROID_ATOMIC_INLINE void android_memory_store_barrier(void)
Duane Sand09604112012-05-24 17:40:21 -070046{
47 __asm__ __volatile__ ("sync" : : : "memory");
48}
49#endif
50
Ben Cheng5206d592012-12-07 10:54:09 -080051extern ANDROID_ATOMIC_INLINE int32_t
52android_atomic_acquire_load(volatile const int32_t *ptr)
Duane Sand09604112012-05-24 17:40:21 -070053{
54 int32_t value = *ptr;
55 android_memory_barrier();
56 return value;
57}
58
Ben Cheng5206d592012-12-07 10:54:09 -080059extern ANDROID_ATOMIC_INLINE int32_t
60android_atomic_release_load(volatile const int32_t *ptr)
Duane Sand09604112012-05-24 17:40:21 -070061{
62 android_memory_barrier();
63 return *ptr;
64}
65
Ben Cheng5206d592012-12-07 10:54:09 -080066extern ANDROID_ATOMIC_INLINE void
67android_atomic_acquire_store(int32_t value, volatile int32_t *ptr)
Duane Sand09604112012-05-24 17:40:21 -070068{
69 *ptr = value;
70 android_memory_barrier();
71}
72
Ben Cheng5206d592012-12-07 10:54:09 -080073extern ANDROID_ATOMIC_INLINE void
74android_atomic_release_store(int32_t value, volatile int32_t *ptr)
Duane Sand09604112012-05-24 17:40:21 -070075{
76 android_memory_barrier();
77 *ptr = value;
78}
79
Ben Cheng5206d592012-12-07 10:54:09 -080080extern ANDROID_ATOMIC_INLINE int
81android_atomic_cas(int32_t old_value, int32_t new_value, volatile int32_t *ptr)
Duane Sand09604112012-05-24 17:40:21 -070082{
83 int32_t prev, status;
84 do {
85 __asm__ __volatile__ (
86 " ll %[prev], (%[ptr])\n"
87 " li %[status], 1\n"
88 " bne %[prev], %[old], 9f\n"
89 " move %[status], %[new_value]\n"
90 " sc %[status], (%[ptr])\n"
91 "9:\n"
92 : [prev] "=&r" (prev), [status] "=&r" (status)
93 : [ptr] "r" (ptr), [old] "r" (old_value), [new_value] "r" (new_value)
94 );
95 } while (__builtin_expect(status == 0, 0));
96 return prev != old_value;
97}
98
Ben Cheng5206d592012-12-07 10:54:09 -080099extern ANDROID_ATOMIC_INLINE int
100android_atomic_acquire_cas(int32_t old_value,
101 int32_t new_value,
102 volatile int32_t *ptr)
Duane Sand09604112012-05-24 17:40:21 -0700103{
104 int status = android_atomic_cas(old_value, new_value, ptr);
105 android_memory_barrier();
106 return status;
107}
108
Ben Cheng5206d592012-12-07 10:54:09 -0800109extern ANDROID_ATOMIC_INLINE int
110android_atomic_release_cas(int32_t old_value,
111 int32_t new_value,
112 volatile int32_t *ptr)
Duane Sand09604112012-05-24 17:40:21 -0700113{
114 android_memory_barrier();
115 return android_atomic_cas(old_value, new_value, ptr);
116}
117
118
Ben Cheng5206d592012-12-07 10:54:09 -0800119extern ANDROID_ATOMIC_INLINE int32_t
120android_atomic_swap(int32_t new_value, volatile int32_t *ptr)
Duane Sand09604112012-05-24 17:40:21 -0700121{
122 int32_t prev, status;
123 do {
124 __asm__ __volatile__ (
125 " move %[status], %[new_value]\n"
126 " ll %[prev], (%[ptr])\n"
127 " sc %[status], (%[ptr])\n"
128 : [prev] "=&r" (prev), [status] "=&r" (status)
129 : [ptr] "r" (ptr), [new_value] "r" (new_value)
130 );
131 } while (__builtin_expect(status == 0, 0));
132 android_memory_barrier();
133 return prev;
134}
135
Ben Cheng5206d592012-12-07 10:54:09 -0800136extern ANDROID_ATOMIC_INLINE int32_t
137android_atomic_add(int32_t increment, volatile int32_t *ptr)
Duane Sand09604112012-05-24 17:40:21 -0700138{
139 int32_t prev, status;
140 android_memory_barrier();
141 do {
142 __asm__ __volatile__ (
143 " ll %[prev], (%[ptr])\n"
144 " addu %[status], %[prev], %[inc]\n"
145 " sc %[status], (%[ptr])\n"
146 : [status] "=&r" (status), [prev] "=&r" (prev)
147 : [ptr] "r" (ptr), [inc] "Ir" (increment)
148 );
149 } while (__builtin_expect(status == 0, 0));
150 return prev;
151}
152
Ben Cheng5206d592012-12-07 10:54:09 -0800153extern ANDROID_ATOMIC_INLINE int32_t
154android_atomic_inc(volatile int32_t *addr)
Duane Sand09604112012-05-24 17:40:21 -0700155{
156 return android_atomic_add(1, addr);
157}
158
Ben Cheng5206d592012-12-07 10:54:09 -0800159extern ANDROID_ATOMIC_INLINE int32_t
160android_atomic_dec(volatile int32_t *addr)
Duane Sand09604112012-05-24 17:40:21 -0700161{
162 return android_atomic_add(-1, addr);
163}
164
Ben Cheng5206d592012-12-07 10:54:09 -0800165extern ANDROID_ATOMIC_INLINE int32_t
166android_atomic_and(int32_t value, volatile int32_t *ptr)
Duane Sand09604112012-05-24 17:40:21 -0700167{
168 int32_t prev, status;
169 android_memory_barrier();
170 do {
171 __asm__ __volatile__ (
172 " ll %[prev], (%[ptr])\n"
173 " and %[status], %[prev], %[value]\n"
174 " sc %[status], (%[ptr])\n"
175 : [prev] "=&r" (prev), [status] "=&r" (status)
176 : [ptr] "r" (ptr), [value] "Ir" (value)
177 );
178 } while (__builtin_expect(status == 0, 0));
179 return prev;
180}
181
Ben Cheng5206d592012-12-07 10:54:09 -0800182extern ANDROID_ATOMIC_INLINE int32_t
183android_atomic_or(int32_t value, volatile int32_t *ptr)
Duane Sand09604112012-05-24 17:40:21 -0700184{
185 int32_t prev, status;
186 android_memory_barrier();
187 do {
188 __asm__ __volatile__ (
189 " ll %[prev], (%[ptr])\n"
190 " or %[status], %[prev], %[value]\n"
191 " sc %[status], (%[ptr])\n"
192 : [prev] "=&r" (prev), [status] "=&r" (status)
193 : [ptr] "r" (ptr), [value] "Ir" (value)
194 );
195 } while (__builtin_expect(status == 0, 0));
196 return prev;
197}
198
199#endif /* ANDROID_CUTILS_ATOMIC_MIPS_H */