00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef ISC_ATOMIC_H
00020 #define ISC_ATOMIC_H 1
00021
00022 #include <isc/platform.h>
00023 #include <isc/types.h>
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #if defined(_AIX)
00046
00047 #include <sys/atomic_op.h>
00048
00049 #define isc_atomic_store(p, v) _clear_lock(p, v)
00050
00051 #ifdef __GNUC__
00052 static inline isc_int32_t
00053 #else
00054 static isc_int32_t
00055 #endif
00056 isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
00057 int ret;
00058
00059 #ifdef __GNUC__
00060 asm("ics");
00061 #else
00062 __isync();
00063 #endif
00064
00065 ret = fetch_and_add((atomic_p)p, (int)val);
00066
00067 #ifdef __GNUC__
00068 asm("ics");
00069 #else
00070 __isync();
00071 #endif
00072
00073 return (ret);
00074 }
00075
00076 #ifdef __GNUC__
00077 static inline int
00078 #else
00079 static int
00080 #endif
00081 isc_atomic_cmpxchg(atomic_p p, int old, int new) {
00082 int orig = old;
00083
00084 #ifdef __GNUC__
00085 asm("ics");
00086 #else
00087 __isync();
00088 #endif
00089 if (compare_and_swap(p, &orig, new))
00090 orig = old;
00091
00092 #ifdef __GNUC__
00093 asm("ics");
00094 #else
00095 __isync();
00096 #endif
00097
00098 return (orig);
00099 }
00100
00101 #elif defined(ISC_PLATFORM_USEGCCASM) || defined(ISC_PLATFORM_USEMACASM)
00102 static inline isc_int32_t
00103 isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
00104 isc_int32_t orig;
00105
00106 __asm__ volatile (
00107 #ifdef ISC_PLATFORM_USEMACASM
00108 "1:"
00109 "lwarx r6, 0, %1\n"
00110 "mr %0, r6\n"
00111 "add r6, r6, %2\n"
00112 "stwcx. r6, 0, %1\n"
00113 "bne- 1b\n"
00114 "sync"
00115 #else
00116 "1:"
00117 "lwarx 6, 0, %1\n"
00118 "mr %0, 6\n"
00119 "add 6, 6, %2\n"
00120 "stwcx. 6, 0, %1\n"
00121 "bne- 1b\n"
00122 "sync"
00123 #endif
00124 : "=&r"(orig)
00125 : "r"(p), "r"(val)
00126 : "r6", "memory"
00127 );
00128
00129 return (orig);
00130 }
00131
00132 static inline void
00133 isc_atomic_store(void *p, isc_int32_t val) {
00134 __asm__ volatile (
00135 #ifdef ISC_PLATFORM_USEMACASM
00136 "1:"
00137 "lwarx r6, 0, %0\n"
00138 "lwz r6, %1\n"
00139 "stwcx. r6, 0, %0\n"
00140 "bne- 1b\n"
00141 "sync"
00142 #else
00143 "1:"
00144 "lwarx 6, 0, %0\n"
00145 "lwz 6, %1\n"
00146 "stwcx. 6, 0, %0\n"
00147 "bne- 1b\n"
00148 "sync"
00149 #endif
00150 :
00151 : "r"(p), "m"(val)
00152 : "r6", "memory"
00153 );
00154 }
00155
00156 static inline isc_int32_t
00157 isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
00158 isc_int32_t orig;
00159
00160 __asm__ volatile (
00161 #ifdef ISC_PLATFORM_USEMACASM
00162 "1:"
00163 "lwarx r6, 0, %1\n"
00164 "mr %0,r6\n"
00165 "cmpw r6, %2\n"
00166 "bne 2f\n"
00167 "mr r6, %3\n"
00168 "stwcx. r6, 0, %1\n"
00169 "bne- 1b\n"
00170 "2:\n"
00171 "sync"
00172 #else
00173 "1:"
00174 "lwarx 6, 0, %1\n"
00175 "mr %0,6\n"
00176 "cmpw 6, %2\n"
00177 "bne 2f\n"
00178 "mr 6, %3\n"
00179 "stwcx. 6, 0, %1\n"
00180 "bne- 1b\n"
00181 "2:\n"
00182 "sync"
00183 #endif
00184 : "=&r" (orig)
00185 : "r"(p), "r"(cmpval), "r"(val)
00186 : "r6", "memory"
00187 );
00188
00189 return (orig);
00190 }
00191
00192 #else
00193
00194 #error "unsupported compiler. disable atomic ops by --disable-atomic"
00195
00196 #endif
00197 #endif