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