diff options
author | Davi Arnaut <Davi.Arnaut@Sun.COM> | 2010-07-05 09:00:39 -0300 |
---|---|---|
committer | Davi Arnaut <Davi.Arnaut@Sun.COM> | 2010-07-05 09:00:39 -0300 |
commit | cd41cd953d9d76b4b9c13fd745856d5023f12d71 (patch) | |
tree | fc5079ee6d597ddaff51838ebd4e62da399f94cd | |
parent | 279b3adfc78ae93f976eb8797f41c64f3bc6b4bb (diff) | |
download | mariadb-git-cd41cd953d9d76b4b9c13fd745856d5023f12d71.tar.gz |
Bug#22320: my_atomic-t unit test fails
The atomic operations implementation on 5.1 has a few problems,
which might cause tests to abort randomly. Since no code in 5.1
uses atomic operations, simply remove the code.
-rw-r--r-- | include/Makefile.am | 6 | ||||
-rw-r--r-- | include/atomic/gcc_builtins.h | 33 | ||||
-rw-r--r-- | include/atomic/nolock.h | 44 | ||||
-rw-r--r-- | include/atomic/rwlock.h | 48 | ||||
-rw-r--r-- | include/atomic/x86-gcc.h | 58 | ||||
-rw-r--r-- | include/atomic/x86-msvc.h | 96 | ||||
-rw-r--r-- | include/my_atomic.h | 142 | ||||
-rw-r--r-- | include/my_pthread.h | 2 | ||||
-rw-r--r-- | mysys/Makefile.am | 3 | ||||
-rw-r--r-- | mysys/my_atomic.c | 45 | ||||
-rw-r--r-- | storage/ibmdb2i/db2i_file.h | 1 | ||||
-rw-r--r-- | unittest/mysys/Makefile.am | 7 | ||||
-rw-r--r-- | unittest/mysys/my_atomic-t.c | 205 |
13 files changed, 4 insertions, 686 deletions
diff --git a/include/Makefile.am b/include/Makefile.am index 64f73af8606..130517a405e 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -36,10 +36,8 @@ noinst_HEADERS = config-win.h config-netware.h my_bit.h \ my_nosys.h my_alarm.h queues.h rijndael.h sha1.h \ my_aes.h my_tree.h my_trie.h hash.h thr_alarm.h \ thr_lock.h t_ctype.h violite.h my_md5.h base64.h \ - my_handler.h my_time.h \ - my_vle.h my_user.h my_atomic.h atomic/nolock.h \ - atomic/rwlock.h atomic/x86-gcc.h atomic/x86-msvc.h \ - atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h + my_handler.h my_time.h my_vle.h my_user.h \ + my_libwrap.h my_stacktrace.h EXTRA_DIST = mysql.h.pp mysql/plugin.h.pp diff --git a/include/atomic/gcc_builtins.h b/include/atomic/gcc_builtins.h deleted file mode 100644 index 509701b30a5..00000000000 --- a/include/atomic/gcc_builtins.h +++ /dev/null @@ -1,33 +0,0 @@ -/* Copyright (C) 2008 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#define make_atomic_add_body(S) \ - v= __sync_fetch_and_add(a, v); -#define make_atomic_swap_body(S) \ - v= __sync_lock_test_and_set(a, v); -#define make_atomic_cas_body(S) \ - int ## S sav; \ - sav= __sync_val_compare_and_swap(a, *cmp, set); \ - if (!(ret= (sav == *cmp))) *cmp= sav; - -#ifdef MY_ATOMIC_MODE_DUMMY -#define make_atomic_load_body(S) ret= *a -#define make_atomic_store_body(S) *a= v -#else -#define make_atomic_load_body(S) \ - ret= __sync_fetch_and_or(a, 0); -#define make_atomic_store_body(S) \ - (void) __sync_lock_test_and_set(a, v); -#endif diff --git a/include/atomic/nolock.h b/include/atomic/nolock.h deleted file mode 100644 index 10ac17884b6..00000000000 --- a/include/atomic/nolock.h +++ /dev/null @@ -1,44 +0,0 @@ -/* Copyright (C) 2006 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#if defined(__i386__) || defined(_M_IX86) || defined(HAVE_GCC_ATOMIC_BUILTINS) - -#ifdef MY_ATOMIC_MODE_DUMMY -# define LOCK "" -#else -# define LOCK "lock" -#endif - -#ifdef HAVE_GCC_ATOMIC_BUILTINS -#include "gcc_builtins.h" -#elif __GNUC__ -#include "x86-gcc.h" -#elif defined(_MSC_VER) -#include "x86-msvc.h" -#endif -#endif - -#ifdef make_atomic_cas_body - -typedef struct { } my_atomic_rwlock_t; -#define my_atomic_rwlock_destroy(name) -#define my_atomic_rwlock_init(name) -#define my_atomic_rwlock_rdlock(name) -#define my_atomic_rwlock_wrlock(name) -#define my_atomic_rwlock_rdunlock(name) -#define my_atomic_rwlock_wrunlock(name) - -#endif - diff --git a/include/atomic/rwlock.h b/include/atomic/rwlock.h deleted file mode 100644 index 18b77e93d80..00000000000 --- a/include/atomic/rwlock.h +++ /dev/null @@ -1,48 +0,0 @@ -/* Copyright (C) 2006 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -typedef struct {pthread_rwlock_t rw;} my_atomic_rwlock_t; - -#ifdef MY_ATOMIC_MODE_DUMMY -/* - the following can never be enabled by ./configure, one need to put #define in - a source to trigger the following warning. The resulting code will be broken, - it only makes sense to do it to see now test_atomic detects broken - implementations (another way is to run a UP build on an SMP box). -*/ -#warning MY_ATOMIC_MODE_DUMMY and MY_ATOMIC_MODE_RWLOCKS are incompatible -#define my_atomic_rwlock_destroy(name) -#define my_atomic_rwlock_init(name) -#define my_atomic_rwlock_rdlock(name) -#define my_atomic_rwlock_wrlock(name) -#define my_atomic_rwlock_rdunlock(name) -#define my_atomic_rwlock_wrunlock(name) -#define MY_ATOMIC_MODE "dummy (non-atomic)" -#else -#define my_atomic_rwlock_destroy(name) pthread_rwlock_destroy(& (name)->rw) -#define my_atomic_rwlock_init(name) pthread_rwlock_init(& (name)->rw, 0) -#define my_atomic_rwlock_rdlock(name) pthread_rwlock_rdlock(& (name)->rw) -#define my_atomic_rwlock_wrlock(name) pthread_rwlock_wrlock(& (name)->rw) -#define my_atomic_rwlock_rdunlock(name) pthread_rwlock_unlock(& (name)->rw) -#define my_atomic_rwlock_wrunlock(name) pthread_rwlock_unlock(& (name)->rw) -#define MY_ATOMIC_MODE "rwlocks" -#endif - -#define make_atomic_add_body(S) int ## S sav; sav= *a; *a+= v; v=sav; -#define make_atomic_swap_body(S) int ## S sav; sav= *a; *a= v; v=sav; -#define make_atomic_cas_body(S) if ((ret= (*a == *cmp))) *a= set; else *cmp=*a; -#define make_atomic_load_body(S) ret= *a; -#define make_atomic_store_body(S) *a= v; - diff --git a/include/atomic/x86-gcc.h b/include/atomic/x86-gcc.h deleted file mode 100644 index d79dadbf05e..00000000000 --- a/include/atomic/x86-gcc.h +++ /dev/null @@ -1,58 +0,0 @@ -/* Copyright (C) 2006 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - XXX 64-bit atomic operations can be implemented using - cmpxchg8b, if necessary. Though I've heard that not all 64-bit - architectures support double-word (128-bit) cas. -*/ - -#ifdef MY_ATOMIC_NO_XADD -#define MY_ATOMIC_MODE "gcc-x86" LOCK "-no-xadd" -#else -#define MY_ATOMIC_MODE "gcc-x86" LOCK -#endif - -/* fix -ansi errors while maintaining readability */ -#ifndef asm -#define asm __asm__ -#endif - -#ifndef MY_ATOMIC_NO_XADD -#define make_atomic_add_body(S) \ - asm volatile (LOCK "; xadd %0, %1;" : "+r" (v) , "+m" (*a)) -#endif -#define make_atomic_swap_body(S) \ - asm volatile ("; xchg %0, %1;" : "+r" (v) , "+m" (*a)) -#define make_atomic_cas_body(S) \ - asm volatile (LOCK "; cmpxchg %3, %0; setz %2;" \ - : "+m" (*a), "+a" (*cmp), "=q" (ret): "r" (set)) - -#ifdef MY_ATOMIC_MODE_DUMMY -#define make_atomic_load_body(S) ret=*a -#define make_atomic_store_body(S) *a=v -#else -/* - Actually 32-bit reads/writes are always atomic on x86 - But we add LOCK here anyway to force memory barriers -*/ -#define make_atomic_load_body(S) \ - ret=0; \ - asm volatile (LOCK "; cmpxchg %2, %0" \ - : "+m" (*a), "+a" (ret): "r" (ret)) -#define make_atomic_store_body(S) \ - asm volatile ("; xchg %0, %1;" : "+m" (*a) : "r" (v)) -#endif - diff --git a/include/atomic/x86-msvc.h b/include/atomic/x86-msvc.h deleted file mode 100644 index c4885bb8451..00000000000 --- a/include/atomic/x86-msvc.h +++ /dev/null @@ -1,96 +0,0 @@ -/* Copyright (C) 2006 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/* - XXX 64-bit atomic operations can be implemented using - cmpxchg8b, if necessary -*/ - -// Would it be better to use intrinsics ? -// (InterlockedCompareExchange, InterlockedCompareExchange16 -// InterlockedExchangeAdd, InterlockedExchange) - -#ifndef _atomic_h_cleanup_ -#define _atomic_h_cleanup_ "atomic/x86-msvc.h" - -#define MY_ATOMIC_MODE "msvc-x86" LOCK - -#define make_atomic_add_body(S) \ - _asm { \ - _asm mov reg_ ## S, v \ - _asm LOCK xadd *a, reg_ ## S \ - _asm movzx v, reg_ ## S \ - } -#define make_atomic_cas_body(S) \ - _asm { \ - _asm mov areg_ ## S, *cmp \ - _asm mov reg2_ ## S, set \ - _asm LOCK cmpxchg *a, reg2_ ## S \ - _asm mov *cmp, areg_ ## S \ - _asm setz al \ - _asm movzx ret, al \ - } -#define make_atomic_swap_body(S) \ - _asm { \ - _asm mov reg_ ## S, v \ - _asm xchg *a, reg_ ## S \ - _asm mov v, reg_ ## S \ - } - -#ifdef MY_ATOMIC_MODE_DUMMY -#define make_atomic_load_body(S) ret=*a -#define make_atomic_store_body(S) *a=v -#else -/* - Actually 32-bit reads/writes are always atomic on x86 - But we add LOCK here anyway to force memory barriers -*/ -#define make_atomic_load_body(S) \ - _asm { \ - _asm mov areg_ ## S, 0 \ - _asm mov reg2_ ## S, areg_ ## S \ - _asm LOCK cmpxchg *a, reg2_ ## S \ - _asm mov ret, areg_ ## S \ - } -#define make_atomic_store_body(S) \ - _asm { \ - _asm mov reg_ ## S, v \ - _asm xchg *a, reg_ ## S \ - } -#endif - -#define reg_8 al -#define reg_16 ax -#define reg_32 eax -#define areg_8 al -#define areg_16 ax -#define areg_32 eax -#define reg2_8 bl -#define reg2_16 bx -#define reg2_32 ebx - -#else /* cleanup */ - -#undef reg_8 -#undef reg_16 -#undef reg_32 -#undef areg_8 -#undef areg_16 -#undef areg_32 -#undef reg2_8 -#undef reg2_16 -#undef reg2_32 -#endif - diff --git a/include/my_atomic.h b/include/my_atomic.h deleted file mode 100644 index ed439e5fe87..00000000000 --- a/include/my_atomic.h +++ /dev/null @@ -1,142 +0,0 @@ -/* Copyright (C) 2006 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#ifndef my_atomic_rwlock_init - -#define intptr void * - -#ifndef MY_ATOMIC_MODE_RWLOCKS -#include "atomic/nolock.h" -#endif - -#ifndef make_atomic_cas_body -#include "atomic/rwlock.h" -#endif - -#ifndef make_atomic_add_body -#define make_atomic_add_body(S) \ - int ## S tmp=*a; \ - while (!my_atomic_cas ## S(a, &tmp, tmp+v)); \ - v=tmp; -#endif - -#ifdef HAVE_INLINE - -#define make_atomic_add(S) \ -STATIC_INLINE int ## S my_atomic_add ## S( \ - int ## S volatile *a, int ## S v) \ -{ \ - make_atomic_add_body(S); \ - return v; \ -} - -#define make_atomic_swap(S) \ -STATIC_INLINE int ## S my_atomic_swap ## S( \ - int ## S volatile *a, int ## S v) \ -{ \ - make_atomic_swap_body(S); \ - return v; \ -} - -#define make_atomic_cas(S) \ -STATIC_INLINE int my_atomic_cas ## S(int ## S volatile *a, \ - int ## S *cmp, int ## S set) \ -{ \ - int8 ret; \ - make_atomic_cas_body(S); \ - return ret; \ -} - -#define make_atomic_load(S) \ -STATIC_INLINE int ## S my_atomic_load ## S(int ## S volatile *a) \ -{ \ - int ## S ret; \ - make_atomic_load_body(S); \ - return ret; \ -} - -#define make_atomic_store(S) \ -STATIC_INLINE void my_atomic_store ## S( \ - int ## S volatile *a, int ## S v) \ -{ \ - make_atomic_store_body(S); \ -} - -#else /* no inline functions */ - -#define make_atomic_add(S) \ -extern int ## S my_atomic_add ## S(int ## S volatile *a, int ## S v); - -#define make_atomic_swap(S) \ -extern int ## S my_atomic_swap ## S(int ## S volatile *a, int ## S v); - -#define make_atomic_cas(S) \ -extern int my_atomic_cas ## S(int ## S volatile *a, int ## S *cmp, int ## S set); - -#define make_atomic_load(S) \ -extern int ## S my_atomic_load ## S(int ## S volatile *a); - -#define make_atomic_store(S) \ -extern void my_atomic_store ## S(int ## S volatile *a, int ## S v); - -#endif - -make_atomic_cas( 8) -make_atomic_cas(16) -make_atomic_cas(32) -make_atomic_cas(ptr) - -make_atomic_add( 8) -make_atomic_add(16) -make_atomic_add(32) - -make_atomic_load( 8) -make_atomic_load(16) -make_atomic_load(32) -make_atomic_load(ptr) - -make_atomic_store( 8) -make_atomic_store(16) -make_atomic_store(32) -make_atomic_store(ptr) - -make_atomic_swap( 8) -make_atomic_swap(16) -make_atomic_swap(32) -make_atomic_swap(ptr) - -#undef make_atomic_add -#undef make_atomic_cas -#undef make_atomic_load -#undef make_atomic_store -#undef make_atomic_swap -#undef make_atomic_add_body -#undef make_atomic_cas_body -#undef make_atomic_load_body -#undef make_atomic_store_body -#undef make_atomic_swap_body -#undef intptr - -#ifdef _atomic_h_cleanup_ -#include _atomic_h_cleanup_ -#undef _atomic_h_cleanup_ -#endif - -#define MY_ATOMIC_OK 0 -#define MY_ATOMIC_NOT_1CPU 1 -extern int my_atomic_initialize(); - -#endif - diff --git a/include/my_pthread.h b/include/my_pthread.h index e9256610ea7..eff6a677192 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -715,7 +715,7 @@ extern uint thd_lib_detected; The implementation is guaranteed to be thread safe, on all platforms. Note that the calling code should *not* assume the counter is protected by the mutex given, as the implementation of these helpers may change - to use my_atomic operations instead. + to use atomic operations instead. */ /* diff --git a/mysys/Makefile.am b/mysys/Makefile.am index 19017330654..e4c71f66079 100644 --- a/mysys/Makefile.am +++ b/mysys/Makefile.am @@ -30,8 +30,7 @@ libmysys_a_SOURCES = my_init.c my_getwd.c mf_getdate.c my_mmap.c \ mf_tempdir.c my_lock.c mf_brkhant.c my_alarm.c \ my_malloc.c my_realloc.c my_once.c mulalloc.c \ my_alloc.c safemalloc.c my_new.cc \ - my_vle.c my_atomic.c \ - my_fopen.c my_fstream.c my_getsystime.c \ + my_vle.c my_fopen.c my_fstream.c my_getsystime.c \ my_error.c errors.c my_div.c my_messnc.c \ mf_format.c mf_same.c mf_dirname.c mf_fn_ext.c \ my_symlink.c my_symlink2.c \ diff --git a/mysys/my_atomic.c b/mysys/my_atomic.c deleted file mode 100644 index aa04d55f624..00000000000 --- a/mysys/my_atomic.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 2006 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include <my_global.h> -#include <my_pthread.h> - -#ifndef HAVE_INLINE -/* the following will cause all inline functions to be instantiated */ -#define HAVE_INLINE -#undef STATIC_INLINE -#define STATIC_INLINE extern -#endif - -#include <my_atomic.h> - -/* - checks that the current build of atomic ops - can run on this machine - - RETURN - ATOMIC_xxx values, see my_atomic.h -*/ -int my_atomic_initialize() -{ - compile_time_assert(sizeof(intptr) == sizeof(void *)); - /* currently the only thing worth checking is SMP/UP issue */ -#ifdef MY_ATOMIC_MODE_DUMMY - return my_getncpus() == 1 ? MY_ATOMIC_OK : MY_ATOMIC_NOT_1CPU; -#else - return MY_ATOMIC_OK; -#endif -} - diff --git a/storage/ibmdb2i/db2i_file.h b/storage/ibmdb2i/db2i_file.h index ff35a473b05..7b63b18c315 100644 --- a/storage/ibmdb2i/db2i_file.h +++ b/storage/ibmdb2i/db2i_file.h @@ -40,7 +40,6 @@ OF SUCH DAMAGE. #include "db2i_global.h" #include "db2i_ileBridge.h" #include "db2i_validatedPointer.h" -#include "my_atomic.h" #include "db2i_iconv.h" #include "db2i_charsetSupport.h" diff --git a/unittest/mysys/Makefile.am b/unittest/mysys/Makefile.am index f0ffc7a6720..b195017e914 100644 --- a/unittest/mysys/Makefile.am +++ b/unittest/mysys/Makefile.am @@ -23,12 +23,5 @@ LDADD = $(top_builddir)/unittest/mytap/libmytap.a \ noinst_PROGRAMS = bitmap-t base64-t -if NEED_THREAD -# my_atomic-t is used to check thread functions, so it is safe to -# ignore the file in non-threaded builds. -# In fact, it will not compile without thread support. -noinst_PROGRAMS += my_atomic-t -endif - # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/unittest/mysys/my_atomic-t.c b/unittest/mysys/my_atomic-t.c deleted file mode 100644 index f2bcd360508..00000000000 --- a/unittest/mysys/my_atomic-t.c +++ /dev/null @@ -1,205 +0,0 @@ -/* Copyright (C) 2006 MySQL AB - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; version 2 of the License. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -#include <my_global.h> -#include <my_sys.h> -#include <my_atomic.h> -#include <tap.h> - -/* at least gcc 3.4.5 and 3.4.6 (but not 3.2.3) on RHEL */ -#if __GNUC__ == 3 && __GNUC_MINOR__ == 4 -#define GCC_BUG_WORKAROUND volatile -#else -#define GCC_BUG_WORKAROUND -#endif - -int32 a32,b32,c32; -my_atomic_rwlock_t rwl; - -pthread_attr_t thr_attr; -pthread_mutex_t mutex; -pthread_cond_t cond; -int N; - -/* add and sub a random number in a loop. Must get 0 at the end */ -pthread_handler_t test_atomic_add_handler(void *arg) -{ - int m=*(int *)arg; - GCC_BUG_WORKAROUND int32 x; - for (x=((int)((long)(&m))); m ; m--) - { - x=x*m+0x87654321; - my_atomic_rwlock_wrlock(&rwl); - my_atomic_add32(&a32, x); - my_atomic_rwlock_wrunlock(&rwl); - - my_atomic_rwlock_wrlock(&rwl); - my_atomic_add32(&a32, -x); - my_atomic_rwlock_wrunlock(&rwl); - } - pthread_mutex_lock(&mutex); - N--; - if (!N) pthread_cond_signal(&cond); - pthread_mutex_unlock(&mutex); - return 0; -} - -/* - 1. generate thread number 0..N-1 from b32 - 2. add it to a32 - 3. swap thread numbers in c32 - 4. (optionally) one more swap to avoid 0 as a result - 5. subtract result from a32 - must get 0 in a32 at the end -*/ -pthread_handler_t test_atomic_swap_handler(void *arg) -{ - int m=*(int *)arg; - int32 x; - - my_atomic_rwlock_wrlock(&rwl); - x=my_atomic_add32(&b32, 1); - my_atomic_rwlock_wrunlock(&rwl); - - my_atomic_rwlock_wrlock(&rwl); - my_atomic_add32(&a32, x); - my_atomic_rwlock_wrunlock(&rwl); - - for (; m ; m--) - { - my_atomic_rwlock_wrlock(&rwl); - x=my_atomic_swap32(&c32, x); - my_atomic_rwlock_wrunlock(&rwl); - } - - if (!x) - { - my_atomic_rwlock_wrlock(&rwl); - x=my_atomic_swap32(&c32, x); - my_atomic_rwlock_wrunlock(&rwl); - } - - my_atomic_rwlock_wrlock(&rwl); - my_atomic_add32(&a32, -x); - my_atomic_rwlock_wrunlock(&rwl); - - pthread_mutex_lock(&mutex); - N--; - if (!N) pthread_cond_signal(&cond); - pthread_mutex_unlock(&mutex); - return 0; -} - -/* - same as test_atomic_add_handler, but my_atomic_add32 is emulated with - (slower) my_atomic_cas32 -*/ -pthread_handler_t test_atomic_cas_handler(void *arg) -{ - int m=*(int *)arg, ok; - GCC_BUG_WORKAROUND int32 x,y; - for (x=((int)((long)(&m))); m ; m--) - { - my_atomic_rwlock_wrlock(&rwl); - y=my_atomic_load32(&a32); - my_atomic_rwlock_wrunlock(&rwl); - - x=x*m+0x87654321; - do { - my_atomic_rwlock_wrlock(&rwl); - ok=my_atomic_cas32(&a32, &y, y+x); - my_atomic_rwlock_wrunlock(&rwl); - } while (!ok); - do { - my_atomic_rwlock_wrlock(&rwl); - ok=my_atomic_cas32(&a32, &y, y-x); - my_atomic_rwlock_wrunlock(&rwl); - } while (!ok); - } - pthread_mutex_lock(&mutex); - N--; - if (!N) pthread_cond_signal(&cond); - pthread_mutex_unlock(&mutex); - return 0; -} - -void test_atomic(const char *test, pthread_handler handler, int n, int m) -{ - pthread_t t; - ulonglong now=my_getsystime(); - - a32= 0; - b32= 0; - c32= 0; - - diag("Testing %s with %d threads, %d iterations... ", test, n, m); - for (N=n ; n ; n--) - { - if (pthread_create(&t, &thr_attr, handler, &m) != 0) - { - diag("Could not create thread"); - a32= 1; - goto err; - } - } - - pthread_mutex_lock(&mutex); - while (N) - pthread_cond_wait(&cond, &mutex); - pthread_mutex_unlock(&mutex); - now=my_getsystime()-now; -err: - ok(a32 == 0, "tested %s in %g secs", test, ((double)now)/1e7); -} - -int main() -{ - int err; - MY_INIT("my_atomic-t.c"); - - diag("N CPUs: %d", my_getncpus()); - err= my_atomic_initialize(); - - plan(4); - ok(err == 0, "my_atomic_initialize() returned %d", err); - - pthread_attr_init(&thr_attr); - pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED); - pthread_mutex_init(&mutex, 0); - pthread_cond_init(&cond, 0); - my_atomic_rwlock_init(&rwl); - -#ifdef HPUX11 -#define CYCLES 1000 -#else -#define CYCLES 10000 -#endif -#define THREADS 100 - test_atomic("my_atomic_add32", test_atomic_add_handler, THREADS, CYCLES); - test_atomic("my_atomic_swap32", test_atomic_swap_handler, THREADS, CYCLES); - test_atomic("my_atomic_cas32", test_atomic_cas_handler, THREADS, CYCLES); - /* - workaround until we know why it crashes randomly on some machine - (BUG#22320). - */ - sleep(2); - - pthread_mutex_destroy(&mutex); - pthread_cond_destroy(&cond); - pthread_attr_destroy(&thr_attr); - my_atomic_rwlock_destroy(&rwl); - return exit_status(); -} - |