BIND - Update BIND to 9.5.2
[dragonfly.git] / contrib / bind-9.5.2 / lib / isc / powerpc / include / isc / atomic.h
1 /*
2  * Copyright (C) 2005, 2007  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 2007/06/18 23:47:47 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_xadd(p, v) fetch_and_add(p, v)
50 #define isc_atomic_store(p, v) _clear_lock(p, v)
51
52 #ifdef __GNUC__
53 static inline int
54 #else
55 static int
56 #endif
57 isc_atomic_cmpxchg(atomic_p p, int old, int new) {
58         int orig = old;
59
60 #ifdef __GNUC__
61         asm("ics");
62 #else
63          __isync();
64 #endif
65         if (compare_and_swap(p, &orig, new))
66                 return (old);
67         return (orig);
68 }
69
70 #elif defined(ISC_PLATFORM_USEGCCASM) || defined(ISC_PLATFORM_USEMACASM)
71 static inline isc_int32_t
72 isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
73         isc_int32_t orig;
74
75         __asm__ volatile (
76 #ifdef ISC_PLATFORM_USEMACASM
77                 "1:"
78                 "lwarx r6, 0, %1\n"
79                 "mr %0, r6\n"
80                 "add r6, r6, %2\n"
81                 "stwcx. r6, 0, %1\n"
82                 "bne- 1b"
83 #else
84                 "1:"
85                 "lwarx 6, 0, %1\n"
86                 "mr %0, 6\n"
87                 "add 6, 6, %2\n"
88                 "stwcx. 6, 0, %1\n"
89                 "bne- 1b"
90 #endif
91                 : "=&r"(orig)
92                 : "r"(p), "r"(val)
93                 : "r6", "memory"
94                 );
95
96         return (orig);
97 }
98
99 static inline void
100 isc_atomic_store(void *p, isc_int32_t val) {
101         __asm__ volatile (
102 #ifdef ISC_PLATFORM_USEMACASM
103                 "1:"
104                 "lwarx r6, 0, %0\n"
105                 "lwz r6, %1\n"
106                 "stwcx. r6, 0, %0\n"
107                 "bne- 1b"
108 #else
109                 "1:"
110                 "lwarx 6, 0, %0\n"
111                 "lwz 6, %1\n"
112                 "stwcx. 6, 0, %0\n"
113                 "bne- 1b"
114 #endif
115                 :
116                 : "r"(p), "m"(val)
117                 : "r6", "memory"
118                 );
119 }
120
121 static inline isc_int32_t
122 isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
123         isc_int32_t orig;
124
125         __asm__ volatile (
126 #ifdef ISC_PLATFORM_USEMACASM
127                 "1:"
128                 "lwarx r6, 0, %1\n"
129                 "mr %0,r6\n"
130                 "cmpw r6, %2\n"
131                 "bne 2f\n"
132                 "mr r6, %3\n"
133                 "stwcx. r6, 0, %1\n"
134                 "bne- 1b\n"
135                 "2:"
136 #else
137                 "1:"
138                 "lwarx 6, 0, %1\n"
139                 "mr %0,6\n"
140                 "cmpw 6, %2\n"
141                 "bne 2f\n"
142                 "mr 6, %3\n"
143                 "stwcx. 6, 0, %1\n"
144                 "bne- 1b\n"
145                 "2:"
146 #endif
147                 : "=&r" (orig)
148                 : "r"(p), "r"(cmpval), "r"(val)
149                 : "r6", "memory"
150                 );
151
152         return (orig);
153 }
154
155 #else
156
157 #error "unsupported compiler.  disable atomic ops by --disable-atomic"
158
159 #endif
160 #endif /* ISC_ATOMIC_H */