MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
mt-asm.h
1 /* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
2 
3  This program is free software; you can redistribute it and/or modify
4  it under the terms of the GNU General Public License as published by
5  the Free Software Foundation; version 2 of the License.
6 
7  This program is distributed in the hope that it will be useful,
8  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  GNU General Public License for more details.
11 
12  You should have received a copy of the GNU General Public License
13  along with this program; if not, write to the Free Software
14  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
15 
20 #ifndef NDB_MT_ASM_H
21 #define NDB_MT_ASM_H
22 
23 #if defined(__GNUC__)
24 /********************
25  * GCC
26  *******************/
27 #if defined(__x86_64__) || defined (__i386__)
28 
29 #define NDB_HAVE_MB
30 #define NDB_HAVE_RMB
31 #define NDB_HAVE_WMB
32 #define NDB_HAVE_READ_BARRIER_DEPENDS
33 #define NDB_HAVE_XCNG
34 #define NDB_HAVE_CPU_PAUSE
35 
36 /* Memory barriers, these definitions are for x64_64. */
37 #define mb() asm volatile("mfence":::"memory")
38 /* According to Intel docs, it does not reorder loads. */
39 /* #define rmb() asm volatile("lfence":::"memory") */
40 #define rmb() asm volatile("" ::: "memory")
41 #define wmb() asm volatile("" ::: "memory")
42 #define read_barrier_depends() do {} while(0)
43 
44 static
45 inline
46 int
47 xcng(volatile unsigned * addr, int val)
48 {
49  asm volatile ("xchg %0, %1;" : "+r" (val) , "+m" (*addr));
50  return val;
51 }
52 
53 static
54 inline
55 void
56 cpu_pause()
57 {
58  asm volatile ("rep;nop");
59 }
60 
61 #elif defined(__sparc__)
62 
63 #define NDB_HAVE_MB
64 #define NDB_HAVE_RMB
65 #define NDB_HAVE_WMB
66 #define NDB_HAVE_READ_BARRIER_DEPENDS
67 
68 #define mb() asm volatile("membar #LoadLoad | #LoadStore | #StoreLoad | #StoreStore":::"memory")
69 #define rmb() asm volatile("membar #LoadLoad" ::: "memory")
70 #define wmb() asm volatile("membar #StoreStore" ::: "memory")
71 #define read_barrier_depends() do {} while(0)
72 
73 #ifdef HAVE_ATOMIC_H
74 #include <atomic.h>
75 #endif
76 
77 #ifdef HAVE_ATOMIC_SWAP_32
78 static inline
79 int
80 xcng(volatile unsigned * addr, int val)
81 {
82  asm volatile("membar #StoreLoad | #LoadLoad");
83  int ret = atomic_swap_32(addr, val);
84  asm volatile("membar #StoreLoad | #StoreStore");
85  return ret;
86 }
87 #define cpu_pause()
88 #define NDB_HAVE_XCNG
89 #define NDB_HAVE_CPU_PAUSE
90 #else
91 /* link error if used incorrectly (i.e wo/ having NDB_HAVE_XCNG) */
92 extern int xcng(volatile unsigned * addr, int val);
93 extern void cpu_pause();
94 #endif
95 
96 #else
97 #define NDB_NO_ASM "Unsupported architecture (gcc)"
98 #endif
99 
100 #elif defined(__sun)
101 /********************
102  * SUN STUDIO
103  *******************/
104 
109 #if defined(__x86_64__)
110 #define NDB_HAVE_MB
111 #define NDB_HAVE_RMB
112 #define NDB_HAVE_WMB
113 #define NDB_HAVE_READ_BARRIER_DEPENDS
114 
115 #define mb() asm ("mfence")
116 /* According to Intel docs, it does not reorder loads. */
117 /* #define rmb() asm ("lfence") */
118 #define rmb() asm ("")
119 #define wmb() asm ("")
120 #define read_barrier_depends() do {} while(0)
121 
122 #elif defined(__sparc)
123 #define NDB_HAVE_MB
124 #define NDB_HAVE_RMB
125 #define NDB_HAVE_WMB
126 #define NDB_HAVE_READ_BARRIER_DEPENDS
127 
128 #define mb() asm ("membar #LoadLoad | #LoadStore | #StoreLoad | #StoreStore")
129 #define rmb() asm ("membar #LoadLoad")
130 #define wmb() asm ("membar #StoreStore")
131 #define read_barrier_depends() do {} while(0)
132 #else
133 #define NDB_NO_ASM "Unsupported architecture (sun studio)"
134 #endif
135 
136 #if defined(__x86_64__) || defined(__sparc)
137 
141 #ifdef HAVE_ATOMIC_H
142 #include <atomic.h>
143 #endif
144 
145 #ifdef HAVE_ATOMIC_SWAP_32
146 #define NDB_HAVE_XCNG
147 #define NDB_HAVE_CPU_PAUSE
148 #if defined(__sparc)
149 static inline
150 int
151 xcng(volatile unsigned * addr, int val)
152 {
153  asm ("membar #StoreLoad | #LoadLoad");
154  int ret = atomic_swap_32(addr, val);
155  asm ("membar #StoreLoad | #StoreStore");
156  return ret;
157 }
158 #define cpu_pause()
159 #elif defined(__x86_64__)
160 static inline
161 int
162 xcng(volatile unsigned * addr, int val)
163 {
168  int ret = atomic_swap_32(addr, val);
169  return ret;
170 }
171 static
172 inline
173 void
174 cpu_pause()
175 {
176  asm volatile ("rep;nop");
177 }
178 #endif
179 #else
180 /* link error if used incorrectly (i.e wo/ having NDB_HAVE_XCNG) */
181 extern int xcng(volatile unsigned * addr, int val);
182 extern void cpu_pause();
183 #endif
184 #endif
185 #elif defined (_MSC_VER)
186 
187 #define NDB_HAVE_MB
188 #define NDB_HAVE_RMB
189 #define NDB_HAVE_WMB
190 #define NDB_HAVE_READ_BARRIER_DEPENDS
191 
192 #include <windows.h>
193 #define mb() MemoryBarrier()
194 #define read_barrier_depends() do {} while(0)
195 #ifdef _DEBUG
196 #define rmb() do {} while(0)
197 #define wmb() do {} while(0)
198 #else
199 #include <intrin.h>
200 /********************
201  * Microsoft
202  *******************/
203 /* Using instrinsics available on all architectures */
204 #define rmb() _ReadBarrier()
205 #define wmb() _WriteBarrier()
206 #endif
207 
208 #define NDB_HAVE_XCNG
209 #define NDB_HAVE_CPU_PAUSE
210 
211 static inline
212 int
213 xcng(volatile unsigned * addr, int val)
214 {
215  return InterlockedExchange((volatile LONG*)addr, val);
216 }
217 
218 static
219 inline
220 void
221 cpu_pause()
222 {
223  YieldProcessor();
224 }
225 #else
226 #define NDB_NO_ASM "Unsupported compiler"
227 #endif
228 
229 #endif