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 #ifdef ISC_PLATFORM_USEGCCASM
00026
00027
00028
00029
00030 static __inline__ isc_int32_t
00031 isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
00032 isc_int32_t prev = val;
00033
00034 __asm__ volatile(
00035 #ifdef ISC_PLATFORM_USETHREADS
00036 "lock;"
00037 #endif
00038 "xadd %0, %1"
00039 :"=q"(prev)
00040 :"m"(*p), "0"(prev)
00041 :"memory", "cc");
00042
00043 return (prev);
00044 }
00045
00046 #ifdef ISC_PLATFORM_HAVEXADDQ
00047 static __inline__ isc_int64_t
00048 isc_atomic_xaddq(isc_int64_t *p, isc_int64_t val) {
00049 isc_int64_t prev = val;
00050
00051 __asm__ volatile(
00052 #ifdef ISC_PLATFORM_USETHREADS
00053 "lock;"
00054 #endif
00055 "xaddq %0, %1"
00056 :"=q"(prev)
00057 :"m"(*p), "0"(prev)
00058 :"memory", "cc");
00059
00060 return (prev);
00061 }
00062 #endif
00063
00064
00065
00066
00067 static __inline__ void
00068 isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
00069 __asm__ volatile(
00070 #ifdef ISC_PLATFORM_USETHREADS
00071
00072
00073
00074
00075 "lock;"
00076 #endif
00077
00078 "xchgl %1, %0"
00079 :
00080 : "r"(val), "m"(*p)
00081 : "memory");
00082 }
00083
00084
00085
00086
00087
00088
00089 static __inline__ isc_int32_t
00090 isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
00091 __asm__ volatile(
00092 #ifdef ISC_PLATFORM_USETHREADS
00093 "lock;"
00094 #endif
00095 "cmpxchgl %1, %2"
00096 : "=a"(cmpval)
00097 : "r"(val), "m"(*p), "a"(cmpval)
00098 : "memory");
00099
00100 return (cmpval);
00101 }
00102
00103 #elif defined(ISC_PLATFORM_USESTDASM)
00104
00105
00106
00107
00108
00109
00110
00111 #include <isc/util.h>
00112
00113 static isc_int32_t
00114 isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
00115 UNUSED(p);
00116 UNUSED(val);
00117
00118 __asm (
00119 "movl 8(%ebp), %ecx\n"
00120 "movl 12(%ebp), %edx\n"
00121 #ifdef ISC_PLATFORM_USETHREADS
00122 "lock;"
00123 #endif
00124 "xadd %edx, (%ecx)\n"
00125
00126
00127
00128
00129
00130
00131 "movl %edx, %eax"
00132 );
00133 }
00134
00135 static void
00136 isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
00137 UNUSED(p);
00138 UNUSED(val);
00139
00140 __asm (
00141 "movl 8(%ebp), %ecx\n"
00142 "movl 12(%ebp), %edx\n"
00143 #ifdef ISC_PLATFORM_USETHREADS
00144 "lock;"
00145 #endif
00146 "xchgl (%ecx), %edx\n"
00147 );
00148 }
00149
00150 static isc_int32_t
00151 isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
00152 UNUSED(p);
00153 UNUSED(cmpval);
00154 UNUSED(val);
00155
00156 __asm (
00157 "movl 8(%ebp), %ecx\n"
00158 "movl 12(%ebp), %eax\n"
00159 "movl 16(%ebp), %edx\n"
00160 #ifdef ISC_PLATFORM_USETHREADS
00161 "lock;"
00162 #endif
00163
00164
00165
00166
00167
00168 "cmpxchgl %edx, (%ecx)"
00169 );
00170 }
00171 #else
00172
00173 #error "unsupported compiler. disable atomic ops by --disable-atomic"
00174
00175 #endif
00176 #endif