]> CyberLeo.Net >> Repos - FreeBSD/releng/8.1.git/blob - contrib/bind9/lib/isc/powerpc/include/isc/atomic.h
Copy stable/8 to releng/8.1 in preparation for 8.1-RC1.
[FreeBSD/releng/8.1.git] / contrib / bind9 / lib / isc / powerpc / include / isc / atomic.h
1 /*
2  * Copyright (C) 2005, 2007, 2009  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: atomic.h,v 1.6.332.2 2009/10/14 23:47:14 tbox Exp $ */
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"
114 #else
115                 "1:"
116                 "lwarx 6, 0, %1\n"
117                 "mr %0, 6\n"
118                 "add 6, 6, %2\n"
119                 "stwcx. 6, 0, %1\n"
120                 "bne- 1b"
121 #endif
122                 : "=&r"(orig)
123                 : "r"(p), "r"(val)
124                 : "r6", "memory"
125                 );
126
127         return (orig);
128 }
129
130 static inline void
131 isc_atomic_store(void *p, isc_int32_t val) {
132         __asm__ volatile (
133 #ifdef ISC_PLATFORM_USEMACASM
134                 "1:"
135                 "lwarx r6, 0, %0\n"
136                 "lwz r6, %1\n"
137                 "stwcx. r6, 0, %0\n"
138                 "bne- 1b"
139 #else
140                 "1:"
141                 "lwarx 6, 0, %0\n"
142                 "lwz 6, %1\n"
143                 "stwcx. 6, 0, %0\n"
144                 "bne- 1b"
145 #endif
146                 :
147                 : "r"(p), "m"(val)
148                 : "r6", "memory"
149                 );
150 }
151
152 static inline isc_int32_t
153 isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
154         isc_int32_t orig;
155
156         __asm__ volatile (
157 #ifdef ISC_PLATFORM_USEMACASM
158                 "1:"
159                 "lwarx r6, 0, %1\n"
160                 "mr %0,r6\n"
161                 "cmpw r6, %2\n"
162                 "bne 2f\n"
163                 "mr r6, %3\n"
164                 "stwcx. r6, 0, %1\n"
165                 "bne- 1b\n"
166                 "2:"
167 #else
168                 "1:"
169                 "lwarx 6, 0, %1\n"
170                 "mr %0,6\n"
171                 "cmpw 6, %2\n"
172                 "bne 2f\n"
173                 "mr 6, %3\n"
174                 "stwcx. 6, 0, %1\n"
175                 "bne- 1b\n"
176                 "2:"
177 #endif
178                 : "=&r" (orig)
179                 : "r"(p), "r"(cmpval), "r"(val)
180                 : "r6", "memory"
181                 );
182
183         return (orig);
184 }
185
186 #else
187
188 #error "unsupported compiler.  disable atomic ops by --disable-atomic"
189
190 #endif
191 #endif /* ISC_ATOMIC_H */