blob: 1ed833de3d8922f4ffbe029a190b280d76945d7f [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
Ben Cheng5206d592012-12-07 10:54:09 -0800120android_atomic_add(int32_t increment, volatile int32_t *ptr)
Duane Sand09604112012-05-24 17:40:21 -0700121{
122 int32_t prev, status;
123 android_memory_barrier();
124 do {
125 __asm__ __volatile__ (
126 " ll %[prev], (%[ptr])\n"
127 " addu %[status], %[prev], %[inc]\n"
128 " sc %[status], (%[ptr])\n"
129 : [status] "=&r" (status), [prev] "=&r" (prev)
130 : [ptr] "r" (ptr), [inc] "Ir" (increment)
131 );
132 } while (__builtin_expect(status == 0, 0));
133 return prev;
134}
135
Ben Cheng5206d592012-12-07 10:54:09 -0800136extern ANDROID_ATOMIC_INLINE int32_t
137android_atomic_inc(volatile int32_t *addr)
Duane Sand09604112012-05-24 17:40:21 -0700138{
139 return android_atomic_add(1, addr);
140}
141
Ben Cheng5206d592012-12-07 10:54:09 -0800142extern ANDROID_ATOMIC_INLINE int32_t
143android_atomic_dec(volatile int32_t *addr)
Duane Sand09604112012-05-24 17:40:21 -0700144{
145 return android_atomic_add(-1, addr);
146}
147
Ben Cheng5206d592012-12-07 10:54:09 -0800148extern ANDROID_ATOMIC_INLINE int32_t
149android_atomic_and(int32_t value, volatile int32_t *ptr)
Duane Sand09604112012-05-24 17:40:21 -0700150{
151 int32_t prev, status;
152 android_memory_barrier();
153 do {
154 __asm__ __volatile__ (
155 " ll %[prev], (%[ptr])\n"
156 " and %[status], %[prev], %[value]\n"
157 " sc %[status], (%[ptr])\n"
158 : [prev] "=&r" (prev), [status] "=&r" (status)
159 : [ptr] "r" (ptr), [value] "Ir" (value)
160 );
161 } while (__builtin_expect(status == 0, 0));
162 return prev;
163}
164
Ben Cheng5206d592012-12-07 10:54:09 -0800165extern ANDROID_ATOMIC_INLINE int32_t
166android_atomic_or(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 " or %[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
182#endif /* ANDROID_CUTILS_ATOMIC_MIPS_H */