]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - contrib/bind9/lib/isc/powerpc/include/isc/atomic.h
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / contrib / bind9 / lib / isc / powerpc / include / isc / atomic.h
1 /*
2  * Copyright (C) 2005, 2007, 2009, 2011, 2012  Internet Systems Consortium, Inc. ("ISC")
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14  * PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 /* $Id$ */
18
19 #ifndef ISC_ATOMIC_H
20 #define ISC_ATOMIC_H 1
21
22 #include <isc/platform.h>
23 #include <isc/types.h>
24
25 /*!\file
26  * static inline isc_int32_t
27  * isc_atomic_xadd(isc_int32_t *p, isc_int32_t val);
28  *
29  * This routine atomically increments the value stored in 'p' by 'val', and
30  * returns the previous value.
31  *
32  * static inline void
33  * isc_atomic_store(void *p, isc_int32_t val);
34  *
35  * This routine atomically stores the value 'val' in 'p'.
36  *
37  * static inline isc_int32_t
38  * isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val);
39  *
40  * This routine atomically replaces the value in 'p' with 'val', if the
41  * original value is equal to 'cmpval'.  The original value is returned in any
42  * case.
43  */
44
45 #if defined(_AIX)
46
47 #include <sys/atomic_op.h>
48
49 #define isc_atomic_store(p, v) _clear_lock(p, v)
50
51 #ifdef __GNUC__
52 static inline isc_int32_t
53 #else
54 static isc_int32_t
55 #endif
56 isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
57         int ret;
58
59 #ifdef __GNUC__
60         asm("ics");
61 #else
62          __isync();
63 #endif
64
65         ret = fetch_and_add((atomic_p)p, (int)val);
66
67 #ifdef __GNUC__
68         asm("ics");
69 #else
70          __isync();
71 #endif
72
73          return (ret);
74 }
75
76 #ifdef __GNUC__
77 static inline int
78 #else
79 static int
80 #endif
81 isc_atomic_cmpxchg(atomic_p p, int old, int new) {
82         int orig = old;
83
84 #ifdef __GNUC__
85         asm("ics");
86 #else
87          __isync();
88 #endif
89         if (compare_and_swap(p, &orig, new))
90                 orig = old;
91
92 #ifdef __GNUC__
93         asm("ics");
94 #else
95          __isync();
96 #endif
97
98         return (orig);
99 }
100
101 #elif defined(ISC_PLATFORM_USEGCCASM) || defined(ISC_PLATFORM_USEMACASM)
102 static inline isc_int32_t
103 isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
104         isc_int32_t orig;
105
106         __asm__ volatile (
107 #ifdef ISC_PLATFORM_USEMACASM
108                 "1:"
109                 "lwarx r6, 0, %1\n"
110                 "mr %0, r6\n"
111                 "add r6, r6, %2\n"
112                 "stwcx. r6, 0, %1\n"
113                 "bne- 1b\n"
114                 "sync"
115 #else
116                 "1:"
117                 "lwarx 6, 0, %1\n"
118                 "mr %0, 6\n"
119                 "add 6, 6, %2\n"
120                 "stwcx. 6, 0, %1\n"
121                 "bne- 1b\n"
122                 "sync"
123 #endif
124                 : "=&r"(orig)
125                 : "r"(p), "r"(val)
126                 : "r6", "memory"
127                 );
128
129         return (orig);
130 }
131
132 static inline void
133 isc_atomic_store(void *p, isc_int32_t val) {
134         __asm__ volatile (
135 #ifdef ISC_PLATFORM_USEMACASM
136                 "1:"
137                 "lwarx r6, 0, %0\n"
138                 "lwz r6, %1\n"
139                 "stwcx. r6, 0, %0\n"
140                 "bne- 1b\n"
141                 "sync"
142 #else
143                 "1:"
144                 "lwarx 6, 0, %0\n"
145                 "lwz 6, %1\n"
146                 "stwcx. 6, 0, %0\n"
147                 "bne- 1b\n"
148                 "sync"
149 #endif
150                 :
151                 : "r"(p), "m"(val)
152                 : "r6", "memory"
153                 );
154 }
155
156 static inline isc_int32_t
157 isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
158         isc_int32_t orig;
159
160         __asm__ volatile (
161 #ifdef ISC_PLATFORM_USEMACASM
162                 "1:"
163                 "lwarx r6, 0, %1\n"
164                 "mr %0,r6\n"
165                 "cmpw r6, %2\n"
166                 "bne 2f\n"
167                 "mr r6, %3\n"
168                 "stwcx. r6, 0, %1\n"
169                 "bne- 1b\n"
170                 "2:\n"
171                 "sync"
172 #else
173                 "1:"
174                 "lwarx 6, 0, %1\n"
175                 "mr %0,6\n"
176                 "cmpw 6, %2\n"
177                 "bne 2f\n"
178                 "mr 6, %3\n"
179                 "stwcx. 6, 0, %1\n"
180                 "bne- 1b\n"
181                 "2:\n"
182                 "sync"
183 #endif
184                 : "=&r" (orig)
185                 : "r"(p), "r"(cmpval), "r"(val)
186                 : "r6", "memory"
187                 );
188
189         return (orig);
190 }
191
192 #else
193
194 #error "unsupported compiler.  disable atomic ops by --disable-atomic"
195
196 #endif
197 #endif /* ISC_ATOMIC_H */