]> git.pld-linux.org Git - packages/mysql.git/blob - mysql-atomic.patch
- expire-logs-days sample
[packages/mysql.git] / mysql-atomic.patch
1 ------------------------------------------------------------
2 revno: 2169.5.4
3 committer: serg@serg.mylan
4 timestamp: Wed 2006-05-31 18:44:09 +0200
5 message:
6   WL#2595 - atomic operations
7 === modified file 'configure.in'
8 --- configure.in        2006-05-26 11:17:09 +0000
9 +++ configure.in        2006-05-31 16:44:09 +0000
10 @@ -778,48 +778,6 @@
11  AC_SUBST(WRAPLIBS)
12  
13  if test "$TARGET_LINUX" = "true"; then
14 -  AC_MSG_CHECKING([for atomic operations])
15 -
16 -  AC_LANG_SAVE
17 -  AC_LANG_CPLUSPLUS
18 -
19 -  atom_ops=
20 -  AC_TRY_RUN([
21 -#include <asm/atomic.h>
22 -int main()
23 -{
24 -  atomic_t v;
25 -
26 -  atomic_set(&v, 23);
27 -  atomic_add(5, &v);
28 -  return atomic_read(&v) == 28 ? 0 : -1;
29 -}
30 -  ],
31 -  [AC_DEFINE([HAVE_ATOMIC_ADD], [1],
32 -             [atomic_add() from <asm/atomic.h> (Linux only)])
33 -   atom_ops="${atom_ops}atomic_add "],
34 -  )
35 -  AC_TRY_RUN([
36 -#include <asm/atomic.h>
37 -int main()
38 -{
39 -  atomic_t v;
40 -
41 -  atomic_set(&v, 23);
42 -  atomic_sub(5, &v);
43 -  return atomic_read(&v) == 18 ? 0 : -1;
44 -}
45 -  ],
46 -  [AC_DEFINE([HAVE_ATOMIC_SUB], [1],
47 -             [atomic_sub() from <asm/atomic.h> (Linux only)])
48 -   atom_ops="${atom_ops}atomic_sub "],
49 -  )
50 -
51 -  if test -z "$atom_ops"; then atom_ops="no"; fi
52 -  AC_MSG_RESULT($atom_ops)
53 -
54 -  AC_LANG_RESTORE
55 -
56    AC_ARG_WITH(pstack,
57      [  --with-pstack           Use the pstack backtrace library],
58      [ USE_PSTACK=$withval ],
59 @@ -1631,6 +1589,20 @@
60    fi
61  fi
62  
63 +AC_ARG_WITH([atomic-ops],
64 +           AC_HELP_STRING([--with-atomic-ops=rwlocks|smp|up],
65 +           [Implement atomic operations using pthread rwlocks or atomic CPU
66 +             instructions for multi-processor (default) or uniprocessor
67 +             configuration]), , [with_atomic_ops=smp])
68 +case "$with_atomic_ops" in
69 +  "up") AC_DEFINE([MY_ATOMIC_MODE_DUMMY], [1],
70 +                  [Assume single-CPU mode, no concurrency]) ;;
71 +  "rwlocks") AC_DEFINE([MY_ATOMIC_MODE_RWLOCKS], [1],
72 +                  [Use pthread rwlocks for atomic ops]) ;;
73 +  "smp") ;;
74 +   *) AC_MSG_ERROR(["$with_atomic_ops" is not a valid value for --with-atomic-ops]) ;;
75 +esac
76 +
77  # Force static compilation to avoid linking problems/get more speed
78  AC_ARG_WITH(mysqld-ldflags,
79      [  --with-mysqld-ldflags   Extra linking arguments for mysqld],
80
81 === added directory 'include/atomic'
82 === added file 'include/atomic/nolock.h'
83 --- include/atomic/nolock.h     1970-01-01 00:00:00 +0000
84 +++ include/atomic/nolock.h     2006-05-31 16:44:09 +0000
85 @@ -0,0 +1,169 @@
86 +/* Copyright (C) 2006 MySQL AB
87 +
88 +   This program is free software; you can redistribute it and/or modify
89 +   it under the terms of the GNU General Public License as published by
90 +   the Free Software Foundation; either version 2 of the License, or
91 +   (at your option) any later version.
92 +
93 +   This program is distributed in the hope that it will be useful,
94 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
95 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
96 +   GNU General Public License for more details.
97 +
98 +   You should have received a copy of the GNU General Public License
99 +   along with this program; if not, write to the Free Software
100 +   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
101 +
102 +#if defined(__i386__) || defined(_M_IX86)
103 +#ifdef MY_ATOMIC_MODE_DUMMY
104 +#  define LOCK ""
105 +#else
106 +#  define LOCK "lock "
107 +#endif
108 +#ifdef __GNUC__
109 +#include "x86-gcc.h"
110 +#elif defined(_MSC_VER)
111 +#include "x86-msvc.h"
112 +#endif
113 +#endif
114 +
115 +#ifdef make_atomic_add_body8
116 +
117 +#ifdef HAVE_INLINE
118 +
119 +#define make_atomic_add(S)                                     \
120 +static inline uint ## S _my_atomic_add ## S(                   \
121 +        my_atomic_ ## S ## _t *a, uint ## S v)                 \
122 +{                                                              \
123 +  make_atomic_add_body ## S;                                   \
124 +  return v;                                                    \
125 +}
126 +
127 +#define make_atomic_swap(S)                                    \
128 +static inline uint ## S _my_atomic_swap ## S(                  \
129 +        my_atomic_ ## S ## _t *a, uint ## S v)                 \
130 +{                                                              \
131 +  make_atomic_swap_body ## S;                                  \
132 +  return v;                                                    \
133 +}
134 +
135 +#define make_atomic_cas(S)                                     \
136 +static inline uint _my_atomic_cas ## S(my_atomic_ ## S ## _t *a,\
137 +        uint ## S *cmp, uint ## S set)                         \
138 +{                                                              \
139 +  uint8 ret;                                                   \
140 +  make_atomic_cas_body ## S;                                   \
141 +  return ret;                                                  \
142 +}
143 +
144 +#define make_atomic_load(S)                                    \
145 +static inline uint ## S _my_atomic_load ## S(                  \
146 +        my_atomic_ ## S ## _t *a)                              \
147 +{                                                              \
148 +  uint ## S ret;                                               \
149 +  make_atomic_load_body ## S;                                  \
150 +  return ret;                                                  \
151 +}
152 +
153 +#define make_atomic_store(S)                                   \
154 +static inline void _my_atomic_store ## S(                      \
155 +        my_atomic_ ## S ## _t *a, uint ## S v)                 \
156 +{                                                              \
157 +  make_atomic_store_body ## S;                                 \
158 +}
159 +
160 +#else /* no inline functions */
161 +
162 +#define make_atomic_add(S)                                     \
163 +extern uint ## S _my_atomic_add ## S(                          \
164 +        my_atomic_ ## S ## _t *a, uint ## S v);
165 +
166 +#define make_atomic_swap(S)                                    \
167 +extern uint ## S _my_atomic_swap ## S(                         \
168 +        my_atomic_ ## S ## _t *a, uint ## S v);
169 +
170 +#define make_atomic_cas(S)                                     \
171 +extern uint _my_atomic_cas ## S(my_atomic_ ## S ## _t *a,      \
172 +        uint ## S *cmp, uint ## S set);
173 +
174 +#define make_atomic_load(S)                                    \
175 +extern uint ## S _my_atomic_load ## S(                         \
176 +        my_atomic_ ## S ## _t *a);
177 +
178 +#define make_atomic_store(S)                                   \
179 +extern void _my_atomic_store ## S(                             \
180 +        my_atomic_ ## S ## _t *a, uint ## S v);
181 +
182 +#endif
183 +
184 +make_atomic_add( 8)
185 +make_atomic_add(16)
186 +make_atomic_add(32)
187 +
188 +make_atomic_cas( 8)
189 +make_atomic_cas(16)
190 +make_atomic_cas(32)
191 +
192 +make_atomic_load( 8)
193 +make_atomic_load(16)
194 +make_atomic_load(32)
195 +
196 +make_atomic_store( 8)
197 +make_atomic_store(16)
198 +make_atomic_store(32)
199 +
200 +make_atomic_swap( 8)
201 +make_atomic_swap(16)
202 +make_atomic_swap(32)
203 +
204 +#undef make_atomic_add_body8
205 +#undef make_atomic_cas_body8
206 +#undef make_atomic_load_body8
207 +#undef make_atomic_store_body8
208 +#undef make_atomic_swap_body8
209 +#undef make_atomic_add_body16
210 +#undef make_atomic_cas_body16
211 +#undef make_atomic_load_body16
212 +#undef make_atomic_store_body16
213 +#undef make_atomic_swap_body16
214 +#undef make_atomic_add_body32
215 +#undef make_atomic_cas_body32
216 +#undef make_atomic_load_body32
217 +#undef make_atomic_store_body32
218 +#undef make_atomic_swap_body32
219 +#undef make_atomic_add
220 +#undef make_atomic_cas
221 +#undef make_atomic_load
222 +#undef make_atomic_store
223 +#undef make_atomic_swap
224 +
225 +#define my_atomic_add8(a,v,L)  _my_atomic_add8(a,v)
226 +#define my_atomic_add16(a,v,L) _my_atomic_add16(a,v)
227 +#define my_atomic_add32(a,v,L) _my_atomic_add32(a,v)
228 +
229 +#define my_atomic_cas8(a,c,v,L)  _my_atomic_cas8(a,c,v)
230 +#define my_atomic_cas16(a,c,v,L) _my_atomic_cas16(a,c,v)
231 +#define my_atomic_cas32(a,c,v,L) _my_atomic_cas32(a,c,v)
232 +
233 +#define my_atomic_load8(a,L)  _my_atomic_load8(a)
234 +#define my_atomic_load16(a,L) _my_atomic_load16(a)
235 +#define my_atomic_load32(a,L) _my_atomic_load32(a)
236 +
237 +#define my_atomic_store8(a,v,L)  _my_atomic_store8(a,v)
238 +#define my_atomic_store16(a,v,L) _my_atomic_store16(a,v)
239 +#define my_atomic_store32(a,v,L) _my_atomic_store32(a,v)
240 +
241 +#define my_atomic_swap8(a,v,L)  _my_atomic_swap8(a,v)
242 +#define my_atomic_swap16(a,v,L) _my_atomic_swap16(a,v)
243 +#define my_atomic_swap32(a,v,L) _my_atomic_swap32(a,v)
244 +
245 +#define my_atomic_rwlock_t typedef int
246 +#define my_atomic_rwlock_destroy(name)
247 +#define my_atomic_rwlock_init(name)
248 +#define my_atomic_rwlock_rdlock(name)
249 +#define my_atomic_rwlock_wrlock(name)
250 +#define my_atomic_rwlock_rdunlock(name)
251 +#define my_atomic_rwlock_wrunlock(name)
252 +
253 +#endif
254 +
255
256 === added file 'include/atomic/rwlock.h'
257 --- include/atomic/rwlock.h     1970-01-01 00:00:00 +0000
258 +++ include/atomic/rwlock.h     2006-05-31 16:44:09 +0000
259 @@ -0,0 +1,161 @@
260 +/* Copyright (C) 2006 MySQL AB
261 +
262 +   This program is free software; you can redistribute it and/or modify
263 +   it under the terms of the GNU General Public License as published by
264 +   the Free Software Foundation; either version 2 of the License, or
265 +   (at your option) any later version.
266 +
267 +   This program is distributed in the hope that it will be useful,
268 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
269 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
270 +   GNU General Public License for more details.
271 +
272 +   You should have received a copy of the GNU General Public License
273 +   along with this program; if not, write to the Free Software
274 +   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
275 +
276 +typedef struct {pthread_rwlock_t rw;} my_atomic_rwlock_t;
277 +
278 +#ifdef MY_ATOMIC_EXTRA_DEBUG
279 +#define CHECK_RW if (rw) if (a->rw) assert(rw == a->rw); else a->rw=rw;
280 +#else
281 +#define CHECK_RW
282 +#endif
283 +
284 +#ifdef MY_ATOMIC_MODE_DUMMY
285 +/*
286 +  the following can never be enabled by ./configure, one need to put #define in
287 +  a source to trigger the following warning. The resulting code will be broken,
288 +  it only makes sense to do it to see now test_atomic detects broken
289 +  implementations (another way is to run a UP build on an SMP box).
290 +*/
291 +#warning MY_ATOMIC_MODE_DUMMY and MY_ATOMIC_MODE_RWLOCKS are incompatible
292 +#define my_atomic_rwlock_destroy(name)
293 +#define my_atomic_rwlock_init(name)
294 +#define my_atomic_rwlock_rdlock(name)
295 +#define my_atomic_rwlock_wrlock(name)
296 +#define my_atomic_rwlock_rdunlock(name)
297 +#define my_atomic_rwlock_wrunlock(name)
298 +#else
299 +#define my_atomic_rwlock_destroy(name)     pthread_rwlock_destroy(& (name)->rw)
300 +#define my_atomic_rwlock_init(name)        pthread_rwlock_init(& (name)->rw, 0)
301 +#define my_atomic_rwlock_rdlock(name)      pthread_rwlock_rdlock(& (name)->rw)
302 +#define my_atomic_rwlock_wrlock(name)      pthread_rwlock_wrlock(& (name)->rw)
303 +#define my_atomic_rwlock_rdunlock(name)    pthread_rwlock_unlock(& (name)->rw)
304 +#define my_atomic_rwlock_wrunlock(name)    pthread_rwlock_unlock(& (name)->rw)
305 +#endif
306 +
307 +#ifdef HAVE_INLINE
308 +
309 +#define make_atomic_add(S)                                             \
310 +static inline uint ## S my_atomic_add ## S(                            \
311 +        my_atomic_ ## S ## _t *a, uint ## S v, my_atomic_rwlock_t *rw) \
312 +{                                                                      \
313 +  uint ## S ret;                                                       \
314 +  CHECK_RW;                                                            \
315 +  if (rw) my_atomic_rwlock_wrlock(rw);                                 \
316 +  ret= a->val;                                                         \
317 +  a->val+= v;                                                          \
318 +  if (rw) my_atomic_rwlock_wrunlock(rw);                               \
319 +  return ret;                                                          \
320 +}
321 +
322 +#define make_atomic_swap(S)                                            \
323 +static inline uint ## S my_atomic_swap ## S(                           \
324 +        my_atomic_ ## S ## _t *a, uint ## S v, my_atomic_rwlock_t *rw) \
325 +{                                                                      \
326 +  uint ## S ret;                                                       \
327 +  CHECK_RW;                                                            \
328 +  if (rw) my_atomic_rwlock_wrlock(rw);                                 \
329 +  ret= a->val;                                                         \
330 +  a->val= v;                                                           \
331 +  if (rw) my_atomic_rwlock_wrunlock(rw);                               \
332 +  return ret;                                                          \
333 +}
334 +
335 +#define make_atomic_cas(S)                                             \
336 +static inline uint my_atomic_cas ## S(my_atomic_ ## S ## _t *a,                \
337 +        uint ## S *cmp, uint ## S set, my_atomic_rwlock_t *rw)         \
338 +{                                                                      \
339 +  uint ret;                                                            \
340 +  CHECK_RW;                                                            \
341 +  if (rw) my_atomic_rwlock_wrlock(rw);                                 \
342 +  if (ret= (a->val == *cmp)) a->val= set; else *cmp=a->val;            \
343 +  if (rw) my_atomic_rwlock_wrunlock(rw);                               \
344 +  return ret;                                                          \
345 +}
346 +
347 +#define make_atomic_load(S)                                            \
348 +static inline uint ## S my_atomic_load ## S(                           \
349 +        my_atomic_ ## S ## _t *a, my_atomic_rwlock_t *rw)              \
350 +{                                                                      \
351 +  uint ## S ret;                                                       \
352 +  CHECK_RW;                                                            \
353 +  if (rw) my_atomic_rwlock_wrlock(rw);                                 \
354 +  ret= a->val;                                                         \
355 +  if (rw) my_atomic_rwlock_wrunlock(rw);                               \
356 +  return ret;                                                          \
357 +}
358 +
359 +#define make_atomic_store(S)                                           \
360 +static inline void my_atomic_store ## S(                               \
361 +        my_atomic_ ## S ## _t *a, uint ## S v, my_atomic_rwlock_t *rw) \
362 +{                                                                      \
363 +  CHECK_RW;                                                            \
364 +  if (rw) my_atomic_rwlock_rdlock(rw);                                 \
365 +  (a)->val= (v);                                                       \
366 +  if (rw) my_atomic_rwlock_rdunlock(rw);                               \
367 +}
368 +
369 +#else /* no inline functions */
370 +
371 +#define make_atomic_add(S)                                             \
372 +extern uint ## S my_atomic_add ## S(                                   \
373 +        my_atomic_ ## S ## _t *a, uint ## S v, my_atomic_rwlock_t *rw);
374 +
375 +#define make_atomic_swap(S)                                            \
376 +extern uint ## S my_atomic_swap ## S(                                  \
377 +        my_atomic_ ## S ## _t *a, uint ## S v, my_atomic_rwlock_t *rw);
378 +
379 +#define make_atomic_cas(S)                                             \
380 +extern uint my_atomic_cas ## S(my_atomic_ ## S ## _t *a,               \
381 +        uint ## S *cmp, uint ## S set, my_atomic_rwlock_t *rw);
382 +
383 +#define make_atomic_load(S)                                            \
384 +extern uint ## S my_atomic_load ## S(                                  \
385 +        my_atomic_ ## S ## _t *a, my_atomic_rwlock_t *rw);
386 +
387 +#define make_atomic_store(S)                                           \
388 +extern void my_atomic_store ## S(                                      \
389 +        my_atomic_ ## S ## _t *a, uint ## S v, my_atomic_rwlock_t *rw);
390 +
391 +#endif
392 +
393 +make_atomic_add( 8)
394 +make_atomic_add(16)
395 +make_atomic_add(32)
396 +make_atomic_add(64)
397 +make_atomic_cas( 8)
398 +make_atomic_cas(16)
399 +make_atomic_cas(32)
400 +make_atomic_cas(64)
401 +make_atomic_load( 8)
402 +make_atomic_load(16)
403 +make_atomic_load(32)
404 +make_atomic_load(64)
405 +make_atomic_store( 8)
406 +make_atomic_store(16)
407 +make_atomic_store(32)
408 +make_atomic_store(64)
409 +make_atomic_swap( 8)
410 +make_atomic_swap(16)
411 +make_atomic_swap(32)
412 +make_atomic_swap(64)
413 +#undef make_atomic_add
414 +#undef make_atomic_cas
415 +#undef make_atomic_load
416 +#undef make_atomic_store
417 +#undef make_atomic_swap
418 +#undef CHECK_RW
419 +
420 +
421
422 === added file 'include/atomic/x86-gcc.h'
423 --- include/atomic/x86-gcc.h    1970-01-01 00:00:00 +0000
424 +++ include/atomic/x86-gcc.h    2006-05-31 16:44:09 +0000
425 @@ -0,0 +1,56 @@
426 +/* Copyright (C) 2006 MySQL AB
427 +
428 +   This program is free software; you can redistribute it and/or modify
429 +   it under the terms of the GNU General Public License as published by
430 +   the Free Software Foundation; either version 2 of the License, or
431 +   (at your option) any later version.
432 +
433 +   This program is distributed in the hope that it will be useful,
434 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
435 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
436 +   GNU General Public License for more details.
437 +
438 +   You should have received a copy of the GNU General Public License
439 +   along with this program; if not, write to the Free Software
440 +   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
441 +
442 +/*
443 +  XXX 64-bit atomic operations can be implemented using
444 +  cmpxchg8b, if necessary
445 +*/
446 +
447 +#define make_atomic_add_body8                                  \
448 +  asm volatile (LOCK "xadd %0, %1;" : "+r" (v) , "+m" (a->val))
449 +#define make_atomic_swap_body8                                 \
450 +  asm volatile ("xchg %0, %1;" : "+r" (v) , "+m" (a->val))
451 +#define make_atomic_cas_body8                                  \
452 +  asm volatile (LOCK "cmpxchg %3, %0; setz %2;"                        \
453 +               : "+m" (a->val), "+a" (*cmp), "=q" (ret): "r" (set))
454 +
455 +#ifdef MY_ATOMIC_MODE_DUMMY
456 +#define make_atomic_load_body8   ret=a->val
457 +#define make_atomic_store_body8         a->val=v
458 +#else
459 +/*
460 +  Actually 32-bit reads/writes are always atomic on x86
461 +  But we add LOCK here anyway to force memory barriers
462 +*/
463 +#define make_atomic_load_body8                                 \
464 +  ret=0;                                                       \
465 +  asm volatile (LOCK "cmpxchg %2, %0"                          \
466 +               : "+m" (a->val), "+a" (ret): "r" (ret))
467 +#define make_atomic_store_body8                                        \
468 +  asm volatile ("xchg %0, %1;" : "+m" (a->val) : "r" (v))
469 +#endif
470 +
471 +#define make_atomic_add_body16   make_atomic_add_body8
472 +#define make_atomic_add_body32   make_atomic_add_body8
473 +#define make_atomic_cas_body16   make_atomic_cas_body8
474 +#define make_atomic_cas_body32   make_atomic_cas_body8
475 +#define make_atomic_load_body16  make_atomic_load_body8
476 +#define make_atomic_load_body32  make_atomic_load_body8
477 +#define make_atomic_store_body16 make_atomic_store_body8
478 +#define make_atomic_store_body32 make_atomic_store_body8
479 +#define make_atomic_swap_body16  make_atomic_swap_body8
480 +#define make_atomic_swap_body32  make_atomic_swap_body8
481 +
482
483 === added file 'include/atomic/x86-msvc.h'
484 --- include/atomic/x86-msvc.h   1970-01-01 00:00:00 +0000
485 +++ include/atomic/x86-msvc.h   2006-05-31 16:44:09 +0000
486 @@ -0,0 +1,85 @@
487 +/* Copyright (C) 2006 MySQL AB
488 +
489 +   This program is free software; you can redistribute it and/or modify
490 +   it under the terms of the GNU General Public License as published by
491 +   the Free Software Foundation; either version 2 of the License, or
492 +   (at your option) any later version.
493 +
494 +   This program is distributed in the hope that it will be useful,
495 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
496 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
497 +   GNU General Public License for more details.
498 +
499 +   You should have received a copy of the GNU General Public License
500 +   along with this program; if not, write to the Free Software
501 +   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
502 +
503 +/*
504 +  XXX 64-bit atomic operations can be implemented using
505 +  cmpxchg8b, if necessary
506 +*/
507 +
508 +// Would it be better to use intrinsics ?
509 +// (InterlockedCompareExchange, InterlockedCompareExchange16
510 +// InterlockedExchangeAdd, InterlockedExchange)
511 +
512 +#define make_atomic_add_body(REG)                              \
513 +  _asm {                                                       \
514 +    _asm mov   REG, v                                          \
515 +    _asm LOCK  xadd a->val, REG                                        \
516 +    _asm movzx v, REG                                          \
517 +  }
518 +#define make_atomic_cas_body(AREG,REG2)                                \
519 +  _asm {                                                       \
520 +    _asm mov    AREG, *cmp                                     \
521 +    _asm mov    REG2, set                                      \
522 +    _asm LOCK cmpxchg a->val, REG2                             \
523 +    _asm mov    *cmp, AREG                                     \
524 +    _asm setz   al                                             \
525 +    _asm movzx  ret, al                                                \
526 +  }
527 +#define make_atomic_swap_body(REG)                             \
528 +  _asm {                                                       \
529 +    _asm mov    REG, v                                         \
530 +    _asm xchg   a->val, REG                                    \
531 +    _asm mov    v, REG                                         \
532 +  }
533 +
534 +#ifdef MY_ATOMIC_MODE_DUMMY
535 +#define make_atomic_load_body(AREG,REG)   ret=a->val
536 +#define make_atomic_store_body(REG)      a->val=v
537 +#else
538 +/*
539 +  Actually 32-bit reads/writes are always atomic on x86
540 +  But we add LOCK here anyway to force memory barriers
541 +*/
542 +#define make_atomic_load_body(AREG,REG2)                       \
543 +  _asm {                                                       \
544 +    _asm mov    AREG, 0                                                \
545 +    _asm mov    REG2, AREG                                     \
546 +    _asm LOCK cmpxchg a->val, REG2                             \
547 +    _asm mov    ret, AREG                                      \
548 +  }
549 +#define make_atomic_store_body(REG)                            \
550 +  _asm {                                                       \
551 +    _asm mov    REG, v                                         \
552 +    _asm xchg   a->val, REG                                    \
553 +  }
554 +#endif
555 +
556 +#define make_atomic_add_body8   make_atomic_add_body(al)
557 +#define make_atomic_add_body16   make_atomic_add_body(ax)
558 +#define make_atomic_add_body32   make_atomic_add_body(eax)
559 +#define make_atomic_cas_body8    make_atomic_cas_body(al, bl)
560 +#define make_atomic_cas_body16   make_atomic_cas_body(ax, bx)
561 +#define make_atomic_cas_body32   make_atomic_cas_body(eax, ebx)
562 +#define make_atomic_load_body8    make_atomic_load_body(al, bl)
563 +#define make_atomic_load_body16   make_atomic_load_body(ax, bx)
564 +#define make_atomic_load_body32   make_atomic_load_body(eax, ebx)
565 +#define make_atomic_store_body8  make_atomic_store_body(al)
566 +#define make_atomic_store_body16 make_atomic_store_body(ax)
567 +#define make_atomic_store_body32 make_atomic_store_body(eax)
568 +#define make_atomic_swap_body8   make_atomic_swap_body(al)
569 +#define make_atomic_swap_body16  make_atomic_swap_body(ax)
570 +#define make_atomic_swap_body32  make_atomic_swap_body(eax)
571 +
572
573 === added file 'include/my_atomic.h'
574 --- include/my_atomic.h 1970-01-01 00:00:00 +0000
575 +++ include/my_atomic.h 2006-05-31 16:44:09 +0000
576 @@ -0,0 +1,46 @@
577 +/* Copyright (C) 2006 MySQL AB
578 +
579 +   This program is free software; you can redistribute it and/or modify
580 +   it under the terms of the GNU General Public License as published by
581 +   the Free Software Foundation; either version 2 of the License, or
582 +   (at your option) any later version.
583 +
584 +   This program is distributed in the hope that it will be useful,
585 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
586 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
587 +   GNU General Public License for more details.
588 +
589 +   You should have received a copy of the GNU General Public License
590 +   along with this program; if not, write to the Free Software
591 +   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
592 +
593 +#ifndef atomic_rwlock_init
594 +
595 +#ifdef MY_ATOMIC_EXTRA_DEBUG
596 +#ifndef MY_ATOMIC_MODE_RWLOCKS
597 +#error MY_ATOMIC_EXTRA_DEBUG can be only used with MY_ATOMIC_MODE_RWLOCKS
598 +#endif
599 +#define LOCK_PTR void *rw;
600 +#else
601 +#define LOCK_PTR
602 +#endif
603 +
604 +typedef volatile struct {uint8   val; LOCK_PTR} my_atomic_8_t;
605 +typedef volatile struct {uint16  val; LOCK_PTR} my_atomic_16_t;
606 +typedef volatile struct {uint32  val; LOCK_PTR} my_atomic_32_t;
607 +typedef volatile struct {uint64  val; LOCK_PTR} my_atomic_64_t;
608 +
609 +#ifndef MY_ATOMIC_MODE_RWLOCKS
610 +#include "atomic/nolock.h"
611 +#endif
612 +
613 +#ifndef my_atomic_rwlock_init
614 +#include "atomic/rwlock.h"
615 +#endif
616 +
617 +#define MY_ATOMIC_OK       0
618 +#define MY_ATOMIC_NOT_1CPU 1
619 +extern int my_atomic_initialize();
620 +
621 +#endif
622 +
623
624 === modified file 'include/my_global.h'
625 --- include/my_global.h 2006-05-02 09:36:05 +0000
626 +++ include/my_global.h 2006-05-31 16:44:09 +0000
627 @@ -181,6 +181,17 @@
628  #define HOT_DATA
629  #endif
630  
631 +/*
632 +  now let's figure out if inline functions are supported
633 +  autoconf defines 'inline' to be empty, if not
634 +*/
635 +#define inline_test_1(X)        X ## 1
636 +#define inline_test_2(X)        inline_test_1(X)
637 +#if inline_test_2(inline) != 1
638 +#define HAVE_INLINE
639 +#endif
640 +#undef inline_test_2
641 +#undef inline_test_1
642  
643  /*
644    The following macros are used to control inlining a bit more than
645 @@ -889,6 +900,8 @@
646  typedef long           longlong;
647  #endif
648  #endif
649 +typedef longlong int64;
650 +typedef ulonglong uint64;
651  
652  #if defined(NO_CLIENT_LONG_LONG)
653  typedef unsigned long my_ulonglong;
654
655 === modified file 'mysys/Makefile.am'
656 --- mysys/Makefile.am   2006-05-12 08:51:07 +0000
657 +++ mysys/Makefile.am   2006-05-31 16:44:09 +0000
658 @@ -19,7 +19,7 @@
659  INCLUDES =             @ZLIB_INCLUDES@ -I$(top_builddir)/include \
660                         -I$(top_srcdir)/include -I$(srcdir)
661  pkglib_LIBRARIES =     libmysys.a
662 -LDADD =                        libmysys.a ../dbug/libdbug.a \
663 +LDADD =                        libmysys.a \
664                         ../strings/libmystrings.a
665  noinst_HEADERS =       mysys_priv.h my_static.h \
666                         my_os2cond.c my_os2dirsrch.c my_os2dirsrch.h \
667 @@ -33,7 +33,7 @@
668                         mf_iocache.c mf_iocache2.c mf_cache.c mf_tempfile.c \
669                         mf_tempdir.c my_lock.c mf_brkhant.c my_alarm.c \
670                         my_malloc.c my_realloc.c my_once.c mulalloc.c \
671 -                       my_alloc.c safemalloc.c my_new.cc \
672 +                       my_alloc.c safemalloc.c my_new.cc my_atomic.c my_getncpus.c \
673                         my_fopen.c my_fstream.c my_getsystime.c \
674                         my_error.c errors.c my_div.c my_messnc.c \
675                         mf_format.c mf_same.c mf_dirname.c mf_fn_ext.c \
676 @@ -64,7 +63,7 @@
677  # testhash_DEPENDENCIES=       $(LIBRARIES)
678  # test_charset_DEPENDENCIES=   $(LIBRARIES)
679  # charset2html_DEPENDENCIES=   $(LIBRARIES)
680 -EXTRA_PROGRAMS =       
681 +noinst_PROGRAMS=       test_atomic$(EXEEXT)
682  DEFS =                 -DDEFAULT_BASEDIR=\"$(prefix)\" \
683                         -DDATADIR="\"$(MYSQLDATAdir)\"" \
684                         -DDEFAULT_CHARSET_HOME="\"$(MYSQLBASEdir)\"" \
685
686 === added file 'mysys/my_atomic.c'
687 --- mysys/my_atomic.c   1970-01-01 00:00:00 +0000
688 +++ mysys/my_atomic.c   2006-05-31 16:44:09 +0000
689 @@ -0,0 +1,46 @@
690 +/* Copyright (C) 2006 MySQL AB
691 +
692 +   This program is free software; you can redistribute it and/or modify
693 +   it under the terms of the GNU General Public License as published by
694 +   the Free Software Foundation; either version 2 of the License, or
695 +   (at your option) any later version.
696 +
697 +   This program is distributed in the hope that it will be useful,
698 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
699 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
700 +   GNU General Public License for more details.
701 +
702 +   You should have received a copy of the GNU General Public License
703 +   along with this program; if not, write to the Free Software
704 +   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
705 +
706 +#include <my_global.h>
707 +#include <my_pthread.h>
708 +
709 +#ifndef HAVE_INLINE
710 +/*
711 +  the following will cause all inline functions to be instantiated
712 +*/
713 +#define HAVE_INLINE
714 +#define static extern
715 +#endif
716 +
717 +#include <my_atomic.h>
718 +
719 +/*
720 +  checks that the current build of atomic ops
721 +  can run on this machine
722 +
723 +  RETURN
724 +    ATOMIC_xxx values, see my_atomic.h
725 +*/
726 +int my_atomic_initialize()
727 +{
728 +  /* currently the only thing worth checking is SMP/UP issue */
729 +#ifdef MY_ATOMIC_MODE_DUMMY
730 +  return my_getncpus() == 1 ? MY_ATOMIC_OK : MY_ATOMIC_NOT_1CPU;
731 +#else
732 +  return MY_ATOMIC_OK;
733 +#endif
734 +}
735 +
736
737 === added file 'mysys/my_getncpus.c'
738 --- mysys/my_getncpus.c 1970-01-01 00:00:00 +0000
739 +++ mysys/my_getncpus.c 2006-05-31 16:44:09 +0000
740 @@ -0,0 +1,40 @@
741 +/* Copyright (C) 2006 MySQL AB
742 +
743 +   This program is free software; you can redistribute it and/or modify
744 +   it under the terms of the GNU General Public License as published by
745 +   the Free Software Foundation; either version 2 of the License, or
746 +   (at your option) any later version.
747 +
748 +   This program is distributed in the hope that it will be useful,
749 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
750 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
751 +   GNU General Public License for more details.
752 +
753 +   You should have received a copy of the GNU General Public License
754 +   along with this program; if not, write to the Free Software
755 +   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
756 +
757 +/* get the number of (online) CPUs */
758 +
759 +#include "mysys_priv.h"
760 +#include <unistd.h>
761 +
762 +static int ncpus=0;
763 +
764 +#ifdef _SC_NPROCESSORS_ONLN
765 +int my_getncpus()
766 +{
767 +  if (!ncpus)
768 +    ncpus= sysconf(_SC_NPROCESSORS_ONLN);
769 +  return ncpus;
770 +}
771 +
772 +#else
773 +/* unknown */
774 +int my_getncpus()
775 +{
776 +  return 2;
777 +}
778 +
779 +#endif
780 +
781
782 === added file 'mysys/test_atomic.c'
783 --- mysys/test_atomic.c 1970-01-01 00:00:00 +0000
784 +++ mysys/test_atomic.c 2006-05-31 16:44:09 +0000
785 @@ -0,0 +1,133 @@
786 +#include <my_global.h>
787 +#include <my_sys.h>
788 +#include <my_atomic.h>
789 +
790 +my_atomic_32_t a32,b32,c32;
791 +my_atomic_rwlock_t rwl;
792 +
793 +pthread_attr_t thr_attr;
794 +pthread_mutex_t mutex;
795 +pthread_cond_t cond;
796 +int N;
797 +
798 +/* add and sub a random number in a loop. Must get 0 at the end */
799 +pthread_handler_t test_atomic_add_handler(void *arg)
800 +{
801 +  int    m=*(int *)arg;
802 +  int32 x;
803 +  for (x=((int)(&m)); m ; m--)
804 +  {
805 +    x=x*m+0x87654321;
806 +    my_atomic_add32(&a32, x,  &rwl);
807 +    my_atomic_add32(&a32, -x, &rwl);
808 +  }
809 +  pthread_mutex_lock(&mutex);
810 +  N--;
811 +  if (!N) pthread_cond_signal(&cond);
812 +  pthread_mutex_unlock(&mutex);
813 +}
814 +
815 +/*
816 +  1. generate thread number 0..N-1 from b32
817 +  2. add it to a32
818 +  3. swap thread numbers in c32
819 +  4. (optionally) one more swap to avoid 0 as a result
820 +  5. subtract result from a32
821 +  must get 0 in a32 at the end
822 +*/
823 +pthread_handler_t test_atomic_swap_handler(void *arg)
824 +{
825 +  int    m=*(int *)arg;
826 +  uint32  x=my_atomic_add32(&b32, 1, &rwl);
827 +
828 +  my_atomic_add32(&a32, x, &rwl);
829 +
830 +  for (; m ; m--)
831 +    x=my_atomic_swap32(&c32, x,&rwl);
832 +
833 +  if (!x)
834 +    x=my_atomic_swap32(&c32, x,&rwl);
835 +
836 +  my_atomic_add32(&a32, -x, &rwl);
837 +
838 +  pthread_mutex_lock(&mutex);
839 +  N--;
840 +  if (!N) pthread_cond_signal(&cond);
841 +  pthread_mutex_unlock(&mutex);
842 +}
843 +
844 +/*
845 +  same as test_atomic_add_handler, but my_atomic_add32 is emulated with
846 +  (slower) my_atomic_cas32
847 +*/
848 +pthread_handler_t test_atomic_cas_handler(void *arg)
849 +{
850 +  int    m=*(int *)arg;
851 +  int32 x;
852 +  for (x=((int)(&m)); m ; m--)
853 +  {
854 +    uint32 y=my_atomic_load32(&a32, &rwl);
855 +    x=x*m+0x87654321;
856 +    while (!my_atomic_cas32(&a32, &y, y+x, &rwl)) ;
857 +    while (!my_atomic_cas32(&a32, &y, y-x, &rwl)) ;
858 +  }
859 +  pthread_mutex_lock(&mutex);
860 +  N--;
861 +  if (!N) pthread_cond_signal(&cond);
862 +  pthread_mutex_unlock(&mutex);
863 +}
864 +
865 +void test_atomic(const char *test, pthread_handler handler, int n, int m)
866 +{
867 +  pthread_t t;
868 +  ulonglong now=my_getsystime();
869 +
870 +  my_atomic_store32(&a32, 0, &rwl);
871 +  my_atomic_store32(&b32, 0, &rwl);
872 +  my_atomic_store32(&c32, 0, &rwl);
873 +
874 +  printf("Testing %s with %d threads, %d iterations... ", test, n, m);
875 +  for (N=n ; n ; n--)
876 +    pthread_create(&t, &thr_attr, handler, &m);
877 +
878 +  pthread_mutex_lock(&mutex);
879 +  while (N)
880 +    pthread_cond_wait(&cond, &mutex);
881 +  pthread_mutex_unlock(&mutex);
882 +  now=my_getsystime()-now;
883 +  printf("got %lu in %g secs\n", my_atomic_load32(&a32, &rwl),
884 +         ((double)now)/1e7);
885 +}
886 +
887 +int main()
888 +{
889 +  int err;
890 +
891 +#ifdef _IONBF
892 +  setvbuf(stdout, 0, _IONBF, 0);
893 +#endif
894 +  printf("N CPUs: %d\n", my_getncpus());
895 +
896 +  if ((err= my_atomic_initialize()))
897 +  {
898 +    printf("my_atomic_initialize() failed. Error=%d\n", err);
899 +    return 1;
900 +  }
901 +
902 +  pthread_attr_init(&thr_attr);
903 +  pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED);
904 +  pthread_mutex_init(&mutex, 0);
905 +  pthread_cond_init(&cond, 0);
906 +  my_atomic_rwlock_init(&rwl);
907 +
908 +  test_atomic("my_atomic_add32", test_atomic_add_handler, 100,1000000);
909 +  test_atomic("my_atomic_swap32", test_atomic_swap_handler, 100,1000000);
910 +  test_atomic("my_atomic_cas32", test_atomic_cas_handler, 100,1000000);
911 +
912 +  pthread_mutex_destroy(&mutex);
913 +  pthread_cond_destroy(&cond);
914 +  pthread_attr_destroy(&thr_attr);
915 +  my_atomic_rwlock_destroy(&rwl);
916 +  return 0;
917 +}
918 +
919 ------------------------------------------------------------
920 revno: 2476.749.1
921 committer: davi@mysql.com/endora.local
922 timestamp: Fri 2008-01-11 20:34:36 -0200
923 message:
924   Bug#33728 Atomic builtins
925   
926   Use compiler provided atomic builtins as a 'backend' for
927   MySQL's atomic primitives. The builtins are available on
928   a handful of platforms and compilers.
929 diff:
930 === modified file 'configure.in'
931 --- configure.in        2007-12-14 17:03:44 +0000
932 +++ configure.in        2008-01-11 22:34:36 +0000
933 @@ -1688,6 +1688,30 @@
934     *) AC_MSG_ERROR(["$with_atomic_ops" is not a valid value for --with-atomic-ops]) ;;
935  esac
936  
937 +AC_CACHE_CHECK([whether the compiler provides atomic builtins],
938 +               [mysql_cv_gcc_atomic_builtins], [AC_TRY_RUN([
939 +  int main()
940 +  {
941 +    int foo= -10; int bar= 10;
942 +    if (!__sync_fetch_and_add(&foo, bar) || foo)
943 +      return -1;
944 +    bar= __sync_lock_test_and_set(&foo, bar);
945 +    if (bar || foo != 10)
946 +      return -1;
947 +    bar= __sync_val_compare_and_swap(&bar, foo, 15);
948 +    if (bar)
949 +      return -1;
950 +    return 0;
951 +  }
952 +], [mysql_cv_gcc_atomic_builtins=yes],
953 +   [mysql_cv_gcc_atomic_builtins=no],
954 +   [mysql_cv_gcc_atomic_builtins=no])])
955 +
956 +if test "x$mysql_cv_gcc_atomic_builtins" = xyes; then
957 +  AC_DEFINE(HAVE_ATOMIC_BUILTINS, 1,
958 +            [Define to 1 if compiler provides atomic builtins.])
959 +fi
960 +
961  # Force static compilation to avoid linking problems/get more speed
962  AC_ARG_WITH(mysqld-ldflags,
963      [  --with-mysqld-ldflags   Extra linking arguments for mysqld],
964
965 === added file 'include/atomic/gcc_builtins.h'
966 --- include/atomic/gcc_builtins.h       1970-01-01 00:00:00 +0000
967 +++ include/atomic/gcc_builtins.h       2008-01-11 22:34:36 +0000
968 @@ -0,0 +1,33 @@
969 +/* Copyright (C) 2008 MySQL AB
970 +
971 +   This program is free software; you can redistribute it and/or modify
972 +   it under the terms of the GNU General Public License as published by
973 +   the Free Software Foundation; version 2 of the License.
974 +
975 +   This program is distributed in the hope that it will be useful,
976 +   but WITHOUT ANY WARRANTY; without even the implied warranty of
977 +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
978 +   GNU General Public License for more details.
979 +
980 +   You should have received a copy of the GNU General Public License
981 +   along with this program; if not, write to the Free Software
982 +   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
983 +
984 +#define make_atomic_add_body(S)                     \
985 +  v= __sync_fetch_and_add(a, v);
986 +#define make_atomic_swap_body(S)                    \
987 +  v= __sync_lock_test_and_set(a, v);
988 +#define make_atomic_cas_body(S)                     \
989 +  int ## S sav;                                     \
990 +  sav= __sync_val_compare_and_swap(a, *cmp, set);   \
991 +  if (!(ret= (sav == *cmp))) *cmp= sav;
992 +
993 +#ifdef MY_ATOMIC_MODE_DUMMY
994 +#define make_atomic_load_body(S)   ret= *a
995 +#define make_atomic_store_body(S)  *a= v
996 +#else
997 +#define make_atomic_load_body(S)                    \
998 +  ret= __sync_fetch_and_or(a, 0);
999 +#define make_atomic_store_body(S)                   \
1000 +  (void) __sync_lock_test_and_set(a, v);
1001 +#endif
1002
1003 === modified file 'include/atomic/nolock.h'
1004 --- include/atomic/nolock.h     2006-12-27 01:23:51 +0000
1005 +++ include/atomic/nolock.h     2008-01-11 22:34:36 +0000
1006 @@ -14,13 +14,15 @@
1007     along with this program; if not, write to the Free Software
1008     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
1009  
1010 -#if defined(__i386__) || defined(_M_IX86)
1011 +#if defined(__i386__) || defined(_M_IX86) || defined(HAVE_ATOMIC_BUILTINS)
1012  #ifdef MY_ATOMIC_MODE_DUMMY
1013  #  define LOCK ""
1014  #else
1015  #  define LOCK "lock "
1016  #endif
1017 -#ifdef __GNUC__
1018 +#ifdef HAVE_ATOMIC_BUILTINS
1019 +#include "gcc_builtins.h"
1020 +#elif __GNUC__
1021  #include "x86-gcc.h"
1022  #elif defined(_MSC_VER)
1023  #include "x86-msvc.h"
This page took 0.180184 seconds and 3 git commands to generate.