From a51280725c911164b47e10b0cd2a62caaacc6e3f Mon Sep 17 00:00:00 2001 From: Mikael Ronstrom Date: Wed, 23 Sep 2009 15:15:35 +0200 Subject: [PATCH 01/23] WL#5105, ptr_cmp optimised on Solaris, more efficient to use memcmp on Solaris than native impl. --- mysys/ptr_cmp.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/mysys/ptr_cmp.c b/mysys/ptr_cmp.c index 24ab6a1ea9c..9f053f0b3b4 100644 --- a/mysys/ptr_cmp.c +++ b/mysys/ptr_cmp.c @@ -22,16 +22,39 @@ #include "mysys_priv.h" #include +#ifdef UNIV_SOLARIS +/* + * On Solaris, memcmp() is normally faster than the unrolled ptr_compare_N + * functions, as memcmp() is usually a platform-specific implementation + * written in assembler, provided in /usr/lib/libc/libc_hwcap*.so.1. + * This implementation is also usually faster than the built-in memcmp + * supplied by GCC, so it is recommended to build with "-fno-builtin-memcmp" + * in CFLAGS if building with GCC on Solaris. + */ + +#include + +static int native_compare(size_t *length, unsigned char **a, unsigned char **b) +{ + return memcmp(*a, *b, *length); +} + +#else /* UNIV_SOLARIS */ + static int ptr_compare(size_t *compare_length, uchar **a, uchar **b); static int ptr_compare_0(size_t *compare_length, uchar **a, uchar **b); static int ptr_compare_1(size_t *compare_length, uchar **a, uchar **b); static int ptr_compare_2(size_t *compare_length, uchar **a, uchar **b); static int ptr_compare_3(size_t *compare_length, uchar **a, uchar **b); +#endif /* UNIV_SOLARIS */ /* Get a pointer to a optimal byte-compare function for a given size */ qsort2_cmp get_ptr_compare (size_t size) { +#ifdef UNIV_SOLARIS + return (qsort2_cmp) native_compare; +#else if (size < 4) return (qsort2_cmp) ptr_compare; switch (size & 3) { @@ -41,6 +64,7 @@ qsort2_cmp get_ptr_compare (size_t size) case 3: return (qsort2_cmp) ptr_compare_3; } return 0; /* Impossible */ +#endif /* UNIV_SOLARIS */ } From a4785fc4a2abeb3f8fbc253b78f558540b949482 Mon Sep 17 00:00:00 2001 From: Mikael Ronstrom Date: Fri, 9 Oct 2009 14:21:29 +0200 Subject: [PATCH 02/23] Moved atomics from 6.0 codebase to prepare for using atomic increments in places where LOCK_thread_count previously was used --- include/atomic/gcc_builtins.h | 10 +- include/atomic/generic-msvc.h | 116 ++++++++++++++ include/atomic/nolock.h | 49 +++--- include/atomic/solaris.h | 8 +- include/atomic/x86-gcc.h | 35 ++-- include/atomic/x86-msvc.h | 96 ----------- include/my_atomic.h | 289 +++++++++++++++++++++++++--------- 7 files changed, 394 insertions(+), 209 deletions(-) create mode 100644 include/atomic/generic-msvc.h delete mode 100644 include/atomic/x86-msvc.h diff --git a/include/atomic/gcc_builtins.h b/include/atomic/gcc_builtins.h index 509701b30a5..100ff80cacd 100644 --- a/include/atomic/gcc_builtins.h +++ b/include/atomic/gcc_builtins.h @@ -1,3 +1,6 @@ +#ifndef ATOMIC_GCC_BUILTINS_INCLUDED +#define ATOMIC_GCC_BUILTINS_INCLUDED + /* Copyright (C) 2008 MySQL AB This program is free software; you can redistribute it and/or modify @@ -15,7 +18,7 @@ #define make_atomic_add_body(S) \ v= __sync_fetch_and_add(a, v); -#define make_atomic_swap_body(S) \ +#define make_atomic_fas_body(S) \ v= __sync_lock_test_and_set(a, v); #define make_atomic_cas_body(S) \ int ## S sav; \ @@ -25,9 +28,14 @@ #ifdef MY_ATOMIC_MODE_DUMMY #define make_atomic_load_body(S) ret= *a #define make_atomic_store_body(S) *a= v +#define MY_ATOMIC_MODE "gcc-builtins-up" + #else +#define MY_ATOMIC_MODE "gcc-builtins-smp" #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 + +#endif /* ATOMIC_GCC_BUILTINS_INCLUDED */ diff --git a/include/atomic/generic-msvc.h b/include/atomic/generic-msvc.h new file mode 100644 index 00000000000..f1e1b0e88c9 --- /dev/null +++ b/include/atomic/generic-msvc.h @@ -0,0 +1,116 @@ +/* Copyright (C) 2006-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. + + 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 _atomic_h_cleanup_ +#define _atomic_h_cleanup_ "atomic/generic-msvc.h" + +/* + We don't implement anything specific for MY_ATOMIC_MODE_DUMMY, always use + intrinsics. + 8 and 16-bit atomics are not implemented, but it can be done if necessary. +*/ +#undef MY_ATOMIC_HAS_8_16 + +/* + x86 compilers (both VS2003 or VS2005) never use instrinsics, but generate + function calls to kernel32 instead, even in the optimized build. + We force intrinsics as described in MSDN documentation for + _InterlockedCompareExchange. +*/ +#ifdef _M_IX86 + +#if (_MSC_VER >= 1500) +#include +#else +C_MODE_START +/*Visual Studio 2003 and earlier do not have prototypes for atomic intrinsics*/ +LONG _InterlockedExchange (LONG volatile *Target,LONG Value); +LONG _InterlockedCompareExchange (LONG volatile *Target, LONG Value, LONG Comp); +LONG _InterlockedExchangeAdd (LONG volatile *Addend, LONG Value); +C_MODE_END + +#pragma intrinsic(_InterlockedExchangeAdd) +#pragma intrinsic(_InterlockedCompareExchange) +#pragma intrinsic(_InterlockedExchange) +#endif + +#define InterlockedExchange _InterlockedExchange +#define InterlockedExchangeAdd _InterlockedExchangeAdd +#define InterlockedCompareExchange _InterlockedCompareExchange +/* + No need to do something special for InterlockedCompareExchangePointer + as it is a #define to InterlockedCompareExchange. The same applies to + InterlockedExchangePointer. +*/ +#endif /*_M_IX86*/ + +#define MY_ATOMIC_MODE "msvc-intrinsics" +#define IL_EXCHG_ADD32(X,Y) InterlockedExchangeAdd((volatile LONG *)(X),(Y)) +#define IL_COMP_EXCHG32(X,Y,Z) InterlockedCompareExchange((volatile LONG *)(X),(Y),(Z)) +#define IL_COMP_EXCHGptr InterlockedCompareExchangePointer +#define IL_EXCHG32(X,Y) InterlockedExchange((volatile LONG *)(X),(Y)) +#define IL_EXCHGptr InterlockedExchangePointer +#define make_atomic_add_body(S) \ + v= IL_EXCHG_ADD ## S (a, v) +#define make_atomic_cas_body(S) \ + int ## S initial_cmp= *cmp; \ + int ## S initial_a= IL_COMP_EXCHG ## S (a, set, initial_cmp); \ + if (!(ret= (initial_a == initial_cmp))) *cmp= initial_a; +#define make_atomic_swap_body(S) \ + v= IL_EXCHG ## S (a, v) +#define make_atomic_load_body(S) \ + ret= 0; /* avoid compiler warning */ \ + ret= IL_COMP_EXCHG ## S (a, ret, ret); + +/* + my_yield_processor (equivalent of x86 PAUSE instruction) should be used + to improve performance on hyperthreaded CPUs. Intel recommends to use it in + spin loops also on non-HT machines to reduce power consumption (see e.g + http://softwarecommunity.intel.com/articles/eng/2004.htm) + + Running benchmarks for spinlocks implemented with InterlockedCompareExchange + and YieldProcessor shows that much better performance is achieved by calling + YieldProcessor in a loop - that is, yielding longer. On Intel boxes setting + loop count in the range 200-300 brought best results. + */ +#ifndef YIELD_LOOPS +#define YIELD_LOOPS 200 +#endif + +static __inline int my_yield_processor() +{ + int i; + for(i=0; i Date: Fri, 9 Oct 2009 14:22:22 +0200 Subject: [PATCH 03/23] A minor change to MySQL's hash where calculation of hash can be done separately to avoid doing it under contended mutex locks --- include/hash.h | 9 +++++++++ mysys/hash.c | 29 +++++++++++++++++++++++++++-- sql/sql_base.cc | 9 +++++++-- 3 files changed, 43 insertions(+), 4 deletions(-) diff --git a/include/hash.h b/include/hash.h index 629b404e8a7..b6fc365ab76 100644 --- a/include/hash.h +++ b/include/hash.h @@ -45,6 +45,7 @@ extern "C" { #define hash_element my_hash_element #define hash_search my_hash_search #define hash_first my_hash_first +#define hash_first_from_hash_value my_hash_first_from_hash_value #define hash_next my_hash_next #define hash_insert my_hash_insert #define hash_delete my_hash_delete @@ -94,8 +95,16 @@ void my_hash_free(HASH *tree); void my_hash_reset(HASH *hash); uchar *my_hash_element(HASH *hash, ulong idx); uchar *my_hash_search(const HASH *info, const uchar *key, size_t length); +uchar *my_hash_search_using_hash_value(const HASH *info, uint hash_value, + const uchar *key, size_t length); +uint my_calc_hash(const HASH *info, const uchar *key, size_t length); uchar *my_hash_first(const HASH *info, const uchar *key, size_t length, HASH_SEARCH_STATE *state); +uchar *my_hash_first_from_hash_value(const HASH *info, + uint hash_value, + const uchar *key, + size_t length, + HASH_SEARCH_STATE *state); uchar *my_hash_next(const HASH *info, const uchar *key, size_t length, HASH_SEARCH_STATE *state); my_bool my_hash_insert(HASH *info, const uchar *data); diff --git a/mysys/hash.c b/mysys/hash.c index 63933abb085..367ac8713dd 100644 --- a/mysys/hash.c +++ b/mysys/hash.c @@ -214,6 +214,20 @@ uchar* my_hash_search(const HASH *hash, const uchar *key, size_t length) return my_hash_first(hash, key, length, &state); } +uchar* my_hash_search_using_hash_value(const HASH *hash, + uint hash_value, + const uchar *key, + size_t length) +{ + HASH_SEARCH_STATE state; + return my_hash_first_from_hash_value(hash, hash_value, + key, length, &state); +} + +uint my_calc_hash(const HASH *hash, const uchar *key, size_t length) +{ + return calc_hash(hash, key, length ? length : hash->key_length); +} /* Search after a record based on a key @@ -223,15 +237,26 @@ uchar* my_hash_search(const HASH *hash, const uchar *key, size_t length) uchar* my_hash_first(const HASH *hash, const uchar *key, size_t length, HASH_SEARCH_STATE *current_record) +{ + return my_hash_first_from_hash_value(hash, + calc_hash(hash, key, length ? length : hash->key_length), + key, length, current_record); +} + +uchar* my_hash_first_from_hash_value(const HASH *hash, + uint hash_value, + const uchar *key, + size_t length, + HASH_SEARCH_STATE *current_record) { HASH_LINK *pos; uint flag,idx; - DBUG_ENTER("my_hash_first"); + DBUG_ENTER("my_hash_first_from_hash_value"); flag=1; if (hash->records) { - idx= my_hash_mask(calc_hash(hash, key, length ? length : hash->key_length), + idx= my_hash_mask(hash_value, hash->blength, hash->records); do { diff --git a/sql/sql_base.cc b/sql/sql_base.cc index b81070000b3..064d277e0b4 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2513,6 +2513,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, char key[MAX_DBKEY_LENGTH]; uint key_length; char *alias= table_list->alias; + uint hash_value; HASH_SEARCH_STATE state; DBUG_ENTER("open_table"); @@ -2702,6 +2703,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, on disk. */ + hash_value= my_calc_hash(&open_cache, (uchar*) key, key_length); VOID(pthread_mutex_lock(&LOCK_open)); /* @@ -2744,8 +2746,11 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, an implicit "pending locks queue" - see wait_for_locked_table_names for details. */ - for (table= (TABLE*) hash_first(&open_cache, (uchar*) key, key_length, - &state); + for (table= (TABLE*) hash_first_from_hash_value(&open_cache, + hash_value, + (uchar*) key, + key_length, + &state); table && table->in_use ; table= (TABLE*) hash_next(&open_cache, (uchar*) key, key_length, &state)) From bae553cfcd9ad8b9df8b5305736f6810fbaed43b Mon Sep 17 00:00:00 2001 From: Mikael Ronstrom Date: Mon, 12 Oct 2009 11:00:39 +0200 Subject: [PATCH 04/23] Backported my_atomic from 6.0-codebase and added support for 64-bit atomics to enable removal of LOCK_thread_count from every query, removed LOCK_thread_count from use in dispatch_command and close of query which is used in every query, now uses atomic increments/decrements instead --- include/Makefile.am | 2 +- include/atomic/rwlock.h | 31 ++++-- include/atomic/x86-gcc.h | 32 +++++- include/my_atomic.h | 12 ++- include/my_global.h | 2 + sql/event_scheduler.cc | 17 ++- sql/log_event.cc | 12 +-- sql/mysql_priv.h | 45 +++++++- sql/mysqld.cc | 6 +- sql/sp_head.cc | 4 +- sql/sql_parse.cc | 57 +++++----- unittest/mysys/my_atomic-t.c | 192 +++++++++++++++------------------- unittest/mysys/thr_template.c | 92 ++++++++++++++++ 13 files changed, 337 insertions(+), 167 deletions(-) create mode 100644 unittest/mysys/thr_template.c diff --git a/include/Makefile.am b/include/Makefile.am index dd6f53f7ca2..d698b1323b8 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -38,7 +38,7 @@ noinst_HEADERS = config-win.h config-netware.h my_bit.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/rwlock.h atomic/x86-gcc.h atomic/generic-msvc.h \ atomic/solaris.h \ atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h diff --git a/include/atomic/rwlock.h b/include/atomic/rwlock.h index 18b77e93d80..29e22fcb3d5 100644 --- a/include/atomic/rwlock.h +++ b/include/atomic/rwlock.h @@ -1,3 +1,6 @@ +#ifndef ATOMIC_RWLOCK_INCLUDED +#define ATOMIC_RWLOCK_INCLUDED + /* Copyright (C) 2006 MySQL AB This program is free software; you can redistribute it and/or modify @@ -13,7 +16,8 @@ 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; +typedef struct {pthread_mutex_t rw;} my_atomic_rwlock_t; +#define MY_ATOMIC_MODE_RWLOCKS 1 #ifdef MY_ATOMIC_MODE_DUMMY /* @@ -31,18 +35,27 @@ typedef struct {pthread_rwlock_t rw;} my_atomic_rwlock_t; #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" +/* + we're using read-write lock macros but map them to mutex locks, and they're + faster. Still, having semantically rich API we can change the + underlying implementation, if necessary. +*/ +#define my_atomic_rwlock_destroy(name) pthread_mutex_destroy(& (name)->rw) +#define my_atomic_rwlock_init(name) pthread_mutex_init(& (name)->rw, 0) +#define my_atomic_rwlock_rdlock(name) pthread_mutex_lock(& (name)->rw) +#define my_atomic_rwlock_wrlock(name) pthread_mutex_lock(& (name)->rw) +#define my_atomic_rwlock_rdunlock(name) pthread_mutex_unlock(& (name)->rw) +#define my_atomic_rwlock_wrunlock(name) pthread_mutex_unlock(& (name)->rw) +#define MY_ATOMIC_MODE "mutex" +#ifndef MY_ATOMIC_MODE_RWLOCKS +#define MY_ATOMIC_MODE_RWLOCKS 1 +#endif #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_fas_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; +#endif /* ATOMIC_RWLOCK_INCLUDED */ diff --git a/include/atomic/x86-gcc.h b/include/atomic/x86-gcc.h index c11483b4083..ba7e7eb572f 100644 --- a/include/atomic/x86-gcc.h +++ b/include/atomic/x86-gcc.h @@ -42,15 +42,37 @@ #endif #ifndef MY_ATOMIC_NO_XADD -#define make_atomic_add_body(S) \ - asm volatile (LOCK_prefix "; xadd %0, %1;" : "+r" (v) , "+m" (*a)) +#define make_atomic_add_body(S) make_atomic_add_body ## S +#define make_atomic_cas_body(S) make_atomic_cas_body ## S #endif -#define make_atomic_fas_body(S) \ - asm volatile ("xchg %0, %1;" : "+q" (v) , "+m" (*a)) -#define make_atomic_cas_body(S) \ + +#define make_atomic_add_body32 \ + asm volatile (LOCK_prefix "; xadd %0, %1;" : "+r" (v) , "+m" (*a)) + +#define make_atomic_cas_body32 \ asm volatile (LOCK_prefix "; cmpxchg %3, %0; setz %2;" \ : "+m" (*a), "+a" (*cmp), "=q" (ret): "r" (set)) +#define make_atomic_cas_bodyptr make_atomic_cas_body32 + +#ifndef __x86_64__ +#define make_atomic_add_body64 make_atomic_add_body32 +#define make_atomic_cas_body64 make_atomic_cas_body32 +#else +#define make_atomic_add_body64 \ + int64 tmp=*a; \ + while (!my_atomic_cas64(a, &tmp, tmp+v)); \ + v=tmp; +#define make_atomic_cas_body64 \ + int32 ebx=(set & 0xFFFFFFFF), ecx=(set >> 32); \ + asm volatile (LOCK_prefix "; cmpxchg8b %0; setz %2;" \ + : "+m" (*a), "+A" (*cmp), "=q" (ret) \ + :"b" (ebx), "c" (ecx)) +#endif + +#define make_atomic_fas_body(S) \ + asm volatile ("xchg %0, %1;" : "+r" (v) , "+m" (*a)) + #ifdef MY_ATOMIC_MODE_DUMMY #define make_atomic_load_body(S) ret=*a #define make_atomic_store_body(S) *a=v diff --git a/include/my_atomic.h b/include/my_atomic.h index f62d3e32b42..4170e45fe8c 100644 --- a/include/my_atomic.h +++ b/include/my_atomic.h @@ -37,7 +37,7 @@ my_atomic_store#(&var, what) store 'what' in *var - '#' is substituted by a size suffix - 8, 16, 32, or ptr + '#' is substituted by a size suffix - 8, 16, 32, 64, or ptr (e.g. my_atomic_add8, my_atomic_fas32, my_atomic_casptr). NOTE This operations are not always atomic, so they always must be @@ -129,6 +129,7 @@ make_transparent_unions(8) make_transparent_unions(16) make_transparent_unions(32) +make_transparent_unions(64) make_transparent_unions(ptr) #undef uintptr #undef make_transparent_unions @@ -140,10 +141,12 @@ make_transparent_unions(ptr) #define U_8 int8 #define U_16 int16 #define U_32 int32 +#define U_64 int64 #define U_ptr intptr #define Uv_8 int8 #define Uv_16 int16 #define Uv_32 int32 +#define Uv_64 int64 #define Uv_ptr intptr #define U_a volatile *a #define U_cmp *cmp @@ -217,6 +220,7 @@ make_atomic_cas(8) make_atomic_cas(16) #endif make_atomic_cas(32) +make_atomic_cas(64) make_atomic_cas(ptr) #ifdef MY_ATOMIC_HAS_8_16 @@ -224,12 +228,14 @@ make_atomic_add(8) make_atomic_add(16) #endif make_atomic_add(32) +make_atomic_add(64) #ifdef MY_ATOMIC_HAS_8_16 make_atomic_load(8) make_atomic_load(16) #endif make_atomic_load(32) +make_atomic_load(64) make_atomic_load(ptr) #ifdef MY_ATOMIC_HAS_8_16 @@ -237,6 +243,7 @@ make_atomic_fas(8) make_atomic_fas(16) #endif make_atomic_fas(32) +make_atomic_fas(64) make_atomic_fas(ptr) #ifdef MY_ATOMIC_HAS_8_16 @@ -244,6 +251,7 @@ make_atomic_store(8) make_atomic_store(16) #endif make_atomic_store(32) +make_atomic_store(64) make_atomic_store(ptr) #ifdef _atomic_h_cleanup_ @@ -254,10 +262,12 @@ make_atomic_store(ptr) #undef U_8 #undef U_16 #undef U_32 +#undef U_64 #undef U_ptr #undef Uv_8 #undef Uv_16 #undef Uv_32 +#undef Uv_64 #undef Uv_ptr #undef a #undef cmp diff --git a/include/my_global.h b/include/my_global.h index 4ad851e9e5d..25d3a9e461b 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -832,6 +832,8 @@ typedef SOCKET_SIZE_TYPE size_socket; #endif #endif /* defined (HAVE_LONG_LONG) && !defined(ULONGLONG_MAX)*/ +#define INT_MIN64 (~0x7FFFFFFFFFFFFFFFLL) +#define INT_MAX64 0x7FFFFFFFFFFFFFFFLL #define INT_MIN32 (~0x7FFFFFFFL) #define INT_MAX32 0x7FFFFFFFL #define UINT_MAX32 0xFFFFFFFFL diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index 8c0025f9ed4..9c825078370 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -132,9 +132,10 @@ post_init_event_thread(THD *thd) pthread_mutex_lock(&LOCK_thread_count); threads.append(thd); thread_count++; - thread_running++; pthread_mutex_unlock(&LOCK_thread_count); - + my_atomic_rwlock_wrlock(&global_query_id_lock); + inc_thread_running(); + my_atomic_rwlock_wrunlock(&global_query_id_lock); return FALSE; } @@ -156,10 +157,12 @@ deinit_event_thread(THD *thd) DBUG_PRINT("exit", ("Event thread finishing")); pthread_mutex_lock(&LOCK_thread_count); thread_count--; - thread_running--; delete thd; pthread_cond_broadcast(&COND_thread_count); pthread_mutex_unlock(&LOCK_thread_count); + my_atomic_rwlock_wrlock(&global_query_id_lock); + dec_thread_running(); + my_atomic_rwlock_wrunlock(&global_query_id_lock); } @@ -417,10 +420,12 @@ Event_scheduler::start() net_end(&new_thd->net); pthread_mutex_lock(&LOCK_thread_count); thread_count--; - thread_running--; delete new_thd; pthread_cond_broadcast(&COND_thread_count); pthread_mutex_unlock(&LOCK_thread_count); + my_atomic_rwlock_wrlock(&global_query_id_lock); + dec_thread_running(); + my_atomic_rwlock_wrunlock(&global_query_id_lock); } end: UNLOCK_DATA(); @@ -550,10 +555,12 @@ error: net_end(&new_thd->net); pthread_mutex_lock(&LOCK_thread_count); thread_count--; - thread_running--; delete new_thd; pthread_cond_broadcast(&COND_thread_count); pthread_mutex_unlock(&LOCK_thread_count); + my_atomic_rwlock_wrlock(&global_query_id_lock); + dec_thread_running(); + my_atomic_rwlock_wrunlock(&global_query_id_lock); } delete event_name; DBUG_RETURN(TRUE); diff --git a/sql/log_event.cc b/sql/log_event.cc index e7cbbaba38e..5b286d94c0b 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -3026,9 +3026,9 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli, { thd->set_time((time_t)when); thd->set_query((char*)query_arg, q_len_arg); - VOID(pthread_mutex_lock(&LOCK_thread_count)); + my_atomic_rwlock_wrlock(&global_query_id_lock); thd->query_id = next_query_id(); - VOID(pthread_mutex_unlock(&LOCK_thread_count)); + my_atomic_rwlock_wrunlock(&global_query_id_lock); thd->variables.pseudo_thread_id= thread_id; // for temp tables DBUG_PRINT("query",("%s",thd->query)); @@ -4504,9 +4504,9 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli, if (rpl_filter->db_ok(thd->db)) { thd->set_time((time_t)when); - VOID(pthread_mutex_lock(&LOCK_thread_count)); + my_atomic_rwlock_wrlock(&global_query_id_lock); thd->query_id = next_query_id(); - VOID(pthread_mutex_unlock(&LOCK_thread_count)); + my_atomic_rwlock_wrunlock(&global_query_id_lock); /* Initing thd->row_count is not necessary in theory as this variable has no influence in the case of the slave SQL thread (it is used to generate a @@ -8025,9 +8025,9 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli) DBUG_ASSERT(rli->sql_thd == thd); /* Step the query id to mark what columns that are actually used. */ - pthread_mutex_lock(&LOCK_thread_count); + my_atomic_rwlock_wrlock(&global_query_id_lock); thd->query_id= next_query_id(); - pthread_mutex_unlock(&LOCK_thread_count); + my_atomic_rwlock_wrunlock(&global_query_id_lock); if (!(memory= my_multi_malloc(MYF(MY_WME), &table_list, (uint) sizeof(RPL_TABLE_LIST), diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index cd1a31f0fab..ff6d3578406 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -43,6 +43,7 @@ #include "sql_array.h" #include "sql_plugin.h" #include "scheduler.h" +#include class Parser_state; @@ -75,11 +76,49 @@ typedef ulong nesting_map; /* Used for flags of nesting constructs */ typedef ulonglong nested_join_map; /* query_id */ -typedef ulonglong query_id_t; +typedef int64 query_id_t; extern query_id_t global_query_id; +extern int32 thread_running; +extern my_atomic_rwlock_t global_query_id_lock; /* increment query_id and return it. */ -inline query_id_t next_query_id() { return global_query_id++; } +inline query_id_t next_query_id() +{ + query_id_t id; + id= my_atomic_add64(&global_query_id, 1); + return (id+1); +} + +inline query_id_t get_query_id() +{ + query_id_t id; + id= my_atomic_load64(&global_query_id); + return id; +} + +inline int32 +inc_thread_running() +{ + int32 num_thread_running; + num_thread_running= my_atomic_add32(&thread_running, 1); + return (num_thread_running+1); +} + +inline int32 +dec_thread_running() +{ + int32 num_thread_running; + num_thread_running= my_atomic_add32(&thread_running, -1); + return (num_thread_running-1); +} + +inline int32 +get_thread_running() +{ + int32 num_thread_running; + num_thread_running= my_atomic_load32(&thread_running); + return num_thread_running; +} /* useful constants */ extern MYSQL_PLUGIN_IMPORT const key_map key_map_empty; @@ -1994,7 +2033,7 @@ extern bool opt_ignore_builtin_innodb; extern my_bool opt_character_set_client_handshake; extern bool volatile abort_loop, shutdown_in_progress; extern bool in_bootstrap; -extern uint volatile thread_count, thread_running, global_read_lock; +extern uint volatile thread_count, global_read_lock; extern uint connection_count; extern my_bool opt_sql_bin_update, opt_safe_user_create, opt_no_mix_types; extern my_bool opt_safe_show_db, opt_local_infile, opt_myisam_use_mmap; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 5dad29a1ab7..1389f0b32f4 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -523,7 +523,8 @@ uint mysqld_port_timeout; uint delay_key_write_options, protocol_version; uint lower_case_table_names; uint tc_heuristic_recover= 0; -uint volatile thread_count, thread_running; +uint volatile thread_count; +int32 thread_running; ulonglong thd_startup_options; ulong back_log, connect_timeout, concurrency, server_id; ulong table_cache_size, table_def_size; @@ -539,6 +540,7 @@ ulonglong max_binlog_cache_size=0; ulong query_cache_size=0; ulong refresh_version; /* Increments on each reload */ query_id_t global_query_id; +my_atomic_rwlock_t global_query_id_lock; ulong aborted_threads, aborted_connects; ulong delayed_insert_timeout, delayed_insert_limit, delayed_queue_size; ulong delayed_insert_threads, delayed_insert_writes, delayed_rows_in_use; @@ -1349,6 +1351,7 @@ void clean_up(bool print_message) DBUG_PRINT("quit", ("Error messages freed")); /* Tell main we are ready */ logger.cleanup_end(); + my_atomic_rwlock_destroy(&global_query_id_lock); (void) pthread_mutex_lock(&LOCK_thread_count); DBUG_PRINT("quit", ("got thread count lock")); ready_to_exit=1; @@ -7730,6 +7733,7 @@ static int mysql_init_variables(void) what_to_log= ~ (1L << (uint) COM_TIME); refresh_version= 1L; /* Increments on each reload */ global_query_id= thread_id= 1L; + my_atomic_rwlock_init(&global_query_id_lock); strmov(server_version, MYSQL_SERVER_VERSION); myisam_recover_options_str= sql_mode_str= "OFF"; myisam_stats_method_str= "nulls_unequal"; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index aed19b76011..83f886a2fdb 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -2702,9 +2702,9 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, */ thd->lex= m_lex; - VOID(pthread_mutex_lock(&LOCK_thread_count)); + my_atomic_rwlock_wrlock(&global_query_id_lock); thd->query_id= next_query_id(); - VOID(pthread_mutex_unlock(&LOCK_thread_count)); + my_atomic_rwlock_wrunlock(&global_query_id_lock); if (thd->prelocked_mode == NON_PRELOCKED) { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index a09fed98d65..b0dcc9aff13 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -505,7 +505,9 @@ pthread_handler_t handle_bootstrap(void *arg) We don't need to obtain LOCK_thread_count here because in bootstrap mode we have only one thread. */ + my_atomic_rwlock_wrlock(&global_query_id_lock); thd->query_id=next_query_id(); + my_atomic_rwlock_wrunlock(&global_query_id_lock); thd->set_time(); mysql_parse(thd, thd->query, length, & found_semicolon); close_thread_tables(thd); // Free tables @@ -971,29 +973,30 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->enable_slow_log= TRUE; thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */ thd->set_time(); - VOID(pthread_mutex_lock(&LOCK_thread_count)); - thd->query_id= global_query_id; - - switch( command ) { - /* Ignore these statements. */ - case COM_STATISTICS: - case COM_PING: - break; - /* Only increase id on these statements but don't count them. */ - case COM_STMT_PREPARE: - case COM_STMT_CLOSE: - case COM_STMT_RESET: - next_query_id(); - break; - /* Increase id and count all other statements. */ - default: - statistic_increment(thd->status_var.questions, &LOCK_status); - next_query_id(); + my_atomic_rwlock_wrlock(&global_query_id_lock); + { + query_id_t query_id; + switch( command ) { + /* Ignore these statements. */ + case COM_STATISTICS: + case COM_PING: + query_id= get_query_id(); + break; + /* Only increase id on these statements but don't count them. */ + case COM_STMT_PREPARE: + case COM_STMT_CLOSE: + case COM_STMT_RESET: + query_id= next_query_id() - 1; + break; + /* Increase id and count all other statements. */ + default: + statistic_increment(thd->status_var.questions, &LOCK_status); + query_id= next_query_id() - 1; + } + thd->query_id= query_id; } - - thread_running++; - /* TODO: set thd->lex->sql_command to SQLCOM_END here */ - VOID(pthread_mutex_unlock(&LOCK_thread_count)); + inc_thread_running(); + my_atomic_rwlock_wrunlock(&global_query_id_lock); /** Clear the set of flags that are expected to be cleared at the @@ -1259,15 +1262,15 @@ bool dispatch_command(enum enum_server_command command, THD *thd, (char *) thd->security_ctx->host_or_ip); thd->set_query(beginning_of_next_stmt, length); - VOID(pthread_mutex_lock(&LOCK_thread_count)); /* Count each statement from the client. */ statistic_increment(thd->status_var.questions, &LOCK_status); + my_atomic_rwlock_wrlock(&global_query_id_lock); thd->query_id= next_query_id(); + my_atomic_rwlock_wrunlock(&global_query_id_lock); thd->set_time(); /* Reset the query start time. */ /* TODO: set thd->lex->sql_command to SQLCOM_END here */ - VOID(pthread_mutex_unlock(&LOCK_thread_count)); mysql_parse(thd, beginning_of_next_stmt, length, &end_of_stmt); } @@ -1610,9 +1613,9 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd_proc_info(thd, "cleaning up"); thd->set_query(NULL, 0); thd->command=COM_SLEEP; - VOID(pthread_mutex_lock(&LOCK_thread_count)); // For process list - thread_running--; - VOID(pthread_mutex_unlock(&LOCK_thread_count)); + my_atomic_rwlock_wrlock(&global_query_id_lock); + dec_thread_running(); + my_atomic_rwlock_wrunlock(&global_query_id_lock); thd_proc_info(thd, 0); thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); diff --git a/unittest/mysys/my_atomic-t.c b/unittest/mysys/my_atomic-t.c index f2bcd360508..9853d3cf964 100644 --- a/unittest/mysys/my_atomic-t.c +++ b/unittest/mysys/my_atomic-t.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2006 MySQL AB +/* Copyright (C) 2006-2008 MySQL AB, 2008 Sun Microsystems, Inc. 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 @@ -13,10 +13,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -#include -#include -#include -#include +#include "thr_template.c" /* at least gcc 3.4.5 and 3.4.6 (but not 3.2.3) on RHEL */ #if __GNUC__ == 3 && __GNUC_MINOR__ == 4 @@ -25,181 +22,162 @@ #define GCC_BUG_WORKAROUND #endif -int32 a32,b32,c32; +volatile uint32 b32; +volatile int32 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) +pthread_handler_t test_atomic_add(void *arg) { - int m=*(int *)arg; + int m= (*(int *)arg)/2; GCC_BUG_WORKAROUND int32 x; - for (x=((int)((long)(&m))); m ; m--) + for (x= ((int)(intptr)(&m)); m ; m--) { - x=x*m+0x87654321; + x= (x*m+0x87654321) & INT_MAX32; my_atomic_rwlock_wrlock(&rwl); - my_atomic_add32(&a32, x); + my_atomic_add32(&bad, x); my_atomic_rwlock_wrunlock(&rwl); my_atomic_rwlock_wrlock(&rwl); - my_atomic_add32(&a32, -x); + my_atomic_add32(&bad, -x); my_atomic_rwlock_wrunlock(&rwl); } pthread_mutex_lock(&mutex); - N--; - if (!N) pthread_cond_signal(&cond); + if (!--running_threads) pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); return 0; } +volatile int64 a64; +/* add and sub a random number in a loop. Must get 0 at the end */ +pthread_handler_t test_atomic_add64(void *arg) +{ + int m= (*(int *)arg)/2; + GCC_BUG_WORKAROUND int64 x; + for (x= ((int64)(intptr)(&m)); m ; m--) + { + x= (x*m+0xfdecba987654321LL) & INT_MAX64; + my_atomic_rwlock_wrlock(&rwl); + my_atomic_add64(&a64, x); + my_atomic_rwlock_wrunlock(&rwl); + + my_atomic_rwlock_wrlock(&rwl); + my_atomic_add64(&a64, -x); + my_atomic_rwlock_wrunlock(&rwl); + } + pthread_mutex_lock(&mutex); + if (!--running_threads) + { + bad= (a64 != 0); + pthread_cond_signal(&cond); + } + pthread_mutex_unlock(&mutex); + return 0; +} + + /* 1. generate thread number 0..N-1 from b32 - 2. add it to a32 + 2. add it to bad 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 + 5. subtract result from bad + must get 0 in bad at the end */ -pthread_handler_t test_atomic_swap_handler(void *arg) +pthread_handler_t test_atomic_fas(void *arg) { - int m=*(int *)arg; - int32 x; + int m= *(int *)arg; + int32 x; my_atomic_rwlock_wrlock(&rwl); - x=my_atomic_add32(&b32, 1); + x= my_atomic_add32(&b32, 1); my_atomic_rwlock_wrunlock(&rwl); my_atomic_rwlock_wrlock(&rwl); - my_atomic_add32(&a32, x); + my_atomic_add32(&bad, x); my_atomic_rwlock_wrunlock(&rwl); for (; m ; m--) { my_atomic_rwlock_wrlock(&rwl); - x=my_atomic_swap32(&c32, x); + x= my_atomic_fas32(&c32, x); my_atomic_rwlock_wrunlock(&rwl); } if (!x) { my_atomic_rwlock_wrlock(&rwl); - x=my_atomic_swap32(&c32, x); + x= my_atomic_fas32(&c32, x); my_atomic_rwlock_wrunlock(&rwl); } my_atomic_rwlock_wrlock(&rwl); - my_atomic_add32(&a32, -x); + my_atomic_add32(&bad, -x); my_atomic_rwlock_wrunlock(&rwl); pthread_mutex_lock(&mutex); - N--; - if (!N) pthread_cond_signal(&cond); + if (!--running_threads) 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 + same as test_atomic_add, but my_atomic_add32 is emulated with + my_atomic_cas32 - notice that the slowdown is proportional to the + number of CPUs */ -pthread_handler_t test_atomic_cas_handler(void *arg) +pthread_handler_t test_atomic_cas(void *arg) { - int m=*(int *)arg, ok; - GCC_BUG_WORKAROUND int32 x,y; - for (x=((int)((long)(&m))); m ; m--) + int m= (*(int *)arg)/2, ok= 0; + GCC_BUG_WORKAROUND int32 x, y; + for (x= ((int)(intptr)(&m)); m ; m--) { my_atomic_rwlock_wrlock(&rwl); - y=my_atomic_load32(&a32); + y= my_atomic_load32(&bad); my_atomic_rwlock_wrunlock(&rwl); - - x=x*m+0x87654321; + x= (x*m+0x87654321) & INT_MAX32; do { my_atomic_rwlock_wrlock(&rwl); - ok=my_atomic_cas32(&a32, &y, y+x); + ok= my_atomic_cas32(&bad, &y, (uint32)y+x); my_atomic_rwlock_wrunlock(&rwl); - } while (!ok); + } while (!ok) ; do { my_atomic_rwlock_wrlock(&rwl); - ok=my_atomic_cas32(&a32, &y, y-x); + ok= my_atomic_cas32(&bad, &y, y-x); my_atomic_rwlock_wrunlock(&rwl); - } while (!ok); + } while (!ok) ; } pthread_mutex_lock(&mutex); - N--; - if (!N) pthread_cond_signal(&cond); + if (!--running_threads) pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); return 0; } -void test_atomic(const char *test, pthread_handler handler, int n, int m) + +void do_tests() { - pthread_t t; - ulonglong now=my_getsystime(); + plan(6); - a32= 0; - b32= 0; - c32= 0; + bad= my_atomic_initialize(); + ok(!bad, "my_atomic_initialize() returned %d", bad); - 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); + b32= c32= 0; + test_concurrently("my_atomic_add32", test_atomic_add, THREADS, CYCLES); + b32= c32= 0; + test_concurrently("my_atomic_fas32", test_atomic_fas, THREADS, CYCLES); + b32= c32= 0; + test_concurrently("my_atomic_cas32", test_atomic_cas, THREADS, CYCLES); + + { + int64 b=0x1000200030004000LL; + a64=0; + my_atomic_add64(&a64, b); + ok(a64==b, "add64"); + } + a64=0; + test_concurrently("my_atomic_add64", test_atomic_add64, THREADS, CYCLES); - pthread_mutex_destroy(&mutex); - pthread_cond_destroy(&cond); - pthread_attr_destroy(&thr_attr); my_atomic_rwlock_destroy(&rwl); - return exit_status(); } - diff --git a/unittest/mysys/thr_template.c b/unittest/mysys/thr_template.c new file mode 100644 index 00000000000..1ac03e474fd --- /dev/null +++ b/unittest/mysys/thr_template.c @@ -0,0 +1,92 @@ +/* Copyright (C) 2006-2008 MySQL AB, 2008 Sun Microsystems, Inc. + + 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 +#include +#include +#include + +volatile uint32 bad; +pthread_attr_t thr_attr; +pthread_mutex_t mutex; +pthread_cond_t cond; +uint running_threads; + +void do_tests(); + +void test_concurrently(const char *test, pthread_handler handler, int n, int m) +{ + pthread_t t; + ulonglong now= my_getsystime(); + + bad= 0; + + diag("Testing %s with %d threads, %d iterations... ", test, n, m); + for (running_threads= n ; n ; n--) + { + if (pthread_create(&t, &thr_attr, handler, &m) != 0) + { + diag("Could not create thread"); + abort(); + } + } + pthread_mutex_lock(&mutex); + while (running_threads) + pthread_cond_wait(&cond, &mutex); + pthread_mutex_unlock(&mutex); + + now= my_getsystime()-now; + ok(!bad, "tested %s in %g secs (%d)", test, ((double)now)/1e7, bad); +} + +int main(int argc __attribute__((unused)), char **argv) +{ + MY_INIT("thd_template"); + + if (argv[1] && *argv[1]) + DBUG_SET_INITIAL(argv[1]); + + pthread_mutex_init(&mutex, 0); + pthread_cond_init(&cond, 0); + pthread_attr_init(&thr_attr); + pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED); + +#ifdef MY_ATOMIC_MODE_RWLOCKS +#if defined(HPUX11) || defined(__POWERPC__) /* showed to be very slow (scheduler-related) */ +#define CYCLES 300 +#else +#define CYCLES 3000 +#endif +#else +#define CYCLES 3000 +#endif +#define THREADS 30 + + diag("N CPUs: %d, atomic ops: %s", my_getncpus(), MY_ATOMIC_MODE); + + do_tests(); + + /* + 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_end(0); + return exit_status(); +} + From 73f9d9c3718be5e2a137c054f9eeeee5da823373 Mon Sep 17 00:00:00 2001 From: Mikael Ronstrom Date: Thu, 15 Oct 2009 15:03:43 +0200 Subject: [PATCH 05/23] Bug fixes to my_atomic infrastructure --- unittest/mysys/Makefile.am | 2 ++ 1 file changed, 2 insertions(+) diff --git a/unittest/mysys/Makefile.am b/unittest/mysys/Makefile.am index be91ef31c9d..118643bb061 100644 --- a/unittest/mysys/Makefile.am +++ b/unittest/mysys/Makefile.am @@ -16,6 +16,8 @@ AM_CPPFLAGS = @ZLIB_INCLUDES@ -I$(top_builddir)/include AM_CPPFLAGS += -I$(top_srcdir)/include -I$(top_srcdir)/unittest/mytap +noinst_HEADERS = thr_template.c + LDADD = $(top_builddir)/unittest/mytap/libmytap.a \ $(top_builddir)/mysys/libmysys.a \ $(top_builddir)/dbug/libdbug.a \ From 58494ba0dfb4fad76deb712383f71c684bb97091 Mon Sep 17 00:00:00 2001 From: Mikael Ronstrom Date: Tue, 10 Nov 2009 15:09:44 +0100 Subject: [PATCH 06/23] Review comments for LOCK_open patch --- include/hash.h | 10 ++++++---- mysys/hash.c | 26 ++++++++++++++++---------- sql/sql_base.cc | 12 ++++++------ 3 files changed, 28 insertions(+), 20 deletions(-) diff --git a/include/hash.h b/include/hash.h index b6fc365ab76..80408f75f4d 100644 --- a/include/hash.h +++ b/include/hash.h @@ -45,7 +45,6 @@ extern "C" { #define hash_element my_hash_element #define hash_search my_hash_search #define hash_first my_hash_first -#define hash_first_from_hash_value my_hash_first_from_hash_value #define hash_next my_hash_next #define hash_insert my_hash_insert #define hash_delete my_hash_delete @@ -65,6 +64,7 @@ extern "C" { /* flags for hash_init */ #define HASH_UNIQUE 1 /* hash_insert fails on duplicate key */ +typedef uint my_hash_value_type; typedef uchar *(*my_hash_get_key)(const uchar *,size_t*,my_bool); typedef void (*my_hash_free_key)(void *); @@ -95,13 +95,15 @@ void my_hash_free(HASH *tree); void my_hash_reset(HASH *hash); uchar *my_hash_element(HASH *hash, ulong idx); uchar *my_hash_search(const HASH *info, const uchar *key, size_t length); -uchar *my_hash_search_using_hash_value(const HASH *info, uint hash_value, +uchar *my_hash_search_using_hash_value(const HASH *info, + my_hash_value_type hash_value, const uchar *key, size_t length); -uint my_calc_hash(const HASH *info, const uchar *key, size_t length); +my_hash_value_type my_calc_hash(const HASH *info, + const uchar *key, size_t length); uchar *my_hash_first(const HASH *info, const uchar *key, size_t length, HASH_SEARCH_STATE *state); uchar *my_hash_first_from_hash_value(const HASH *info, - uint hash_value, + my_hash_value_type hash_value, const uchar *key, size_t length, HASH_SEARCH_STATE *state); diff --git a/mysys/hash.c b/mysys/hash.c index 367ac8713dd..ae754e5bd93 100644 --- a/mysys/hash.c +++ b/mysys/hash.c @@ -33,16 +33,18 @@ typedef struct st_hash_info { uchar *data; /* data for current entry */ } HASH_LINK; -static uint my_hash_mask(size_t hashnr, size_t buffmax, size_t maxlength); +static uint my_hash_mask(my_hash_value_type hashnr, + size_t buffmax, size_t maxlength); static void movelink(HASH_LINK *array,uint pos,uint next_link,uint newlink); static int hashcmp(const HASH *hash, HASH_LINK *pos, const uchar *key, size_t length); -static uint calc_hash(const HASH *hash, const uchar *key, size_t length) +static my_hash_value_type calc_hash(const HASH *hash, + const uchar *key, size_t length) { ulong nr1=1, nr2=4; hash->charset->coll->hash_sort(hash->charset,(uchar*) key,length,&nr1,&nr2); - return nr1; + return (my_hash_value_type)nr1; } /** @@ -179,7 +181,8 @@ my_hash_key(const HASH *hash, const uchar *record, size_t *length, /* Calculate pos according to keys */ -static uint my_hash_mask(size_t hashnr, size_t buffmax, size_t maxlength) +static uint my_hash_mask(my_hash_value_type hashnr, size_t buffmax, + size_t maxlength) { if ((hashnr & (buffmax-1)) < maxlength) return (hashnr & (buffmax-1)); return (hashnr & ((buffmax >> 1) -1)); @@ -200,7 +203,7 @@ static #if !defined(__USLC__) && !defined(__sgi) inline #endif -unsigned int rec_hashnr(HASH *hash,const uchar *record) +my_hash_value_type rec_hashnr(HASH *hash,const uchar *record) { size_t length; uchar *key= (uchar*) my_hash_key(hash, record, &length, 0); @@ -215,7 +218,7 @@ uchar* my_hash_search(const HASH *hash, const uchar *key, size_t length) } uchar* my_hash_search_using_hash_value(const HASH *hash, - uint hash_value, + my_hash_value_type hash_value, const uchar *key, size_t length) { @@ -224,7 +227,8 @@ uchar* my_hash_search_using_hash_value(const HASH *hash, key, length, &state); } -uint my_calc_hash(const HASH *hash, const uchar *key, size_t length) +my_hash_value_type my_calc_hash(const HASH *hash, + const uchar *key, size_t length) { return calc_hash(hash, key, length ? length : hash->key_length); } @@ -244,7 +248,7 @@ uchar* my_hash_first(const HASH *hash, const uchar *key, size_t length, } uchar* my_hash_first_from_hash_value(const HASH *hash, - uint hash_value, + my_hash_value_type hash_value, const uchar *key, size_t length, HASH_SEARCH_STATE *current_record) @@ -356,7 +360,8 @@ static int hashcmp(const HASH *hash, HASH_LINK *pos, const uchar *key, my_bool my_hash_insert(HASH *info, const uchar *record) { int flag; - size_t idx,halfbuff,hash_nr,first_index; + size_t idx,halfbuff,first_index; + my_hash_value_type hash_nr; uchar *ptr_to_rec,*ptr_to_rec2; HASH_LINK *data,*empty,*gpos,*gpos2,*pos; @@ -497,7 +502,8 @@ my_bool my_hash_insert(HASH *info, const uchar *record) my_bool my_hash_delete(HASH *hash, uchar *record) { - uint blength,pos2,pos_hashnr,lastpos_hashnr,idx,empty_index; + uint blength,pos2,idx,empty_index; + my_hash_value_type pos_hashnr, lastpos_hashnr; HASH_LINK *data,*lastpos,*gpos,*pos,*pos3,*empty; DBUG_ENTER("my_hash_delete"); if (!hash->records) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 064d277e0b4..9116d89ceed 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2513,7 +2513,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, char key[MAX_DBKEY_LENGTH]; uint key_length; char *alias= table_list->alias; - uint hash_value; + my_hash_value_type hash_value; HASH_SEARCH_STATE state; DBUG_ENTER("open_table"); @@ -2746,11 +2746,11 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, an implicit "pending locks queue" - see wait_for_locked_table_names for details. */ - for (table= (TABLE*) hash_first_from_hash_value(&open_cache, - hash_value, - (uchar*) key, - key_length, - &state); + for (table= (TABLE*) my_hash_first_from_hash_value(&open_cache, + hash_value, + (uchar*) key, + key_length, + &state); table && table->in_use ; table= (TABLE*) hash_next(&open_cache, (uchar*) key, key_length, &state)) From a11a7b7a8db6b2151321ae2b3f4a9702de72160a Mon Sep 17 00:00:00 2001 From: Mikael Ronstrom Date: Thu, 12 Nov 2009 12:17:31 +0100 Subject: [PATCH 07/23] WL#4949, Remove use of LOCK_alarm by instead using SO_SNDTIME0/SO_RCVTIME0 --- configure.in | 67 +++++++++++++++++++++++++++++++++++++++++++++++-- sql/net_serv.cc | 2 ++ 2 files changed, 67 insertions(+), 2 deletions(-) diff --git a/configure.in b/configure.in index 9fe5c741a03..227f7844037 100644 --- a/configure.in +++ b/configure.in @@ -859,10 +859,73 @@ AC_CHECK_DECLS(MHA_MAPSIZE_VA, #include ] ) - - fi +dnl Use of ALARMs to wakeup on timeout on sockets +dnl +dnl This feature makes use of a mutex and is a scalability hog we +dnl try to avoid using. However we need support for SO_SNDTIMEO and +dnl SO_RCVTIMEO socket options for this to work. So we will check +dnl if this feature is supported by a simple AC_RUN_IFELSE macro. However +dnl on some OS's there is support for setting those variables but +dnl they are silently ignored. For those OS's we will not attempt +dnl o use SO_SNDTIMEO and SO_RCVTIMEO even if it is said to work. +dnl See Bug#29093 for the problem with SO_SND/RCVTIMEO on HP/UX. +dnl To use alarm is simple, simply avoid setting anything. + + +AC_CACHE_CHECK([whether SO_SNDTIMEO and SO_RCVTIMEO work], + [mysql_cv_socket_timeout], + [AC_RUN_IFELSE( + [AC_LANG_PROGRAM([[ + #include + #include + #include + ]],[[ + int fd = socket(AF_INET, SOCK_STREAM, 0); + struct timeval tv; + int ret= 0; + tv.tv_sec= 2; + tv.tv_usec= 0; + ret|= setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); + ret|= setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); + return !!ret; + ]])], + [mysql_cv_socket_timeout=yes], + [mysql_cv_socket_timeout=no], + [mysql_cv_socket_timeout=no + AC_MSG_WARN([Socket timeout options disabled due to cross-compiling])]) + ]) + +use_alarm=yes + +if test "$mysql_cv_socket_timeout" = yes; then + case $SYSTEM_TYPE in + dnl We trust the result from the following systems + *solaris*) use_alarm=no ;; + *freebsd*) use_alarm=no ;; + *darwin*) use_alarm=no ;; + *) + dnl We trust the result from Linux also + if test "$TARGET_LINUX" = "true"; then + use_alarm=no + fi + dnl We trust no one else for the moment + dnl (Windows is hardcoded to not use alarms) + ;; + esac +fi + +AC_ARG_WITH(alarm, + AS_HELP_STRING([--with-alarm], [Use alarm to implement socket timeout.]), + [use_alarm=$withval], []) + +AC_MSG_CHECKING(whether to use alarms to implement socket timeout) +if test "$use_alarm" = no ; then + AC_DEFINE([NO_ALARM], [1], [No need to use alarm for socket timeout]) +fi +AC_MSG_RESULT($use_alarm) + #-------------------------------------------------------------------- # Check for TCP wrapper support #-------------------------------------------------------------------- diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 5cf3597c638..d54ff1d2779 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -71,8 +71,10 @@ #if defined(__WIN__) || !defined(MYSQL_SERVER) /* The following is because alarms doesn't work on windows. */ +#ifndef NO_ALARM #define NO_ALARM #endif +#endif #ifndef NO_ALARM #include "my_pthread.h" From c9442b67f61e94a2489a360f2f627f5b82341d90 Mon Sep 17 00:00:00 2001 From: Mikael Ronstrom Date: Fri, 20 Nov 2009 16:43:21 +0100 Subject: [PATCH 08/23] WL#5138, review fixes --- sql/event_scheduler.cc | 18 +++++++++--------- sql/mysql_priv.h | 4 ++-- sql/mysqld.cc | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index 880bccdd67e..411be5a9d20 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -158,12 +158,12 @@ deinit_event_thread(THD *thd) DBUG_PRINT("exit", ("Event thread finishing")); pthread_mutex_lock(&LOCK_thread_count); thread_count--; - delete thd; - pthread_cond_broadcast(&COND_thread_count); - pthread_mutex_unlock(&LOCK_thread_count); my_atomic_rwlock_wrlock(&global_query_id_lock); dec_thread_running(); my_atomic_rwlock_wrunlock(&global_query_id_lock); + delete thd; + pthread_cond_broadcast(&COND_thread_count); + pthread_mutex_unlock(&LOCK_thread_count); } @@ -421,12 +421,12 @@ Event_scheduler::start() net_end(&new_thd->net); pthread_mutex_lock(&LOCK_thread_count); thread_count--; - delete new_thd; - pthread_cond_broadcast(&COND_thread_count); - pthread_mutex_unlock(&LOCK_thread_count); my_atomic_rwlock_wrlock(&global_query_id_lock); dec_thread_running(); my_atomic_rwlock_wrunlock(&global_query_id_lock); + delete new_thd; + pthread_cond_broadcast(&COND_thread_count); + pthread_mutex_unlock(&LOCK_thread_count); } end: UNLOCK_DATA(); @@ -556,12 +556,12 @@ error: net_end(&new_thd->net); pthread_mutex_lock(&LOCK_thread_count); thread_count--; - delete new_thd; - pthread_cond_broadcast(&COND_thread_count); - pthread_mutex_unlock(&LOCK_thread_count); my_atomic_rwlock_wrlock(&global_query_id_lock); dec_thread_running(); my_atomic_rwlock_wrunlock(&global_query_id_lock); + delete new_thd; + pthread_cond_broadcast(&COND_thread_count); + pthread_mutex_unlock(&LOCK_thread_count); } delete event_name; DBUG_RETURN(TRUE); diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 0caf3197fb8..b816f692320 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -86,9 +86,9 @@ typedef ulong nesting_map; /* Used for flags of nesting constructs */ typedef ulonglong nested_join_map; /* query_id */ -typedef int64 query_id_t; +typedef uint64 query_id_t; extern query_id_t global_query_id; -extern int32 thread_running; +extern uint32 thread_running; extern my_atomic_rwlock_t global_query_id_lock; /* increment query_id and return it. */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index ddc6d53e019..253ed36ce31 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -532,7 +532,7 @@ uint delay_key_write_options, protocol_version; uint lower_case_table_names; uint tc_heuristic_recover= 0; uint volatile thread_count; -int32 thread_running; +uint32 thread_running; ulonglong thd_startup_options; ulong back_log, connect_timeout, concurrency, server_id; ulong table_cache_size, table_def_size; From 0e613ab88486f275f2fed06dea3f85109d90e248 Mon Sep 17 00:00:00 2001 From: Mikael Ronstrom Date: Fri, 20 Nov 2009 18:42:15 +0100 Subject: [PATCH 09/23] WL#5138, reverted some review fixes --- sql/mysql_priv.h | 4 ++-- sql/mysqld.cc | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index b816f692320..0caf3197fb8 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -86,9 +86,9 @@ typedef ulong nesting_map; /* Used for flags of nesting constructs */ typedef ulonglong nested_join_map; /* query_id */ -typedef uint64 query_id_t; +typedef int64 query_id_t; extern query_id_t global_query_id; -extern uint32 thread_running; +extern int32 thread_running; extern my_atomic_rwlock_t global_query_id_lock; /* increment query_id and return it. */ diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 253ed36ce31..ddc6d53e019 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -532,7 +532,7 @@ uint delay_key_write_options, protocol_version; uint lower_case_table_names; uint tc_heuristic_recover= 0; uint volatile thread_count; -uint32 thread_running; +int32 thread_running; ulonglong thd_startup_options; ulong back_log, connect_timeout, concurrency, server_id; ulong table_cache_size, table_def_size; From 1ab1e21ef640a50044a5d800c7b402d73d07003e Mon Sep 17 00:00:00 2001 From: Mikael Ronstrom Date: Fri, 20 Nov 2009 20:01:43 +0100 Subject: [PATCH 10/23] WL#5105, review fix --- mysys/ptr_cmp.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/mysys/ptr_cmp.c b/mysys/ptr_cmp.c index 9f053f0b3b4..2005e3eb2b7 100644 --- a/mysys/ptr_cmp.c +++ b/mysys/ptr_cmp.c @@ -22,7 +22,7 @@ #include "mysys_priv.h" #include -#ifdef UNIV_SOLARIS +#ifdef TARGET_OS_SOLARIS /* * On Solaris, memcmp() is normally faster than the unrolled ptr_compare_N * functions, as memcmp() is usually a platform-specific implementation @@ -39,20 +39,20 @@ static int native_compare(size_t *length, unsigned char **a, unsigned char **b) return memcmp(*a, *b, *length); } -#else /* UNIV_SOLARIS */ +#else /* TARGET_OS_SOLARIS */ static int ptr_compare(size_t *compare_length, uchar **a, uchar **b); static int ptr_compare_0(size_t *compare_length, uchar **a, uchar **b); static int ptr_compare_1(size_t *compare_length, uchar **a, uchar **b); static int ptr_compare_2(size_t *compare_length, uchar **a, uchar **b); static int ptr_compare_3(size_t *compare_length, uchar **a, uchar **b); -#endif /* UNIV_SOLARIS */ +#endif /* TARGET_OS_SOLARIS */ /* Get a pointer to a optimal byte-compare function for a given size */ qsort2_cmp get_ptr_compare (size_t size) { -#ifdef UNIV_SOLARIS +#ifdef TARGET_OS_SOLARIS return (qsort2_cmp) native_compare; #else if (size < 4) @@ -64,7 +64,7 @@ qsort2_cmp get_ptr_compare (size_t size) case 3: return (qsort2_cmp) ptr_compare_3; } return 0; /* Impossible */ -#endif /* UNIV_SOLARIS */ +#endif /* TARGET_OS_SOLARIS */ } From 39703a1b933779436cbb2b0d2fcdd99a0864855b Mon Sep 17 00:00:00 2001 From: Mikael Ronstrom Date: Mon, 23 Nov 2009 17:57:21 +0100 Subject: [PATCH 11/23] WL#5138, fixed review comments --- sql/event_scheduler.cc | 10 +--------- sql/log_event.cc | 6 ------ sql/mysql_priv.h | 11 +++++++++++ sql/mysqld.cc | 3 +++ sql/sp_head.cc | 2 -- sql/sql_parse.cc | 8 -------- 6 files changed, 15 insertions(+), 25 deletions(-) diff --git a/sql/event_scheduler.cc b/sql/event_scheduler.cc index 411be5a9d20..69e5f30ad31 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -133,10 +133,8 @@ post_init_event_thread(THD *thd) pthread_mutex_lock(&LOCK_thread_count); threads.append(thd); thread_count++; - pthread_mutex_unlock(&LOCK_thread_count); - my_atomic_rwlock_wrlock(&global_query_id_lock); inc_thread_running(); - my_atomic_rwlock_wrunlock(&global_query_id_lock); + pthread_mutex_unlock(&LOCK_thread_count); return FALSE; } @@ -158,9 +156,7 @@ deinit_event_thread(THD *thd) DBUG_PRINT("exit", ("Event thread finishing")); pthread_mutex_lock(&LOCK_thread_count); thread_count--; - my_atomic_rwlock_wrlock(&global_query_id_lock); dec_thread_running(); - my_atomic_rwlock_wrunlock(&global_query_id_lock); delete thd; pthread_cond_broadcast(&COND_thread_count); pthread_mutex_unlock(&LOCK_thread_count); @@ -421,9 +417,7 @@ Event_scheduler::start() net_end(&new_thd->net); pthread_mutex_lock(&LOCK_thread_count); thread_count--; - my_atomic_rwlock_wrlock(&global_query_id_lock); dec_thread_running(); - my_atomic_rwlock_wrunlock(&global_query_id_lock); delete new_thd; pthread_cond_broadcast(&COND_thread_count); pthread_mutex_unlock(&LOCK_thread_count); @@ -556,9 +550,7 @@ error: net_end(&new_thd->net); pthread_mutex_lock(&LOCK_thread_count); thread_count--; - my_atomic_rwlock_wrlock(&global_query_id_lock); dec_thread_running(); - my_atomic_rwlock_wrunlock(&global_query_id_lock); delete new_thd; pthread_cond_broadcast(&COND_thread_count); pthread_mutex_unlock(&LOCK_thread_count); diff --git a/sql/log_event.cc b/sql/log_event.cc index 31908a818be..58ed5aa6a60 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -3056,9 +3056,7 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli, { thd->set_time((time_t)when); thd->set_query((char*)query_arg, q_len_arg); - my_atomic_rwlock_wrlock(&global_query_id_lock); thd->query_id = next_query_id(); - my_atomic_rwlock_wrunlock(&global_query_id_lock); thd->variables.pseudo_thread_id= thread_id; // for temp tables DBUG_PRINT("query",("%s", thd->query())); @@ -4581,9 +4579,7 @@ int Load_log_event::do_apply_event(NET* net, Relay_log_info const *rli, if (rpl_filter->db_ok(thd->db)) { thd->set_time((time_t)when); - my_atomic_rwlock_wrlock(&global_query_id_lock); thd->query_id = next_query_id(); - my_atomic_rwlock_wrunlock(&global_query_id_lock); thd->warning_info->opt_clear_warning_info(thd->query_id); TABLE_LIST tables; @@ -8072,9 +8068,7 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli) DBUG_ASSERT(rli->sql_thd == thd); /* Step the query id to mark what columns that are actually used. */ - my_atomic_rwlock_wrlock(&global_query_id_lock); thd->query_id= next_query_id(); - my_atomic_rwlock_wrunlock(&global_query_id_lock); if (!(memory= my_multi_malloc(MYF(MY_WME), &table_list, (uint) sizeof(RPL_TABLE_LIST), diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 0caf3197fb8..ec6aa274e49 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -90,19 +90,24 @@ typedef int64 query_id_t; extern query_id_t global_query_id; extern int32 thread_running; extern my_atomic_rwlock_t global_query_id_lock; +extern my_atomic_rwlock_t thread_running_lock; /* increment query_id and return it. */ inline query_id_t next_query_id() { query_id_t id; + my_atomic_rwlock_wrlock(&global_query_id_lock); id= my_atomic_add64(&global_query_id, 1); + my_atomic_rwlock_wrunlock(&global_query_id_lock); return (id+1); } inline query_id_t get_query_id() { query_id_t id; + my_atomic_rwlock_wrlock(&global_query_id_lock); id= my_atomic_load64(&global_query_id); + my_atomic_rwlock_wrunlock(&global_query_id_lock); return id; } @@ -110,7 +115,9 @@ inline int32 inc_thread_running() { int32 num_thread_running; + my_atomic_rwlock_wrlock(&thread_running_lock); num_thread_running= my_atomic_add32(&thread_running, 1); + my_atomic_rwlock_wrunlock(&thread_running_lock); return (num_thread_running+1); } @@ -118,7 +125,9 @@ inline int32 dec_thread_running() { int32 num_thread_running; + my_atomic_rwlock_wrlock(&thread_running_lock); num_thread_running= my_atomic_add32(&thread_running, -1); + my_atomic_rwlock_wrunlock(&thread_running_lock); return (num_thread_running-1); } @@ -126,7 +135,9 @@ inline int32 get_thread_running() { int32 num_thread_running; + my_atomic_rwlock_wrlock(&thread_running_lock); num_thread_running= my_atomic_load32(&thread_running); + my_atomic_rwlock_wrunlock(&thread_running_lock); return num_thread_running; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index ddc6d53e019..e841f869b95 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -549,6 +549,7 @@ ulong query_cache_size=0; ulong refresh_version; /* Increments on each reload */ query_id_t global_query_id; my_atomic_rwlock_t global_query_id_lock; +my_atomic_rwlock_t thread_running_lock; ulong aborted_threads, aborted_connects; ulong delayed_insert_timeout, delayed_insert_limit, delayed_queue_size; ulong delayed_insert_threads, delayed_insert_writes, delayed_rows_in_use; @@ -1383,6 +1384,7 @@ void clean_up(bool print_message) /* Tell main we are ready */ logger.cleanup_end(); my_atomic_rwlock_destroy(&global_query_id_lock); + my_atomic_rwlock_destroy(&thread_running_lock); (void) pthread_mutex_lock(&LOCK_thread_count); DBUG_PRINT("quit", ("got thread count lock")); ready_to_exit=1; @@ -7799,6 +7801,7 @@ static int mysql_init_variables(void) refresh_version= 1L; /* Increments on each reload */ global_query_id= thread_id= 1L; my_atomic_rwlock_init(&global_query_id_lock); + my_atomic_rwlock_init(&thread_running_lock); strmov(server_version, MYSQL_SERVER_VERSION); myisam_recover_options_str= sql_mode_str= "OFF"; myisam_stats_method_str= "nulls_unequal"; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index d0453c08a00..705fd2f702b 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -2736,9 +2736,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, */ thd->lex= m_lex; - my_atomic_rwlock_wrlock(&global_query_id_lock); thd->query_id= next_query_id(); - my_atomic_rwlock_wrunlock(&global_query_id_lock); if (thd->prelocked_mode == NON_PRELOCKED) { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 7b5df421785..83a54d1a59f 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -495,9 +495,7 @@ static void handle_bootstrap_impl(THD *thd) We don't need to obtain LOCK_thread_count here because in bootstrap mode we have only one thread. */ - my_atomic_rwlock_wrlock(&global_query_id_lock); thd->query_id=next_query_id(); - my_atomic_rwlock_wrunlock(&global_query_id_lock); thd->set_time(); mysql_parse(thd, thd->query(), length, & found_semicolon); close_thread_tables(thd); // Free tables @@ -991,7 +989,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->enable_slow_log= TRUE; thd->lex->sql_command= SQLCOM_END; /* to avoid confusing VIEW detectors */ thd->set_time(); - my_atomic_rwlock_wrlock(&global_query_id_lock); { query_id_t query_id; switch( command ) { @@ -1014,7 +1011,6 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->query_id= query_id; } inc_thread_running(); - my_atomic_rwlock_wrunlock(&global_query_id_lock); /** Clear the set of flags that are expected to be cleared at the @@ -1284,9 +1280,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, Count each statement from the client. */ statistic_increment(thd->status_var.questions, &LOCK_status); - my_atomic_rwlock_wrlock(&global_query_id_lock); thd->query_id= next_query_id(); - my_atomic_rwlock_wrunlock(&global_query_id_lock); thd->set_time(); /* Reset the query start time. */ /* TODO: set thd->lex->sql_command to SQLCOM_END here */ mysql_parse(thd, beginning_of_next_stmt, length, &end_of_stmt); @@ -1604,9 +1598,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd_proc_info(thd, "cleaning up"); thd->set_query(NULL, 0); thd->command=COM_SLEEP; - my_atomic_rwlock_wrlock(&global_query_id_lock); dec_thread_running(); - my_atomic_rwlock_wrunlock(&global_query_id_lock); thd_proc_info(thd, 0); thd->packet.shrink(thd->variables.net_buffer_length); // Reclaim some memory free_root(thd->mem_root,MYF(MY_KEEP_PREALLOC)); From 9ea65e5fa98ad56925d709d853a621de38cf1a71 Mon Sep 17 00:00:00 2001 From: Mikael Ronstrom Date: Tue, 24 Nov 2009 14:28:38 +0100 Subject: [PATCH 12/23] WL#5138, Fixed according to code review comments from Davi --- sql/log_event.cc | 5 ++--- sql/sp_head.cc | 4 ++-- sql/sql_class.cc | 20 ++++++++++++++++++++ sql/sql_class.h | 5 ++++- sql/sql_cursor.cc | 2 +- sql/sql_parse.cc | 8 +++----- 6 files changed, 32 insertions(+), 12 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 58ed5aa6a60..608f4d25cf4 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -3055,8 +3055,7 @@ int Query_log_event::do_apply_event(Relay_log_info const *rli, rpl_filter->db_ok(thd->db)) { thd->set_time((time_t)when); - thd->set_query((char*)query_arg, q_len_arg); - thd->query_id = next_query_id(); + thd->set_query_and_id((char*)query_arg, q_len_arg, next_query_id()); thd->variables.pseudo_thread_id= thread_id; // for temp tables DBUG_PRINT("query",("%s", thd->query())); @@ -8068,7 +8067,7 @@ int Table_map_log_event::do_apply_event(Relay_log_info const *rli) DBUG_ASSERT(rli->sql_thd == thd); /* Step the query id to mark what columns that are actually used. */ - thd->query_id= next_query_id(); + thd->set_query_id(next_query_id()); if (!(memory= my_multi_malloc(MYF(MY_WME), &table_list, (uint) sizeof(RPL_TABLE_LIST), diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 705fd2f702b..dae4a03c7f5 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1338,7 +1338,7 @@ sp_head::execute(THD *thd) /* To avoid wiping out thd->change_list on old_change_list destruction */ old_change_list.empty(); thd->lex= old_lex; - thd->query_id= old_query_id; + thd->set_query_id(old_query_id); DBUG_ASSERT(!thd->derived_tables); thd->derived_tables= old_derived_tables; thd->variables.sql_mode= save_sql_mode; @@ -2736,7 +2736,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, */ thd->lex= m_lex; - thd->query_id= next_query_id(); + thd->set_query_id(next_query_id()); if (thd->prelocked_mode == NON_PRELOCKED) { diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 60aed4ce53b..d8fb64878aa 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -3273,6 +3273,26 @@ void THD::set_query(char *query_arg, uint32 query_length_arg) pthread_mutex_unlock(&LOCK_thd_data); } +/** Assign a new value to thd->query and thd->query_id. */ + +void THD::set_query_and_id(char *query_arg, uint32 query_length_arg, + query_id_t new_query_id) +{ + pthread_mutex_lock(&LOCK_thd_data); + set_query_inner(query_arg, query_length_arg); + query_id= new_query_id; + pthread_mutex_unlock(&LOCK_thd_data); +} + +/** Assign a new value to thd->query_id. */ + +void THD::set_query_id(query_id_t new_query_id) +{ + pthread_mutex_lock(&LOCK_thd_data); + query_id= new_query_id; + pthread_mutex_unlock(&LOCK_thd_data); +} + /** Mark transaction to rollback and mark error as fatal to a sub-statement. diff --git a/sql/sql_class.h b/sql/sql_class.h index 2dd45997ee1..79e87a5ca3d 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2324,10 +2324,13 @@ public: virtual void set_statement(Statement *stmt); /** - Assign a new value to thd->query. + Assign a new value to thd->query and thd->query_id. Protected with LOCK_thd_data mutex. */ void set_query(char *query_arg, uint32 query_length_arg); + void set_query_and_id(char *query_arg, uint32 query_length_arg, + query_id_t new_query_id); + void set_query_id(query_id_t new_query_id); private: /** The current internal error handler for this thread, or NULL. */ Internal_error_handler *m_internal_handler; diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index ffc3fafe55f..533b47e61da 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -438,7 +438,7 @@ Sensitive_cursor::fetch(ulong num_rows) thd->derived_tables= derived_tables; thd->open_tables= open_tables; thd->lock= lock; - thd->query_id= query_id; + thd->set_query_id(query_id); thd->change_list= change_list; /* save references to memory allocated during fetch */ thd->set_n_backup_active_arena(this, &backup_arena); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 83a54d1a59f..f2b9d613e3a 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -484,7 +484,7 @@ static void handle_bootstrap_impl(THD *thd) query= (char *) thd->memdup_w_gap(buff, length + 1, thd->db_length + 1 + QUERY_CACHE_FLAGS_SIZE); - thd->set_query(query, length); + thd->set_query_and_id(query, length, next_query_id()); DBUG_PRINT("query",("%-.4096s",thd->query())); #if defined(ENABLED_PROFILING) thd->profiling.start_new_query(); @@ -495,7 +495,6 @@ static void handle_bootstrap_impl(THD *thd) We don't need to obtain LOCK_thread_count here because in bootstrap mode we have only one thread. */ - thd->query_id=next_query_id(); thd->set_time(); mysql_parse(thd, thd->query(), length, & found_semicolon); close_thread_tables(thd); // Free tables @@ -1008,7 +1007,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, statistic_increment(thd->status_var.questions, &LOCK_status); query_id= next_query_id() - 1; } - thd->query_id= query_id; + thd->set_query_id(query_id); } inc_thread_running(); @@ -1275,12 +1274,11 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->security_ctx->priv_user, (char *) thd->security_ctx->host_or_ip); - thd->set_query(beginning_of_next_stmt, length); + thd->set_query_and_id(beginning_of_next_stmt, length, next_query_id()); /* Count each statement from the client. */ statistic_increment(thd->status_var.questions, &LOCK_status); - thd->query_id= next_query_id(); thd->set_time(); /* Reset the query start time. */ /* TODO: set thd->lex->sql_command to SQLCOM_END here */ mysql_parse(thd, beginning_of_next_stmt, length, &end_of_stmt); From 62c39a339b0b5d57595e98dded3c82cc5fc394ac Mon Sep 17 00:00:00 2001 From: Mikael Ronstrom Date: Thu, 26 Nov 2009 13:48:21 +0100 Subject: [PATCH 13/23] Fixed kill_alarm test and got it working --- configure.in | 1 + mysql-test/r/kill_alarm.result | 10 ++++++++++ mysql-test/t/kill_alarm.test | 13 +++++++++++++ 3 files changed, 24 insertions(+) create mode 100644 mysql-test/r/kill_alarm.result create mode 100644 mysql-test/t/kill_alarm.test diff --git a/configure.in b/configure.in index 783b4444a28..890fc333cee 100644 --- a/configure.in +++ b/configure.in @@ -923,6 +923,7 @@ AC_ARG_WITH(alarm, AC_MSG_CHECKING(whether to use alarms to implement socket timeout) if test "$use_alarm" = no ; then AC_DEFINE([NO_ALARM], [1], [No need to use alarm for socket timeout]) + AC_DEFINE([SIGNAL_WITH_VIO_CLOSE], [1], [Need to use vio close for kill connection]) fi AC_MSG_RESULT($use_alarm) diff --git a/mysql-test/r/kill_alarm.result b/mysql-test/r/kill_alarm.result new file mode 100644 index 00000000000..27636f55c97 --- /dev/null +++ b/mysql-test/r/kill_alarm.result @@ -0,0 +1,10 @@ +show processlist; +Id User Host db Command Time State Info +2 root localhost test Sleep 0 NULL +3 root localhost test Sleep 0 NULL +4 root localhost test Query 0 NULL show processlist +kill connection 3; +show processlist; +Id User Host db Command Time State Info +2 root localhost test Sleep 4 NULL +4 root localhost test Query 0 NULL show processlist diff --git a/mysql-test/t/kill_alarm.test b/mysql-test/t/kill_alarm.test new file mode 100644 index 00000000000..c08eb3dcf83 --- /dev/null +++ b/mysql-test/t/kill_alarm.test @@ -0,0 +1,13 @@ +-- source include/not_embedded.inc + +connect (con1, localhost, root,,); +connect (con2, localhost, root,,); + +connection con1; +let $ID=`select connection_id()`; + +connection con2; +show processlist; +eval kill connection $ID; +--sleep 4 +show processlist; From 8df0c15b36964eac2dfc259ad59fa692fbb63184 Mon Sep 17 00:00:00 2001 From: Mikael Ronstrom Date: Thu, 26 Nov 2009 13:58:59 +0100 Subject: [PATCH 14/23] Removed extra test case after review comment --- mysql-test/r/kill_alarm.result | 10 ---------- mysql-test/t/kill_alarm.test | 13 ------------- 2 files changed, 23 deletions(-) delete mode 100644 mysql-test/r/kill_alarm.result delete mode 100644 mysql-test/t/kill_alarm.test diff --git a/mysql-test/r/kill_alarm.result b/mysql-test/r/kill_alarm.result deleted file mode 100644 index 27636f55c97..00000000000 --- a/mysql-test/r/kill_alarm.result +++ /dev/null @@ -1,10 +0,0 @@ -show processlist; -Id User Host db Command Time State Info -2 root localhost test Sleep 0 NULL -3 root localhost test Sleep 0 NULL -4 root localhost test Query 0 NULL show processlist -kill connection 3; -show processlist; -Id User Host db Command Time State Info -2 root localhost test Sleep 4 NULL -4 root localhost test Query 0 NULL show processlist diff --git a/mysql-test/t/kill_alarm.test b/mysql-test/t/kill_alarm.test deleted file mode 100644 index c08eb3dcf83..00000000000 --- a/mysql-test/t/kill_alarm.test +++ /dev/null @@ -1,13 +0,0 @@ --- source include/not_embedded.inc - -connect (con1, localhost, root,,); -connect (con2, localhost, root,,); - -connection con1; -let $ID=`select connection_id()`; - -connection con2; -show processlist; -eval kill connection $ID; ---sleep 4 -show processlist; From 268be884572918ac227573a9fd9eb811d74c1a7d Mon Sep 17 00:00:00 2001 From: Mikael Ronstrom Date: Tue, 8 Dec 2009 11:14:51 +0100 Subject: [PATCH 15/23] Fixed --fast flag on Linux to use -O3 --- BUILD/build_mccge.sh | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/BUILD/build_mccge.sh b/BUILD/build_mccge.sh index 3345ac3dcb5..8ca31b2d119 100755 --- a/BUILD/build_mccge.sh +++ b/BUILD/build_mccge.sh @@ -1303,7 +1303,11 @@ set_linux_configs() compiler_flags="$compiler_flags -m32" fi if test "x$fast_flag" != "xno" ; then - compiler_flags="$compiler_flags -O2" + if test "x$fast_flag" = "xyes" ; then + compiler_flags="$compiler_flags -O3" + else + compiler_flags="$compiler_flags -O2" + fi else compiler_flags="$compiler_flags -O0" fi From c082955f0676efe069f30384102ba7807b49dee6 Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Wed, 9 Dec 2009 20:19:51 -0700 Subject: [PATCH 16/23] WL#2360 Performance schema Part III: mysys instrumentation --- client/client_priv.h | 23 ++- client/mysqlcheck.c | 9 +- client/mysqldump.c | 24 ++- include/keycache.h | 4 +- include/my_bitmap.h | 4 +- include/my_pthread.h | 18 +- include/my_sys.h | 13 +- include/thr_lock.h | 9 +- mysys/charset.c | 16 +- mysys/default.c | 12 +- mysys/mf_iocache.c | 48 +++--- mysys/mf_iocache2.c | 6 +- mysys/mf_keycache.c | 65 ++++---- mysys/mf_tempdir.c | 12 +- mysys/my_bitmap.c | 14 +- mysys/my_fopen.c | 16 +- mysys/my_gethostbyname.c | 8 +- mysys/my_getopt.c | 42 +++-- mysys/my_getsystime.c | 6 +- mysys/my_init.c | 194 +++++++++++++++++++--- mysys/my_largepage.c | 11 +- mysys/my_lib.c | 8 +- mysys/my_lock.c | 6 +- mysys/my_lockmem.c | 10 +- mysys/my_net.c | 6 +- mysys/my_open.c | 17 +- mysys/my_pread.c | 10 +- mysys/my_pthread.c | 20 +-- mysys/my_thr_init.c | 190 +++++++++++++++------ mysys/my_winfile.c | 6 +- mysys/mysys_priv.h | 6 +- mysys/safemalloc.c | 18 +- mysys/thr_alarm.c | 111 +++++++------ mysys/thr_lock.c | 150 ++++++++--------- mysys/thr_mutex.c | 11 +- plugin/semisync/semisync_master.cc | 24 +-- plugin/semisync/semisync_master.h | 14 +- plugin/semisync/semisync_master_plugin.cc | 36 +++- sql/debug_sync.cc | 96 +++++++---- sql/ha_ndbcluster.cc | 24 +-- sql/ha_ndbcluster_binlog.cc | 38 ++--- sql/item_func.cc | 104 +++++++----- sql/lock.cc | 12 +- sql/mysql_priv.h | 17 +- sql/mysqld.cc | 61 ++++--- sql/replication.h | 6 +- sql/sp_cache.cc | 30 +++- sql/sql_base.cc | 152 ++++++++--------- sql/sql_class.cc | 18 +- sql/sql_class.h | 16 +- sql/sql_db.cc | 116 ++++++++----- sql/sql_delete.cc | 12 +- sql/sql_handler.cc | 6 +- sql/sql_insert.cc | 177 ++++++++++---------- sql/sql_parse.cc | 4 +- sql/sql_partition.cc | 8 +- sql/sql_plugin.cc | 4 +- sql/sql_rename.cc | 10 +- sql/sql_show.cc | 28 ++-- sql/sql_table.cc | 134 +++++++-------- sql/sql_test.cc | 16 +- sql/sql_trigger.cc | 6 +- sql/sql_view.cc | 8 +- storage/federated/ha_federated.cc | 2 +- 64 files changed, 1383 insertions(+), 919 deletions(-) diff --git a/client/client_priv.h b/client/client_priv.h index 53027465771..97a8920f744 100644 --- a/client/client_priv.h +++ b/client/client_priv.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2001-2006 MySQL AB +/* Copyright (C) 2001-2006 MySQL AB, 2009 Sun Microsystems, Inc 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 @@ -87,3 +87,24 @@ enum options_client OPT_INIT_COMMAND, OPT_MAX_CLIENT_OPTION }; + +/** + First mysql version supporting the information schema. +*/ +#define FIRST_INFORMATION_SCHEMA_VERSION 50003 + +/** + Name of the information schema database. +*/ +#define INFORMATION_SCHEMA_DB_NAME "information_schema" + +/** + First mysql version supporting the performance schema. +*/ +#define FIRST_PERFORMANCE_SCHEMA_VERSION 50600 + +/** + Name of the performance schema database. +*/ +#define PERFORMANCE_SCHEMA_DB_NAME "performance_schema" + diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index 5c801eb6e26..efbb95b6657 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000 MySQL AB, 2009 Sun Microsystems, Inc 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 @@ -644,8 +644,11 @@ static int process_one_db(char *database) static int use_db(char *database) { - if (mysql_get_server_version(sock) >= 50003 && - !my_strcasecmp(&my_charset_latin1, database, "information_schema")) + if (mysql_get_server_version(sock) >= FIRST_INFORMATION_SCHEMA_VERSION && + !my_strcasecmp(&my_charset_latin1, database, INFORMATION_SCHEMA_DB_NAME)) + return 1; + if (mysql_get_server_version(sock) >= FIRST_PERFORMANCE_SCHEMA_VERSION && + !my_strcasecmp(&my_charset_latin1, database, PERFORMANCE_SCHEMA_DB_NAME)) return 1; if (mysql_select_db(sock, database)) { diff --git a/client/mysqldump.c b/client/mysqldump.c index ebf0add4590..f9a64e4c9d2 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -3836,8 +3836,12 @@ static int dump_all_databases() return 1; while ((row= mysql_fetch_row(tableres))) { - if (mysql_get_server_version(mysql) >= 50003 && - !my_strcasecmp(&my_charset_latin1, row[0], "information_schema")) + if (mysql_get_server_version(mysql) >= FIRST_INFORMATION_SCHEMA_VERSION && + !my_strcasecmp(&my_charset_latin1, row[0], INFORMATION_SCHEMA_DB_NAME)) + continue; + + if (mysql_get_server_version(mysql) >= FIRST_PERFORMANCE_SCHEMA_VERSION && + !my_strcasecmp(&my_charset_latin1, row[0], PERFORMANCE_SCHEMA_DB_NAME)) continue; if (dump_all_tables_in_db(row[0])) @@ -3854,8 +3858,12 @@ static int dump_all_databases() } while ((row= mysql_fetch_row(tableres))) { - if (mysql_get_server_version(mysql) >= 50003 && - !my_strcasecmp(&my_charset_latin1, row[0], "information_schema")) + if (mysql_get_server_version(mysql) >= FIRST_INFORMATION_SCHEMA_VERSION && + !my_strcasecmp(&my_charset_latin1, row[0], INFORMATION_SCHEMA_DB_NAME)) + continue; + + if (mysql_get_server_version(mysql) >= FIRST_PERFORMANCE_SCHEMA_VERSION && + !my_strcasecmp(&my_charset_latin1, row[0], PERFORMANCE_SCHEMA_DB_NAME)) continue; if (dump_all_views_in_db(row[0])) @@ -4256,10 +4264,12 @@ static int dump_selected_tables(char *db, char **table_names, int tables) } end= pos; - /* Can't LOCK TABLES in INFORMATION_SCHEMA, so don't try. */ + /* Can't LOCK TABLES in I_S / P_S, so don't try. */ if (lock_tables && - !(mysql_get_server_version(mysql) >= 50003 && - !my_strcasecmp(&my_charset_latin1, db, "information_schema"))) + !(mysql_get_server_version(mysql) >= FIRST_INFORMATION_SCHEMA_VERSION && + !my_strcasecmp(&my_charset_latin1, db, INFORMATION_SCHEMA_DB_NAME)) && + !(mysql_get_server_version(mysql) >= FIRST_PERFORMANCE_SCHEMA_VERSION && + !my_strcasecmp(&my_charset_latin1, db, PERFORMANCE_SCHEMA_DB_NAME))) { if (mysql_real_query(mysql, lock_tables_query.str, lock_tables_query.length-1)) diff --git a/include/keycache.h b/include/keycache.h index a6005bae878..4e715dda88d 100644 --- a/include/keycache.h +++ b/include/keycache.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2003 MySQL AB +/* Copyright (C) 2003 MySQL AB, 2009 Sun Microsystems, Inc 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 @@ -70,7 +70,7 @@ typedef struct st_key_cache uchar HUGE_PTR *block_mem; /* memory for block buffers */ BLOCK_LINK *used_last; /* ptr to the last block of the LRU chain */ BLOCK_LINK *used_ins; /* ptr to the insertion block in LRU chain */ - pthread_mutex_t cache_lock; /* to lock access to the cache structure */ + mysql_mutex_t cache_lock; /* to lock access to the cache structure */ KEYCACHE_WQUEUE resize_queue; /* threads waiting during resize operation */ /* Waiting for a zero resize count. Using a queue for symmetry though diff --git a/include/my_bitmap.h b/include/my_bitmap.h index 78642df3362..314dac983b0 100644 --- a/include/my_bitmap.h +++ b/include/my_bitmap.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000 MySQL AB, 2009 Sun Microsystems, Inc 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 @@ -34,7 +34,7 @@ typedef struct st_bitmap acquiring the mutex */ #ifdef THREAD - pthread_mutex_t *mutex; + mysql_mutex_t *mutex; #endif } MY_BITMAP; diff --git a/include/my_pthread.h b/include/my_pthread.h index c4d4e3d7adf..bfb5a2f67f4 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -607,6 +607,8 @@ extern pthread_mutexattr_t my_errorcheck_mutexattr; typedef ulong my_thread_id; extern my_bool my_thread_global_init(void); +extern my_bool my_thread_basic_global_init(void); +extern void my_thread_basic_global_reinit(void); extern void my_thread_global_end(void); extern my_bool my_thread_init(void); extern void my_thread_end(void); @@ -637,10 +639,10 @@ extern int pthread_dummy(int); struct st_my_thread_var { int thr_errno; - pthread_cond_t suspend; - pthread_mutex_t mutex; - pthread_mutex_t * volatile current_mutex; - pthread_cond_t * volatile current_cond; + mysql_cond_t suspend; + mysql_mutex_t mutex; + mysql_mutex_t * volatile current_mutex; + mysql_cond_t * volatile current_cond; pthread_t pthread_self; my_thread_id id; int cmp_length; @@ -692,16 +694,16 @@ extern uint thd_lib_detected; #ifdef THREAD #ifndef thread_safe_increment #define thread_safe_increment(V,L) \ - (pthread_mutex_lock((L)), (V)++, pthread_mutex_unlock((L))) + (mysql_mutex_lock((L)), (V)++, mysql_mutex_unlock((L))) #define thread_safe_decrement(V,L) \ - (pthread_mutex_lock((L)), (V)--, pthread_mutex_unlock((L))) + (mysql_mutex_lock((L)), (V)--, mysql_mutex_unlock((L))) #endif #ifndef thread_safe_add #define thread_safe_add(V,C,L) \ - (pthread_mutex_lock((L)), (V)+=(C), pthread_mutex_unlock((L))) + (mysql_mutex_lock((L)), (V)+=(C), mysql_mutex_unlock((L))) #define thread_safe_sub(V,C,L) \ - (pthread_mutex_lock((L)), (V)-=(C), pthread_mutex_unlock((L))) + (mysql_mutex_lock((L)), (V)-=(C), mysql_mutex_unlock((L))) #endif #endif diff --git a/include/my_sys.h b/include/my_sys.h index f4217b17fee..6e66dc30f9b 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -338,7 +338,7 @@ struct st_my_file_info #endif enum file_type type; #if defined(THREAD) && !defined(HAVE_PREAD) && !defined(_WIN32) - pthread_mutex_t mutex; + mysql_mutex_t mutex; #endif }; @@ -358,7 +358,7 @@ typedef struct st_my_tmpdir char **list; uint cur, max; #ifdef THREAD - pthread_mutex_t mutex; + mysql_mutex_t mutex; #endif } MY_TMPDIR; @@ -374,9 +374,9 @@ typedef int (*IO_CACHE_CALLBACK)(struct st_io_cache*); #ifdef THREAD typedef struct st_io_cache_share { - pthread_mutex_t mutex; /* To sync on reads into buffer. */ - pthread_cond_t cond; /* To wait for signals. */ - pthread_cond_t cond_writer; /* For a synchronized writer. */ + mysql_mutex_t mutex; /* To sync on reads into buffer. */ + mysql_cond_t cond; /* To wait for signals. */ + mysql_cond_t cond_writer; /* For a synchronized writer. */ /* Offset in file corresponding to the first byte of buffer. */ my_off_t pos_in_file; /* If a synchronized write cache is the source of the data. */ @@ -437,7 +437,7 @@ typedef struct st_io_cache /* Used when cacheing files */ The lock is for append buffer used in SEQ_READ_APPEND cache need mutex copying from append buffer to read buffer. */ - pthread_mutex_t append_buffer_lock; + mysql_mutex_t append_buffer_lock; /* The following is used when several threads are reading the same file in parallel. They are synchronized on disk @@ -691,6 +691,7 @@ extern const char **my_error_unregister(int first, int last); extern void my_message(uint my_err, const char *str,myf MyFlags); extern void my_message_no_curses(uint my_err, const char *str,myf MyFlags); extern void my_message_curses(uint my_err, const char *str,myf MyFlags); +extern my_bool my_basic_init(void); extern my_bool my_init(void); extern void my_end(int infoflag); extern int my_redel(const char *from, const char *to, int MyFlags); diff --git a/include/thr_lock.h b/include/thr_lock.h index fb70c57c0e7..d669d2dd2ab 100644 --- a/include/thr_lock.h +++ b/include/thr_lock.h @@ -1,4 +1,4 @@ -/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. 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 @@ -115,10 +115,11 @@ typedef struct st_thr_lock_data { THR_LOCK_OWNER *owner; struct st_thr_lock_data *next,**prev; struct st_thr_lock *lock; - pthread_cond_t *cond; + mysql_cond_t *cond; enum thr_lock_type type; void *status_param; /* Param to status functions */ void *debug_print_param; + struct PSI_table *m_psi; } THR_LOCK_DATA; struct st_lock_list { @@ -127,7 +128,7 @@ struct st_lock_list { typedef struct st_thr_lock { LIST list; - pthread_mutex_t mutex; + mysql_mutex_t mutex; struct st_lock_list read_wait; struct st_lock_list read; struct st_lock_list write_wait; @@ -144,7 +145,7 @@ typedef struct st_thr_lock { extern LIST *thr_lock_thread_list; -extern pthread_mutex_t THR_LOCK_lock; +extern mysql_mutex_t THR_LOCK_lock; my_bool init_thr_lock(void); /* Must be called once/thread */ #define thr_lock_owner_init(owner, info_arg) (owner)->info= (info_arg) diff --git a/mysys/charset.c b/mysys/charset.c index 280b2ad6091..3f3f62a0ae1 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -339,10 +339,10 @@ static my_bool my_read_charset_file(const char *filename, myf myflags) !(buf= (uchar*) my_malloc(len,myflags))) return TRUE; - if ((fd=my_open(filename,O_RDONLY,myflags)) < 0) + if ((fd= mysql_file_open(key_file_charset, filename, O_RDONLY, myflags)) < 0) goto error; - tmp_len=my_read(fd, buf, len, myflags); - my_close(fd,myflags); + tmp_len= mysql_file_read(fd, buf, len, myflags); + mysql_file_close(fd, myflags); if (tmp_len != len) goto error; @@ -421,7 +421,7 @@ static my_bool init_available_charsets(myf myflags) To make things thread safe we are not allowing other threads to interfere while we may changing the cs_info_table */ - pthread_mutex_lock(&THR_LOCK_charset); + mysql_mutex_lock(&THR_LOCK_charset); if (!charset_initialized) { bzero(&all_charsets,sizeof(all_charsets)); @@ -444,7 +444,7 @@ static my_bool init_available_charsets(myf myflags) error= my_read_charset_file(fname,myflags); charset_initialized=1; } - pthread_mutex_unlock(&THR_LOCK_charset); + mysql_mutex_unlock(&THR_LOCK_charset); } return error; } @@ -507,7 +507,7 @@ static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags) To make things thread safe we are not allowing other threads to interfere while we may changing the cs_info_table */ - pthread_mutex_lock(&THR_LOCK_charset); + mysql_mutex_lock(&THR_LOCK_charset); if (!(cs->state & (MY_CS_COMPILED|MY_CS_LOADED))) /* if CS is not in memory */ { @@ -529,7 +529,7 @@ static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags) else cs= NULL; - pthread_mutex_unlock(&THR_LOCK_charset); + mysql_mutex_unlock(&THR_LOCK_charset); } return cs; } diff --git a/mysys/default.c b/mysys/default.c index 6468cf2b35d..b9bcbff72da 100644 --- a/mysys/default.c +++ b/mysys/default.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2003 MySQL AB +/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -683,7 +683,7 @@ static int search_default_file_with_ext(Process_option_func opt_handler, static const char includedir_keyword[]= "includedir"; static const char include_keyword[]= "include"; const int max_recursion_level= 10; - FILE *fp; + MYSQL_FILE *fp; uint line=0; my_bool found_group=0; uint i; @@ -723,10 +723,10 @@ static int search_default_file_with_ext(Process_option_func opt_handler, } } #endif - if (!(fp= my_fopen(name, O_RDONLY, MYF(0)))) + if (!(fp= mysql_file_fopen(key_file_cnf, name, O_RDONLY, MYF(0)))) return 1; /* Ignore wrong files */ - while (fgets(buff, sizeof(buff) - 1, fp)) + while (mysql_file_fgets(buff, sizeof(buff) - 1, fp)) { line++; /* Ignore comment and empty lines */ @@ -916,11 +916,11 @@ static int search_default_file_with_ext(Process_option_func opt_handler, goto err; } } - my_fclose(fp,MYF(0)); + mysql_file_fclose(fp, MYF(0)); return(0); err: - my_fclose(fp,MYF(0)); + mysql_file_fclose(fp, MYF(0)); return -1; /* Fatal error */ } diff --git a/mysys/mf_iocache.c b/mysys/mf_iocache.c index 1a47982b221..620ac667a8b 100644 --- a/mysys/mf_iocache.c +++ b/mysys/mf_iocache.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -58,9 +58,9 @@ static void my_aiowait(my_aio_result *result); #ifdef THREAD #define lock_append_buffer(info) \ - pthread_mutex_lock(&(info)->append_buffer_lock) + mysql_mutex_lock(&(info)->append_buffer_lock) #define unlock_append_buffer(info) \ - pthread_mutex_unlock(&(info)->append_buffer_lock) + mysql_mutex_unlock(&(info)->append_buffer_lock) #else #define lock_append_buffer(info) #define unlock_append_buffer(info) @@ -265,7 +265,8 @@ int init_io_cache(IO_CACHE *info, File file, size_t cachesize, info->append_read_pos = info->write_pos = info->write_buffer; info->write_end = info->write_buffer + info->buffer_length; #ifdef THREAD - pthread_mutex_init(&info->append_buffer_lock,MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_IO_CACHE_append_buffer_lock, + &info->append_buffer_lock, MY_MUTEX_INIT_FAST); #endif } #if defined(SAFE_MUTEX) && defined(THREAD) @@ -639,9 +640,10 @@ void init_io_cache_share(IO_CACHE *read_cache, IO_CACHE_SHARE *cshare, DBUG_ASSERT(read_cache->type == READ_CACHE); DBUG_ASSERT(!write_cache || (write_cache->type == WRITE_CACHE)); - pthread_mutex_init(&cshare->mutex, MY_MUTEX_INIT_FAST); - pthread_cond_init(&cshare->cond, 0); - pthread_cond_init(&cshare->cond_writer, 0); + mysql_mutex_init(key_IO_CACHE_SHARE_mutex, + &cshare->mutex, MY_MUTEX_INIT_FAST); + mysql_cond_init(key_IO_CACHE_SHARE_cond, &cshare->cond, 0); + mysql_cond_init(key_IO_CACHE_SHARE_cond_writer, &cshare->cond_writer, 0); cshare->running_threads= num_threads; cshare->total_threads= num_threads; @@ -692,7 +694,7 @@ void remove_io_thread(IO_CACHE *cache) if (cache == cshare->source_cache) flush_io_cache(cache); - pthread_mutex_lock(&cshare->mutex); + mysql_mutex_lock(&cshare->mutex); DBUG_PRINT("io_cache_share", ("%s: 0x%lx", (cache == cshare->source_cache) ? "writer" : "reader", (long) cache)); @@ -715,18 +717,18 @@ void remove_io_thread(IO_CACHE *cache) if (!--cshare->running_threads) { DBUG_PRINT("io_cache_share", ("the last running thread leaves, wake all")); - pthread_cond_signal(&cshare->cond_writer); - pthread_cond_broadcast(&cshare->cond); + mysql_cond_signal(&cshare->cond_writer); + mysql_cond_broadcast(&cshare->cond); } - pthread_mutex_unlock(&cshare->mutex); + mysql_mutex_unlock(&cshare->mutex); if (!total) { DBUG_PRINT("io_cache_share", ("last thread removed, destroy share")); - pthread_cond_destroy (&cshare->cond_writer); - pthread_cond_destroy (&cshare->cond); - pthread_mutex_destroy(&cshare->mutex); + mysql_cond_destroy (&cshare->cond_writer); + mysql_cond_destroy (&cshare->cond); + mysql_mutex_destroy(&cshare->mutex); } DBUG_VOID_RETURN; @@ -767,7 +769,7 @@ static int lock_io_cache(IO_CACHE *cache, my_off_t pos) DBUG_ENTER("lock_io_cache"); /* Enter the lock. */ - pthread_mutex_lock(&cshare->mutex); + mysql_mutex_lock(&cshare->mutex); cshare->running_threads--; DBUG_PRINT("io_cache_share", ("%s: 0x%lx pos: %lu running: %u", (cache == cshare->source_cache) ? @@ -784,7 +786,7 @@ static int lock_io_cache(IO_CACHE *cache, my_off_t pos) while (cshare->running_threads) { DBUG_PRINT("io_cache_share", ("writer waits in lock")); - pthread_cond_wait(&cshare->cond_writer, &cshare->mutex); + mysql_cond_wait(&cshare->cond_writer, &cshare->mutex); } DBUG_PRINT("io_cache_share", ("writer awoke, going to copy")); @@ -796,7 +798,7 @@ static int lock_io_cache(IO_CACHE *cache, my_off_t pos) if (!cshare->running_threads) { DBUG_PRINT("io_cache_share", ("waking writer")); - pthread_cond_signal(&cshare->cond_writer); + mysql_cond_signal(&cshare->cond_writer); } /* @@ -808,7 +810,7 @@ static int lock_io_cache(IO_CACHE *cache, my_off_t pos) cshare->source_cache) { DBUG_PRINT("io_cache_share", ("reader waits in lock")); - pthread_cond_wait(&cshare->cond, &cshare->mutex); + mysql_cond_wait(&cshare->cond, &cshare->mutex); } /* @@ -850,7 +852,7 @@ static int lock_io_cache(IO_CACHE *cache, my_off_t pos) cshare->running_threads) { DBUG_PRINT("io_cache_share", ("reader waits in lock")); - pthread_cond_wait(&cshare->cond, &cshare->mutex); + mysql_cond_wait(&cshare->cond, &cshare->mutex); } /* If the block is not yet read, continue with a locked cache and read. */ @@ -872,7 +874,7 @@ static int lock_io_cache(IO_CACHE *cache, my_off_t pos) Leave the lock. Do not call unlock_io_cache() later. The thread that filled the buffer did this and marked all threads as running. */ - pthread_mutex_unlock(&cshare->mutex); + mysql_mutex_unlock(&cshare->mutex); DBUG_RETURN(0); } @@ -915,8 +917,8 @@ static void unlock_io_cache(IO_CACHE *cache) cshare->total_threads)); cshare->running_threads= cshare->total_threads; - pthread_cond_broadcast(&cshare->cond); - pthread_mutex_unlock(&cshare->mutex); + mysql_cond_broadcast(&cshare->cond); + mysql_mutex_unlock(&cshare->mutex); DBUG_VOID_RETURN; } @@ -1837,7 +1839,7 @@ int end_io_cache(IO_CACHE *info) /* Destroy allocated mutex */ info->type= TYPE_NOT_SET; #ifdef THREAD - pthread_mutex_destroy(&info->append_buffer_lock); + mysql_mutex_destroy(&info->append_buffer_lock); #endif } DBUG_RETURN(error); diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c index 705a3fc46ec..5e34bff2b51 100644 --- a/mysys/mf_iocache2.c +++ b/mysys/mf_iocache2.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -82,7 +82,7 @@ my_off_t my_b_append_tell(IO_CACHE* info) answer to the question. */ #ifdef THREAD - pthread_mutex_lock(&info->append_buffer_lock); + mysql_mutex_lock(&info->append_buffer_lock); #endif #ifndef DBUG_OFF /* @@ -104,7 +104,7 @@ my_off_t my_b_append_tell(IO_CACHE* info) #endif res = info->end_of_file + (info->write_pos-info->append_read_pos); #ifdef THREAD - pthread_mutex_unlock(&info->append_buffer_lock); + mysql_mutex_unlock(&info->append_buffer_lock); #endif return res; } diff --git a/mysys/mf_keycache.c b/mysys/mf_keycache.c index 139a61da1f0..9cbe3a21bce 100644 --- a/mysys/mf_keycache.c +++ b/mysys/mf_keycache.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -59,13 +59,13 @@ time only. Before starting to wait on its condition variable with - pthread_cond_wait(), the thread enters itself to a specific wait queue + mysql_cond_wait(), the thread enters itself to a specific wait queue with link_into_queue() (double linked with '*next' + '**prev') or wait_on_queue() (single linked with '*next'). Another thread, when releasing a resource, looks up the waiting thread in the related wait queue. It sends a signal with - pthread_cond_signal() to the waiting thread. + mysql_cond_signal() to the waiting thread. NOTE: Depending on the particular wait situation, either the sending thread removes the waiting thread from the wait queue with @@ -128,8 +128,8 @@ accessing it; to set this number equal to add #define MAX_THREADS - - to substitute calls of pthread_cond_wait for calls of - pthread_cond_timedwait (wait with timeout set up); + - to substitute calls of mysql_cond_wait for calls of + mysql_cond_timedwait (wait with timeout set up); this setting should be used only when you want to trap a deadlock situation, which theoretically should not happen; to set timeout equal to seconds add @@ -160,7 +160,7 @@ #define COND_FOR_SAVED 1 #define COND_FOR_READERS 2 -typedef pthread_cond_t KEYCACHE_CONDVAR; +typedef mysql_cond_t KEYCACHE_CONDVAR; /* descriptor of the page in the key cache block buffer */ struct st_keycache_page @@ -227,7 +227,7 @@ KEY_CACHE *dflt_key_cache= &dflt_key_cache_var; static int flush_all_key_blocks(KEY_CACHE *keycache); #ifdef THREAD static void wait_on_queue(KEYCACHE_WQUEUE *wqueue, - pthread_mutex_t *mutex); + mysql_mutex_t *mutex); static void release_whole_queue(KEYCACHE_WQUEUE *wqueue); #else #define wait_on_queue(wqueue, mutex) do {} while (0) @@ -314,20 +314,20 @@ static long keycache_thread_id; ((uint) (((char*)(h)-(char *) keycache->hash_link_root)/sizeof(HASH_LINK))) #if (defined(KEYCACHE_TIMEOUT) && !defined(__WIN__)) || defined(KEYCACHE_DEBUG) -static int keycache_pthread_cond_wait(pthread_cond_t *cond, - pthread_mutex_t *mutex); +static int keycache_pthread_cond_wait(mysql_cond_t *cond, + mysql_mutex_t *mutex); #else -#define keycache_pthread_cond_wait pthread_cond_wait +#define keycache_pthread_cond_wait(C, M) mysql_cond_wait(C, M) #endif #if defined(KEYCACHE_DEBUG) -static int keycache_pthread_mutex_lock(pthread_mutex_t *mutex); -static void keycache_pthread_mutex_unlock(pthread_mutex_t *mutex); -static int keycache_pthread_cond_signal(pthread_cond_t *cond); +static int keycache_pthread_mutex_lock(mysql_mutex_t *mutex); +static void keycache_pthread_mutex_unlock(mysql_mutex_t *mutex); +static int keycache_pthread_cond_signal(mysql_cond_t *cond); #else -#define keycache_pthread_mutex_lock pthread_mutex_lock -#define keycache_pthread_mutex_unlock pthread_mutex_unlock -#define keycache_pthread_cond_signal pthread_cond_signal +#define keycache_pthread_mutex_lock(M) mysql_mutex_lock(M) +#define keycache_pthread_mutex_unlock(M) mysql_mutex_unlock(M) +#define keycache_pthread_cond_signal(C) mysql_cond_signal(C) #endif /* defined(KEYCACHE_DEBUG) */ #if !defined(DBUG_OFF) @@ -403,7 +403,8 @@ int init_key_cache(KEY_CACHE *keycache, uint key_cache_block_size, keycache->cnt_for_resize_op= 0; keycache->waiting_for_resize_cnt.last_thread= NULL; keycache->in_init= 0; - pthread_mutex_init(&keycache->cache_lock, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_KEY_CACHE_cache_lock, + &keycache->cache_lock, MY_MUTEX_INIT_FAST); keycache->resize_queue.last_thread= NULL; } @@ -773,7 +774,7 @@ void end_key_cache(KEY_CACHE *keycache, my_bool cleanup) if (cleanup) { - pthread_mutex_destroy(&keycache->cache_lock); + mysql_mutex_destroy(&keycache->cache_lock); keycache->key_cache_inited= keycache->can_be_used= 0; KEYCACHE_DEBUG_CLOSE; } @@ -888,7 +889,7 @@ static void unlink_from_queue(KEYCACHE_WQUEUE *wqueue, */ static void wait_on_queue(KEYCACHE_WQUEUE *wqueue, - pthread_mutex_t *mutex) + mysql_mutex_t *mutex) { struct st_my_thread_var *last; struct st_my_thread_var *thread= my_thread_var; @@ -4166,7 +4167,7 @@ static int flush_all_key_blocks(KEY_CACHE *keycache) do { - safe_mutex_assert_owner(&keycache->cache_lock); + mysql_mutex_assert_owner(&keycache->cache_lock); total_found= 0; /* @@ -4407,8 +4408,8 @@ static void keycache_dump(KEY_CACHE *keycache) #if defined(KEYCACHE_TIMEOUT) && !defined(__WIN__) -static int keycache_pthread_cond_wait(pthread_cond_t *cond, - pthread_mutex_t *mutex) +static int keycache_pthread_cond_wait(mysql_cond_t *cond, + mysql_mutex_t *mutex) { int rc; struct timeval now; /* time when we started waiting */ @@ -4435,7 +4436,7 @@ static int keycache_pthread_cond_wait(pthread_cond_t *cond, fprintf(keycache_debug_log, "waiting...\n"); fflush(keycache_debug_log); #endif - rc= pthread_cond_timedwait(cond, mutex, &timeout); + rc= mysql_cond_timedwait(cond, mutex, &timeout); KEYCACHE_THREAD_TRACE_BEGIN("finished waiting"); if (rc == ETIMEDOUT || rc == ETIME) { @@ -4456,12 +4457,12 @@ static int keycache_pthread_cond_wait(pthread_cond_t *cond, } #else #if defined(KEYCACHE_DEBUG) -static int keycache_pthread_cond_wait(pthread_cond_t *cond, - pthread_mutex_t *mutex) +static int keycache_pthread_cond_wait(mysql_cond_t *cond, + mysql_mutex_t *mutex) { int rc; KEYCACHE_THREAD_TRACE_END("started waiting"); - rc= pthread_cond_wait(cond, mutex); + rc= mysql_cond_wait(cond, mutex); KEYCACHE_THREAD_TRACE_BEGIN("finished waiting"); return rc; } @@ -4471,27 +4472,27 @@ static int keycache_pthread_cond_wait(pthread_cond_t *cond, #if defined(KEYCACHE_DEBUG) -static int keycache_pthread_mutex_lock(pthread_mutex_t *mutex) +static int keycache_pthread_mutex_lock(mysql_mutex_t *mutex) { int rc; - rc= pthread_mutex_lock(mutex); + rc= mysql_mutex_lock(mutex); KEYCACHE_THREAD_TRACE_BEGIN(""); return rc; } -static void keycache_pthread_mutex_unlock(pthread_mutex_t *mutex) +static void keycache_pthread_mutex_unlock(mysql_mutex_t *mutex) { KEYCACHE_THREAD_TRACE_END(""); - pthread_mutex_unlock(mutex); + mysql_mutex_unlock(mutex); } -static int keycache_pthread_cond_signal(pthread_cond_t *cond) +static int keycache_pthread_cond_signal(mysql_cond_t *cond) { int rc; KEYCACHE_THREAD_TRACE("signal"); - rc= pthread_cond_signal(cond); + rc= mysql_cond_signal(cond); return rc; } diff --git a/mysys/mf_tempdir.c b/mysys/mf_tempdir.c index f41bbab946f..5633182ab3a 100644 --- a/mysys/mf_tempdir.c +++ b/mysys/mf_tempdir.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -29,7 +29,7 @@ my_bool init_tmpdir(MY_TMPDIR *tmpdir, const char *pathlist) DBUG_ENTER("init_tmpdir"); DBUG_PRINT("enter", ("pathlist: %s", pathlist ? pathlist : "NULL")); - pthread_mutex_init(&tmpdir->mutex, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_TMPDIR_mutex, &tmpdir->mutex, MY_MUTEX_INIT_FAST); if (my_init_dynamic_array(&tmpdir->full_list, sizeof(char*), 1, 5)) goto err; if (!pathlist || !pathlist[0]) @@ -65,7 +65,7 @@ my_bool init_tmpdir(MY_TMPDIR *tmpdir, const char *pathlist) err: delete_dynamic(&tmpdir->full_list); /* Safe to free */ - pthread_mutex_destroy(&tmpdir->mutex); + mysql_mutex_destroy(&tmpdir->mutex); DBUG_RETURN(TRUE); } @@ -75,10 +75,10 @@ char *my_tmpdir(MY_TMPDIR *tmpdir) char *dir; if (!tmpdir->max) return tmpdir->list[0]; - pthread_mutex_lock(&tmpdir->mutex); + mysql_mutex_lock(&tmpdir->mutex); dir=tmpdir->list[tmpdir->cur]; tmpdir->cur= (tmpdir->cur == tmpdir->max) ? 0 : tmpdir->cur+1; - pthread_mutex_unlock(&tmpdir->mutex); + mysql_mutex_unlock(&tmpdir->mutex); return dir; } @@ -90,6 +90,6 @@ void free_tmpdir(MY_TMPDIR *tmpdir) for (i=0; i<=tmpdir->max; i++) my_free(tmpdir->list[i], MYF(0)); delete_dynamic(&tmpdir->full_list); - pthread_mutex_destroy(&tmpdir->mutex); + mysql_mutex_destroy(&tmpdir->mutex); } diff --git a/mysys/my_bitmap.c b/mysys/my_bitmap.c index e127b2584ae..91370bd3727 100644 --- a/mysys/my_bitmap.c +++ b/mysys/my_bitmap.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -87,7 +87,7 @@ static inline void bitmap_lock(MY_BITMAP *map __attribute__((unused))) { #ifdef THREAD if (map->mutex) - pthread_mutex_lock(map->mutex); + mysql_mutex_lock(map->mutex); #endif } @@ -95,7 +95,7 @@ static inline void bitmap_unlock(MY_BITMAP *map __attribute__((unused))) { #ifdef THREAD if (map->mutex) - pthread_mutex_unlock(map->mutex); + mysql_mutex_unlock(map->mutex); #endif } @@ -112,7 +112,7 @@ my_bool bitmap_init(MY_BITMAP *map, my_bitmap_map *buf, uint n_bits, if (thread_safe) { size_in_bytes= ALIGN_SIZE(size_in_bytes); - extra= sizeof(pthread_mutex_t); + extra= sizeof(mysql_mutex_t); } map->mutex= 0; #endif @@ -121,8 +121,8 @@ my_bool bitmap_init(MY_BITMAP *map, my_bitmap_map *buf, uint n_bits, #ifdef THREAD if (thread_safe) { - map->mutex= (pthread_mutex_t *) ((char*) buf + size_in_bytes); - pthread_mutex_init(map->mutex, MY_MUTEX_INIT_FAST); + map->mutex= (mysql_mutex_t *) ((char*) buf + size_in_bytes); + mysql_mutex_init(key_BITMAP_mutex, map->mutex, MY_MUTEX_INIT_FAST); } #endif } @@ -148,7 +148,7 @@ void bitmap_free(MY_BITMAP *map) { #ifdef THREAD if (map->mutex) - pthread_mutex_destroy(map->mutex); + mysql_mutex_destroy(map->mutex); #endif my_free((char*) map->bitmap, MYF(0)); map->bitmap=0; diff --git a/mysys/my_fopen.c b/mysys/my_fopen.c index 879acac0111..3f2bc08df65 100644 --- a/mysys/my_fopen.c +++ b/mysys/my_fopen.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -63,18 +63,18 @@ FILE *my_fopen(const char *filename, int flags, myf MyFlags) thread_safe_increment(my_stream_opened,&THR_LOCK_open); DBUG_RETURN(fd); /* safeguard */ } - pthread_mutex_lock(&THR_LOCK_open); + mysql_mutex_lock(&THR_LOCK_open); if ((my_file_info[filedesc].name= (char*) my_strdup(filename,MyFlags))) { my_stream_opened++; my_file_total_opened++; my_file_info[filedesc].type= STREAM_BY_FOPEN; - pthread_mutex_unlock(&THR_LOCK_open); + mysql_mutex_unlock(&THR_LOCK_open); DBUG_PRINT("exit",("stream: 0x%lx", (long) fd)); DBUG_RETURN(fd); } - pthread_mutex_unlock(&THR_LOCK_open); + mysql_mutex_unlock(&THR_LOCK_open); (void) my_fclose(fd,MyFlags); my_errno=ENOMEM; } @@ -98,7 +98,7 @@ int my_fclose(FILE *fd, myf MyFlags) DBUG_ENTER("my_fclose"); DBUG_PRINT("my",("stream: 0x%lx MyFlags: %d", (long) fd, MyFlags)); - pthread_mutex_lock(&THR_LOCK_open); + mysql_mutex_lock(&THR_LOCK_open); file= my_fileno(fd); #ifndef _WIN32 err= fclose(fd); @@ -119,7 +119,7 @@ int my_fclose(FILE *fd, myf MyFlags) my_file_info[file].type = UNOPEN; my_free(my_file_info[file].name, MYF(MY_ALLOW_ZERO_PTR)); } - pthread_mutex_unlock(&THR_LOCK_open); + mysql_mutex_unlock(&THR_LOCK_open); DBUG_RETURN(err); } /* my_fclose */ @@ -149,7 +149,7 @@ FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags) } else { - pthread_mutex_lock(&THR_LOCK_open); + mysql_mutex_lock(&THR_LOCK_open); my_stream_opened++; if ((uint) Filedes < (uint) my_file_limit) { @@ -163,7 +163,7 @@ FILE *my_fdopen(File Filedes, const char *name, int Flags, myf MyFlags) } my_file_info[Filedes].type = STREAM_BY_FDOPEN; } - pthread_mutex_unlock(&THR_LOCK_open); + mysql_mutex_unlock(&THR_LOCK_open); } DBUG_PRINT("exit",("stream: 0x%lx", (long) fd)); diff --git a/mysys/my_gethostbyname.c b/mysys/my_gethostbyname.c index 067fdfee9db..4b7e9054d61 100644 --- a/mysys/my_gethostbyname.c +++ b/mysys/my_gethostbyname.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002, 2004 MySQL AB +/* Copyright (C) 2002, 2004 MySQL AB, 2008-2009 Sun Microsystems, Inc This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public @@ -79,7 +79,7 @@ struct hostent *my_gethostbyname_r(const char *name, #else /* !HAVE_GETHOSTBYNAME_R */ #ifdef THREAD -extern pthread_mutex_t LOCK_gethostbyname_r; +extern mysql_mutex_t LOCK_gethostbyname_r; #endif /* @@ -96,7 +96,7 @@ struct hostent *my_gethostbyname_r(const char *name, int buflen, int *h_errnop) { struct hostent *hp; - pthread_mutex_lock(&LOCK_gethostbyname_r); + mysql_mutex_lock(&LOCK_gethostbyname_r); hp= gethostbyname(name); *h_errnop= h_errno; return hp; @@ -104,7 +104,7 @@ struct hostent *my_gethostbyname_r(const char *name, void my_gethostbyname_r_free() { - pthread_mutex_unlock(&LOCK_gethostbyname_r); + mysql_mutex_unlock(&LOCK_gethostbyname_r); } #endif /* !HAVE_GETHOSTBYNAME_R */ diff --git a/mysys/my_getopt.c b/mysys/my_getopt.c index 2e8f09f14fd..8361d288bc7 100644 --- a/mysys/my_getopt.c +++ b/mysys/my_getopt.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002-2006 MySQL AB +/* Copyright (C) 2002-2006 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -91,16 +91,6 @@ static void default_reporter(enum loglevel level, fflush(stderr); } -/* - function: handle_options - - Sort options; put options first, until special end of options (--), or - until end of argv. Parse options; check that the given option matches with - one of the options in struct 'my_option', return error in case of ambiguous - or unknown option. Check that option was given an argument if it requires - one. Call function 'get_one_option()' once for each option. -*/ - static uchar** (*getopt_get_addr)(const char *, uint, const struct my_option *, int *); void my_getopt_register_get_addr(uchar** (*func_addr)(const char *, uint, @@ -109,6 +99,22 @@ void my_getopt_register_get_addr(uchar** (*func_addr)(const char *, uint, getopt_get_addr= func_addr; } +/** + Handle command line options. + Sort options. + Put options first, until special end of options (--), + or until the end of argv. Parse options, check that the given option + matches with one of the options in struct 'my_option'. + Check that option was given an argument if it requires one + Call the optional 'get_one_option()' function once for each option. + @param [in, out] argc command line options (count) + @param [in, out] argv command line options (values) + @param [in] longopts descriptor of all valid options + @param [in] get_one_option optional callback function to process each option, + can be NULL. + @return error in case of ambiguous or unknown options, + 0 on success. +*/ int handle_options(int *argc, char ***argv, const struct my_option *longopts, my_get_one_option get_one_option) @@ -427,9 +433,9 @@ invalid value '%s'", my_progname, optp->name, optend); continue; } - if (get_one_option(optp->id, optp, - *((my_bool*) value) ? - (char*) "1" : disabled_my_option)) + if (get_one_option && get_one_option(optp->id, optp, + *((my_bool*) value) ? + (char*) "1" : disabled_my_option)) return EXIT_ARGUMENT_INVALID; continue; } @@ -493,7 +499,7 @@ invalid value '%s'", optp->arg_type == NO_ARG) { *((my_bool*) optp->value)= (my_bool) 1; - if (get_one_option(optp->id, optp, argument)) + if (get_one_option && get_one_option(optp->id, optp, argument)) return EXIT_UNSPECIFIED_ERROR; continue; } @@ -513,7 +519,7 @@ invalid value '%s'", { if (optp->var_type == GET_BOOL) *((my_bool*) optp->value)= (my_bool) 1; - if (get_one_option(optp->id, optp, argument)) + if (get_one_option && get_one_option(optp->id, optp, argument)) return EXIT_UNSPECIFIED_ERROR; continue; } @@ -539,7 +545,7 @@ invalid value '%s'", my_progname, argument, optp->name); return error; } - if (get_one_option(optp->id, optp, argument)) + if (get_one_option && get_one_option(optp->id, optp, argument)) return EXIT_UNSPECIFIED_ERROR; break; } @@ -563,7 +569,7 @@ invalid value '%s'", my_progname, argument, optp->name); return error; } - if (get_one_option(optp->id, optp, argument)) + if (get_one_option && get_one_option(optp->id, optp, argument)) return EXIT_UNSPECIFIED_ERROR; (*argc)--; /* option handled (short or long), decrease argument count */ diff --git a/mysys/my_getsystime.c b/mysys/my_getsystime.c index b692b18bfc7..81bb3e15298 100644 --- a/mysys/my_getsystime.c +++ b/mysys/my_getsystime.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2004 MySQL AB +/* Copyright (C) 2004 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -168,7 +168,7 @@ ulonglong my_micro_time_and_time(time_t *time_arg) static time_t cur_time= 0; hrtime_t cur_gethrtime; - pthread_mutex_lock(&THR_LOCK_time); + mysql_mutex_lock(&THR_LOCK_time); cur_gethrtime= gethrtime(); if ((cur_gethrtime - prev_gethrtime) > DELTA_FOR_SECONDS) { @@ -176,7 +176,7 @@ ulonglong my_micro_time_and_time(time_t *time_arg) prev_gethrtime= cur_gethrtime; } *time_arg= cur_time; - pthread_mutex_unlock(&THR_LOCK_time); + mysql_mutex_unlock(&THR_LOCK_time); return cur_gethrtime/1000; #else ulonglong newtime; diff --git a/mysys/my_init.c b/mysys/my_init.c index c4fda599481..fa68bb2b1cb 100644 --- a/mysys/my_init.c +++ b/mysys/my_init.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2003 MySQL AB +/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -43,6 +43,8 @@ static void netware_init(); #endif my_bool my_init_done= 0; +/** True if @c my_basic_init() has been called. */ +my_bool my_basic_init_done= 0; uint mysys_usage_id= 0; /* Incremented for each my_init() */ ulong my_thread_stack_size= 65536; @@ -57,6 +59,57 @@ static ulong atoi_octal(const char *str) return (ulong) tmp; } +MYSQL_FILE *mysql_stdin= NULL; +static MYSQL_FILE instrumented_stdin; + +/** + Perform a limited initialisation of mysys. + This initialisation is sufficient to: + - allocate memory, + - read configuration files, + - parse command lines arguments. + To complete the mysys initialisation, + call my_init(). + @return 0 on success +*/ +my_bool my_basic_init(void) +{ + if (my_basic_init_done) + return 0; + my_basic_init_done= 1; + + mysys_usage_id++; + my_umask= 0660; /* Default umask for new files */ + my_umask_dir= 0700; /* Default umask for new directories */ + + init_glob_errs(); + + instrumented_stdin.m_file= stdin; + instrumented_stdin.m_psi= NULL; /* not yet instrumented */ + mysql_stdin= & instrumented_stdin; + +#if defined(THREAD) + if (my_thread_global_init()) + return 1; +# if defined(SAFE_MUTEX) + safe_mutex_global_init(); /* Must be called early */ +# endif +#endif +#if defined(THREAD) && defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) + fastmutex_global_init(); /* Must be called early */ +#endif + netware_init(); +#ifdef THREAD +#if defined(HAVE_PTHREAD_INIT) + pthread_init(); /* Must be called before DBUG_ENTER */ +#endif + if (my_thread_basic_global_init()) + return 1; +#endif + + return 0; +} + /* Init my_sys functions and my_sys variabels @@ -74,26 +127,14 @@ my_bool my_init(void) char * str; if (my_init_done) return 0; - my_init_done=1; - mysys_usage_id++; - my_umask= 0660; /* Default umask for new files */ - my_umask_dir= 0700; /* Default umask for new directories */ - init_glob_errs(); -#if defined(THREAD) + my_init_done= 1; + + if (my_basic_init()) + return 1; + +#ifdef THREAD if (my_thread_global_init()) return 1; -# if defined(SAFE_MUTEX) - safe_mutex_global_init(); /* Must be called early */ -# endif -#endif -#if defined(THREAD) && defined(MY_PTHREAD_FASTMUTEX) && !defined(SAFE_MUTEX) - fastmutex_global_init(); /* Must be called early */ -#endif - netware_init(); -#ifdef THREAD -#if defined(HAVE_PTHREAD_INIT) - pthread_init(); /* Must be called before DBUG_ENTER */ -#endif #if !defined( __WIN__) && !defined(__NETWARE__) sigfillset(&my_signals); /* signals blocked by mf_brkhant */ #endif @@ -239,6 +280,7 @@ Voluntary context switches %ld, Involuntary context switches %ld\n", WSACleanup(); #endif /* __WIN__ */ my_init_done=0; + my_basic_init_done= 0; } /* my_end */ @@ -538,3 +580,117 @@ static void netware_init() DBUG_VOID_RETURN; } #endif /* __NETWARE__ */ + +#ifdef HAVE_PSI_INTERFACE + +#if !defined(HAVE_PREAD) && !defined(_WIN32) +PSI_mutex_key key_my_file_info_mutex; +#endif /* !defined(HAVE_PREAD) && !defined(_WIN32) */ + +#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) +PSI_mutex_key key_LOCK_localtime_r; +#endif /* !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) */ + +#ifndef HAVE_GETHOSTBYNAME_R +PSI_mutex_key key_LOCK_gethostbyname_r; +#endif /* HAVE_GETHOSTBYNAME_R */ + +PSI_mutex_key key_BITMAP_mutex, key_IO_CACHE_append_buffer_lock, + key_IO_CACHE_SHARE_mutex, key_KEY_CACHE_cache_lock, key_LOCK_alarm, + key_my_thread_var_mutex, key_THR_LOCK_charset, key_THR_LOCK_heap, + key_THR_LOCK_isam, key_THR_LOCK_lock, key_THR_LOCK_malloc, + key_THR_LOCK_mutex, key_THR_LOCK_myisam, key_THR_LOCK_net, + key_THR_LOCK_open, key_THR_LOCK_threads, key_THR_LOCK_time, + key_TMPDIR_mutex; + +static PSI_mutex_info all_mysys_mutexes[]= +{ +#if defined(THREAD) && !defined(HAVE_PREAD) && !defined(_WIN32) + { &key_my_file_info_mutex, "st_my_file_info:mutex", 0}, +#endif /* !defined(HAVE_PREAD) && !defined(_WIN32) */ +#if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) + { &key_LOCK_localtime_r, "LOCK_localtime_r", PSI_FLAG_GLOBAL}, +#endif /* !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) */ +#ifndef HAVE_GETHOSTBYNAME_R + { &key_LOCK_gethostbyname_r, "LOCK_gethostbyname_r", PSI_FLAG_GLOBAL}, +#endif /* HAVE_GETHOSTBYNAME_R */ + { &key_BITMAP_mutex, "BITMAP::mutex", 0}, + { &key_IO_CACHE_append_buffer_lock, "IO_CACHE::append_buffer_lock", 0}, + { &key_IO_CACHE_SHARE_mutex, "IO_CACHE::SHARE_mutex", 0}, + { &key_KEY_CACHE_cache_lock, "KEY_CACHE::cache_lock", 0}, + { &key_LOCK_alarm, "LOCK_alarm", PSI_FLAG_GLOBAL}, + { &key_my_thread_var_mutex, "my_thread_var::mutex", 0}, + { &key_THR_LOCK_charset, "THR_LOCK_charset", PSI_FLAG_GLOBAL}, + { &key_THR_LOCK_heap, "THR_LOCK_heap", PSI_FLAG_GLOBAL}, + { &key_THR_LOCK_isam, "THR_LOCK_isam", PSI_FLAG_GLOBAL}, + { &key_THR_LOCK_lock, "THR_LOCK_lock", PSI_FLAG_GLOBAL}, + { &key_THR_LOCK_malloc, "THR_LOCK_malloc", PSI_FLAG_GLOBAL}, + { &key_THR_LOCK_mutex, "THR_LOCK::mutex", 0}, + { &key_THR_LOCK_myisam, "THR_LOCK_myisam", PSI_FLAG_GLOBAL}, + { &key_THR_LOCK_net, "THR_LOCK_net", PSI_FLAG_GLOBAL}, + { &key_THR_LOCK_open, "THR_LOCK_open", PSI_FLAG_GLOBAL}, + { &key_THR_LOCK_threads, "THR_LOCK_threads", PSI_FLAG_GLOBAL}, + { &key_THR_LOCK_time, "THR_LOCK_time", PSI_FLAG_GLOBAL}, + { &key_TMPDIR_mutex, "TMPDIR_mutex", PSI_FLAG_GLOBAL} +}; + +PSI_cond_key key_COND_alarm, key_IO_CACHE_SHARE_cond, + key_IO_CACHE_SHARE_cond_writer, key_my_thread_var_suspend, + key_THR_COND_threads; + +static PSI_cond_info all_mysys_conds[]= +{ + { &key_COND_alarm, "COND_alarm", PSI_FLAG_GLOBAL}, + { &key_IO_CACHE_SHARE_cond, "IO_CACHE_SHARE::cond", 0}, + { &key_IO_CACHE_SHARE_cond_writer, "IO_CACHE_SHARE::cond_writer", 0}, + { &key_my_thread_var_suspend, "my_thread_var::suspend", 0}, + { &key_THR_COND_threads, "THR_COND_threads", 0} +}; + +#ifdef USE_ALARM_THREAD +PSI_thread_key key_thread_alarm; + +static PSI_thread_info all_mysys_threads[]= +{ + { &key_thread_alarm, "alarm", PSI_FLAG_GLOBAL} +}; +#endif /* USE_ALARM_THREAD */ + +#ifdef HUGETLB_USE_PROC_MEMINFO +PSI_file_key key_file_proc_meminfo; +#endif /* HUGETLB_USE_PROC_MEMINFO */ +PSI_file_key key_file_charset, key_file_cnf; + +static PSI_file_info all_mysys_files[]= +{ +#ifdef HUGETLB_USE_PROC_MEMINFO + { &key_file_proc_meminfo, "proc_meminfo", 0}, +#endif /* HUGETLB_USE_PROC_MEMINFO */ + { &key_file_charset, "charset", 0}, + { &key_file_cnf, "cnf", 0} +}; + +void my_init_mysys_psi_keys() +{ + const char* category= "mysys"; + int count; + + if (PSI_server == NULL) + return; + + count= sizeof(all_mysys_mutexes)/sizeof(all_mysys_mutexes[0]); + PSI_server->register_mutex(category, all_mysys_mutexes, count); + + count= sizeof(all_mysys_conds)/sizeof(all_mysys_conds[0]); + PSI_server->register_cond(category, all_mysys_conds, count); + +#ifdef USE_ALARM_THREAD + count= sizeof(all_mysys_threads)/sizeof(all_mysys_threads[0]); + PSI_server->register_thread(category, all_mysys_threads, count); +#endif /* USE_ALARM_THREAD */ + + count= sizeof(all_mysys_files)/sizeof(all_mysys_files[0]); + PSI_server->register_file(category, all_mysys_files, count); +} +#endif /* HAVE_PSI_INTERFACE */ + diff --git a/mysys/my_largepage.c b/mysys/my_largepage.c index d96e1048fd0..e65d3a0a5f5 100644 --- a/mysys/my_largepage.c +++ b/mysys/my_largepage.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2004 MySQL AB +/* Copyright (C) 2004 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -91,19 +91,20 @@ void my_large_free(uchar* ptr, myf my_flags __attribute__((unused))) uint my_get_large_page_size_int(void) { - FILE *f; + MYSQL_FILE *f; uint size = 0; char buf[256]; DBUG_ENTER("my_get_large_page_size_int"); - if (!(f = my_fopen("/proc/meminfo", O_RDONLY, MYF(MY_WME)))) + if (!(f= mysql_file_fopen(key_file_proc_meminfo, "/proc/meminfo", + O_RDONLY, MYF(MY_WME)))) goto finish; - while (fgets(buf, sizeof(buf), f)) + while (mysql_file_fgets(buf, sizeof(buf), f)) if (sscanf(buf, "Hugepagesize: %u kB", &size)) break; - my_fclose(f, MYF(MY_WME)); + mysql_file_fclose(f, MYF(MY_WME)); finish: DBUG_RETURN(size * 1024); diff --git a/mysys/my_lib.c b/mysys/my_lib.c index dcc1263f383..0113d1498df 100644 --- a/mysys/my_lib.c +++ b/mysys/my_lib.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -110,7 +110,7 @@ MY_DIR *my_dir(const char *path, myf MyFlags) DBUG_PRINT("my",("path: '%s' MyFlags: %d",path,MyFlags)); #if defined(THREAD) && !defined(HAVE_READDIR_R) - pthread_mutex_lock(&THR_LOCK_open); + mysql_mutex_lock(&THR_LOCK_open); #endif dirp = opendir(directory_file_name(tmp_path,(char *) path)); @@ -173,7 +173,7 @@ MY_DIR *my_dir(const char *path, myf MyFlags) (void) closedir(dirp); #if defined(THREAD) && !defined(HAVE_READDIR_R) - pthread_mutex_unlock(&THR_LOCK_open); + mysql_mutex_unlock(&THR_LOCK_open); #endif result->dir_entry= (FILEINFO *)dir_entries_storage->buffer; result->number_off_files= dir_entries_storage->elements; @@ -185,7 +185,7 @@ MY_DIR *my_dir(const char *path, myf MyFlags) error: #if defined(THREAD) && !defined(HAVE_READDIR_R) - pthread_mutex_unlock(&THR_LOCK_open); + mysql_mutex_unlock(&THR_LOCK_open); #endif my_errno=errno; if (dirp) diff --git a/mysys/my_lock.c b/mysys/my_lock.c index 62f39bd3b71..1436c845286 100644 --- a/mysys/my_lock.c +++ b/mysys/my_lock.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2003 MySQL AB +/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -206,8 +206,8 @@ int my_lock(File fd, int locktype, my_off_t start, my_off_t length, else timeout_sec= WIN_LOCK_INFINITE; - if(win_lock(fd, locktype, start, length, timeout_sec) == 0) - DBUG_RETURN(0); + if (win_lock(fd, locktype, start, length, timeout_sec) == 0) + DBUG_RETURN(0); } #else #if defined(HAVE_FCNTL) diff --git a/mysys/my_lockmem.c b/mysys/my_lockmem.c index f2c6d52a382..1b582783d33 100644 --- a/mysys/my_lockmem.c +++ b/mysys/my_lockmem.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -66,9 +66,9 @@ uchar *my_malloc_lock(uint size,myf MyFlags) element->list.data=(uchar*) element; element->page=ptr; element->size=size; - pthread_mutex_lock(&THR_LOCK_malloc); + mysql_mutex_lock(&THR_LOCK_malloc); mem_list=list_add(mem_list,&element->list); - pthread_mutex_unlock(&THR_LOCK_malloc); + mysql_mutex_unlock(&THR_LOCK_malloc); } DBUG_RETURN(ptr); } @@ -79,7 +79,7 @@ void my_free_lock(uchar *ptr,myf Myflags __attribute__((unused))) LIST *list; struct st_mem_list *element=0; - pthread_mutex_lock(&THR_LOCK_malloc); + mysql_mutex_lock(&THR_LOCK_malloc); for (list=mem_list ; list ; list=list->next) { element=(struct st_mem_list*) list->data; @@ -90,7 +90,7 @@ void my_free_lock(uchar *ptr,myf Myflags __attribute__((unused))) break; } } - pthread_mutex_unlock(&THR_LOCK_malloc); + mysql_mutex_unlock(&THR_LOCK_malloc); if (element) my_free((uchar*) element,MYF(0)); free(ptr); /* Free even if not locked */ diff --git a/mysys/my_net.c b/mysys/my_net.c index 81d977210f8..e584e541175 100644 --- a/mysys/my_net.c +++ b/mysys/my_net.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -35,8 +35,8 @@ void my_inet_ntoa(struct in_addr in, char *buf) { char *ptr; - pthread_mutex_lock(&THR_LOCK_net); + mysql_mutex_lock(&THR_LOCK_net); ptr=inet_ntoa(in); strmov(buf,ptr); - pthread_mutex_unlock(&THR_LOCK_net); + mysql_mutex_unlock(&THR_LOCK_net); } diff --git a/mysys/my_open.c b/mysys/my_open.c index 79a4da242f9..a50baf2c417 100644 --- a/mysys/my_open.c +++ b/mysys/my_open.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -70,7 +70,7 @@ int my_close(File fd, myf MyFlags) DBUG_ENTER("my_close"); DBUG_PRINT("my",("fd: %d MyFlags: %d",fd, MyFlags)); - pthread_mutex_lock(&THR_LOCK_open); + mysql_mutex_lock(&THR_LOCK_open); #ifndef _WIN32 do { @@ -90,12 +90,12 @@ int my_close(File fd, myf MyFlags) { my_free(my_file_info[fd].name, MYF(0)); #if defined(THREAD) && !defined(HAVE_PREAD) && !defined(_WIN32) - pthread_mutex_destroy(&my_file_info[fd].mutex); + mysql_mutex_destroy(&my_file_info[fd].mutex); #endif my_file_info[fd].type = UNOPEN; } my_file_opened--; - pthread_mutex_unlock(&THR_LOCK_open); + mysql_mutex_unlock(&THR_LOCK_open); DBUG_RETURN(err); } /* my_close */ @@ -134,20 +134,21 @@ File my_register_filename(File fd, const char *FileName, enum file_type } else { - pthread_mutex_lock(&THR_LOCK_open); + mysql_mutex_lock(&THR_LOCK_open); if ((my_file_info[fd].name = (char*) my_strdup(FileName,MyFlags))) { my_file_opened++; my_file_total_opened++; my_file_info[fd].type = type_of_file; #if defined(THREAD) && !defined(HAVE_PREAD) && !defined(_WIN32) - pthread_mutex_init(&my_file_info[fd].mutex,MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_my_file_info_mutex, &my_file_info[fd].mutex, + MY_MUTEX_INIT_FAST); #endif - pthread_mutex_unlock(&THR_LOCK_open); + mysql_mutex_unlock(&THR_LOCK_open); DBUG_PRINT("exit",("fd: %d",fd)); DBUG_RETURN(fd); } - pthread_mutex_unlock(&THR_LOCK_open); + mysql_mutex_unlock(&THR_LOCK_open); my_errno= ENOMEM; } (void) my_close(fd, MyFlags); diff --git a/mysys/my_pread.c b/mysys/my_pread.c index eaabcb1b728..d0a0ddaec66 100644 --- a/mysys/my_pread.c +++ b/mysys/my_pread.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -60,12 +60,12 @@ size_t my_pread(File Filedes, uchar *Buffer, size_t Count, my_off_t offset, { errno= 0; /* Linux, Windows don't reset this on EOF/success */ #if !defined (HAVE_PREAD) && !defined (_WIN32) - pthread_mutex_lock(&my_file_info[Filedes].mutex); + mysql_mutex_lock(&my_file_info[Filedes].mutex); readbytes= (uint) -1; error= (lseek(Filedes, offset, MY_SEEK_SET) == (my_off_t) -1 || (readbytes= read(Filedes, Buffer, Count)) != Count); save_errno= errno; - pthread_mutex_unlock(&my_file_info[Filedes].mutex); + mysql_mutex_unlock(&my_file_info[Filedes].mutex); if (error) errno= save_errno; #else @@ -150,10 +150,10 @@ size_t my_pwrite(File Filedes, const uchar *Buffer, size_t Count, #if !defined (HAVE_PREAD) && !defined (_WIN32) int error; writtenbytes= (size_t) -1; - pthread_mutex_lock(&my_file_info[Filedes].mutex); + mysql_mutex_lock(&my_file_info[Filedes].mutex); error= (lseek(Filedes, offset, MY_SEEK_SET) != (my_off_t) -1 && (writtenbytes= write(Filedes, Buffer, Count)) == Count); - pthread_mutex_unlock(&my_file_info[Filedes].mutex); + mysql_mutex_unlock(&my_file_info[Filedes].mutex); if (error) break; #elif defined (_WIN32) diff --git a/mysys/my_pthread.c b/mysys/my_pthread.c index fd1798ab203..b6b7e7db857 100644 --- a/mysys/my_pthread.c +++ b/mysys/my_pthread.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2003 MySQL AB +/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -96,7 +96,7 @@ int my_sigwait(const sigset_t *set,int *sig) #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) -extern pthread_mutex_t LOCK_localtime_r; +extern mysql_mutex_t LOCK_localtime_r; #endif @@ -104,10 +104,10 @@ extern pthread_mutex_t LOCK_localtime_r; struct tm *localtime_r(const time_t *clock, struct tm *res) { struct tm *tmp; - pthread_mutex_lock(&LOCK_localtime_r); + mysql_mutex_lock(&LOCK_localtime_r); tmp=localtime(clock); *res= *tmp; - pthread_mutex_unlock(&LOCK_localtime_r); + mysql_mutex_unlock(&LOCK_localtime_r); return res; } #endif @@ -121,10 +121,10 @@ struct tm *localtime_r(const time_t *clock, struct tm *res) struct tm *gmtime_r(const time_t *clock, struct tm *res) { struct tm *tmp; - pthread_mutex_lock(&LOCK_localtime_r); + mysql_mutex_lock(&LOCK_localtime_r); tmp= gmtime(clock); *res= *tmp; - pthread_mutex_unlock(&LOCK_localtime_r); + mysql_mutex_unlock(&LOCK_localtime_r); return res; } #endif @@ -317,14 +317,14 @@ int sigwait(sigset_t *setp, int *sigp) pthread_t sigwait_thread_id; inited=1; sigemptyset(&pending_set); - pthread_mutex_init(&LOCK_sigwait,MY_MUTEX_INIT_FAST); - pthread_cond_init(&COND_sigwait,NULL); + pthread_mutex_init(&LOCK_sigwait, MY_MUTEX_INIT_FAST); + pthread_cond_init(&COND_sigwait, NULL); pthread_attr_init(&thr_attr); pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS); pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED); pthread_attr_setstacksize(&thr_attr,8196); - pthread_create(&sigwait_thread_id,&thr_attr,sigwait_thread,setp); + pthread_create(&sigwait_thread_id, &thr_attr, sigwait_thread, setp); pthread_attr_destroy(&thr_attr); } @@ -351,7 +351,7 @@ int sigwait(sigset_t *setp, int *sigp) return 0; } } - pthread_cond_wait(&COND_sigwait,&LOCK_sigwait); + pthread_cond_wait(&COND_sigwait, &LOCK_sigwait); } return 0; } diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index ba59c483012..b3d7d63b197 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -24,17 +24,17 @@ #ifdef THREAD pthread_key(struct st_my_thread_var*, THR_KEY_mysys); -pthread_mutex_t THR_LOCK_malloc,THR_LOCK_open, - THR_LOCK_lock,THR_LOCK_isam,THR_LOCK_myisam,THR_LOCK_heap, - THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads, THR_LOCK_time; -pthread_cond_t THR_COND_threads; +mysql_mutex_t THR_LOCK_malloc, THR_LOCK_open, + THR_LOCK_lock, THR_LOCK_isam, THR_LOCK_myisam, THR_LOCK_heap, + THR_LOCK_net, THR_LOCK_charset, THR_LOCK_threads, THR_LOCK_time; +mysql_cond_t THR_COND_threads; uint THR_thread_count= 0; uint my_thread_end_wait_time= 5; #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) -pthread_mutex_t LOCK_localtime_r; +mysql_mutex_t LOCK_localtime_r; #endif #ifndef HAVE_GETHOSTBYNAME_R -pthread_mutex_t LOCK_gethostbyname_r; +mysql_mutex_t LOCK_gethostbyname_r; #endif #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP pthread_mutexattr_t my_fast_mutexattr; @@ -65,6 +65,84 @@ nptl_pthread_exit_hack_handler(void *arg __attribute((unused))) static uint get_thread_lib(void); +/** True if @c my_thread_basic_global_init() has been called. */ +static my_bool my_thread_basic_global_init_done= 0; + +/** + Perform a minimal initialisation of mysys, when compiled with threads. + The initialisation performed is sufficient to: + - allocate memory + - perform file operations + - use charsets + - use my_errno + @sa my_basic_init + @sa my_thread_basic_global_reinit +*/ +my_bool my_thread_basic_global_init(void) +{ + int pth_ret; + + if (my_thread_basic_global_init_done) + return 0; + my_thread_basic_global_init_done= 1; + + mysql_mutex_init(key_THR_LOCK_malloc, &THR_LOCK_malloc, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_THR_LOCK_open, &THR_LOCK_open, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_THR_LOCK_charset, &THR_LOCK_charset, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_THR_LOCK_threads, &THR_LOCK_threads, MY_MUTEX_INIT_FAST); + + if ((pth_ret= pthread_key_create(&THR_KEY_mysys, NULL)) != 0) + { + fprintf(stderr, "Can't initialize threads: error %d\n", pth_ret); + return 1; + } + + if (my_thread_init()) + return 1; + + return 0; +} + +/** + Re-initialize components initialized early with @c my_thread_basic_global_init. + Some mutexes were initialized before the instrumentation. + Destroy + create them again, now that the instrumentation + is in place. + This is safe, since this function() is called before creating new threads, + so the mutexes are not in use. +*/ +void my_thread_basic_global_reinit(void) +{ + struct st_my_thread_var *tmp; + + DBUG_ASSERT(my_thread_basic_global_init_done); + +#ifdef HAVE_PSI_INTERFACE + my_init_mysys_psi_keys(); +#endif + + mysql_mutex_destroy(&THR_LOCK_malloc); + mysql_mutex_init(key_THR_LOCK_malloc, &THR_LOCK_malloc, MY_MUTEX_INIT_FAST); + + mysql_mutex_destroy(&THR_LOCK_open); + mysql_mutex_init(key_THR_LOCK_open, &THR_LOCK_open, MY_MUTEX_INIT_FAST); + + mysql_mutex_destroy(&THR_LOCK_charset); + mysql_mutex_init(key_THR_LOCK_charset, &THR_LOCK_charset, MY_MUTEX_INIT_FAST); + + mysql_mutex_destroy(&THR_LOCK_threads); + mysql_mutex_init(key_THR_LOCK_threads, &THR_LOCK_threads, MY_MUTEX_INIT_FAST); + + tmp= my_pthread_getspecific(struct st_my_thread_var*, THR_KEY_mysys); + DBUG_ASSERT(tmp); + + mysql_mutex_destroy(&tmp->mutex); + mysql_mutex_init(key_my_thread_var_mutex, &tmp->mutex, MY_MUTEX_INIT_FAST); + + mysql_cond_destroy(&tmp->suspend); + mysql_cond_init(key_my_thread_var_suspend, &tmp->suspend, NULL); +} + /* initialize thread environment @@ -78,14 +156,10 @@ static uint get_thread_lib(void); my_bool my_thread_global_init(void) { - int pth_ret; - thd_lib_detected= get_thread_lib(); - - if ((pth_ret= pthread_key_create(&THR_KEY_mysys, NULL)) != 0) - { - fprintf(stderr,"Can't initialize threads: error %d\n", pth_ret); + if (my_thread_basic_global_init()) return 1; - } + + thd_lib_detected= get_thread_lib(); #ifdef TARGET_OS_LINUX /* @@ -137,23 +211,20 @@ my_bool my_thread_global_init(void) PTHREAD_MUTEX_ERRORCHECK); #endif - pthread_mutex_init(&THR_LOCK_malloc,MY_MUTEX_INIT_FAST); - pthread_mutex_init(&THR_LOCK_open,MY_MUTEX_INIT_FAST); - pthread_mutex_init(&THR_LOCK_lock,MY_MUTEX_INIT_FAST); - pthread_mutex_init(&THR_LOCK_isam,MY_MUTEX_INIT_SLOW); - pthread_mutex_init(&THR_LOCK_myisam,MY_MUTEX_INIT_SLOW); - pthread_mutex_init(&THR_LOCK_heap,MY_MUTEX_INIT_FAST); - pthread_mutex_init(&THR_LOCK_net,MY_MUTEX_INIT_FAST); - pthread_mutex_init(&THR_LOCK_charset,MY_MUTEX_INIT_FAST); - pthread_mutex_init(&THR_LOCK_threads,MY_MUTEX_INIT_FAST); - pthread_mutex_init(&THR_LOCK_time,MY_MUTEX_INIT_FAST); - pthread_cond_init(&THR_COND_threads, NULL); + mysql_mutex_init(key_THR_LOCK_lock, &THR_LOCK_lock, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_THR_LOCK_isam, &THR_LOCK_isam, MY_MUTEX_INIT_SLOW); + mysql_mutex_init(key_THR_LOCK_myisam, &THR_LOCK_myisam, MY_MUTEX_INIT_SLOW); + mysql_mutex_init(key_THR_LOCK_heap, &THR_LOCK_heap, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_THR_LOCK_net, &THR_LOCK_net, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_THR_LOCK_time, &THR_LOCK_time, MY_MUTEX_INIT_FAST); + mysql_cond_init(key_THR_COND_threads, &THR_COND_threads, NULL); #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) - pthread_mutex_init(&LOCK_localtime_r,MY_MUTEX_INIT_SLOW); + mysql_mutex_init(key_LOCK_localtime_r, &LOCK_localtime_r, MY_MUTEX_INIT_SLOW); #endif #ifndef HAVE_GETHOSTBYNAME_R - pthread_mutex_init(&LOCK_gethostbyname_r,MY_MUTEX_INIT_SLOW); + mysql_mutex_init(key_LOCK_gethostbyname_r, + &LOCK_gethostbyname_r, MY_MUTEX_INIT_SLOW); #endif #ifdef _MSC_VER @@ -175,11 +246,11 @@ void my_thread_global_end(void) my_bool all_threads_killed= 1; set_timespec(abstime, my_thread_end_wait_time); - pthread_mutex_lock(&THR_LOCK_threads); + mysql_mutex_lock(&THR_LOCK_threads); while (THR_thread_count > 0) { - int error= pthread_cond_timedwait(&THR_COND_threads, &THR_LOCK_threads, - &abstime); + int error= mysql_cond_timedwait(&THR_COND_threads, &THR_LOCK_threads, + &abstime); if (error == ETIMEDOUT || error == ETIME) { #ifdef HAVE_PTHREAD_KILL @@ -197,7 +268,7 @@ void my_thread_global_end(void) break; } } - pthread_mutex_unlock(&THR_LOCK_threads); + mysql_mutex_unlock(&THR_LOCK_threads); pthread_key_delete(THR_KEY_mysys); #ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP @@ -206,25 +277,25 @@ void my_thread_global_end(void) #ifdef PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP pthread_mutexattr_destroy(&my_errorcheck_mutexattr); #endif - pthread_mutex_destroy(&THR_LOCK_malloc); - pthread_mutex_destroy(&THR_LOCK_open); - pthread_mutex_destroy(&THR_LOCK_lock); - pthread_mutex_destroy(&THR_LOCK_isam); - pthread_mutex_destroy(&THR_LOCK_myisam); - pthread_mutex_destroy(&THR_LOCK_heap); - pthread_mutex_destroy(&THR_LOCK_net); - pthread_mutex_destroy(&THR_LOCK_time); - pthread_mutex_destroy(&THR_LOCK_charset); + mysql_mutex_destroy(&THR_LOCK_malloc); + mysql_mutex_destroy(&THR_LOCK_open); + mysql_mutex_destroy(&THR_LOCK_lock); + mysql_mutex_destroy(&THR_LOCK_isam); + mysql_mutex_destroy(&THR_LOCK_myisam); + mysql_mutex_destroy(&THR_LOCK_heap); + mysql_mutex_destroy(&THR_LOCK_net); + mysql_mutex_destroy(&THR_LOCK_time); + mysql_mutex_destroy(&THR_LOCK_charset); if (all_threads_killed) { - pthread_mutex_destroy(&THR_LOCK_threads); - pthread_cond_destroy(&THR_COND_threads); + mysql_mutex_destroy(&THR_LOCK_threads); + mysql_cond_destroy(&THR_COND_threads); } #if !defined(HAVE_LOCALTIME_R) || !defined(HAVE_GMTIME_R) - pthread_mutex_destroy(&LOCK_localtime_r); + mysql_mutex_destroy(&LOCK_localtime_r); #endif #ifndef HAVE_GETHOSTBYNAME_R - pthread_mutex_destroy(&LOCK_gethostbyname_r); + mysql_mutex_destroy(&LOCK_gethostbyname_r); #endif } @@ -280,17 +351,17 @@ my_bool my_thread_init(void) } pthread_setspecific(THR_KEY_mysys,tmp); tmp->pthread_self= pthread_self(); - pthread_mutex_init(&tmp->mutex,MY_MUTEX_INIT_FAST); - pthread_cond_init(&tmp->suspend, NULL); - tmp->init= 1; + mysql_mutex_init(key_my_thread_var_mutex, &tmp->mutex, MY_MUTEX_INIT_FAST); + mysql_cond_init(key_my_thread_var_suspend, &tmp->suspend, NULL); tmp->stack_ends_here= (char*)&tmp + STACK_DIRECTION * (long)my_thread_stack_size; - pthread_mutex_lock(&THR_LOCK_threads); + mysql_mutex_lock(&THR_LOCK_threads); tmp->id= ++thread_id; ++THR_thread_count; - pthread_mutex_unlock(&THR_LOCK_threads); + mysql_mutex_unlock(&THR_LOCK_threads); + tmp->init= 1; #ifndef DBUG_OFF /* Generate unique name for thread */ (void) my_thread_name(); @@ -322,6 +393,17 @@ void my_thread_end(void) fprintf(stderr,"my_thread_end(): tmp: 0x%lx pthread_self: 0x%lx thread_id: %ld\n", (long) tmp, (long) pthread_self(), tmp ? (long) tmp->id : 0L); #endif + +#ifdef HAVE_PSI_INTERFACE + /* + Remove the instrumentation for this thread. + This must be done before trashing st_my_thread_var, + because the LF_HASH depends on it. + */ + if (PSI_server) + PSI_server->delete_current_thread(); +#endif + if (tmp && tmp->init) { #if !defined(DBUG_OFF) @@ -335,9 +417,9 @@ void my_thread_end(void) #endif #if !defined(__bsdi__) && !defined(__OpenBSD__) /* bsdi and openbsd 3.5 dumps core here */ - pthread_cond_destroy(&tmp->suspend); + mysql_cond_destroy(&tmp->suspend); #endif - pthread_mutex_destroy(&tmp->mutex); + mysql_mutex_destroy(&tmp->mutex); free(tmp); /* @@ -346,11 +428,11 @@ void my_thread_end(void) my_thread_end and thus freed all memory they have allocated in my_thread_init() and DBUG_xxxx */ - pthread_mutex_lock(&THR_LOCK_threads); + mysql_mutex_lock(&THR_LOCK_threads); DBUG_ASSERT(THR_thread_count != 0); if (--THR_thread_count == 0) - pthread_cond_signal(&THR_COND_threads); - pthread_mutex_unlock(&THR_LOCK_threads); + mysql_cond_signal(&THR_COND_threads); + mysql_mutex_unlock(&THR_LOCK_threads); } pthread_setspecific(THR_KEY_mysys,0); } diff --git a/mysys/my_winfile.c b/mysys/my_winfile.c index 6a2cda5ba29..6c0b191ca2c 100644 --- a/mysys/my_winfile.c +++ b/mysys/my_winfile.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2008 MySQL AB +/* Copyright (C) 2008 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -57,7 +57,7 @@ File my_open_osfhandle(HANDLE handle, int oflag) uint i; DBUG_ENTER("my_open_osfhandle"); - pthread_mutex_lock(&THR_LOCK_open); + mysql_mutex_lock(&THR_LOCK_open); for(i= MY_FILE_MIN; i < my_file_limit;i++) { if(my_file_info[i].fhandle == 0) @@ -70,7 +70,7 @@ File my_open_osfhandle(HANDLE handle, int oflag) break; } } - pthread_mutex_unlock(&THR_LOCK_open); + mysql_mutex_unlock(&THR_LOCK_open); if(offset == -1) errno= EMFILE; /* to many file handles open */ DBUG_RETURN(offset); diff --git a/mysys/mysys_priv.h b/mysys/mysys_priv.h index 5c5bd6c2908..3a663dfefbf 100644 --- a/mysys/mysys_priv.h +++ b/mysys/mysys_priv.h @@ -59,9 +59,9 @@ extern PSI_thread_key key_thread_alarm; #endif /* HAVE_PSI_INTERFACE */ -extern pthread_mutex_t THR_LOCK_malloc, THR_LOCK_open, THR_LOCK_keycache; -extern pthread_mutex_t THR_LOCK_lock, THR_LOCK_isam, THR_LOCK_net; -extern pthread_mutex_t THR_LOCK_charset, THR_LOCK_time; +extern mysql_mutex_t THR_LOCK_malloc, THR_LOCK_open, THR_LOCK_keycache; +extern mysql_mutex_t THR_LOCK_lock, THR_LOCK_isam, THR_LOCK_net; +extern mysql_mutex_t THR_LOCK_charset, THR_LOCK_time; #else /* THREAD */ #include #endif /* THREAD */ diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index c484f1d4c54..675fa62380a 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2003 MySQL AB +/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -178,7 +178,7 @@ void *_mymalloc(size_t size, const char *filename, uint lineno, myf MyFlags) irem->prev= NULL; /* Add this remember structure to the linked list */ - pthread_mutex_lock(&THR_LOCK_malloc); + mysql_mutex_lock(&THR_LOCK_malloc); if ((irem->next= sf_malloc_root)) sf_malloc_root->prev= irem; sf_malloc_root= irem; @@ -188,7 +188,7 @@ void *_mymalloc(size_t size, const char *filename, uint lineno, myf MyFlags) if (sf_malloc_cur_memory > sf_malloc_max_memory) sf_malloc_max_memory= sf_malloc_cur_memory; sf_malloc_count++; - pthread_mutex_unlock(&THR_LOCK_malloc); + mysql_mutex_unlock(&THR_LOCK_malloc); /* Set the memory to the aribtrary wierd value */ if ((MyFlags & MY_ZEROFILL) || !sf_malloc_quick) @@ -291,7 +291,7 @@ void _myfree(void *ptr, const char *filename, uint lineno, myf myflags) } /* Remove this structure from the linked list */ - pthread_mutex_lock(&THR_LOCK_malloc); + mysql_mutex_lock(&THR_LOCK_malloc); if (irem->prev) irem->prev->next= irem->next; else @@ -302,7 +302,7 @@ void _myfree(void *ptr, const char *filename, uint lineno, myf myflags) /* Handle the statistics */ sf_malloc_cur_memory-= irem->datasize; sf_malloc_count--; - pthread_mutex_unlock(&THR_LOCK_malloc); + mysql_mutex_unlock(&THR_LOCK_malloc); #ifndef HAVE_purify /* Mark this data as free'ed */ @@ -365,7 +365,7 @@ void TERMINATE(FILE *file, uint flag) { struct st_irem *irem; DBUG_ENTER("TERMINATE"); - pthread_mutex_lock(&THR_LOCK_malloc); + mysql_mutex_lock(&THR_LOCK_malloc); /* Report the difference between number of calls to @@ -428,7 +428,7 @@ void TERMINATE(FILE *file, uint flag) DBUG_PRINT("safe",("Maximum memory usage: %lu bytes (%luk)", (ulong) sf_malloc_max_memory, (ulong) (sf_malloc_max_memory + 1023L) /1024L)); - pthread_mutex_unlock(&THR_LOCK_malloc); + mysql_mutex_unlock(&THR_LOCK_malloc); DBUG_VOID_RETURN; } @@ -505,7 +505,7 @@ int _sanity(const char *filename, uint lineno) reg2 int flag=0; uint count=0; - pthread_mutex_lock(&THR_LOCK_malloc); + mysql_mutex_lock(&THR_LOCK_malloc); #ifndef PEDANTIC_SAFEMALLOC if (sf_malloc_tampered && (int) sf_malloc_count < 0) sf_malloc_count=0; @@ -513,7 +513,7 @@ int _sanity(const char *filename, uint lineno) count=sf_malloc_count; for (irem= sf_malloc_root; irem != NULL && count-- ; irem= irem->next) flag+= _checkchunk (irem, filename, lineno); - pthread_mutex_unlock(&THR_LOCK_malloc); + mysql_mutex_unlock(&THR_LOCK_malloc); if (count || irem) { const char *format="Error: Safemalloc link list destroyed, discovered at '%s:%d'"; diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c index 9ab862fa755..8ee89cfb55d 100644 --- a/mysys/thr_alarm.c +++ b/mysys/thr_alarm.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -15,6 +15,7 @@ /* To avoid problems with alarms in debug code, we disable DBUG here */ #define FORCE_DBUG_OFF +#include "mysys_priv.h" #include #if defined(THREAD) && !defined(DONT_USE_THR_ALARM) @@ -43,8 +44,8 @@ static sig_handler process_alarm_part2(int sig); #if !defined(__WIN__) -static pthread_mutex_t LOCK_alarm; -static pthread_cond_t COND_alarm; +static mysql_mutex_t LOCK_alarm; +static mysql_cond_t COND_alarm; static sigset_t full_signal_set; static QUEUE alarm_queue; static uint max_used_alarms=0; @@ -52,7 +53,7 @@ pthread_t alarm_thread; #ifdef USE_ALARM_THREAD static void *alarm_handler(void *arg); -#define reschedule_alarms() pthread_cond_signal(&COND_alarm) +#define reschedule_alarms() mysql_cond_signal(&COND_alarm) #else #define reschedule_alarms() pthread_kill(alarm_thread,THR_SERVER_ALARM) #endif @@ -75,8 +76,8 @@ void init_thr_alarm(uint max_alarms) init_queue(&alarm_queue,max_alarms+1,offsetof(ALARM,expire_time),0, compare_ulong,NullS); sigfillset(&full_signal_set); /* Neaded to block signals */ - pthread_mutex_init(&LOCK_alarm,MY_MUTEX_INIT_FAST); - pthread_cond_init(&COND_alarm,NULL); + mysql_mutex_init(key_LOCK_alarm, &LOCK_alarm, MY_MUTEX_INIT_FAST); + mysql_cond_init(key_COND_alarm, &COND_alarm, NULL); if (thd_lib_detected == THD_LIB_LT) thr_client_alarm= SIGALRM; else @@ -97,7 +98,8 @@ void init_thr_alarm(uint max_alarms) pthread_attr_setscope(&thr_attr,PTHREAD_SCOPE_PROCESS); pthread_attr_setdetachstate(&thr_attr,PTHREAD_CREATE_DETACHED); pthread_attr_setstacksize(&thr_attr,8196); - pthread_create(&alarm_thread,&thr_attr,alarm_handler,NULL); + mysql_thread_create(key_thread_alarm, + &alarm_thread, &thr_attr, alarm_handler, NULL); pthread_attr_destroy(&thr_attr); } #elif defined(USE_ONE_SIGNAL_HAND) @@ -117,14 +119,14 @@ void init_thr_alarm(uint max_alarms) void resize_thr_alarm(uint max_alarms) { - pthread_mutex_lock(&LOCK_alarm); + mysql_mutex_lock(&LOCK_alarm); /* It's ok not to shrink the queue as there may be more pending alarms than than max_alarms */ if (alarm_queue.elements < max_alarms) resize_queue(&alarm_queue,max_alarms+1); - pthread_mutex_unlock(&LOCK_alarm); + mysql_mutex_unlock(&LOCK_alarm); } @@ -162,12 +164,12 @@ my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data) #ifndef USE_ONE_SIGNAL_HAND pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask); #endif - pthread_mutex_lock(&LOCK_alarm); /* Lock from threads & alarms */ + mysql_mutex_lock(&LOCK_alarm); /* Lock from threads & alarms */ if (alarm_aborted > 0) { /* No signal thread */ DBUG_PRINT("info", ("alarm aborted")); *alrm= 0; /* No alarm */ - pthread_mutex_unlock(&LOCK_alarm); + mysql_mutex_unlock(&LOCK_alarm); #ifndef USE_ONE_SIGNAL_HAND pthread_sigmask(SIG_SETMASK,&old_mask,NULL); #endif @@ -183,7 +185,7 @@ my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data) DBUG_PRINT("info", ("alarm queue full")); fprintf(stderr,"Warning: thr_alarm queue is full\n"); *alrm= 0; /* No alarm */ - pthread_mutex_unlock(&LOCK_alarm); + mysql_mutex_unlock(&LOCK_alarm); #ifndef USE_ONE_SIGNAL_HAND pthread_sigmask(SIG_SETMASK,&old_mask,NULL); #endif @@ -198,7 +200,7 @@ my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data) { DBUG_PRINT("info", ("failed my_malloc()")); *alrm= 0; /* No alarm */ - pthread_mutex_unlock(&LOCK_alarm); + mysql_mutex_unlock(&LOCK_alarm); #ifndef USE_ONE_SIGNAL_HAND pthread_sigmask(SIG_SETMASK,&old_mask,NULL); #endif @@ -226,7 +228,7 @@ my_bool thr_alarm(thr_alarm_t *alrm, uint sec, ALARM *alarm_data) else reschedule_alarms(); /* Reschedule alarms */ } - pthread_mutex_unlock(&LOCK_alarm); + mysql_mutex_unlock(&LOCK_alarm); #ifndef USE_ONE_SIGNAL_HAND pthread_sigmask(SIG_SETMASK,&old_mask,NULL); #endif @@ -251,7 +253,7 @@ void thr_end_alarm(thr_alarm_t *alarmed) #ifndef USE_ONE_SIGNAL_HAND pthread_sigmask(SIG_BLOCK,&full_signal_set,&old_mask); #endif - pthread_mutex_lock(&LOCK_alarm); + mysql_mutex_lock(&LOCK_alarm); alarm_data= (ALARM*) ((uchar*) *alarmed - offsetof(ALARM,alarmed)); for (i=0 ; i < alarm_queue.elements ; i++) @@ -276,7 +278,7 @@ void thr_end_alarm(thr_alarm_t *alarmed) DBUG_PRINT("warning",("Didn't find alarm 0x%lx in queue\n", (long) *alarmed)); } - pthread_mutex_unlock(&LOCK_alarm); + mysql_mutex_unlock(&LOCK_alarm); #ifndef USE_ONE_SIGNAL_HAND pthread_sigmask(SIG_SETMASK,&old_mask,NULL); #endif @@ -319,14 +321,14 @@ sig_handler process_alarm(int sig __attribute__((unused))) #ifndef USE_ALARM_THREAD pthread_sigmask(SIG_SETMASK,&full_signal_set,&old_mask); - pthread_mutex_lock(&LOCK_alarm); + mysql_mutex_lock(&LOCK_alarm); #endif process_alarm_part2(sig); #ifndef USE_ALARM_THREAD #if defined(DONT_REMEMBER_SIGNAL) && !defined(USE_ONE_SIGNAL_HAND) my_sigset(THR_SERVER_ALARM,process_alarm); #endif - pthread_mutex_unlock(&LOCK_alarm); + mysql_mutex_unlock(&LOCK_alarm); pthread_sigmask(SIG_SETMASK,&old_mask,NULL); #endif return; @@ -434,7 +436,7 @@ void end_thr_alarm(my_bool free_structures) DBUG_ENTER("end_thr_alarm"); if (alarm_aborted != 1) /* If memory not freed */ { - pthread_mutex_lock(&LOCK_alarm); + mysql_mutex_lock(&LOCK_alarm); DBUG_PRINT("info",("Resheduling %d waiting alarms",alarm_queue.elements)); alarm_aborted= -1; /* mark aborted */ if (alarm_queue.elements || (alarm_thread_running && free_structures)) @@ -454,21 +456,21 @@ void end_thr_alarm(my_bool free_structures) set_timespec(abstime, 10); /* Wait up to 10 seconds */ while (alarm_thread_running) { - int error= pthread_cond_timedwait(&COND_alarm, &LOCK_alarm, &abstime); + int error= mysql_cond_timedwait(&COND_alarm, &LOCK_alarm, &abstime); if (error == ETIME || error == ETIMEDOUT) break; /* Don't wait forever */ } delete_queue(&alarm_queue); alarm_aborted= 1; - pthread_mutex_unlock(&LOCK_alarm); + mysql_mutex_unlock(&LOCK_alarm); if (!alarm_thread_running) /* Safety */ { - pthread_mutex_destroy(&LOCK_alarm); - pthread_cond_destroy(&COND_alarm); + mysql_mutex_destroy(&LOCK_alarm); + mysql_cond_destroy(&COND_alarm); } } else - pthread_mutex_unlock(&LOCK_alarm); + mysql_mutex_unlock(&LOCK_alarm); } DBUG_VOID_RETURN; } @@ -483,7 +485,7 @@ void thr_alarm_kill(my_thread_id thread_id) uint i; if (alarm_aborted) return; - pthread_mutex_lock(&LOCK_alarm); + mysql_mutex_lock(&LOCK_alarm); for (i=0 ; i < alarm_queue.elements ; i++) { if (((ALARM*) queue_element(&alarm_queue,i))->thread_id == thread_id) @@ -495,13 +497,13 @@ void thr_alarm_kill(my_thread_id thread_id) break; } } - pthread_mutex_unlock(&LOCK_alarm); + mysql_mutex_unlock(&LOCK_alarm); } void thr_alarm_info(ALARM_INFO *info) { - pthread_mutex_lock(&LOCK_alarm); + mysql_mutex_lock(&LOCK_alarm); info->next_alarm_time= 0; info->max_used_alarms= max_used_alarms; if ((info->active_alarms= alarm_queue.elements)) @@ -512,7 +514,7 @@ void thr_alarm_info(ALARM_INFO *info) time_diff= (long) (alarm_data->expire_time - now); info->next_alarm_time= (ulong) (time_diff < 0 ? 0 : time_diff); } - pthread_mutex_unlock(&LOCK_alarm); + mysql_mutex_unlock(&LOCK_alarm); } /* @@ -549,7 +551,7 @@ static void *alarm_handler(void *arg __attribute__((unused))) #endif my_thread_init(); alarm_thread_running= 1; - pthread_mutex_lock(&LOCK_alarm); + mysql_mutex_lock(&LOCK_alarm); for (;;) { if (alarm_queue.elements) @@ -564,7 +566,7 @@ static void *alarm_handler(void *arg __attribute__((unused))) abstime.tv_sec=sleep_time; abstime.tv_nsec=0; next_alarm_expire_time= sleep_time; - if ((error=pthread_cond_timedwait(&COND_alarm,&LOCK_alarm,&abstime)) && + if ((error= mysql_cond_timedwait(&COND_alarm, &LOCK_alarm, &abstime)) && error != ETIME && error != ETIMEDOUT) { #ifdef MAIN @@ -579,7 +581,7 @@ static void *alarm_handler(void *arg __attribute__((unused))) else { next_alarm_expire_time= ~ (time_t) 0; - if ((error=pthread_cond_wait(&COND_alarm,&LOCK_alarm))) + if ((error= mysql_cond_wait(&COND_alarm, &LOCK_alarm))) { #ifdef MAIN printf("Got error: %d from ptread_cond_wait (errno: %d)\n", @@ -591,8 +593,8 @@ static void *alarm_handler(void *arg __attribute__((unused))) } bzero((char*) &alarm_thread,sizeof(alarm_thread)); /* For easy debugging */ alarm_thread_running= 0; - pthread_cond_signal(&COND_alarm); - pthread_mutex_unlock(&LOCK_alarm); + mysql_cond_signal(&COND_alarm); + mysql_mutex_unlock(&LOCK_alarm); pthread_exit(0); return 0; /* Impossible */ } @@ -694,8 +696,8 @@ void resize_thr_alarm(uint max_alarms) #ifdef MAIN #if defined(THREAD) && !defined(DONT_USE_THR_ALARM) -static pthread_cond_t COND_thread_count; -static pthread_mutex_t LOCK_thread_count; +static mysql_cond_t COND_thread_count; +static mysql_mutex_t LOCK_thread_count; static uint thread_count; #ifdef HPUX10 @@ -782,10 +784,10 @@ static void *test_thread(void *arg) thr_end_alarm(&got_alarm); fflush(stdout); } - pthread_mutex_lock(&LOCK_thread_count); + mysql_mutex_lock(&LOCK_thread_count); thread_count--; - pthread_cond_signal(&COND_thread_count); /* Tell main we are ready */ - pthread_mutex_unlock(&LOCK_thread_count); + mysql_cond_signal(&COND_thread_count); /* Tell main we are ready */ + mysql_mutex_unlock(&LOCK_thread_count); free((uchar*) arg); return 0; } @@ -812,9 +814,9 @@ static void *signal_hand(void *arg __attribute__((unused))) my_thread_init(); pthread_detach_this_thread(); init_thr_alarm(10); /* Setup alarm handler */ - pthread_mutex_lock(&LOCK_thread_count); /* Required by bsdi */ - pthread_cond_signal(&COND_thread_count); /* Tell main we are ready */ - pthread_mutex_unlock(&LOCK_thread_count); + mysql_mutex_lock(&LOCK_thread_count); /* Required by bsdi */ + mysql_cond_signal(&COND_thread_count); /* Tell main we are ready */ + mysql_mutex_unlock(&LOCK_thread_count); sigemptyset(&set); /* Catch all signals */ sigaddset(&set,SIGINT); @@ -885,8 +887,8 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused))) { DBUG_PUSH(argv[1]+2); } - pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST); - pthread_cond_init(&COND_thread_count,NULL); + mysql_mutex_init(0, &LOCK_thread_count, MY_MUTEX_INIT_FAST); + mysql_cond_init(0, &COND_thread_count, NULL); /* Start a alarm handling thread */ sigemptyset(&set); @@ -913,10 +915,11 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused))) pthread_attr_setstacksize(&thr_attr,65536L); /* Start signal thread and wait for it to start */ - pthread_mutex_lock(&LOCK_thread_count); - pthread_create(&tid,&thr_attr,signal_hand,NULL); - pthread_cond_wait(&COND_thread_count,&LOCK_thread_count); - pthread_mutex_unlock(&LOCK_thread_count); + mysql_mutex_lock(&LOCK_thread_count); + mysql_thread_create(0, + &tid, &thr_attr, signal_hand, NULL); + mysql_cond_wait(&COND_thread_count, &LOCK_thread_count); + mysql_mutex_unlock(&LOCK_thread_count); DBUG_PRINT("info",("signal thread created")); thr_setconcurrency(3); @@ -926,32 +929,34 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused))) { param=(int*) malloc(sizeof(int)); *param= i; - pthread_mutex_lock(&LOCK_thread_count); - if ((error=pthread_create(&tid,&thr_attr,test_thread,(void*) param))) + mysql_mutex_lock(&LOCK_thread_count); + if ((error= mysql_thread_create(0, + &tid, &thr_attr, test_thread, + (void*) param))) { printf("Can't create thread %d, error: %d\n",i,error); exit(1); } thread_count++; - pthread_mutex_unlock(&LOCK_thread_count); + mysql_mutex_unlock(&LOCK_thread_count); } pthread_attr_destroy(&thr_attr); - pthread_mutex_lock(&LOCK_thread_count); + mysql_mutex_lock(&LOCK_thread_count); thr_alarm_info(&alarm_info); printf("Main_thread: Alarms: %u max_alarms: %u next_alarm_time: %lu\n", alarm_info.active_alarms, alarm_info.max_used_alarms, alarm_info.next_alarm_time); while (thread_count) { - pthread_cond_wait(&COND_thread_count,&LOCK_thread_count); + mysql_cond_wait(&COND_thread_count, &LOCK_thread_count); if (thread_count == 1) { printf("Calling end_thr_alarm. This should cancel the last thread\n"); end_thr_alarm(0); } } - pthread_mutex_unlock(&LOCK_thread_count); + mysql_mutex_unlock(&LOCK_thread_count); thr_alarm_info(&alarm_info); end_thr_alarm(1); printf("Main_thread: Alarms: %u max_alarms: %u next_alarm_time: %lu\n", diff --git a/mysys/thr_lock.c b/mysys/thr_lock.c index 1d724de641c..5a71e58cdbf 100644 --- a/mysys/thr_lock.c +++ b/mysys/thr_lock.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -94,7 +94,7 @@ enum thr_lock_type thr_upgraded_concurrent_insert_lock = TL_WRITE; LIST *thr_lock_thread_list; /* List of threads in use */ ulong max_write_lock_count= ~(ulong) 0L; -static inline pthread_cond_t *get_cond(void) +static inline mysql_cond_t *get_cond(void) { return &my_thread_var->suspend; } @@ -316,16 +316,16 @@ void thr_lock_init(THR_LOCK *lock) { DBUG_ENTER("thr_lock_init"); bzero((char*) lock,sizeof(*lock)); - pthread_mutex_init(&lock->mutex,MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_THR_LOCK_mutex, &lock->mutex, MY_MUTEX_INIT_FAST); lock->read.last= &lock->read.data; lock->read_wait.last= &lock->read_wait.data; lock->write_wait.last= &lock->write_wait.data; lock->write.last= &lock->write.data; - pthread_mutex_lock(&THR_LOCK_lock); /* Add to locks in use */ + mysql_mutex_lock(&THR_LOCK_lock); /* Add to locks in use */ lock->list.data=(void*) lock; thr_lock_thread_list=list_add(thr_lock_thread_list,&lock->list); - pthread_mutex_unlock(&THR_LOCK_lock); + mysql_mutex_unlock(&THR_LOCK_lock); DBUG_VOID_RETURN; } @@ -333,10 +333,10 @@ void thr_lock_init(THR_LOCK *lock) void thr_lock_delete(THR_LOCK *lock) { DBUG_ENTER("thr_lock_delete"); - pthread_mutex_lock(&THR_LOCK_lock); + mysql_mutex_lock(&THR_LOCK_lock); thr_lock_thread_list=list_delete(thr_lock_thread_list,&lock->list); - pthread_mutex_unlock(&THR_LOCK_lock); - pthread_mutex_destroy(&lock->mutex); + mysql_mutex_unlock(&THR_LOCK_lock); + mysql_mutex_destroy(&lock->mutex); DBUG_VOID_RETURN; } @@ -392,7 +392,7 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, my_bool in_wait_list) { struct st_my_thread_var *thread_var= my_thread_var; - pthread_cond_t *cond= &thread_var->suspend; + mysql_cond_t *cond= &thread_var->suspend; struct timespec wait_timeout; enum enum_thr_lock_result result= THR_LOCK_ABORTED; my_bool can_deadlock= test(data->owner->info->n_cursors); @@ -439,9 +439,9 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, while (!thread_var->abort || in_wait_list) { int rc= (can_deadlock ? - pthread_cond_timedwait(cond, &data->lock->mutex, - &wait_timeout) : - pthread_cond_wait(cond, &data->lock->mutex)); + mysql_cond_timedwait(cond, &data->lock->mutex, + &wait_timeout) : + mysql_cond_wait(cond, &data->lock->mutex)); /* We must break the wait if one of the following occurs: - the connection has been aborted (!thread_var->abort), but @@ -497,13 +497,13 @@ wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data, (*data->lock->get_status)(data->status_param, 0); check_locks(data->lock,"got wait_for_lock",0); } - pthread_mutex_unlock(&data->lock->mutex); + mysql_mutex_unlock(&data->lock->mutex); /* The following must be done after unlock of lock->mutex */ - pthread_mutex_lock(&thread_var->mutex); + mysql_mutex_lock(&thread_var->mutex); thread_var->current_mutex= 0; thread_var->current_cond= 0; - pthread_mutex_unlock(&thread_var->mutex); + mysql_mutex_unlock(&thread_var->mutex); DBUG_RETURN(result); } @@ -522,7 +522,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner, data->cond=0; /* safety */ data->type=lock_type; data->owner= owner; /* Must be reset ! */ - pthread_mutex_lock(&lock->mutex); + mysql_mutex_lock(&lock->mutex); DBUG_PRINT("lock",("data: 0x%lx thread: 0x%lx lock: 0x%lx type: %d", (long) data, data->owner->info->thread_id, (long) lock, (int) lock_type)); @@ -747,7 +747,7 @@ thr_lock(THR_LOCK_DATA *data, THR_LOCK_OWNER *owner, /* Can't get lock yet; Wait for it */ DBUG_RETURN(wait_for_lock(wait_queue, data, 0)); end: - pthread_mutex_unlock(&lock->mutex); + mysql_mutex_unlock(&lock->mutex); DBUG_RETURN(result); } @@ -769,7 +769,7 @@ static inline void free_all_read_locks(THR_LOCK *lock, do { - pthread_cond_t *cond=data->cond; + mysql_cond_t *cond= data->cond; if ((int) data->type == (int) TL_READ_NO_INSERT) { if (using_concurrent_insert) @@ -794,7 +794,7 @@ static inline void free_all_read_locks(THR_LOCK *lock, data->owner->info->thread_id)); /* purecov: end */ data->cond=0; /* Mark thread free */ - pthread_cond_signal(cond); + mysql_cond_signal(cond); } while ((data=data->next)); *lock->read_wait.last=0; if (!lock->read_wait.data) @@ -811,7 +811,7 @@ void thr_unlock(THR_LOCK_DATA *data) DBUG_ENTER("thr_unlock"); DBUG_PRINT("lock",("data: 0x%lx thread: 0x%lx lock: 0x%lx", (long) data, data->owner->info->thread_id, (long) lock)); - pthread_mutex_lock(&lock->mutex); + mysql_mutex_lock(&lock->mutex); check_locks(lock,"start of release lock",0); if (((*data->prev)=data->next)) /* remove from lock-list */ @@ -843,7 +843,7 @@ void thr_unlock(THR_LOCK_DATA *data) data->type=TL_UNLOCK; /* Mark unlocked */ check_locks(lock,"after releasing lock",1); wake_up_waiters(lock); - pthread_mutex_unlock(&lock->mutex); + mysql_mutex_unlock(&lock->mutex); DBUG_VOID_RETURN; } @@ -902,9 +902,9 @@ static void wake_up_waiters(THR_LOCK *lock) data->type, data->owner->info->thread_id)); /* purecov: end */ { - pthread_cond_t *cond=data->cond; + mysql_cond_t *cond= data->cond; data->cond=0; /* Mark thread free */ - pthread_cond_signal(cond); /* Start waiting thread */ + mysql_cond_signal(cond); /* Start waiting thread */ } if (data->type != TL_WRITE_ALLOW_WRITE || !lock->write_wait.data || @@ -945,7 +945,7 @@ static void wake_up_waiters(THR_LOCK *lock) goto end; } do { - pthread_cond_t *cond=data->cond; + mysql_cond_t *cond= data->cond; if (((*data->prev)=data->next)) /* remove from wait-list */ data->next->prev= data->prev; else @@ -955,7 +955,7 @@ static void wake_up_waiters(THR_LOCK *lock) lock->write.last= &data->next; data->next=0; /* Only one write lock */ data->cond=0; /* Mark thread free */ - pthread_cond_signal(cond); /* Start waiting thread */ + mysql_cond_signal(cond); /* Start waiting thread */ } while (lock_type == TL_WRITE_ALLOW_WRITE && (data=lock->write_wait.data) && data->type == TL_WRITE_ALLOW_WRITE); @@ -1112,19 +1112,19 @@ void thr_abort_locks(THR_LOCK *lock, my_bool upgrade_lock) { THR_LOCK_DATA *data; DBUG_ENTER("thr_abort_locks"); - pthread_mutex_lock(&lock->mutex); + mysql_mutex_lock(&lock->mutex); for (data=lock->read_wait.data; data ; data=data->next) { data->type=TL_UNLOCK; /* Mark killed */ /* It's safe to signal the cond first: we're still holding the mutex. */ - pthread_cond_signal(data->cond); + mysql_cond_signal(data->cond); data->cond=0; /* Removed from list */ } for (data=lock->write_wait.data; data ; data=data->next) { data->type=TL_UNLOCK; - pthread_cond_signal(data->cond); + mysql_cond_signal(data->cond); data->cond=0; } lock->read_wait.last= &lock->read_wait.data; @@ -1132,7 +1132,7 @@ void thr_abort_locks(THR_LOCK *lock, my_bool upgrade_lock) lock->read_wait.data=lock->write_wait.data=0; if (upgrade_lock && lock->write.data) lock->write.data->type=TL_WRITE_ONLY; - pthread_mutex_unlock(&lock->mutex); + mysql_mutex_unlock(&lock->mutex); DBUG_VOID_RETURN; } @@ -1149,7 +1149,7 @@ my_bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread_id) my_bool found= FALSE; DBUG_ENTER("thr_abort_locks_for_thread"); - pthread_mutex_lock(&lock->mutex); + mysql_mutex_lock(&lock->mutex); for (data= lock->read_wait.data; data ; data= data->next) { if (data->owner->info->thread_id == thread_id) /* purecov: tested */ @@ -1158,7 +1158,7 @@ my_bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread_id) data->type= TL_UNLOCK; /* Mark killed */ /* It's safe to signal the cond first: we're still holding the mutex. */ found= TRUE; - pthread_cond_signal(data->cond); + mysql_cond_signal(data->cond); data->cond= 0; /* Removed from list */ if (((*data->prev)= data->next)) @@ -1174,7 +1174,7 @@ my_bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread_id) DBUG_PRINT("info",("Aborting write-wait lock")); data->type= TL_UNLOCK; found= TRUE; - pthread_cond_signal(data->cond); + mysql_cond_signal(data->cond); data->cond= 0; if (((*data->prev)= data->next)) @@ -1184,7 +1184,7 @@ my_bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread_id) } } wake_up_waiters(lock); - pthread_mutex_unlock(&lock->mutex); + mysql_mutex_unlock(&lock->mutex); DBUG_RETURN(found); } @@ -1233,7 +1233,7 @@ void thr_downgrade_write_lock(THR_LOCK_DATA *in_data, #endif DBUG_ENTER("thr_downgrade_write_only_lock"); - pthread_mutex_lock(&lock->mutex); + mysql_mutex_lock(&lock->mutex); DBUG_ASSERT(old_lock_type == TL_WRITE_ONLY); DBUG_ASSERT(old_lock_type > new_lock_type); in_data->type= new_lock_type; @@ -1325,7 +1325,7 @@ void thr_downgrade_write_lock(THR_LOCK_DATA *in_data, next= data->next; if (start_writers && data->type == new_lock_type) { - pthread_cond_t *cond= data->cond; + mysql_cond_t *cond= data->cond; /* It is ok to start this waiter. Move from being first in wait queue to be last in write queue. @@ -1339,7 +1339,7 @@ void thr_downgrade_write_lock(THR_LOCK_DATA *in_data, data->next= 0; check_locks(lock, "Started write lock after downgrade",0); data->cond= 0; - pthread_cond_signal(cond); + mysql_cond_signal(cond); } else { @@ -1379,7 +1379,7 @@ void thr_downgrade_write_lock(THR_LOCK_DATA *in_data, if (new_lock_type != TL_WRITE_ALLOW_READ || data->type != TL_READ_NO_INSERT) { - pthread_cond_t *cond= data->cond; + mysql_cond_t *cond= data->cond; if (((*data->prev)= data->next)) data->next->prev= data->prev; else @@ -1392,13 +1392,13 @@ void thr_downgrade_write_lock(THR_LOCK_DATA *in_data, lock->read_no_write_count++; check_locks(lock, "Started read lock after downgrade",0); data->cond= 0; - pthread_cond_signal(cond); + mysql_cond_signal(cond); } } } check_locks(lock,"after starting waiters after downgrading lock",0); #endif - pthread_mutex_unlock(&lock->mutex); + mysql_mutex_unlock(&lock->mutex); DBUG_VOID_RETURN; } @@ -1410,10 +1410,10 @@ my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data, THR_LOCK *lock=data->lock; DBUG_ENTER("thr_upgrade_write_delay_lock"); - pthread_mutex_lock(&lock->mutex); + mysql_mutex_lock(&lock->mutex); if (data->type == TL_UNLOCK || data->type >= TL_WRITE_LOW_PRIORITY) { - pthread_mutex_unlock(&lock->mutex); + mysql_mutex_unlock(&lock->mutex); DBUG_RETURN(data->type == TL_UNLOCK); /* Test if Aborted */ } check_locks(lock,"before upgrading lock",0); @@ -1427,7 +1427,7 @@ my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data, { /* We have the lock */ if (data->lock->get_status) (*data->lock->get_status)(data->status_param, 0); - pthread_mutex_unlock(&lock->mutex); + mysql_mutex_unlock(&lock->mutex); DBUG_RETURN(0); } @@ -1460,10 +1460,10 @@ my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data) enum thr_lock_type write_lock_type; DBUG_ENTER("thr_reschedule_write_lock"); - pthread_mutex_lock(&lock->mutex); + mysql_mutex_lock(&lock->mutex); if (!lock->read_wait.data) /* No waiting read locks */ { - pthread_mutex_unlock(&lock->mutex); + mysql_mutex_unlock(&lock->mutex); DBUG_RETURN(0); } @@ -1485,7 +1485,7 @@ my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data) lock->write_wait.data=data; free_all_read_locks(lock,0); - pthread_mutex_unlock(&lock->mutex); + mysql_mutex_unlock(&lock->mutex); DBUG_RETURN(thr_upgrade_write_delay_lock(data, write_lock_type)); } @@ -1520,13 +1520,13 @@ void thr_print_locks(void) LIST *list; uint count=0; - pthread_mutex_lock(&THR_LOCK_lock); + mysql_mutex_lock(&THR_LOCK_lock); puts("Current locks:"); for (list= thr_lock_thread_list; list && count++ < MAX_THREADS; list= list_rest(list)) { THR_LOCK *lock=(THR_LOCK*) list->data; - pthread_mutex_lock(&lock->mutex); + mysql_mutex_lock(&lock->mutex); printf("lock: 0x%lx:",(ulong) lock); if ((lock->write_wait.data || lock->read_wait.data) && (! lock->read.data && ! lock->write.data)) @@ -1544,11 +1544,11 @@ void thr_print_locks(void) thr_print_lock("write_wait",&lock->write_wait); thr_print_lock("read",&lock->read); thr_print_lock("read_wait",&lock->read_wait); - pthread_mutex_unlock(&lock->mutex); + mysql_mutex_unlock(&lock->mutex); puts(""); } fflush(stdout); - pthread_mutex_unlock(&THR_LOCK_lock); + mysql_mutex_unlock(&THR_LOCK_lock); } #endif /* THREAD */ @@ -1609,8 +1609,8 @@ int lock_counts[]= {sizeof(test_0)/sizeof(struct st_test), }; -static pthread_cond_t COND_thread_count; -static pthread_mutex_t LOCK_thread_count; +static mysql_cond_t COND_thread_count; +static mysql_mutex_t LOCK_thread_count; static uint thread_count; static ulong sum=0; @@ -1662,7 +1662,7 @@ static void *test_thread(void *arg) data[i].type= tests[param][i].lock_type; } thr_multi_lock(multi_locks, lock_counts[param], &owner); - pthread_mutex_lock(&LOCK_thread_count); + mysql_mutex_lock(&LOCK_thread_count); { int tmp=rand() & 7; /* Do something from 0-2 sec */ if (tmp == 0) @@ -1676,16 +1676,16 @@ static void *test_thread(void *arg) sum+=k; } } - pthread_mutex_unlock(&LOCK_thread_count); + mysql_mutex_unlock(&LOCK_thread_count); thr_multi_unlock(multi_locks,lock_counts[param]); } printf("Thread %s (%d) ended\n",my_thread_name(),param); fflush(stdout); thr_print_locks(); - pthread_mutex_lock(&LOCK_thread_count); + mysql_mutex_lock(&LOCK_thread_count); thread_count--; - pthread_cond_signal(&COND_thread_count); /* Tell main we are ready */ - pthread_mutex_unlock(&LOCK_thread_count); + mysql_cond_signal(&COND_thread_count); /* Tell main we are ready */ + mysql_mutex_unlock(&LOCK_thread_count); free((uchar*) arg); return 0; } @@ -1702,15 +1702,15 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused))) printf("Main thread: %s\n",my_thread_name()); - if ((error=pthread_cond_init(&COND_thread_count,NULL))) + if ((error= mysql_cond_init(0, &COND_thread_count, NULL))) { - fprintf(stderr,"Got error: %d from pthread_cond_init (errno: %d)", + fprintf(stderr, "Got error: %d from mysql_cond_init (errno: %d)", error,errno); exit(1); } - if ((error=pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST))) + if ((error= mysql_mutex_init(0, &LOCK_thread_count, MY_MUTEX_INIT_FAST))) { - fprintf(stderr,"Got error: %d from pthread_cond_init (errno: %d)", + fprintf(stderr, "Got error: %d from mysql_cond_init (errno: %d)", error,errno); exit(1); } @@ -1752,33 +1752,35 @@ int main(int argc __attribute__((unused)),char **argv __attribute__((unused))) param=(int*) malloc(sizeof(int)); *param=i; - if ((error=pthread_mutex_lock(&LOCK_thread_count))) + if ((error= mysql_mutex_lock(&LOCK_thread_count))) { - fprintf(stderr,"Got error: %d from pthread_mutex_lock (errno: %d)", - error,errno); + fprintf(stderr, "Got error: %d from mysql_mutex_lock (errno: %d)", + error, errno); exit(1); } - if ((error=pthread_create(&tid,&thr_attr,test_thread,(void*) param))) + if ((error= mysql_thread_create(0, + &tid, &thr_attr, test_thread, + (void*) param))) { - fprintf(stderr,"Got error: %d from pthread_create (errno: %d)\n", - error,errno); - pthread_mutex_unlock(&LOCK_thread_count); + fprintf(stderr, "Got error: %d from mysql_thread_create (errno: %d)\n", + error, errno); + mysql_mutex_unlock(&LOCK_thread_count); exit(1); } thread_count++; - pthread_mutex_unlock(&LOCK_thread_count); + mysql_mutex_unlock(&LOCK_thread_count); } pthread_attr_destroy(&thr_attr); - if ((error=pthread_mutex_lock(&LOCK_thread_count))) - fprintf(stderr,"Got error: %d from pthread_mutex_lock\n",error); + if ((error= mysql_mutex_lock(&LOCK_thread_count))) + fprintf(stderr, "Got error: %d from mysql_mutex_lock\n", error); while (thread_count) { - if ((error=pthread_cond_wait(&COND_thread_count,&LOCK_thread_count))) - fprintf(stderr,"Got error: %d from pthread_cond_wait\n",error); + if ((error= mysql_cond_wait(&COND_thread_count, &LOCK_thread_count))) + fprintf(stderr, "Got error: %d from mysql_cond_wait\n", error); } - if ((error=pthread_mutex_unlock(&LOCK_thread_count))) - fprintf(stderr,"Got error: %d from pthread_mutex_unlock\n",error); + if ((error= mysql_mutex_unlock(&LOCK_thread_count))) + fprintf(stderr, "Got error: %d from mysql_mutex_unlock\n", error); for (i=0 ; i < (int) array_elements(locks) ; i++) thr_lock_delete(locks+i); #ifdef EXTRA_DEBUG diff --git a/mysys/thr_mutex.c b/mysys/thr_mutex.c index 8f9928026ba..db35d5a13a6 100644 --- a/mysys/thr_mutex.c +++ b/mysys/thr_mutex.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2003 MySQL AB +/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -39,6 +39,7 @@ #endif #endif /* DO_NOT_REMOVE_THREAD_WRAPPERS */ +/* Not instrumented */ static pthread_mutex_t THR_LOCK_mutex; static ulong safe_mutex_count= 0; /* Number of mutexes created */ #ifdef SAFE_MUTEX_DETECT_DESTROY @@ -85,7 +86,9 @@ int safe_mutex_init(safe_mutex_t *mp, pthread_mutex_unlock(&THR_LOCK_mutex); } #else - thread_safe_increment(safe_mutex_count, &THR_LOCK_mutex); + pthread_mutex_lock(&THR_LOCK_mutex); + safe_mutex_count++; + pthread_mutex_unlock(&THR_LOCK_mutex); #endif /* SAFE_MUTEX_DETECT_DESTROY */ return 0; } @@ -344,7 +347,9 @@ int safe_mutex_destroy(safe_mutex_t *mp, const char *file, uint line) mp->info= NULL; /* Get crash if double free */ } #else - thread_safe_sub(safe_mutex_count, 1, &THR_LOCK_mutex); + pthread_mutex_lock(&THR_LOCK_mutex); + safe_mutex_count--; + pthread_mutex_unlock(&THR_LOCK_mutex); #endif /* SAFE_MUTEX_DETECT_DESTROY */ return error; } diff --git a/plugin/semisync/semisync_master.cc b/plugin/semisync/semisync_master.cc index cc83978ad4e..23c78eca587 100644 --- a/plugin/semisync/semisync_master.cc +++ b/plugin/semisync/semisync_master.cc @@ -1,5 +1,5 @@ /* Copyright (C) 2007 Google Inc. - Copyright (C) 2008 MySQL AB + Copyright (C) 2008 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -64,7 +64,7 @@ static int gettimeofday(struct timeval *tv, void *tz) ******************************************************************************/ ActiveTranx::ActiveTranx(int max_connections, - pthread_mutex_t *lock, + mysql_mutex_t *lock, unsigned long trace_level) : Trace(trace_level), num_transactions_(max_connections), num_entries_(max_connections << 1), @@ -416,8 +416,10 @@ int ReplSemiSyncMaster::initObject() max_transactions_ = (int)max_connections; /* Mutex initialization can only be done after MY_INIT(). */ - pthread_mutex_init(&LOCK_binlog_, MY_MUTEX_INIT_FAST); - pthread_cond_init(&COND_binlog_send_, NULL); + mysql_mutex_init(key_ss_mutex_LOCK_binlog_, + &LOCK_binlog_, MY_MUTEX_INIT_FAST); + mysql_cond_init(key_ss_cond_COND_binlog_send_, + &COND_binlog_send_, NULL); if (rpl_semi_sync_master_enabled) result = enableMaster(); @@ -494,8 +496,8 @@ ReplSemiSyncMaster::~ReplSemiSyncMaster() { if (init_done_) { - pthread_mutex_destroy(&LOCK_binlog_); - pthread_cond_destroy(&COND_binlog_send_); + mysql_mutex_destroy(&LOCK_binlog_); + mysql_cond_destroy(&COND_binlog_send_); } delete active_tranxs_; @@ -503,17 +505,17 @@ ReplSemiSyncMaster::~ReplSemiSyncMaster() void ReplSemiSyncMaster::lock() { - pthread_mutex_lock(&LOCK_binlog_); + mysql_mutex_lock(&LOCK_binlog_); } void ReplSemiSyncMaster::unlock() { - pthread_mutex_unlock(&LOCK_binlog_); + mysql_mutex_unlock(&LOCK_binlog_); } void ReplSemiSyncMaster::cond_broadcast() { - pthread_cond_broadcast(&COND_binlog_send_); + mysql_cond_broadcast(&COND_binlog_send_); } int ReplSemiSyncMaster::cond_timewait(struct timespec *wait_time) @@ -522,8 +524,8 @@ int ReplSemiSyncMaster::cond_timewait(struct timespec *wait_time) int wait_res; function_enter(kWho); - wait_res = pthread_cond_timedwait(&COND_binlog_send_, - &LOCK_binlog_, wait_time); + wait_res= mysql_cond_timedwait(&COND_binlog_send_, + &LOCK_binlog_, wait_time); return function_exit(kWho, wait_res); } diff --git a/plugin/semisync/semisync_master.h b/plugin/semisync/semisync_master.h index d2b87745600..dbe8bb9d5e2 100644 --- a/plugin/semisync/semisync_master.h +++ b/plugin/semisync/semisync_master.h @@ -1,5 +1,6 @@ /* Copyright (C) 2007 Google Inc. Copyright (C) 2008 MySQL AB + Copyright (C) 2009 Sun Microsystems, Inc 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 @@ -20,6 +21,11 @@ #include "semisync.h" +#ifdef HAVE_PSI_INTERFACE +extern PSI_mutex_key key_ss_mutex_LOCK_binlog_; +extern PSI_cond_key key_ss_cond_COND_binlog_send_; +#endif + /** This class manages memory for active transaction list. @@ -49,7 +55,7 @@ private: int num_transactions_; /* maximum transactions */ int num_entries_; /* maximum hash table entries */ - pthread_mutex_t *lock_; /* mutex lock */ + mysql_mutex_t *lock_; /* mutex lock */ inline void assert_lock_owner(); @@ -74,7 +80,7 @@ private: } public: - ActiveTranx(int max_connections, pthread_mutex_t *lock, + ActiveTranx(int max_connections, mysql_mutex_t *lock, unsigned long trace_level); ~ActiveTranx(); @@ -124,14 +130,14 @@ class ReplSemiSyncMaster /* This cond variable is signaled when enough binlog has been sent to slave, * so that a waiting trx can return the 'ok' to the client for a commit. */ - pthread_cond_t COND_binlog_send_; + mysql_cond_t COND_binlog_send_; /* Mutex that protects the following state variables and the active * transaction list. * Under no cirumstances we can acquire mysql_bin_log.LOCK_log if we are * already holding LOCK_binlog_ because it can cause deadlocks. */ - pthread_mutex_t LOCK_binlog_; + mysql_mutex_t LOCK_binlog_; /* This is set to true when reply_file_name_ contains meaningful data. */ bool reply_file_name_inited_; diff --git a/plugin/semisync/semisync_master_plugin.cc b/plugin/semisync/semisync_master_plugin.cc index efcb7172b28..e371df3edc3 100644 --- a/plugin/semisync/semisync_master_plugin.cc +++ b/plugin/semisync/semisync_master_plugin.cc @@ -1,5 +1,5 @@ /* Copyright (C) 2007 Google Inc. - Copyright (C) 2008 MySQL AB + Copyright (C) 2008 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -334,9 +334,43 @@ static SHOW_VAR semi_sync_master_status_vars[]= { {NULL, NULL, SHOW_LONG}, }; +#ifdef HAVE_PSI_INTERFACE +PSI_mutex_key key_ss_mutex_LOCK_binlog_; + +static PSI_mutex_info all_semisync_mutexes[]= +{ + { &key_ss_mutex_LOCK_binlog_, "LOCK_binlog_", 0} +}; + +PSI_cond_key key_ss_cond_COND_binlog_send_; + +static PSI_cond_info all_semisync_conds[]= +{ + { &key_ss_cond_COND_binlog_send_, "COND_binlog_send_", 0} +}; + +static void init_semisync_psi_keys(void) +{ + const char* category= "semisync"; + int count; + + if (PSI_server == NULL) + return; + + count= array_elements(all_semisync_mutexes); + PSI_server->register_mutex(category, all_semisync_mutexes, count); + + count= array_elements(all_semisync_conds); + PSI_server->register_cond(category, all_semisync_conds, count); +} +#endif /* HAVE_PSI_INTERFACE */ static int semi_sync_master_plugin_init(void *p) { +#ifdef HAVE_PSI_INTERFACE + init_semisync_psi_keys(); +#endif + if (repl_semisync.initObject()) return 1; if (register_trans_observer(&trans_observer, p)) diff --git a/sql/debug_sync.cc b/sql/debug_sync.cc index 81870e6b7a3..3c8e24f6901 100644 --- a/sql/debug_sync.cc +++ b/sql/debug_sync.cc @@ -221,14 +221,14 @@ There are quite a few places in MySQL, where we use a synchronization pattern like this: - pthread_mutex_lock(&mutex); + mysql_mutex_lock(&mutex); thd->enter_cond(&condition_variable, &mutex, new_message); #if defined(ENABLE_DEBUG_SYNC) if (!thd->killed && !end_of_wait_condition) DEBUG_SYNC(thd, "sync_point_name"); #endif while (!thd->killed && !end_of_wait_condition) - pthread_cond_wait(&condition_variable, &mutex); + mysql_cond_wait(&condition_variable, &mutex); thd->exit_cond(old_message); Here some explanations: @@ -264,12 +264,12 @@ while (!thd->killed && !end_of_wait_condition) { - pthread_mutex_lock(&mutex); + mysql_mutex_lock(&mutex); thd->enter_cond(&condition_variable, &mutex, new_message); if (!thd->killed [&& !end_of_wait_condition]) { [DEBUG_SYNC(thd, "sync_point_name");] - pthread_cond_wait(&condition_variable, &mutex); + mysql_cond_wait(&condition_variable, &mutex); } thd->exit_cond(old_message); } @@ -285,7 +285,7 @@ before sleeping, we hold the mutex, which is registered in mysys_var. The killing thread would try to acquire the mutex before signaling the condition variable. Since the mutex is only released implicitly in - pthread_cond_wait(), the signaling happens at the right place. We + mysql_cond_wait(), the signaling happens at the right place. We have a safe synchronization. === Co-work with the DBUG facility === @@ -373,8 +373,8 @@ struct st_debug_sync_control struct st_debug_sync_globals { String ds_signal; /* signal variable */ - pthread_cond_t ds_cond; /* condition variable */ - pthread_mutex_t ds_mutex; /* mutex variable */ + mysql_cond_t ds_cond; /* condition variable */ + mysql_mutex_t ds_mutex; /* mutex variable */ ulonglong dsp_hits; /* statistics */ ulonglong dsp_executed; /* statistics */ ulonglong dsp_max_active; /* statistics */ @@ -425,6 +425,37 @@ static void debug_sync_C_callback(const char *sync_point_name, debug_sync(current_thd, sync_point_name, name_len); } +#ifdef HAVE_PSI_INTERFACE +static PSI_mutex_key key_debug_sync_globals_ds_mutex; + +static PSI_mutex_info all_debug_sync_mutexes[]= +{ + { &key_debug_sync_globals_ds_mutex, "DEBUG_SYNC::mutex", PSI_FLAG_GLOBAL} +}; + +static PSI_cond_key key_debug_sync_globals_ds_cond; + +static PSI_cond_info all_debug_sync_conds[]= +{ + { &key_debug_sync_globals_ds_cond, "DEBUG_SYNC::cond", PSI_FLAG_GLOBAL} +}; + +static void init_debug_sync_psi_keys(void) +{ + const char* category= "sql"; + int count; + + if (PSI_server == NULL) + return; + + count= array_elements(all_debug_sync_mutexes); + PSI_server->register_mutex(category, all_debug_sync_mutexes, count); + + count= array_elements(all_debug_sync_conds); + PSI_server->register_cond(category, all_debug_sync_conds, count); +} +#endif /* HAVE_PSI_INTERFACE */ + /** Initialize the debug sync facility at server start. @@ -438,15 +469,21 @@ int debug_sync_init(void) { DBUG_ENTER("debug_sync_init"); +#ifdef HAVE_PSI_INTERFACE + init_debug_sync_psi_keys(); +#endif + if (opt_debug_sync_timeout) { int rc; /* Initialize the global variables. */ debug_sync_global.ds_signal.length(0); - if ((rc= pthread_cond_init(&debug_sync_global.ds_cond, NULL)) || - (rc= pthread_mutex_init(&debug_sync_global.ds_mutex, - MY_MUTEX_INIT_FAST))) + if ((rc= mysql_cond_init(key_debug_sync_globals_ds_cond, + &debug_sync_global.ds_cond, NULL)) || + (rc= mysql_mutex_init(key_debug_sync_globals_ds_mutex, + &debug_sync_global.ds_mutex, + MY_MUTEX_INIT_FAST))) DBUG_RETURN(rc); /* purecov: inspected */ /* Set the call back pointer in C files. */ @@ -476,8 +513,8 @@ void debug_sync_end(void) /* Destroy the global variables. */ debug_sync_global.ds_signal.free(); - (void) pthread_cond_destroy(&debug_sync_global.ds_cond); - (void) pthread_mutex_destroy(&debug_sync_global.ds_mutex); + mysql_cond_destroy(&debug_sync_global.ds_cond); + mysql_mutex_destroy(&debug_sync_global.ds_mutex); /* Print statistics. */ { @@ -585,12 +622,12 @@ void debug_sync_end_thread(THD *thd) } /* Statistics. */ - pthread_mutex_lock(&debug_sync_global.ds_mutex); + mysql_mutex_lock(&debug_sync_global.ds_mutex); debug_sync_global.dsp_hits+= ds_control->dsp_hits; debug_sync_global.dsp_executed+= ds_control->dsp_executed; if (debug_sync_global.dsp_max_active < ds_control->dsp_max_active) debug_sync_global.dsp_max_active= ds_control->dsp_max_active; - pthread_mutex_unlock(&debug_sync_global.ds_mutex); + mysql_mutex_unlock(&debug_sync_global.ds_mutex); my_free(ds_control, MYF(0)); thd->debug_sync_control= NULL; @@ -824,9 +861,9 @@ static void debug_sync_reset(THD *thd) ds_control->ds_active= 0; /* Clear the global signal. */ - pthread_mutex_lock(&debug_sync_global.ds_mutex); + mysql_mutex_lock(&debug_sync_global.ds_mutex); debug_sync_global.ds_signal.length(0); - pthread_mutex_unlock(&debug_sync_global.ds_mutex); + mysql_mutex_unlock(&debug_sync_global.ds_mutex); DBUG_VOID_RETURN; } @@ -1659,7 +1696,7 @@ uchar *sys_var_debug_sync::value_ptr(THD *thd, static char on[]= "ON - current signal: '"; // Ensure exclusive access to debug_sync_global.ds_signal - pthread_mutex_lock(&debug_sync_global.ds_mutex); + mysql_mutex_lock(&debug_sync_global.ds_mutex); size_t lgt= (sizeof(on) /* includes '\0' */ + debug_sync_global.ds_signal.length() + 1 /* for '\'' */); @@ -1676,7 +1713,7 @@ uchar *sys_var_debug_sync::value_ptr(THD *thd, *(vptr++)= '\''; *vptr= '\0'; /* We have one byte reserved for the worst case. */ } - pthread_mutex_unlock(&debug_sync_global.ds_mutex); + mysql_mutex_unlock(&debug_sync_global.ds_mutex); } else { @@ -1744,7 +1781,7 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action) read access too, to create a memory barrier in order to avoid that threads just reads an old cached version of the signal. */ - pthread_mutex_lock(&debug_sync_global.ds_mutex); + mysql_mutex_lock(&debug_sync_global.ds_mutex); if (action->signal.length()) { @@ -1758,15 +1795,15 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action) debug_sync_emergency_disable(); /* purecov: tested */ } /* Wake threads waiting in a sync point. */ - pthread_cond_broadcast(&debug_sync_global.ds_cond); + mysql_cond_broadcast(&debug_sync_global.ds_cond); DBUG_PRINT("debug_sync_exec", ("signal '%s' at: '%s'", sig_emit, dsp_name)); } /* end if (action->signal.length()) */ if (action->wait_for.length()) { - pthread_mutex_t *old_mutex; - pthread_cond_t *old_cond; + mysql_mutex_t *old_mutex; + mysql_cond_t *old_cond; int error= 0; struct timespec abstime; @@ -1797,9 +1834,9 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action) while (stringcmp(&debug_sync_global.ds_signal, &action->wait_for) && !thd->killed && opt_debug_sync_timeout) { - error= pthread_cond_timedwait(&debug_sync_global.ds_cond, - &debug_sync_global.ds_mutex, - &abstime); + error= mysql_cond_timedwait(&debug_sync_global.ds_cond, + &debug_sync_global.ds_mutex, + &abstime); DBUG_EXECUTE("debug_sync", { /* Functions as DBUG_PRINT args can change keyword and line nr. */ const char *sig_glob= debug_sync_global.ds_signal.c_ptr(); @@ -1832,18 +1869,17 @@ static void debug_sync_execute(THD *thd, st_debug_sync_action *action) protected mutex must always unlocked _before_ mysys_var->mutex is locked. (See comment in THD::exit_cond().) */ - pthread_mutex_unlock(&debug_sync_global.ds_mutex); - pthread_mutex_lock(&thd->mysys_var->mutex); + mysql_mutex_unlock(&debug_sync_global.ds_mutex); + mysql_mutex_lock(&thd->mysys_var->mutex); thd->mysys_var->current_mutex= old_mutex; thd->mysys_var->current_cond= old_cond; thd_proc_info(thd, old_proc_info); - pthread_mutex_unlock(&thd->mysys_var->mutex); - + mysql_mutex_unlock(&thd->mysys_var->mutex); } else { /* In case we don't wait, we just release the mutex. */ - pthread_mutex_unlock(&debug_sync_global.ds_mutex); + mysql_mutex_unlock(&debug_sync_global.ds_mutex); } /* end if (action->wait_for.length()) */ } /* end if (action->execute) */ diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index b71a7f602ab..4b72a7c8904 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -6904,7 +6904,7 @@ int ndbcluster_drop_database_impl(const char *path) while ((tabname=it++)) { tablename_to_filename(tabname, tmp, FN_REFLEN - (tmp - full_path)-1); - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); if (ha_ndbcluster::delete_table(0, ndb, full_path, dbname, tabname)) { const NdbError err= dict->getNdbError(); @@ -6914,7 +6914,7 @@ int ndbcluster_drop_database_impl(const char *path) ret= ndb_to_mysql_error(&err); } } - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } DBUG_RETURN(ret); } @@ -7067,7 +7067,7 @@ int ndbcluster_find_all_files(THD *thd) my_free((char*) data, MYF(MY_ALLOW_ZERO_PTR)); my_free((char*) pack_data, MYF(MY_ALLOW_ZERO_PTR)); - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); if (discover) { /* ToDo 4.1 database needs to be created if missing */ @@ -7085,7 +7085,7 @@ int ndbcluster_find_all_files(THD *thd) TRUE); } #endif - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } } while (unhandled && retries); @@ -7178,19 +7178,19 @@ int ndbcluster_find_files(handlerton *hton, THD *thd, file_name->str, reg_ext, 0); if (my_access(name, F_OK)) { - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); DBUG_PRINT("info", ("Table %s listed and need discovery", file_name->str)); if (ndb_create_table_from_engine(thd, db, file_name->str)) { - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_TABLE_EXISTS_ERROR, "Discover of table %s.%s failed", db, file_name->str); continue; } - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } DBUG_PRINT("info", ("%s existed in NDB _and_ on disk ", file_name->str)); file_on_disk= TRUE; @@ -7247,10 +7247,10 @@ int ndbcluster_find_files(handlerton *hton, THD *thd, file_name_str= (char*)my_hash_element(&ok_tables, i); end= end1 + tablename_to_filename(file_name_str, end1, sizeof(name) - (end1 - name)); - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); ndbcluster_create_binlog_setup(ndb, name, end-name, db, file_name_str, TRUE); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } } #endif @@ -7299,7 +7299,7 @@ int ndbcluster_find_files(handlerton *hton, THD *thd, } } - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); // Create new files List_iterator_fast it2(create_list); while ((file_name_str=it2++)) @@ -7314,7 +7314,7 @@ int ndbcluster_find_files(handlerton *hton, THD *thd, } } - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); my_hash_free(&ok_tables); my_hash_free(&ndb_tables); @@ -8214,7 +8214,7 @@ int handle_trailing_share(NDB_SHARE *share) bzero((char*) &table_list,sizeof(table_list)); table_list.db= share->db; table_list.alias= table_list.table_name= share->table_name; - safe_mutex_assert_owner(&LOCK_open); + mysql_mutex_assert_owner(&LOCK_open); close_cached_tables(thd, &table_list, TRUE, FALSE, FALSE); pthread_mutex_lock(&ndbcluster_mutex); diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc index e34a22cf9f4..d2ac46ae235 100644 --- a/sql/ha_ndbcluster_binlog.cc +++ b/sql/ha_ndbcluster_binlog.cc @@ -343,7 +343,7 @@ ndbcluster_binlog_open_table(THD *thd, NDB_SHARE *share, int error; DBUG_ENTER("ndbcluster_binlog_open_table"); - safe_mutex_assert_owner(&LOCK_open); + mysql_mutex_assert_owner(&LOCK_open); init_tmp_table_share(thd, table_share, share->db, 0, share->table_name, share->key); if ((error= open_table_def(thd, table_share, 0))) @@ -891,9 +891,9 @@ int ndbcluster_setup_binlog_table_shares(THD *thd) if (!ndb_schema_share && ndbcluster_check_ndb_schema_share() == 0) { - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); ndb_create_table_from_engine(thd, NDB_REP_DB, NDB_SCHEMA_TABLE); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); if (!ndb_schema_share) { ndbcluster_create_schema_table(thd); @@ -905,9 +905,9 @@ int ndbcluster_setup_binlog_table_shares(THD *thd) if (!ndb_apply_status_share && ndbcluster_check_ndb_apply_status_share() == 0) { - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); ndb_create_table_from_engine(thd, NDB_REP_DB, NDB_APPLY_TABLE); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); if (!ndb_apply_status_share) { ndbcluster_create_ndb_apply_status_table(thd); @@ -917,12 +917,12 @@ int ndbcluster_setup_binlog_table_shares(THD *thd) } if (!ndbcluster_find_all_files(thd)) { - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); ndb_binlog_tables_inited= TRUE; if (ndb_extra_logging) sql_print_information("NDB Binlog: ndb tables writable"); close_cached_tables(NULL, NULL, TRUE, FALSE, FALSE); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); /* Signal injector thread that all is setup */ pthread_cond_signal(&injector_cond); } @@ -1565,8 +1565,8 @@ end: (void) pthread_mutex_lock(&ndb_schema_object->mutex); if (have_lock_open) { - safe_mutex_assert_owner(&LOCK_open); - (void) pthread_mutex_unlock(&LOCK_open); + mysql_mutex_assert_owner(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } while (1) { @@ -1625,7 +1625,7 @@ end: } if (have_lock_open) { - (void) pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); } (void) pthread_mutex_unlock(&ndb_schema_object->mutex); } @@ -1709,7 +1709,7 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp, { DBUG_DUMP("frm", (uchar*) altered_table->getFrmData(), altered_table->getFrmLength()); - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); Ndb_table_guard ndbtab_g(dict, tabname); const NDBTAB *old= ndbtab_g.get_table(); if (!old && @@ -1747,7 +1747,7 @@ ndb_handle_schema_change(THD *thd, Ndb *ndb, NdbEventOperation *pOp, dbname= table_share->db.str; tabname= table_share->table_name.str; - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } my_free((char*)data, MYF(MY_ALLOW_ZERO_PTR)); my_free((char*)pack_data, MYF(MY_ALLOW_ZERO_PTR)); @@ -1974,7 +1974,7 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb, } // fall through case SOT_CREATE_TABLE: - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); if (ndbcluster_check_if_local_table(schema->db, schema->name)) { DBUG_PRINT("info", ("NDB Binlog: Skipping locally defined table '%s.%s'", @@ -1988,7 +1988,7 @@ ndb_binlog_thread_handle_schema_event(THD *thd, Ndb *ndb, { print_could_not_discover_error(thd, schema); } - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); log_query= 1; break; case SOT_DROP_DB: @@ -2257,7 +2257,7 @@ ndb_binlog_thread_handle_schema_event_post_epoch(THD *thd, free_share(&share); share= 0; } - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); if (ndbcluster_check_if_local_table(schema->db, schema->name)) { DBUG_PRINT("info", ("NDB Binlog: Skipping locally defined table '%s.%s'", @@ -2271,7 +2271,7 @@ ndb_binlog_thread_handle_schema_event_post_epoch(THD *thd, { print_could_not_discover_error(thd, schema); } - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } break; default: @@ -3155,8 +3155,8 @@ ndbcluster_handle_drop_table(Ndb *ndb, const char *event_name, #ifdef SYNC_DROP_ thd->proc_info= "Syncing ndb table schema operation and binlog"; (void) pthread_mutex_lock(&share->mutex); - safe_mutex_assert_owner(&LOCK_open); - (void) pthread_mutex_unlock(&LOCK_open); + mysql_mutex_assert_owner(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); int max_timeout= opt_ndb_sync_timeout; while (share->op) { @@ -3182,7 +3182,7 @@ ndbcluster_handle_drop_table(Ndb *ndb, const char *event_name, type_str, share->key); } } - (void) pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); (void) pthread_mutex_unlock(&share->mutex); #else (void) pthread_mutex_lock(&share->mutex); diff --git a/sql/item_func.cc b/sql/item_func.cc index ccb55feff81..f23bc340e71 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -1,4 +1,4 @@ -/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. 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 @@ -3287,7 +3287,7 @@ bool udf_handler::get_arguments() { return 0; } ** User level locks */ -pthread_mutex_t LOCK_user_locks; +mysql_mutex_t LOCK_user_locks; static HASH hash_user_locks; class User_level_lock @@ -3298,7 +3298,7 @@ class User_level_lock public: int count; bool locked; - pthread_cond_t cond; + mysql_cond_t cond; my_thread_id thread_id; void set_thread(THD *thd) { thread_id= thd->thread_id; } @@ -3306,7 +3306,7 @@ public: :key_length(length),count(1),locked(1), thread_id(id) { key= (uchar*) my_memdup(key_arg,length,MYF(0)); - pthread_cond_init(&cond,NULL); + mysql_cond_init(key_user_level_lock_cond, &cond, NULL); if (key) { if (my_hash_insert(&hash_user_locks,(uchar*) this)) @@ -3323,7 +3323,7 @@ public: my_hash_delete(&hash_user_locks,(uchar*) this); my_free(key, MYF(0)); } - pthread_cond_destroy(&cond); + mysql_cond_destroy(&cond); } inline bool initialized() { return key != 0; } friend void item_user_lock_release(User_level_lock *ull); @@ -3338,12 +3338,36 @@ uchar *ull_get_key(const User_level_lock *ull, size_t *length, return ull->key; } +#ifdef HAVE_PSI_INTERFACE +static PSI_mutex_key key_LOCK_user_locks; + +static PSI_mutex_info all_user_mutexes[]= +{ + { &key_LOCK_user_locks, "LOCK_user_locks", PSI_FLAG_GLOBAL} +}; + +static void init_user_lock_psi_keys(void) +{ + const char* category= "sql"; + int count; + + if (PSI_server == NULL) + return; + + count= array_elements(all_user_mutexes); + PSI_server->register_mutex(category, all_user_mutexes, count); +} +#endif static bool item_user_lock_inited= 0; void item_user_lock_init(void) { - pthread_mutex_init(&LOCK_user_locks,MY_MUTEX_INIT_SLOW); +#ifdef HAVE_PSI_INTERFACE + init_user_lock_psi_keys(); +#endif + + mysql_mutex_init(key_LOCK_user_locks, &LOCK_user_locks, MY_MUTEX_INIT_SLOW); my_hash_init(&hash_user_locks,system_charset_info, 16,0,0,(my_hash_get_key) ull_get_key,NULL,0); item_user_lock_inited= 1; @@ -3355,7 +3379,7 @@ void item_user_lock_free(void) { item_user_lock_inited= 0; my_hash_free(&hash_user_locks); - pthread_mutex_destroy(&LOCK_user_locks); + mysql_mutex_destroy(&LOCK_user_locks); } } @@ -3364,7 +3388,7 @@ void item_user_lock_release(User_level_lock *ull) ull->locked=0; ull->thread_id= 0; if (--ull->count) - pthread_cond_signal(&ull->cond); + mysql_cond_signal(&ull->cond); else delete ull; } @@ -3407,7 +3431,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout) struct timespec abstime; size_t lock_name_len; lock_name_len= strlen(lock_name); - pthread_mutex_lock(&LOCK_user_locks); + mysql_mutex_lock(&LOCK_user_locks); if (thd->ull) { @@ -3425,7 +3449,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout) (uchar*) lock_name, lock_name_len)))) { - pthread_mutex_unlock(&LOCK_user_locks); + mysql_mutex_unlock(&LOCK_user_locks); return; } ull->count++; @@ -3441,7 +3465,7 @@ void debug_sync_point(const char* lock_name, uint lock_timeout) set_timespec(abstime,lock_timeout); while (ull->locked && !thd->killed) { - int error= pthread_cond_timedwait(&ull->cond, &LOCK_user_locks, &abstime); + int error= mysql_cond_timedwait(&ull->cond, &LOCK_user_locks, &abstime); if (error == ETIMEDOUT || error == ETIME) break; } @@ -3457,19 +3481,19 @@ void debug_sync_point(const char* lock_name, uint lock_timeout) ull->set_thread(thd); thd->ull=ull; } - pthread_mutex_unlock(&LOCK_user_locks); - pthread_mutex_lock(&thd->mysys_var->mutex); + mysql_mutex_unlock(&LOCK_user_locks); + mysql_mutex_lock(&thd->mysys_var->mutex); thd_proc_info(thd, 0); thd->mysys_var->current_mutex= 0; thd->mysys_var->current_cond= 0; - pthread_mutex_unlock(&thd->mysys_var->mutex); - pthread_mutex_lock(&LOCK_user_locks); + mysql_mutex_unlock(&thd->mysys_var->mutex); + mysql_mutex_lock(&LOCK_user_locks); if (thd->ull) { item_user_lock_release(thd->ull); thd->ull=0; } - pthread_mutex_unlock(&LOCK_user_locks); + mysql_mutex_unlock(&LOCK_user_locks); } #endif @@ -3487,8 +3511,8 @@ void debug_sync_point(const char* lock_name, uint lock_timeout) #define INTERRUPT_INTERVAL (5 * ULL(1000000000)) -static int interruptible_wait(THD *thd, pthread_cond_t *cond, - pthread_mutex_t *lock, double time) +static int interruptible_wait(THD *thd, mysql_cond_t *cond, + mysql_mutex_t *lock, double time) { int error; struct timespec abstime; @@ -3504,7 +3528,7 @@ static int interruptible_wait(THD *thd, pthread_cond_t *cond, timeout-= slice; set_timespec_nsec(abstime, slice); - error= pthread_cond_timedwait(cond, lock, &abstime); + error= mysql_cond_timedwait(cond, lock, &abstime); if (error == ETIMEDOUT || error == ETIME) { /* Return error if timed out or connection is broken. */ @@ -3547,11 +3571,11 @@ longlong Item_func_get_lock::val_int() if (thd->slave_thread) DBUG_RETURN(1); - pthread_mutex_lock(&LOCK_user_locks); + mysql_mutex_lock(&LOCK_user_locks); if (!res || !res->length()) { - pthread_mutex_unlock(&LOCK_user_locks); + mysql_mutex_unlock(&LOCK_user_locks); null_value=1; DBUG_RETURN(0); } @@ -3574,13 +3598,13 @@ longlong Item_func_get_lock::val_int() if (!ull || !ull->initialized()) { delete ull; - pthread_mutex_unlock(&LOCK_user_locks); + mysql_mutex_unlock(&LOCK_user_locks); null_value=1; // Probably out of memory DBUG_RETURN(0); } ull->set_thread(thd); thd->ull=ull; - pthread_mutex_unlock(&LOCK_user_locks); + mysql_mutex_unlock(&LOCK_user_locks); DBUG_PRINT("info", ("made new lock")); DBUG_RETURN(1); // Got new lock } @@ -3630,13 +3654,13 @@ longlong Item_func_get_lock::val_int() error=0; DBUG_PRINT("info", ("got the lock")); } - pthread_mutex_unlock(&LOCK_user_locks); + mysql_mutex_unlock(&LOCK_user_locks); - pthread_mutex_lock(&thd->mysys_var->mutex); + mysql_mutex_lock(&thd->mysys_var->mutex); thd_proc_info(thd, 0); thd->mysys_var->current_mutex= 0; thd->mysys_var->current_cond= 0; - pthread_mutex_unlock(&thd->mysys_var->mutex); + mysql_mutex_unlock(&thd->mysys_var->mutex); DBUG_RETURN(!error ? 1 : 0); } @@ -3667,7 +3691,7 @@ longlong Item_func_release_lock::val_int() null_value=0; result=0; - pthread_mutex_lock(&LOCK_user_locks); + mysql_mutex_lock(&LOCK_user_locks); if (!(ull= ((User_level_lock*) my_hash_search(&hash_user_locks, (const uchar*) res->ptr(), (size_t) res->length())))) @@ -3688,7 +3712,7 @@ longlong Item_func_release_lock::val_int() thd->ull=0; } } - pthread_mutex_unlock(&LOCK_user_locks); + mysql_mutex_unlock(&LOCK_user_locks); DBUG_RETURN(result); } @@ -3794,7 +3818,7 @@ void Item_func_benchmark::print(String *str, enum_query_type query_type) longlong Item_func_sleep::val_int() { THD *thd= current_thd; - pthread_cond_t cond; + mysql_cond_t cond; double timeout; int error; @@ -3808,13 +3832,13 @@ longlong Item_func_sleep::val_int() When given a very short timeout (< 10 mcs) just return immediately. We assume that the lines between this test and the call - to pthread_cond_timedwait() will be executed in less than 0.00001 sec. + to mysql_cond_timedwait() will be executed in less than 0.00001 sec. */ if (timeout < 0.00001) return 0; - pthread_cond_init(&cond, NULL); - pthread_mutex_lock(&LOCK_user_locks); + mysql_cond_init(key_item_func_sleep_cond, &cond, NULL); + mysql_mutex_lock(&LOCK_user_locks); thd_proc_info(thd, "User sleep"); thd->mysys_var->current_mutex= &LOCK_user_locks; @@ -3829,13 +3853,13 @@ longlong Item_func_sleep::val_int() error= 0; } thd_proc_info(thd, 0); - pthread_mutex_unlock(&LOCK_user_locks); - pthread_mutex_lock(&thd->mysys_var->mutex); + mysql_mutex_unlock(&LOCK_user_locks); + mysql_mutex_lock(&thd->mysys_var->mutex); thd->mysys_var->current_mutex= 0; thd->mysys_var->current_cond= 0; - pthread_mutex_unlock(&thd->mysys_var->mutex); + mysql_mutex_unlock(&thd->mysys_var->mutex); - pthread_cond_destroy(&cond); + mysql_cond_destroy(&cond); return test(!error); // Return 1 killed } @@ -5763,10 +5787,10 @@ longlong Item_func_is_free_lock::val_int() return 0; } - pthread_mutex_lock(&LOCK_user_locks); + mysql_mutex_lock(&LOCK_user_locks); ull= (User_level_lock *) my_hash_search(&hash_user_locks, (uchar*) res->ptr(), (size_t) res->length()); - pthread_mutex_unlock(&LOCK_user_locks); + mysql_mutex_unlock(&LOCK_user_locks); if (!ull || !ull->locked) return 1; return 0; @@ -5782,10 +5806,10 @@ longlong Item_func_is_used_lock::val_int() if (!res || !res->length()) return 0; - pthread_mutex_lock(&LOCK_user_locks); + mysql_mutex_lock(&LOCK_user_locks); ull= (User_level_lock *) my_hash_search(&hash_user_locks, (uchar*) res->ptr(), (size_t) res->length()); - pthread_mutex_unlock(&LOCK_user_locks); + mysql_mutex_unlock(&LOCK_user_locks); if (!ull || !ull->locked) return 0; diff --git a/sql/lock.cc b/sql/lock.cc index 56ae94ddc39..03524712259 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -978,7 +978,7 @@ int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list) if (wait_if_global_read_lock(thd, 0, 1)) DBUG_RETURN(1); - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); if ((lock_retcode = lock_table_name(thd, table_list, TRUE)) < 0) goto end; if (lock_retcode && wait_for_locked_table_names(thd, table_list)) @@ -989,7 +989,7 @@ int lock_and_wait_for_table_name(THD *thd, TABLE_LIST *table_list) error=0; end: - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); start_waiting_global_read_lock(thd); DBUG_RETURN(error); } @@ -1118,7 +1118,7 @@ bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list) bool result=0; DBUG_ENTER("wait_for_locked_table_names"); - safe_mutex_assert_owner(&LOCK_open); + mysql_mutex_assert_owner(&LOCK_open); while (locked_named_table(thd,table_list)) { @@ -1128,7 +1128,7 @@ bool wait_for_locked_table_names(THD *thd, TABLE_LIST *table_list) break; } wait_for_condition(thd, &LOCK_open, &COND_refresh); - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); } DBUG_RETURN(result); } @@ -1508,7 +1508,7 @@ bool wait_if_global_read_lock(THD *thd, bool abort_on_refresh, threads could not close their tables. This would make a pretty deadlock. */ - safe_mutex_assert_not_owner(&LOCK_open); + mysql_mutex_assert_not_owner(&LOCK_open); (void) pthread_mutex_lock(&LOCK_global_read_lock); if ((need_exit_cond= must_wait)) @@ -1622,7 +1622,7 @@ bool make_global_read_lock_block_commit(THD *thd) void broadcast_refresh(void) { - pthread_cond_broadcast(&COND_refresh); + mysql_cond_broadcast(&COND_refresh); pthread_cond_broadcast(&COND_global_read_lock); } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index ca5b48d66bd..8b750f20b19 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1496,8 +1496,8 @@ int setup_conds(THD *thd, TABLE_LIST *tables, TABLE_LIST *leaves, COND **conds); int setup_ftfuncs(SELECT_LEX* select); int init_ftfuncs(THD *thd, SELECT_LEX* select, bool no_order); -void wait_for_condition(THD *thd, pthread_mutex_t *mutex, - pthread_cond_t *cond); +void wait_for_condition(THD *thd, mysql_mutex_t *mutex, + mysql_cond_t *cond); int open_tables(THD *thd, TABLE_LIST **tables, uint *counter, uint flags); /* open_and_lock_tables with optional derived handling */ int open_and_lock_tables_derived(THD *thd, TABLE_LIST *tables, bool derived); @@ -1986,13 +1986,15 @@ extern FILE *bootstrap_file; extern int bootstrap_error; extern FILE *stderror_file; extern pthread_key(MEM_ROOT**,THR_MALLOC); -extern pthread_mutex_t LOCK_mysql_create_db, LOCK_open, LOCK_lock_db, - LOCK_mapped_file,LOCK_user_locks, LOCK_status, - LOCK_error_log, LOCK_delayed_insert, LOCK_uuid_generator, - LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_timezone, +extern pthread_mutex_t LOCK_mapped_file, + LOCK_error_log, LOCK_uuid_generator, + LOCK_crypt, LOCK_timezone, LOCK_slave_list, LOCK_active_mi, LOCK_manager, LOCK_global_read_lock, LOCK_global_system_variables, LOCK_user_conn, LOCK_prepared_stmt_count, LOCK_error_messages, LOCK_connection_count; +extern mysql_mutex_t LOCK_mysql_create_db, LOCK_lock_db, LOCK_open, + LOCK_user_locks, LOCK_status, LOCK_delayed_status, LOCK_delayed_insert, + LOCK_delayed_create; extern MYSQL_PLUGIN_IMPORT pthread_mutex_t LOCK_thread_count; #ifdef HAVE_OPENSSL extern pthread_mutex_t LOCK_des_key_file; @@ -2002,7 +2004,8 @@ extern pthread_cond_t COND_server_started; extern int mysqld_server_started; extern rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave; extern rw_lock_t LOCK_system_variables_hash; -extern pthread_cond_t COND_refresh, COND_thread_count, COND_manager; +extern mysql_cond_t COND_refresh; +extern pthread_cond_t COND_thread_count, COND_manager; extern pthread_cond_t COND_global_read_lock; extern pthread_attr_t connection_attrib; extern I_List threads; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 30ea646d2fd..25523d5b0ae 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -647,14 +647,16 @@ SHOW_COMP_OPTION have_profiling; pthread_key(MEM_ROOT**,THR_MALLOC); pthread_key(THD*, THR_THD); -pthread_mutex_t LOCK_mysql_create_db, LOCK_open, LOCK_thread_count, - LOCK_mapped_file, LOCK_status, LOCK_global_read_lock, +pthread_mutex_t LOCK_thread_count, + LOCK_mapped_file, LOCK_global_read_lock, LOCK_error_log, LOCK_uuid_generator, - LOCK_delayed_insert, LOCK_delayed_status, LOCK_delayed_create, LOCK_crypt, LOCK_global_system_variables, LOCK_user_conn, LOCK_slave_list, LOCK_active_mi, LOCK_connection_count, LOCK_error_messages; +mysql_mutex_t LOCK_open, LOCK_mysql_create_db, LOCK_status, LOCK_delayed_status, + LOCK_delayed_insert, LOCK_delayed_create; + /** The below lock protects access to two global server variables: max_prepared_stmt_count and prepared_stmt_count. These variables @@ -668,7 +670,8 @@ pthread_mutex_t LOCK_des_key_file; #endif rw_lock_t LOCK_grant, LOCK_sys_init_connect, LOCK_sys_init_slave; rw_lock_t LOCK_system_variables_hash; -pthread_cond_t COND_refresh, COND_thread_count, COND_global_read_lock; +mysql_cond_t COND_refresh; +pthread_cond_t COND_thread_count, COND_global_read_lock; pthread_t signal_thread; pthread_attr_t connection_attrib; pthread_mutex_t LOCK_server_started; @@ -958,14 +961,14 @@ static void close_connections(void) if (tmp->mysys_var) { tmp->mysys_var->abort=1; - pthread_mutex_lock(&tmp->mysys_var->mutex); + mysql_mutex_lock(&tmp->mysys_var->mutex); if (tmp->mysys_var->current_cond) { - pthread_mutex_lock(tmp->mysys_var->current_mutex); - pthread_cond_broadcast(tmp->mysys_var->current_cond); - pthread_mutex_unlock(tmp->mysys_var->current_mutex); + mysql_mutex_lock(tmp->mysys_var->current_mutex); + mysql_cond_broadcast(tmp->mysys_var->current_cond); + mysql_mutex_unlock(tmp->mysys_var->current_mutex); } - pthread_mutex_unlock(&tmp->mysys_var->mutex); + mysql_mutex_unlock(&tmp->mysys_var->mutex); } } (void) pthread_mutex_unlock(&LOCK_thread_count); // For unlink from list @@ -1410,17 +1413,17 @@ static void wait_for_signal_thread_to_end() static void clean_up_mutexes() { - (void) pthread_mutex_destroy(&LOCK_mysql_create_db); - (void) pthread_mutex_destroy(&LOCK_lock_db); + mysql_mutex_destroy(&LOCK_mysql_create_db); + mysql_mutex_destroy(&LOCK_lock_db); (void) rwlock_destroy(&LOCK_grant); - (void) pthread_mutex_destroy(&LOCK_open); + mysql_mutex_destroy(&LOCK_open); (void) pthread_mutex_destroy(&LOCK_thread_count); (void) pthread_mutex_destroy(&LOCK_mapped_file); - (void) pthread_mutex_destroy(&LOCK_status); + mysql_mutex_destroy(&LOCK_status); (void) pthread_mutex_destroy(&LOCK_error_log); - (void) pthread_mutex_destroy(&LOCK_delayed_insert); - (void) pthread_mutex_destroy(&LOCK_delayed_status); - (void) pthread_mutex_destroy(&LOCK_delayed_create); + mysql_mutex_destroy(&LOCK_delayed_insert); + mysql_mutex_destroy(&LOCK_delayed_status); + mysql_mutex_destroy(&LOCK_delayed_create); (void) pthread_mutex_destroy(&LOCK_manager); (void) pthread_mutex_destroy(&LOCK_crypt); (void) pthread_mutex_destroy(&LOCK_user_conn); @@ -1448,7 +1451,7 @@ static void clean_up_mutexes() (void) pthread_mutex_destroy(&LOCK_prepared_stmt_count); (void) pthread_mutex_destroy(&LOCK_error_messages); (void) pthread_cond_destroy(&COND_thread_count); - (void) pthread_cond_destroy(&COND_refresh); + mysql_cond_destroy(&COND_refresh); (void) pthread_cond_destroy(&COND_global_read_lock); (void) pthread_cond_destroy(&COND_thread_cache); (void) pthread_cond_destroy(&COND_flush_thread_cache); @@ -3591,16 +3594,20 @@ You should consider changing lower_case_table_names to 1 or 2", static int init_thread_environment() { - (void) pthread_mutex_init(&LOCK_mysql_create_db,MY_MUTEX_INIT_SLOW); - (void) pthread_mutex_init(&LOCK_lock_db,MY_MUTEX_INIT_SLOW); - (void) pthread_mutex_init(&LOCK_open, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_LOCK_mysql_create_db, + &LOCK_mysql_create_db, MY_MUTEX_INIT_SLOW); + mysql_mutex_init(key_LOCK_lock_db, &LOCK_lock_db, MY_MUTEX_INIT_SLOW); + mysql_mutex_init(key_LOCK_open, &LOCK_open, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_thread_count,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_mapped_file,MY_MUTEX_INIT_SLOW); - (void) pthread_mutex_init(&LOCK_status,MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_LOCK_status, &LOCK_status, MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_error_log,MY_MUTEX_INIT_FAST); - (void) pthread_mutex_init(&LOCK_delayed_insert,MY_MUTEX_INIT_FAST); - (void) pthread_mutex_init(&LOCK_delayed_status,MY_MUTEX_INIT_FAST); - (void) pthread_mutex_init(&LOCK_delayed_create,MY_MUTEX_INIT_SLOW); + mysql_mutex_init(key_LOCK_deleyed_insert, + &LOCK_delayed_insert, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_LOCK_delayed_status, + &LOCK_delayed_status, MY_MUTEX_INIT_FAST); + mysql_mutex_init(key_LOCK_delayed_create, + &LOCK_delayed_create, MY_MUTEX_INIT_SLOW); (void) pthread_mutex_init(&LOCK_manager,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_crypt,MY_MUTEX_INIT_FAST); (void) pthread_mutex_init(&LOCK_user_conn, MY_MUTEX_INIT_FAST); @@ -3630,7 +3637,7 @@ static int init_thread_environment() (void) my_rwlock_init(&LOCK_sys_init_slave, NULL); (void) my_rwlock_init(&LOCK_grant, NULL); (void) pthread_cond_init(&COND_thread_count,NULL); - (void) pthread_cond_init(&COND_refresh,NULL); + mysql_cond_init(key_COND_refresh, &COND_refresh, NULL); (void) pthread_cond_init(&COND_global_read_lock,NULL); (void) pthread_cond_init(&COND_thread_cache,NULL); (void) pthread_cond_init(&COND_flush_thread_cache,NULL); @@ -8896,7 +8903,7 @@ static void create_pid_file() /** Clear most status variables. */ void refresh_status(THD *thd) { - pthread_mutex_lock(&LOCK_status); + mysql_mutex_lock(&LOCK_status); /* Add thread's status variabes to global status */ add_to_status(&global_status_var, &thd->status_var); @@ -8910,7 +8917,7 @@ void refresh_status(THD *thd) /* Reset the counters of all key caches (default and named). */ process_key_caches(reset_key_cache_counters); flush_status_time= time((time_t*) 0); - pthread_mutex_unlock(&LOCK_status); + mysql_mutex_unlock(&LOCK_status); /* Set max_used_connections to the number of currently open diff --git a/sql/replication.h b/sql/replication.h index eea77ef9f8e..5e9c09adf31 100644 --- a/sql/replication.h +++ b/sql/replication.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2008 MySQL AB +/* Copyright (C) 2008 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -470,8 +470,8 @@ MYSQL *rpl_connect_master(MYSQL *mysql); held before call this function @param msg The new process message for the thread */ -const char* thd_enter_cond(MYSQL_THD thd, pthread_cond_t *cond, - pthread_mutex_t *mutex, const char *msg); +const char* thd_enter_cond(MYSQL_THD thd, mysql_cond_t *cond, + mysql_mutex_t *mutex, const char *msg); /** Set thread leaving a condition diff --git a/sql/sp_cache.cc b/sql/sp_cache.cc index d9a23d2be4e..e1f2bb1c95b 100644 --- a/sql/sp_cache.cc +++ b/sql/sp_cache.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 MySQL AB +/* Copyright (C) 2002 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -20,7 +20,7 @@ #include "sp_cache.h" #include "sp_head.h" -static pthread_mutex_t Cversion_lock; +static mysql_mutex_t Cversion_lock; static ulong volatile Cversion= 0; @@ -75,12 +75,36 @@ private: HASH m_hashtable; }; // class sp_cache +#ifdef HAVE_PSI_INTERFACE +static PSI_mutex_key key_Cversion_lock; + +static PSI_mutex_info all_sp_cache_mutexes[]= +{ + { &key_Cversion_lock, "Cversion_lock", PSI_FLAG_GLOBAL} +}; + +static void init_sp_cache_psi_keys(void) +{ + const char* category= "sql"; + int count; + + if (PSI_server == NULL) + return; + + count= array_elements(all_sp_cache_mutexes); + PSI_server->register_mutex(category, all_sp_cache_mutexes, count); +} +#endif /* Initialize the SP caching once at startup */ void sp_cache_init() { - pthread_mutex_init(&Cversion_lock, MY_MUTEX_INIT_FAST); +#ifdef HAVE_PSI_INTERFACE + init_sp_cache_psi_keys(); +#endif + + mysql_mutex_init(key_Cversion_lock, &Cversion_lock, MY_MUTEX_INIT_FAST); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 4a8dd135879..3fd0e6a2376 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -566,7 +566,7 @@ void release_table_share(TABLE_SHARE *share, enum release_type type) (ulong) share, share->db.str, share->table_name.str, share->ref_count, share->version)); - safe_mutex_assert_owner(&LOCK_open); + mysql_mutex_assert_owner(&LOCK_open); pthread_mutex_lock(&share->mutex); if (!--share->ref_count) @@ -619,7 +619,7 @@ TABLE_SHARE *get_cached_table_share(const char *db, const char *table_name) char key[NAME_LEN*2+2]; TABLE_LIST table_list; uint key_length; - safe_mutex_assert_owner(&LOCK_open); + mysql_mutex_assert_owner(&LOCK_open); table_list.db= (char*) db; table_list.table_name= (char*) table_name; @@ -714,7 +714,7 @@ OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild) TABLE_LIST table_list; DBUG_ENTER("list_open_tables"); - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); bzero((char*) &table_list,sizeof(table_list)); start_list= &open_list; open_list=0; @@ -767,7 +767,7 @@ OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *db, const char *wild) start_list= &(*start_list)->next; *start_list=0; } - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(open_list); } @@ -864,7 +864,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock, DBUG_ASSERT(thd || (!wait_for_refresh && !tables)); if (!have_lock) - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); if (!tables) { refresh_version++; // Force close of open tables @@ -994,7 +994,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock, { found=1; DBUG_PRINT("signal", ("Waiting for COND_refresh")); - pthread_cond_wait(&COND_refresh,&LOCK_open); + mysql_cond_wait(&COND_refresh, &LOCK_open); break; } } @@ -1019,14 +1019,14 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock, } } if (!have_lock) - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); if (wait_for_refresh) { - pthread_mutex_lock(&thd->mysys_var->mutex); + mysql_mutex_lock(&thd->mysys_var->mutex); thd->mysys_var->current_mutex= 0; thd->mysys_var->current_cond= 0; thd_proc_info(thd, 0); - pthread_mutex_unlock(&thd->mysys_var->mutex); + mysql_mutex_unlock(&thd->mysys_var->mutex); } DBUG_RETURN(result); } @@ -1049,7 +1049,7 @@ bool close_cached_connection_tables(THD *thd, bool if_wait_for_refresh, bzero(&tmp, sizeof(TABLE_LIST)); if (!have_lock) - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); for (idx= 0; idx < table_def_cache.records; idx++) { @@ -1082,15 +1082,15 @@ bool close_cached_connection_tables(THD *thd, bool if_wait_for_refresh, result= close_cached_tables(thd, tables, TRUE, FALSE, FALSE); if (!have_lock) - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); if (if_wait_for_refresh) { - pthread_mutex_lock(&thd->mysys_var->mutex); + mysql_mutex_lock(&thd->mysys_var->mutex); thd->mysys_var->current_mutex= 0; thd->mysys_var->current_cond= 0; thd->proc_info=0; - pthread_mutex_unlock(&thd->mysys_var->mutex); + mysql_mutex_unlock(&thd->mysys_var->mutex); } DBUG_RETURN(result); @@ -1197,9 +1197,9 @@ static void close_open_tables(THD *thd) { bool found_old_table= 0; - safe_mutex_assert_not_owner(&LOCK_open); + mysql_mutex_assert_not_owner(&LOCK_open); - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); DBUG_PRINT("info", ("thd->open_tables: 0x%lx", (long) thd->open_tables)); @@ -1217,7 +1217,7 @@ static void close_open_tables(THD *thd) broadcast_refresh(); } - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } @@ -2094,7 +2094,7 @@ void unlink_open_table(THD *thd, TABLE *find, bool unlock) TABLE *list, **prev; DBUG_ENTER("unlink_open_table"); - safe_mutex_assert_owner(&LOCK_open); + mysql_mutex_assert_owner(&LOCK_open); memcpy(key, find->s->table_cache_key.str, key_length); /* @@ -2163,14 +2163,14 @@ void drop_open_table(THD *thd, TABLE *table, const char *db_name, else { handlerton *table_type= table->s->db_type(); - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); /* unlink_open_table() also tells threads waiting for refresh or close that something has happened. */ unlink_open_table(thd, table, FALSE); quick_rm_table(table_type, db_name, table_name, 0); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } } @@ -2186,7 +2186,7 @@ void drop_open_table(THD *thd, TABLE *table, const char *db_name, cond Condition to wait for */ -void wait_for_condition(THD *thd, pthread_mutex_t *mutex, pthread_cond_t *cond) +void wait_for_condition(THD *thd, mysql_mutex_t *mutex, mysql_cond_t *cond) { /* Wait until the current table is up to date */ const char *proc_info; @@ -2196,7 +2196,7 @@ void wait_for_condition(THD *thd, pthread_mutex_t *mutex, pthread_cond_t *cond) thd_proc_info(thd, "Waiting for table"); DBUG_ENTER("wait_for_condition"); if (!thd->killed) - (void) pthread_cond_wait(cond, mutex); + mysql_cond_wait(cond, mutex); /* We must unlock mutex first to avoid deadlock becasue conditions are @@ -2209,12 +2209,12 @@ void wait_for_condition(THD *thd, pthread_mutex_t *mutex, pthread_cond_t *cond) mutex is unlocked */ - pthread_mutex_unlock(mutex); - pthread_mutex_lock(&thd->mysys_var->mutex); + mysql_mutex_unlock(mutex); + mysql_mutex_lock(&thd->mysys_var->mutex); thd->mysys_var->current_mutex= 0; thd->mysys_var->current_cond= 0; thd_proc_info(thd, proc_info); - pthread_mutex_unlock(&thd->mysys_var->mutex); + mysql_mutex_unlock(&thd->mysys_var->mutex); DBUG_VOID_RETURN; } @@ -2285,7 +2285,7 @@ bool reopen_name_locked_table(THD* thd, TABLE_LIST* table_list, bool link_in) TABLE orig_table; DBUG_ENTER("reopen_name_locked_table"); - safe_mutex_assert_owner(&LOCK_open); + mysql_mutex_assert_owner(&LOCK_open); if (thd->killed || !table) DBUG_RETURN(TRUE); @@ -2365,7 +2365,7 @@ TABLE *table_cache_insert_placeholder(THD *thd, const char *key, char *key_buff; DBUG_ENTER("table_cache_insert_placeholder"); - safe_mutex_assert_owner(&LOCK_open); + mysql_mutex_assert_owner(&LOCK_open); /* Create a table entry with the right key and with an old refresh version @@ -2425,24 +2425,24 @@ bool lock_table_name_if_not_cached(THD *thd, const char *db, DBUG_ENTER("lock_table_name_if_not_cached"); key_length= (uint)(strmov(strmov(key, db) + 1, table_name) - key) + 1; - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); if (my_hash_search(&open_cache, (uchar *)key, key_length)) { - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_PRINT("info", ("Table is cached, name-lock is not obtained")); *table= 0; DBUG_RETURN(FALSE); } if (!(*table= table_cache_insert_placeholder(thd, key, key_length))) { - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(TRUE); } (*table)->open_placeholder= 1; (*table)->next= thd->open_tables; thd->open_tables= *table; - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(FALSE); } @@ -2474,7 +2474,7 @@ bool check_if_table_exists(THD *thd, TABLE_LIST *table, bool *exists) int rc; DBUG_ENTER("check_if_table_exists"); - safe_mutex_assert_owner(&LOCK_open); + mysql_mutex_assert_owner(&LOCK_open); *exists= TRUE; @@ -2699,15 +2699,15 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, */ TABLE tab; table= &tab; - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); if (!open_unireg_entry(thd, table, table_list, alias, key, key_length, mem_root, 0)) { DBUG_ASSERT(table_list->view != 0); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(0); // VIEW } - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } } /* @@ -2740,7 +2740,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, on disk. */ - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); /* If it's the first table from a list of tables used in a query, @@ -2758,7 +2758,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, /* Someone did a refresh while thread was opening tables */ if (refresh) *refresh=1; - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(0); } @@ -2824,7 +2824,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, /* Avoid self-deadlocks by detecting self-dependencies. */ if (table->open_placeholder && table->in_use == thd) { - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); my_error(ER_UPDATE_TABLE_USED, MYF(0), table->s->table_name.str); DBUG_RETURN(0); } @@ -2865,7 +2865,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, } else { - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } /* There is a refresh in progress for this table. @@ -2906,7 +2906,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, if (check_if_table_exists(thd, table_list, &exists)) { - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(NULL); } @@ -2917,7 +2917,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, */ if (!(table= table_cache_insert_placeholder(thd, key, key_length))) { - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(NULL); } /* @@ -2928,7 +2928,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, table->open_placeholder= 1; table->next= thd->open_tables; thd->open_tables= table; - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(table); } /* Table exists. Let us try to open it. */ @@ -2937,7 +2937,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, /* make a new table */ if (!(table=(TABLE*) my_malloc(sizeof(*table),MYF(MY_WME)))) { - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(NULL); } @@ -2946,7 +2946,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, if (error > 0) { my_free((uchar*)table, MYF(0)); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(NULL); } if (table_list->view || error < 0) @@ -2959,7 +2959,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, table_list->view= (LEX*)1; my_free((uchar*)table, MYF(0)); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(0); // VIEW } DBUG_PRINT("info", ("inserting table '%s'.'%s' 0x%lx into the cache", @@ -2970,7 +2970,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, check_unused(); // Debugging call - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); if (refresh) { table->next=thd->open_tables; /* Link into simple list */ @@ -3174,7 +3174,7 @@ void close_data_files_and_morph_locks(THD *thd, const char *db, TABLE *table; DBUG_ENTER("close_data_files_and_morph_locks"); - safe_mutex_assert_owner(&LOCK_open); + mysql_mutex_assert_owner(&LOCK_open); if (thd->lock) { @@ -3313,7 +3313,7 @@ bool reopen_tables(THD *thd, bool get_locks, bool mark_share_as_old) if (!thd->open_tables) DBUG_RETURN(0); - safe_mutex_assert_owner(&LOCK_open); + mysql_mutex_assert_owner(&LOCK_open); if (get_locks) { /* @@ -3576,7 +3576,7 @@ bool wait_for_tables(THD *thd) DBUG_ENTER("wait_for_tables"); thd_proc_info(thd, "Waiting for tables"); - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); while (!thd->killed) { thd->some_tables_deleted=0; @@ -3584,7 +3584,7 @@ bool wait_for_tables(THD *thd) mysql_ha_flush(thd); if (!table_is_used(thd->open_tables,1)) break; - (void) pthread_cond_wait(&COND_refresh,&LOCK_open); + mysql_cond_wait(&COND_refresh, &LOCK_open); } if (thd->killed) result= 1; // aborted @@ -3595,7 +3595,7 @@ bool wait_for_tables(THD *thd) thd->version= refresh_version; result=reopen_tables(thd,0,0); } - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); thd_proc_info(thd, 0); DBUG_RETURN(result); } @@ -3748,7 +3748,7 @@ void assign_new_table_id(TABLE_SHARE *share) /* Preconditions */ DBUG_ASSERT(share != NULL); - safe_mutex_assert_owner(&LOCK_open); + mysql_mutex_assert_owner(&LOCK_open); ulong tid= ++last_table_id; /* get next id */ /* @@ -3872,7 +3872,7 @@ static int open_unireg_entry(THD *thd, TABLE *entry, TABLE_LIST *table_list, uint discover_retry_count= 0; DBUG_ENTER("open_unireg_entry"); - safe_mutex_assert_owner(&LOCK_open); + mysql_mutex_assert_owner(&LOCK_open); retry: if (!(share= get_table_share_with_create(thd, table_list, cache_key, cache_key_length, @@ -4001,7 +4001,7 @@ retry: goto err; } } - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); thd->clear_error(); // Clear error message error= 0; if (open_table_from_share(thd, share, alias, @@ -4024,7 +4024,7 @@ retry: } else thd->clear_error(); // Clear error message - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); unlock_table_name(thd, table_list); if (error) @@ -8430,10 +8430,10 @@ void remove_db_from_cache(const char *db) void flush_tables() { - (void) pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); while (unused_tables) my_hash_delete(&open_cache,(uchar*) unused_tables); - (void) pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } @@ -8504,15 +8504,15 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name, ! in_use->killed) { in_use->killed= THD::KILL_CONNECTION; - pthread_mutex_lock(&in_use->mysys_var->mutex); + mysql_mutex_lock(&in_use->mysys_var->mutex); if (in_use->mysys_var->current_cond) { - pthread_mutex_lock(in_use->mysys_var->current_mutex); + mysql_mutex_lock(in_use->mysys_var->current_mutex); signalled= 1; - pthread_cond_broadcast(in_use->mysys_var->current_cond); - pthread_mutex_unlock(in_use->mysys_var->current_mutex); + mysql_cond_broadcast(in_use->mysys_var->current_cond); + mysql_mutex_unlock(in_use->mysys_var->current_mutex); } - pthread_mutex_unlock(&in_use->mysys_var->mutex); + mysql_mutex_unlock(&in_use->mysys_var->mutex); } /* Now we must abort all tables locks used by this thread @@ -8569,7 +8569,7 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name, { dropping_tables++; if (likely(signalled)) - (void) pthread_cond_wait(&COND_refresh, &LOCK_open); + mysql_cond_wait(&COND_refresh, &LOCK_open); else { struct timespec abstime; @@ -8584,7 +8584,7 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name, remove_table_from_cache routine. */ set_timespec(abstime, 10); - pthread_cond_timedwait(&COND_refresh, &LOCK_open, &abstime); + mysql_cond_timedwait(&COND_refresh, &LOCK_open, &abstime); } dropping_tables--; continue; @@ -8730,12 +8730,12 @@ int abort_and_upgrade_lock(ALTER_PARTITION_PARAM_TYPE *lpt) DBUG_ENTER("abort_and_upgrade_locks"); lpt->old_lock_type= lpt->table->reginfo.lock_type; - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); /* If MERGE child, forward lock handling to parent. */ mysql_lock_abort(lpt->thd, lpt->table->parent ? lpt->table->parent : lpt->table, TRUE); (void) remove_table_from_cache(lpt->thd, lpt->db, lpt->table_name, flags); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(0); } @@ -8757,10 +8757,10 @@ int abort_and_upgrade_lock(ALTER_PARTITION_PARAM_TYPE *lpt) /* purecov: begin deadcode */ void close_open_tables_and_downgrade(ALTER_PARTITION_PARAM_TYPE *lpt) { - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); remove_table_from_cache(lpt->thd, lpt->db, lpt->table_name, RTFC_WAIT_OTHER_THREAD_FLAG); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); /* If MERGE child, forward lock handling to parent. */ mysql_lock_downgrade_write(lpt->thd, lpt->table->parent ? lpt->table->parent : lpt->table, lpt->old_lock_type); @@ -8799,7 +8799,7 @@ void mysql_wait_completed_table(ALTER_PARTITION_PARAM_TYPE *lpt, TABLE *my_table DBUG_ENTER("mysql_wait_completed_table"); key_length=(uint) (strmov(strmov(key,lpt->db)+1,lpt->table_name)-key)+1; - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); HASH_SEARCH_STATE state; for (table= (TABLE*) my_hash_first(&open_cache,(uchar*) key,key_length, &state) ; @@ -8820,14 +8820,14 @@ void mysql_wait_completed_table(ALTER_PARTITION_PARAM_TYPE *lpt, TABLE *my_table ! in_use->killed) { in_use->killed= THD::KILL_CONNECTION; - pthread_mutex_lock(&in_use->mysys_var->mutex); + mysql_mutex_lock(&in_use->mysys_var->mutex); if (in_use->mysys_var->current_cond) { - pthread_mutex_lock(in_use->mysys_var->current_mutex); - pthread_cond_broadcast(in_use->mysys_var->current_cond); - pthread_mutex_unlock(in_use->mysys_var->current_mutex); + mysql_mutex_lock(in_use->mysys_var->current_mutex); + mysql_cond_broadcast(in_use->mysys_var->current_cond); + mysql_mutex_unlock(in_use->mysys_var->current_mutex); } - pthread_mutex_unlock(&in_use->mysys_var->mutex); + mysql_mutex_unlock(&in_use->mysys_var->mutex); } /* Now we must abort all tables locks used by this thread @@ -8857,7 +8857,7 @@ void mysql_wait_completed_table(ALTER_PARTITION_PARAM_TYPE *lpt, TABLE *my_table */ mysql_lock_abort(lpt->thd, my_table->parent ? my_table->parent : my_table, FALSE); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_VOID_RETURN; } @@ -9096,7 +9096,7 @@ void close_performance_schema_table(THD *thd, Open_tables_state *backup) mysql_unlock_tables(thd, thd->lock); thd->lock= 0; - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); found_old_table= false; /* @@ -9112,7 +9112,7 @@ void close_performance_schema_table(THD *thd, Open_tables_state *backup) if (found_old_table) broadcast_refresh(); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); thd->restore_backup_open_tables_state(backup); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index b7d88eca89a..2d1722267d9 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -957,9 +957,9 @@ void THD::init_for_queries() void THD::change_user(void) { - pthread_mutex_lock(&LOCK_status); + mysql_mutex_lock(&LOCK_status); add_to_status(&global_status_var, &status_var); - pthread_mutex_unlock(&LOCK_status); + mysql_mutex_unlock(&LOCK_status); cleanup(); killed= NOT_KILLED; @@ -1018,9 +1018,9 @@ void THD::cleanup(void) unlock_global_read_lock(this); if (ull) { - pthread_mutex_lock(&LOCK_user_locks); + mysql_mutex_lock(&LOCK_user_locks); item_user_lock_release(ull); - pthread_mutex_unlock(&LOCK_user_locks); + mysql_mutex_unlock(&LOCK_user_locks); ull= NULL; } @@ -1159,7 +1159,7 @@ void THD::awake(THD::killed_state state_to_set) } if (mysys_var) { - pthread_mutex_lock(&mysys_var->mutex); + mysql_mutex_lock(&mysys_var->mutex); if (!system_thread) // Don't abort locks mysys_var->abort=1; /* @@ -1183,11 +1183,11 @@ void THD::awake(THD::killed_state state_to_set) */ if (mysys_var->current_cond && mysys_var->current_mutex) { - pthread_mutex_lock(mysys_var->current_mutex); - pthread_cond_broadcast(mysys_var->current_cond); - pthread_mutex_unlock(mysys_var->current_mutex); + mysql_mutex_lock(mysys_var->current_mutex); + mysql_cond_broadcast(mysys_var->current_cond); + mysql_mutex_unlock(mysys_var->current_mutex); } - pthread_mutex_unlock(&mysys_var->mutex); + mysql_mutex_unlock(&mysys_var->mutex); } DBUG_VOID_RETURN; } diff --git a/sql/sql_class.h b/sql/sql_class.h index ed8b995fc96..b90d69e712e 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1874,21 +1874,21 @@ public: enter_cond(); this mutex is then released by exit_cond(). Usage must be: lock mutex; enter_cond(); your code; exit_cond(). */ - inline const char* enter_cond(pthread_cond_t *cond, pthread_mutex_t* mutex, - const char* msg) + inline const char* enter_cond(mysql_cond_t *cond, mysql_mutex_t* mutex, + const char* msg) { const char* old_msg = proc_info; - safe_mutex_assert_owner(mutex); + mysql_mutex_assert_owner(mutex); mysys_var->current_mutex = mutex; mysys_var->current_cond = cond; proc_info = msg; return old_msg; } - inline const char* enter_cond(mysql_cond_t *cond, mysql_mutex_t *mutex, + inline const char* enter_cond(pthread_cond_t *cond, pthread_mutex_t *mutex, const char *msg) { /* TO BE REMOVED: temporary helper, to help with merges */ - return enter_cond(&cond->m_cond, &mutex->m_mutex, msg); + return enter_cond((mysql_cond_t*) cond, (mysql_mutex_t*) mutex, msg); } inline void exit_cond(const char* old_msg) { @@ -1898,12 +1898,12 @@ public: locked (if that would not be the case, you'll get a deadlock if someone does a THD::awake() on you). */ - pthread_mutex_unlock(mysys_var->current_mutex); - pthread_mutex_lock(&mysys_var->mutex); + mysql_mutex_unlock(mysys_var->current_mutex); + mysql_mutex_lock(&mysys_var->mutex); mysys_var->current_mutex = 0; mysys_var->current_cond = 0; proc_info = old_msg; - pthread_mutex_unlock(&mysys_var->mutex); + mysql_mutex_unlock(&mysys_var->mutex); return; } inline time_t query_start() { query_start_used=1; return start_time; } diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 17626f05aa1..eb2e3915177 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2003 MySQL AB +/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 @@ -47,7 +47,7 @@ static void mysql_change_db_impl(THD *thd, /* Database lock hash */ HASH lock_db_cache; -pthread_mutex_t LOCK_lock_db; +mysql_mutex_t LOCK_lock_db; int creating_database= 0; // how many database locks are made @@ -103,7 +103,7 @@ static my_bool lock_db_insert(const char *dbname, uint length) my_bool error= 0; DBUG_ENTER("lock_db_insert"); - safe_mutex_assert_owner(&LOCK_lock_db); + mysql_mutex_assert_owner(&LOCK_lock_db); if (!(opt= (my_dblock_t*) my_hash_search(&lock_db_cache, (uchar*) dbname, length))) @@ -138,7 +138,7 @@ end: void lock_db_delete(const char *name, uint length) { my_dblock_t *opt; - safe_mutex_assert_owner(&LOCK_lock_db); + mysql_mutex_assert_owner(&LOCK_lock_db); if ((opt= (my_dblock_t *)my_hash_search(&lock_db_cache, (const uchar*) name, length))) my_hash_delete(&lock_db_cache, (uchar*) opt); @@ -148,7 +148,7 @@ void lock_db_delete(const char *name, uint length) /* Database options hash */ static HASH dboptions; static my_bool dboptions_init= 0; -static rw_lock_t LOCK_dboptions; +static mysql_rwlock_t LOCK_dboptions; /* Structure for database options */ typedef struct my_dbopt_st @@ -199,6 +199,26 @@ void free_dbopt(void *dbopt) my_free((uchar*) dbopt, MYF(0)); } +#ifdef HAVE_PSI_INTERFACE +static PSI_rwlock_key key_rwlock_LOCK_dboptions; + +static PSI_rwlock_info all_database_names_rwlocks[]= +{ + { &key_rwlock_LOCK_dboptions, "LOCK_dboptions", PSI_FLAG_GLOBAL} +}; + +static void init_database_names_psi_keys(void) +{ + const char* category= "sql"; + int count; + + if (PSI_server == NULL) + return; + + count= array_elements(all_database_names_rwlocks); + PSI_server->register_rwlock(category, all_database_names_rwlocks, count); +} +#endif /* Initialize database option hash and locked database hash. @@ -216,8 +236,12 @@ void free_dbopt(void *dbopt) bool my_database_names_init(void) { +#ifdef HAVE_PSI_INTERFACE + init_database_names_psi_keys(); +#endif + bool error= 0; - (void) my_rwlock_init(&LOCK_dboptions, NULL); + mysql_rwlock_init(key_rwlock_LOCK_dboptions, &LOCK_dboptions); if (!dboptions_init) { dboptions_init= 1; @@ -246,7 +270,7 @@ void my_database_names_free(void) { dboptions_init= 0; my_hash_free(&dboptions); - (void) rwlock_destroy(&LOCK_dboptions); + mysql_rwlock_destroy(&LOCK_dboptions); my_hash_free(&lock_db_cache); } } @@ -258,13 +282,13 @@ void my_database_names_free(void) void my_dbopt_cleanup(void) { - rw_wrlock(&LOCK_dboptions); + mysql_rwlock_wrlock(&LOCK_dboptions); my_hash_free(&dboptions); my_hash_init(&dboptions, lower_case_table_names ? &my_charset_bin : system_charset_info, 32, 0, 0, (my_hash_get_key) dboptions_get_key, free_dbopt,0); - rw_unlock(&LOCK_dboptions); + mysql_rwlock_unlock(&LOCK_dboptions); } @@ -288,13 +312,13 @@ static my_bool get_dbopt(const char *dbname, HA_CREATE_INFO *create) length= (uint) strlen(dbname); - rw_rdlock(&LOCK_dboptions); + mysql_rwlock_rdlock(&LOCK_dboptions); if ((opt= (my_dbopt_t*) my_hash_search(&dboptions, (uchar*) dbname, length))) { create->default_table_charset= opt->charset; error= 0; } - rw_unlock(&LOCK_dboptions); + mysql_rwlock_unlock(&LOCK_dboptions); return error; } @@ -320,7 +344,7 @@ static my_bool put_dbopt(const char *dbname, HA_CREATE_INFO *create) length= (uint) strlen(dbname); - rw_wrlock(&LOCK_dboptions); + mysql_rwlock_wrlock(&LOCK_dboptions); if (!(opt= (my_dbopt_t*) my_hash_search(&dboptions, (uchar*) dbname, length))) { @@ -349,7 +373,7 @@ static my_bool put_dbopt(const char *dbname, HA_CREATE_INFO *create) opt->charset= create->default_table_charset; end: - rw_unlock(&LOCK_dboptions); + mysql_rwlock_unlock(&LOCK_dboptions); DBUG_RETURN(error); } @@ -361,11 +385,11 @@ end: void del_dbopt(const char *path) { my_dbopt_t *opt; - rw_wrlock(&LOCK_dboptions); + mysql_rwlock_wrlock(&LOCK_dboptions); if ((opt= (my_dbopt_t *)my_hash_search(&dboptions, (const uchar*) path, strlen(path)))) my_hash_delete(&dboptions, (uchar*) opt); - rw_unlock(&LOCK_dboptions); + mysql_rwlock_unlock(&LOCK_dboptions); } @@ -392,7 +416,8 @@ static bool write_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create) if (put_dbopt(path, create)) return 1; - if ((file=my_create(path, CREATE_MODE,O_RDWR | O_TRUNC,MYF(MY_WME))) >= 0) + if ((file= mysql_file_create(key_file_dbopt, path, CREATE_MODE, + O_RDWR | O_TRUNC, MYF(MY_WME))) >= 0) { ulong length; length= (ulong) (strxnmov(buf, sizeof(buf)-1, "default-character-set=", @@ -401,10 +426,10 @@ static bool write_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create) create->default_table_charset->name, "\n", NullS) - buf); - /* Error is written by my_write */ - if (!my_write(file,(uchar*) buf, length, MYF(MY_NABP+MY_WME))) + /* Error is written by mysql_file_write */ + if (!mysql_file_write(file, (uchar*) buf, length, MYF(MY_NABP+MY_WME))) error=0; - my_close(file,MYF(0)); + mysql_file_close(file, MYF(0)); } return error; } @@ -441,7 +466,8 @@ bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create) DBUG_RETURN(0); /* Otherwise, load options from the .opt file */ - if ((file=my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0) + if ((file= mysql_file_open(key_file_dbopt, + path, O_RDONLY | O_SHARE, MYF(0))) < 0) goto err1; IO_CACHE cache; @@ -499,7 +525,7 @@ bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create) end_io_cache(&cache); err2: - my_close(file,MYF(0)); + mysql_file_close(file, MYF(0)); err1: DBUG_RETURN(error); } @@ -643,13 +669,13 @@ int mysql_create_db(THD *thd, char *db, HA_CREATE_INFO *create_info, goto exit2; } - pthread_mutex_lock(&LOCK_mysql_create_db); + mysql_mutex_lock(&LOCK_mysql_create_db); /* Check directory */ path_len= build_table_filename(path, sizeof(path) - 1, db, "", "", 0); path[path_len-1]= 0; // Remove last '/' from path - if (my_stat(path,&stat_info,MYF(0))) + if (mysql_file_stat(key_file_misc, path, &stat_info, MYF(0))) { if (!(create_options & HA_LEX_CREATE_IF_NOT_EXISTS)) { @@ -753,7 +779,7 @@ not_silent: } exit: - pthread_mutex_unlock(&LOCK_mysql_create_db); + mysql_mutex_unlock(&LOCK_mysql_create_db); start_waiting_global_read_lock(thd); exit2: DBUG_RETURN(error); @@ -784,7 +810,7 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) if ((error=wait_if_global_read_lock(thd,0,1))) goto exit2; - pthread_mutex_lock(&LOCK_mysql_create_db); + mysql_mutex_lock(&LOCK_mysql_create_db); /* Recreate db options file: /dbpath/.db.opt @@ -830,7 +856,7 @@ bool mysql_alter_db(THD *thd, const char *db, HA_CREATE_INFO *create_info) my_ok(thd, result); exit: - pthread_mutex_unlock(&LOCK_mysql_create_db); + mysql_mutex_unlock(&LOCK_mysql_create_db); start_waiting_global_read_lock(thd); exit2: DBUG_RETURN(error); @@ -882,7 +908,7 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) goto exit2; } - pthread_mutex_lock(&LOCK_mysql_create_db); + mysql_mutex_lock(&LOCK_mysql_create_db); length= build_table_filename(path, sizeof(path) - 1, db, "", "", 0); strmov(path+length, MY_DB_OPT_FILE); // Append db option file name @@ -904,9 +930,9 @@ bool mysql_rm_db(THD *thd,char *db,bool if_exists, bool silent) } else { - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); remove_db_from_cache(db); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); Drop_table_error_handler err_handler(thd->get_internal_handler()); thd->push_internal_handler(&err_handler); @@ -1030,7 +1056,7 @@ exit: */ if (thd->db && !strcmp(thd->db, db) && error == 0) mysql_change_db_impl(thd, NULL, 0, thd->variables.collation_server); - pthread_mutex_unlock(&LOCK_mysql_create_db); + mysql_mutex_unlock(&LOCK_mysql_create_db); start_waiting_global_read_lock(thd); exit2: DBUG_RETURN(error); @@ -1156,7 +1182,7 @@ static long mysql_rm_known_files(THD *thd, MY_DIR *dirp, const char *db, else { strxmov(filePath, org_path, "/", file->name, NullS); - if (my_delete_with_symlink(filePath,MYF(MY_WME))) + if (mysql_file_delete_with_symlink(key_file_misc, filePath, MYF(MY_WME))) { goto err; } @@ -1234,7 +1260,7 @@ static my_bool rm_dir_w_symlink(const char *org_path, my_bool send_error) DBUG_RETURN(1); if (!error) { - if (my_delete(path, MYF(send_error ? MY_WME : 0))) + if (mysql_file_delete(key_file_misc, path, MYF(send_error ? MY_WME : 0))) { DBUG_RETURN(send_error); } @@ -1311,7 +1337,7 @@ long mysql_rm_arc_files(THD *thd, MY_DIR *dirp, const char *org_path) continue; } strxmov(filePath, org_path, "/", file->name, NullS); - if (my_delete_with_symlink(filePath,MYF(MY_WME))) + if (mysql_file_delete_with_symlink(key_file_misc, filePath, MYF(MY_WME))) { goto err; } @@ -1718,18 +1744,18 @@ static int lock_databases(THD *thd, const char *db1, uint length1, const char *db2, uint length2) { - pthread_mutex_lock(&LOCK_lock_db); + mysql_mutex_lock(&LOCK_lock_db); while (!thd->killed && (my_hash_search(&lock_db_cache,(uchar*) db1, length1) || my_hash_search(&lock_db_cache,(uchar*) db2, length2))) { wait_for_condition(thd, &LOCK_lock_db, &COND_refresh); - pthread_mutex_lock(&LOCK_lock_db); + mysql_mutex_lock(&LOCK_lock_db); } if (thd->killed) { - pthread_mutex_unlock(&LOCK_lock_db); + mysql_mutex_unlock(&LOCK_lock_db); return 1; } @@ -1746,7 +1772,7 @@ lock_databases(THD *thd, const char *db1, uint length1, while (!thd->killed && creating_table) { wait_for_condition(thd, &LOCK_lock_db, &COND_refresh); - pthread_mutex_lock(&LOCK_lock_db); + mysql_mutex_lock(&LOCK_lock_db); } if (thd->killed) @@ -1754,8 +1780,8 @@ lock_databases(THD *thd, const char *db1, uint length1, lock_db_delete(db1, length1); lock_db_delete(db2, length2); creating_database--; - pthread_mutex_unlock(&LOCK_lock_db); - pthread_cond_signal(&COND_refresh); + mysql_mutex_unlock(&LOCK_lock_db); + mysql_cond_signal(&COND_refresh); return(1); } @@ -1763,7 +1789,7 @@ lock_databases(THD *thd, const char *db1, uint length1, We can unlock now as the hash will protect against anyone creating a table in the databases we are using */ - pthread_mutex_unlock(&LOCK_lock_db); + mysql_mutex_unlock(&LOCK_lock_db); return 0; } @@ -1892,7 +1918,7 @@ bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db) */ build_table_filename(path, sizeof(path)-1, new_db.str,"",MY_DB_OPT_FILE, 0); - my_delete(path, MYF(MY_WME)); + mysql_file_delete(key_file_dbopt, path, MYF(MY_WME)); length= build_table_filename(path, sizeof(path)-1, new_db.str, "", "", 0); if (length && path[length-1] == FN_LIBCHAR) path[length-1]=0; // remove ending '\' @@ -1948,7 +1974,7 @@ bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db) old_db->str, "", file->name, 0); build_table_filename(newname, sizeof(newname)-1, new_db.str, "", file->name, 0); - my_rename(oldname, newname, MYF(MY_WME)); + mysql_file_rename(key_file_misc, oldname, newname, MYF(MY_WME)); } my_dirend(dirp); } @@ -1976,14 +2002,14 @@ bool mysql_upgrade_db(THD *thd, LEX_STRING *old_db) error|= mysql_change_db(thd, & new_db, FALSE); exit: - pthread_mutex_lock(&LOCK_lock_db); + mysql_mutex_lock(&LOCK_lock_db); /* Remove the databases from db lock cache */ lock_db_delete(old_db->str, old_db->length); lock_db_delete(new_db.str, new_db.length); creating_database--; /* Signal waiting CREATE TABLE's to continue */ - pthread_cond_signal(&COND_refresh); - pthread_mutex_unlock(&LOCK_lock_db); + mysql_cond_signal(&COND_refresh); + mysql_mutex_unlock(&LOCK_lock_db); DBUG_RETURN(error); } diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index d8aa27c9695..17f1036d70e 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -1166,10 +1166,10 @@ bool mysql_truncate(THD *thd, TABLE_LIST *table_list, bool dont_send_ok) // crashes, replacement works. *(path + path_length - reg_ext_length)= // '\0'; path[path_length - reg_ext_length] = 0; - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); error= ha_create_table(thd, path, table_list->db, table_list->table_name, &create_info, 1); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); query_cache_invalidate3(thd, table_list, 0); end: @@ -1184,15 +1184,15 @@ end: write_bin_log(thd, TRUE, thd->query(), thd->query_length()); my_ok(thd); // This should return record count } - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); unlock_table_name(thd, table_list); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } else if (error) { - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); unlock_table_name(thd, table_list); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } DBUG_RETURN(error); diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index da5ee93fcb9..b6c399d9908 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -143,14 +143,14 @@ static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables, { (*table_ptr)->file->ha_index_or_rnd_end(); if (! is_locked) - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); if (close_thread_table(thd, table_ptr)) { /* Tell threads waiting for refresh that something has happened */ broadcast_refresh(); } if (! is_locked) - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } else if (tables->table) { @@ -775,7 +775,7 @@ void mysql_ha_flush(THD *thd) TABLE_LIST *hash_tables; DBUG_ENTER("mysql_ha_flush"); - safe_mutex_assert_owner(&LOCK_open); + mysql_mutex_assert_owner(&LOCK_open); for (uint i= 0; i < thd->handler_tables_hash.records; i++) { diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index efdc8caa3e5..340765c80e0 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1,4 +1,4 @@ -/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. 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 @@ -888,7 +888,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, thd->net.last_error/errno. For example if there has been a disk full error when writing the row, and it was MyISAM, then thd->net.last_error/errno will be set to - "disk full"... and the my_pwrite() will wait until free + "disk full"... and the mysql_file_pwrite() will wait until free space appears, and so when it finishes then the write_row() was entirely successful */ @@ -1730,8 +1730,8 @@ class Delayed_insert :public ilink { public: THD thd; TABLE *table; - pthread_mutex_t mutex; - pthread_cond_t cond,cond_client; + mysql_mutex_t mutex; + mysql_cond_t cond, cond_client; volatile uint tables_in_use,stacked_inserts; volatile bool status,dead; COPY_INFO info; @@ -1763,9 +1763,9 @@ public: thd.system_thread= SYSTEM_THREAD_DELAYED_INSERT; thd.security_ctx->host_or_ip= ""; bzero((char*) &info,sizeof(info)); - pthread_mutex_init(&mutex,MY_MUTEX_INIT_FAST); - pthread_cond_init(&cond,NULL); - pthread_cond_init(&cond_client,NULL); + mysql_mutex_init(key_delayed_insert_mutex, &mutex, MY_MUTEX_INIT_FAST); + mysql_cond_init(key_delayed_insert_cond, &cond, NULL); + mysql_cond_init(key_delayed_insert_cond_client, &cond_client, NULL); pthread_mutex_lock(&LOCK_thread_count); delayed_insert_threads++; delayed_lock= global_system_variables.low_priority_updates ? @@ -1781,9 +1781,9 @@ public: if (table) close_thread_tables(&thd); pthread_mutex_lock(&LOCK_thread_count); - pthread_mutex_destroy(&mutex); - pthread_cond_destroy(&cond); - pthread_cond_destroy(&cond_client); + mysql_mutex_destroy(&mutex); + mysql_cond_destroy(&cond); + mysql_cond_destroy(&cond_client); thd.unlink(); // Must be unlinked under lock x_free(thd.query()); thd.security_ctx->user= thd.security_ctx->host=0; @@ -1800,18 +1800,18 @@ public: } void unlock() { - pthread_mutex_lock(&LOCK_delayed_insert); + mysql_mutex_lock(&LOCK_delayed_insert); if (!--locks_in_memory) { - pthread_mutex_lock(&mutex); + mysql_mutex_lock(&mutex); if (thd.killed && ! stacked_inserts && ! tables_in_use) { - pthread_cond_signal(&cond); + mysql_cond_signal(&cond); status=1; } - pthread_mutex_unlock(&mutex); + mysql_mutex_unlock(&mutex); } - pthread_mutex_unlock(&LOCK_delayed_insert); + mysql_mutex_unlock(&LOCK_delayed_insert); } inline uint lock_count() { return locks_in_memory; } @@ -1832,7 +1832,7 @@ static Delayed_insert *find_handler(THD *thd, TABLE_LIST *table_list) { thd_proc_info(thd, "waiting for delay_list"); - pthread_mutex_lock(&LOCK_delayed_insert); // Protect master list + mysql_mutex_lock(&LOCK_delayed_insert); // Protect master list I_List_iterator it(delayed_threads); Delayed_insert *di; while ((di= it++)) @@ -1844,7 +1844,7 @@ Delayed_insert *find_handler(THD *thd, TABLE_LIST *table_list) break; } } - pthread_mutex_unlock(&LOCK_delayed_insert); // For unlink from list + mysql_mutex_unlock(&LOCK_delayed_insert); // For unlink from list return di; } @@ -1914,7 +1914,7 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list) if (delayed_insert_threads >= thd->variables.max_insert_delayed_threads) DBUG_RETURN(0); thd_proc_info(thd, "Creating delayed handler"); - pthread_mutex_lock(&LOCK_delayed_create); + mysql_mutex_lock(&LOCK_delayed_create); /* The first search above was done without LOCK_delayed_create. Another thread might have created the handler in between. Search again. @@ -1940,14 +1940,15 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list) di->table_list.alias= di->table_list.table_name= di->thd.query(); di->table_list.db= di->thd.db; di->lock(); - pthread_mutex_lock(&di->mutex); - if ((error= pthread_create(&di->thd.real_id, &connection_attrib, - handle_delayed_insert, (void*) di))) + mysql_mutex_lock(&di->mutex); + if ((error= mysql_thread_create(key_thread_delayed_insert, + &di->thd.real_id, &connection_attrib, + handle_delayed_insert, (void*) di))) { DBUG_PRINT("error", ("Can't create thread to handle delayed insert (error %d)", error)); - pthread_mutex_unlock(&di->mutex); + mysql_mutex_unlock(&di->mutex); di->unlock(); delete di; my_error(ER_CANT_CREATE_THREAD, MYF(ME_FATALERROR), error); @@ -1958,9 +1959,9 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list) thd_proc_info(thd, "waiting for handler open"); while (!di->thd.killed && !di->table && !thd->killed) { - pthread_cond_wait(&di->cond_client, &di->mutex); + mysql_cond_wait(&di->cond_client, &di->mutex); } - pthread_mutex_unlock(&di->mutex); + mysql_mutex_unlock(&di->mutex); thd_proc_info(thd, "got old table"); if (di->thd.killed) { @@ -1983,16 +1984,16 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list) di->unlock(); goto end_create; } - pthread_mutex_lock(&LOCK_delayed_insert); + mysql_mutex_lock(&LOCK_delayed_insert); delayed_threads.append(di); - pthread_mutex_unlock(&LOCK_delayed_insert); + mysql_mutex_unlock(&LOCK_delayed_insert); } - pthread_mutex_unlock(&LOCK_delayed_create); + mysql_mutex_unlock(&LOCK_delayed_create); } - pthread_mutex_lock(&di->mutex); + mysql_mutex_lock(&di->mutex); table_list->table= di->get_local_table(thd); - pthread_mutex_unlock(&di->mutex); + mysql_mutex_unlock(&di->mutex); if (table_list->table) { DBUG_ASSERT(! thd->is_error()); @@ -2003,7 +2004,7 @@ bool delayed_get_table(THD *thd, TABLE_LIST *table_list) DBUG_RETURN((table_list->table == NULL)); end_create: - pthread_mutex_unlock(&LOCK_delayed_create); + mysql_mutex_unlock(&LOCK_delayed_create); DBUG_RETURN(thd->is_error()); } @@ -2039,10 +2040,10 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) if (!thd.lock) // Table is not locked { thd_proc_info(client_thd, "waiting for handler lock"); - pthread_cond_signal(&cond); // Tell handler to lock table + mysql_cond_signal(&cond); // Tell handler to lock table while (!dead && !thd.lock && ! client_thd->killed) { - pthread_cond_wait(&cond_client,&mutex); + mysql_cond_wait(&cond_client, &mutex); } thd_proc_info(client_thd, "got handler lock"); if (client_thd->killed) @@ -2129,7 +2130,7 @@ TABLE *Delayed_insert::get_local_table(THD* client_thd) error: tables_in_use--; status=1; - pthread_cond_signal(&cond); // Inform thread about abort + mysql_cond_signal(&cond); // Inform thread about abort DBUG_RETURN(0); } @@ -2148,9 +2149,9 @@ int write_delayed(THD *thd, TABLE *table, enum_duplicates duplic, (ulong) query.length)); thd_proc_info(thd, "waiting for handler insert"); - pthread_mutex_lock(&di->mutex); + mysql_mutex_lock(&di->mutex); while (di->stacked_inserts >= delayed_queue_size && !thd->killed) - pthread_cond_wait(&di->cond_client,&di->mutex); + mysql_cond_wait(&di->cond_client, &di->mutex); thd_proc_info(thd, "storing row into queue"); if (thd->killed) @@ -2225,15 +2226,15 @@ int write_delayed(THD *thd, TABLE *table, enum_duplicates duplic, di->status=1; if (table->s->blob_fields) unlink_blobs(table); - pthread_cond_signal(&di->cond); + mysql_cond_signal(&di->cond); thread_safe_increment(delayed_rows_in_use,&LOCK_delayed_status); - pthread_mutex_unlock(&di->mutex); + mysql_mutex_unlock(&di->mutex); DBUG_RETURN(0); err: delete row; - pthread_mutex_unlock(&di->mutex); + mysql_mutex_unlock(&di->mutex); DBUG_RETURN(1); } @@ -2246,14 +2247,14 @@ static void end_delayed_insert(THD *thd) { DBUG_ENTER("end_delayed_insert"); Delayed_insert *di=thd->di; - pthread_mutex_lock(&di->mutex); + mysql_mutex_lock(&di->mutex); DBUG_PRINT("info",("tables in use: %d",di->tables_in_use)); if (!--di->tables_in_use || di->thd.killed) { // Unlock table di->status=1; - pthread_cond_signal(&di->cond); + mysql_cond_signal(&di->cond); } - pthread_mutex_unlock(&di->mutex); + mysql_mutex_unlock(&di->mutex); DBUG_VOID_RETURN; } @@ -2262,7 +2263,7 @@ static void end_delayed_insert(THD *thd) void kill_delayed_threads(void) { - pthread_mutex_lock(&LOCK_delayed_insert); // For unlink from list + mysql_mutex_lock(&LOCK_delayed_insert); // For unlink from list I_List_iterator it(delayed_threads); Delayed_insert *di; @@ -2271,7 +2272,7 @@ void kill_delayed_threads(void) di->thd.killed= THD::KILL_CONNECTION; if (di->thd.mysys_var) { - pthread_mutex_lock(&di->thd.mysys_var->mutex); + mysql_mutex_lock(&di->thd.mysys_var->mutex); if (di->thd.mysys_var->current_cond) { /* @@ -2279,15 +2280,15 @@ void kill_delayed_threads(void) in handle_delayed_insert() */ if (&di->mutex != di->thd.mysys_var->current_mutex) - pthread_mutex_lock(di->thd.mysys_var->current_mutex); - pthread_cond_broadcast(di->thd.mysys_var->current_cond); + mysql_mutex_lock(di->thd.mysys_var->current_mutex); + mysql_cond_broadcast(di->thd.mysys_var->current_cond); if (&di->mutex != di->thd.mysys_var->current_mutex) - pthread_mutex_unlock(di->thd.mysys_var->current_mutex); + mysql_mutex_unlock(di->thd.mysys_var->current_mutex); } - pthread_mutex_unlock(&di->thd.mysys_var->mutex); + mysql_mutex_unlock(&di->thd.mysys_var->mutex); } } - pthread_mutex_unlock(&LOCK_delayed_insert); // For unlink from list + mysql_mutex_unlock(&LOCK_delayed_insert); // For unlink from list } @@ -2309,15 +2310,17 @@ pthread_handler_t handle_delayed_insert(void *arg) thd->killed=abort_loop ? THD::KILL_CONNECTION : THD::NOT_KILLED; pthread_mutex_unlock(&LOCK_thread_count); + mysql_thread_set_psi_id(thd->thread_id); + /* - Wait until the client runs into pthread_cond_wait(), + Wait until the client runs into mysql_cond_wait(), where we free it after the table is opened and di linked in the list. If we did not wait here, the client might detect the opened table before it is linked to the list. It would release LOCK_delayed_create and allow another thread to create another handler for the same table, since it does not find one in the list. */ - pthread_mutex_lock(&di->mutex); + mysql_mutex_lock(&di->mutex); if (my_thread_init()) { /* Can't use my_error since store_globals has not yet been called */ @@ -2376,7 +2379,7 @@ pthread_handler_t handle_delayed_insert(void *arg) di->table->copy_blobs=1; /* Tell client that the thread is initialized */ - pthread_cond_signal(&di->cond_client); + mysql_cond_signal(&di->cond_client); /* Now wait until we get an insert or lock to handle */ /* We will not abort as long as a client thread uses this thread */ @@ -2390,12 +2393,12 @@ pthread_handler_t handle_delayed_insert(void *arg) Remove this from delay insert list so that no one can request a table from this */ - pthread_mutex_unlock(&di->mutex); - pthread_mutex_lock(&LOCK_delayed_insert); + mysql_mutex_unlock(&di->mutex); + mysql_mutex_lock(&LOCK_delayed_insert); di->unlink(); lock_count=di->lock_count(); - pthread_mutex_unlock(&LOCK_delayed_insert); - pthread_mutex_lock(&di->mutex); + mysql_mutex_unlock(&LOCK_delayed_insert); + mysql_mutex_lock(&di->mutex); if (!lock_count && !di->tables_in_use && !di->stacked_inserts) break; // Time to die } @@ -2415,15 +2418,15 @@ pthread_handler_t handle_delayed_insert(void *arg) { int error; #if defined(HAVE_BROKEN_COND_TIMEDWAIT) - error=pthread_cond_wait(&di->cond,&di->mutex); + error= mysql_cond_wait(&di->cond, &di->mutex); #else - error=pthread_cond_timedwait(&di->cond,&di->mutex,&abstime); + error= mysql_cond_timedwait(&di->cond, &di->mutex, &abstime); #ifdef EXTRA_DEBUG if (error && error != EINTR && error != ETIMEDOUT) { - fprintf(stderr, "Got error %d from pthread_cond_timedwait\n",error); - DBUG_PRINT("error",("Got error %d from pthread_cond_timedwait", - error)); + fprintf(stderr, "Got error %d from mysql_cond_timedwait\n", error); + DBUG_PRINT("error", ("Got error %d from mysql_cond_timedwait", + error)); } #endif #endif @@ -2436,12 +2439,12 @@ pthread_handler_t handle_delayed_insert(void *arg) } } /* We can't lock di->mutex and mysys_var->mutex at the same time */ - pthread_mutex_unlock(&di->mutex); - pthread_mutex_lock(&di->thd.mysys_var->mutex); + mysql_mutex_unlock(&di->mutex); + mysql_mutex_lock(&di->thd.mysys_var->mutex); di->thd.mysys_var->current_mutex= 0; di->thd.mysys_var->current_cond= 0; - pthread_mutex_unlock(&di->thd.mysys_var->mutex); - pthread_mutex_lock(&di->mutex); + mysql_mutex_unlock(&di->thd.mysys_var->mutex); + mysql_mutex_lock(&di->mutex); } thd_proc_info(&(di->thd), 0); @@ -2466,7 +2469,7 @@ pthread_handler_t handle_delayed_insert(void *arg) di->dead= 1; thd->killed= THD::KILL_CONNECTION; } - pthread_cond_broadcast(&di->cond_client); + mysql_cond_broadcast(&di->cond_client); } if (di->stacked_inserts) { @@ -2486,7 +2489,7 @@ pthread_handler_t handle_delayed_insert(void *arg) */ MYSQL_LOCK *lock=thd->lock; thd->lock=0; - pthread_mutex_unlock(&di->mutex); + mysql_mutex_unlock(&di->mutex); /* We need to release next_insert_id before unlocking. This is enforced by handler::ha_external_lock(). @@ -2495,10 +2498,10 @@ pthread_handler_t handle_delayed_insert(void *arg) mysql_unlock_tables(thd, lock); ha_autocommit_or_rollback(thd, 0); di->group_count=0; - pthread_mutex_lock(&di->mutex); + mysql_mutex_lock(&di->mutex); } if (di->tables_in_use) - pthread_cond_broadcast(&di->cond_client); // If waiting clients + mysql_cond_broadcast(&di->cond_client); // If waiting clients } err: @@ -2527,14 +2530,14 @@ pthread_handler_t handle_delayed_insert(void *arg) di->table=0; di->dead= 1; // If error thd->killed= THD::KILL_CONNECTION; // If error - pthread_cond_broadcast(&di->cond_client); // Safety - pthread_mutex_unlock(&di->mutex); + mysql_cond_broadcast(&di->cond_client); // Safety + mysql_mutex_unlock(&di->mutex); - pthread_mutex_lock(&LOCK_delayed_create); // Because of delayed_get_table - pthread_mutex_lock(&LOCK_delayed_insert); + mysql_mutex_lock(&LOCK_delayed_create); // Because of delayed_get_table + mysql_mutex_lock(&LOCK_delayed_insert); delete di; - pthread_mutex_unlock(&LOCK_delayed_insert); - pthread_mutex_unlock(&LOCK_delayed_create); + mysql_mutex_unlock(&LOCK_delayed_insert); + mysql_mutex_unlock(&LOCK_delayed_create); my_thread_end(); pthread_exit(0); @@ -2581,7 +2584,7 @@ bool Delayed_insert::handle_inserts(void) DBUG_ENTER("handle_inserts"); /* Allow client to insert new rows */ - pthread_mutex_unlock(&mutex); + mysql_mutex_unlock(&mutex); table->next_number_field=table->found_next_number_field; table->use_all_columns(); @@ -2614,12 +2617,12 @@ bool Delayed_insert::handle_inserts(void) */ if (!using_bin_log) table->file->extra(HA_EXTRA_WRITE_CACHE); - pthread_mutex_lock(&mutex); + mysql_mutex_lock(&mutex); while ((row=rows.get())) { stacked_inserts--; - pthread_mutex_unlock(&mutex); + mysql_mutex_unlock(&mutex); memcpy(table->record[0],row->record,table->s->reclength); thd.start_time=row->start_time; @@ -2737,7 +2740,7 @@ bool Delayed_insert::handle_inserts(void) free_delayed_insert_blobs(table); thread_safe_decrement(delayed_rows_in_use,&LOCK_delayed_status); thread_safe_increment(delayed_insert_writes,&LOCK_delayed_status); - pthread_mutex_lock(&mutex); + mysql_mutex_lock(&mutex); /* Reset the table->auto_increment_field_not_null as it is valid for @@ -2759,9 +2762,9 @@ bool Delayed_insert::handle_inserts(void) if (stacked_inserts || tables_in_use) // Let these wait a while { if (tables_in_use) - pthread_cond_broadcast(&cond_client); // If waiting clients + mysql_cond_broadcast(&cond_client); // If waiting clients thd_proc_info(&thd, "reschedule"); - pthread_mutex_unlock(&mutex); + mysql_mutex_unlock(&mutex); if ((error=table->file->extra(HA_EXTRA_NO_CACHE))) { /* This should never happen */ @@ -2780,15 +2783,15 @@ bool Delayed_insert::handle_inserts(void) } if (!using_bin_log) table->file->extra(HA_EXTRA_WRITE_CACHE); - pthread_mutex_lock(&mutex); + mysql_mutex_lock(&mutex); thd_proc_info(&thd, "insert"); } if (tables_in_use) - pthread_cond_broadcast(&cond_client); // If waiting clients + mysql_cond_broadcast(&cond_client); // If waiting clients } } thd_proc_info(&thd, 0); - pthread_mutex_unlock(&mutex); + mysql_mutex_unlock(&mutex); /* We need to flush the pending event when using row-based @@ -2813,7 +2816,7 @@ bool Delayed_insert::handle_inserts(void) goto err; } query_cache_invalidate3(&thd, table, 1); - pthread_mutex_lock(&mutex); + mysql_mutex_lock(&mutex); DBUG_RETURN(0); err: @@ -2837,7 +2840,7 @@ bool Delayed_insert::handle_inserts(void) } DBUG_PRINT("error", ("dropped %lu rows after an error", max_rows)); thread_safe_increment(delayed_insert_errors, &LOCK_delayed_status); - pthread_mutex_lock(&mutex); + mysql_mutex_lock(&mutex); DBUG_RETURN(1); } #endif /* EMBEDDED_LIBRARY */ @@ -3494,7 +3497,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE)) { - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); if (reopen_name_locked_table(thd, create_table, FALSE)) { quick_rm_table(create_info->db_type, create_table->db, @@ -3503,7 +3506,7 @@ static TABLE *create_table_from_items(THD *thd, HA_CREATE_INFO *create_info, } else table= create_table->table; - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } else { diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 32c94f0908f..0198d2530d8 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -2081,11 +2081,11 @@ mysql_execute_command(THD *thd) restore status variables, as we don't want 'show status' to cause changes */ - pthread_mutex_lock(&LOCK_status); + mysql_mutex_lock(&LOCK_status); add_diff_to_status(&global_status_var, &thd->status_var, &old_status_var); thd->status_var= old_status_var; - pthread_mutex_unlock(&LOCK_status); + mysql_mutex_unlock(&LOCK_status); break; } case SQLCOM_SHOW_DATABASES: diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 868dfc3e968..b0fa5354567 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -6223,7 +6223,7 @@ static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt) since all table objects were closed and removed as part of the ALTER TABLE of partitioning structure. */ - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); lpt->thd->in_lock_tables= 1; err= reopen_tables(lpt->thd, 1, 1); lpt->thd->in_lock_tables= 0; @@ -6237,7 +6237,7 @@ static void alter_partition_lock_handling(ALTER_PARTITION_PARAM_TYPE *lpt) unlink_open_table(lpt->thd, lpt->table, FALSE); sql_print_warning("We failed to reacquire LOCKs in ALTER TABLE"); } - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } } @@ -6261,9 +6261,9 @@ static int alter_close_tables(ALTER_PARTITION_PARAM_TYPE *lpt) We set lock to zero to ensure we don't do this twice and we set db_stat to zero to ensure we don't close twice. */ - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); close_data_files_and_morph_locks(thd, db, table_name); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(0); } diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 936c9ae8866..098783111a1 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1372,10 +1372,10 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv) When building an embedded library, if the mysql.plugin table does not exist, we silently ignore the missing table */ - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); if (check_if_table_exists(new_thd, &tables, &table_exists)) table_exists= FALSE; - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); if (!table_exists) goto end; #endif /* EMBEDDED_LIBRARY */ diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index dac96f2e9c4..1dee391fa8b 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -133,10 +133,10 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent) } } - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); if (lock_table_names_exclusively(thd, table_list)) { - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); goto err; } @@ -172,7 +172,7 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent) higher concurrency - query_cache_invalidate can take minutes to complete. */ - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); /* Lets hope this doesn't fail as the result will be messy */ if (!silent && !error) @@ -184,9 +184,9 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent) if (!error) query_cache_invalidate3(thd, table_list, 0); - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); unlock_table_names(thd, table_list, (TABLE_LIST*) 0); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); err: start_waiting_global_read_lock(thd); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index dfb88af95d3..5a644dba15d 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1759,11 +1759,11 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose) thd_info->db=thd->strdup(thd_info->db); thd_info->command=(int) tmp->command; if ((mysys_var= tmp->mysys_var)) - pthread_mutex_lock(&mysys_var->mutex); + mysql_mutex_lock(&mysys_var->mutex); thd_info->proc_info= (char*) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0); thd_info->state_info= thread_state_info(tmp); if (mysys_var) - pthread_mutex_unlock(&mysys_var->mutex); + mysql_mutex_unlock(&mysys_var->mutex); thd_info->start_time= tmp->start_time; thd_info->query=0; @@ -1862,7 +1862,7 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond) } if ((mysys_var= tmp->mysys_var)) - pthread_mutex_lock(&mysys_var->mutex); + mysql_mutex_lock(&mysys_var->mutex); /* COMMAND */ if ((val= (char *) (tmp->killed == THD::KILL_CONNECTION? "Killed" : 0))) table->field[4]->store(val, strlen(val), cs); @@ -1880,7 +1880,7 @@ int fill_schema_processlist(THD* thd, TABLE_LIST* tables, COND* cond) } if (mysys_var) - pthread_mutex_unlock(&mysys_var->mutex); + mysql_mutex_unlock(&mysys_var->mutex); /* INFO */ if (tmp->query()) @@ -1958,7 +1958,7 @@ int add_status_vars(SHOW_VAR *list) { int res= 0; if (status_vars_inited) - pthread_mutex_lock(&LOCK_status); + mysql_mutex_lock(&LOCK_status); if (!all_status_vars.buffer && // array is not allocated yet - do it now my_init_dynamic_array(&all_status_vars, sizeof(SHOW_VAR), 200, 20)) { @@ -1973,7 +1973,7 @@ int add_status_vars(SHOW_VAR *list) sort_dynamic(&all_status_vars, show_var_cmp); err: if (status_vars_inited) - pthread_mutex_unlock(&LOCK_status); + mysql_mutex_unlock(&LOCK_status); return res; } @@ -2035,7 +2035,7 @@ void remove_status_vars(SHOW_VAR *list) { if (status_vars_inited) { - pthread_mutex_lock(&LOCK_status); + mysql_mutex_lock(&LOCK_status); SHOW_VAR *all= dynamic_element(&all_status_vars, 0, SHOW_VAR *); int a= 0, b= all_status_vars.elements, c= (a+b)/2; @@ -2056,7 +2056,7 @@ void remove_status_vars(SHOW_VAR *list) all[c].type= SHOW_UNDEF; } shrink_var_array(&all_status_vars); - pthread_mutex_unlock(&LOCK_status); + mysql_mutex_unlock(&LOCK_status); } else { @@ -3102,7 +3102,7 @@ static int fill_schema_table_from_frm(THD *thd,TABLE *table, } key_length= create_table_def_key(thd, key, &table_list, 0); - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); share= get_table_share(thd, &table_list, key, key_length, OPEN_VIEW, &error); if (!share) @@ -3149,7 +3149,7 @@ err1: release_table_share(share, RELEASE_NORMAL); err: - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); thd->clear_error(); return res; } @@ -5524,14 +5524,14 @@ int fill_status(THD *thd, TABLE_LIST *tables, COND *cond) tmp1= &thd->status_var; } - pthread_mutex_lock(&LOCK_status); + mysql_mutex_lock(&LOCK_status); if (option_type == OPT_GLOBAL) calc_sum_of_all_status(&tmp); res= show_status_array(thd, wild, (SHOW_VAR *)all_status_vars.buffer, option_type, tmp1, "", tables->table, upper_case_names, cond); - pthread_mutex_unlock(&LOCK_status); + mysql_mutex_unlock(&LOCK_status); DBUG_RETURN(res); } @@ -7192,7 +7192,7 @@ static TABLE_LIST *get_trigger_table(THD *thd, const sp_name *trg_name) { /* Acquire LOCK_open (stop the server). */ - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); /* Load base table name from the TRN-file and create TABLE_LIST object. @@ -7202,7 +7202,7 @@ static TABLE_LIST *get_trigger_table(THD *thd, const sp_name *trg_name) /* Release LOCK_open (continue the server). */ - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); /* That's it. */ diff --git a/sql/sql_table.cc b/sql/sql_table.cc index e594499b4d8..65e320f5218 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1653,7 +1653,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) completing this we write a new phase to the log entry that will deactivate it. */ - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); if (my_delete(frm_name, MYF(MY_WME)) || #ifdef WITH_PARTITION_STORAGE_ENGINE lpt->table->file->ha_create_handler_files(path, shadow_path, @@ -1706,7 +1706,7 @@ bool mysql_write_frm(ALTER_PARTITION_PARAM_TYPE *lpt, uint flags) #endif err: - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); #ifdef WITH_PARTITION_STORAGE_ENGINE deactivate_ddl_log_entry(part_info->frm_log_entry->entry_pos); part_info->frm_log_entry= NULL; @@ -1869,7 +1869,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, mysql_ha_rm_tables(thd, tables, FALSE); - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); /* If we have the table in the definition cache, we don't have to check the @@ -1890,14 +1890,14 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, table->table_name_length, table->table_name, 1)) { my_error(ER_BAD_LOG_STATEMENT, MYF(0), "DROP"); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(1); } } if (!drop_temporary && lock_table_names_exclusively(thd, tables)) { - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(1); } @@ -2068,7 +2068,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, It's safe to unlock LOCK_open: we have an exclusive lock on the table name. */ - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); thd->thread_specific_used|= tmp_table_deleted; error= 0; if (wrong_tables.length()) @@ -2151,10 +2151,10 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, */ } } - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); err_with_placeholders: unlock_table_names(thd, tables, (TABLE_LIST*) 0); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(error); } @@ -3870,7 +3870,7 @@ bool mysql_create_table_no_lock(THD *thd, goto err; } - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE)) { if (!access(path,F_OK)) @@ -4015,7 +4015,7 @@ bool mysql_create_table_no_lock(THD *thd, write_create_table_bin_log(thd, create_info, internal_tmp_table); error= FALSE; unlock_and_end: - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); err: thd_proc_info(thd, "After create"); @@ -4048,21 +4048,21 @@ bool mysql_create_table(THD *thd, const char *db, const char *table_name, DBUG_ENTER("mysql_create_table"); /* Wait for any database locks */ - pthread_mutex_lock(&LOCK_lock_db); + mysql_mutex_lock(&LOCK_lock_db); while (!thd->killed && my_hash_search(&lock_db_cache,(uchar*) db, strlen(db))) { wait_for_condition(thd, &LOCK_lock_db, &COND_refresh); - pthread_mutex_lock(&LOCK_lock_db); + mysql_mutex_lock(&LOCK_lock_db); } if (thd->killed) { - pthread_mutex_unlock(&LOCK_lock_db); + mysql_mutex_unlock(&LOCK_lock_db); DBUG_RETURN(TRUE); } creating_table++; - pthread_mutex_unlock(&LOCK_lock_db); + mysql_mutex_unlock(&LOCK_lock_db); if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE)) { @@ -4099,14 +4099,14 @@ bool mysql_create_table(THD *thd, const char *db, const char *table_name, unlock: if (name_lock) { - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); unlink_open_table(thd, name_lock, FALSE); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } - pthread_mutex_lock(&LOCK_lock_db); + mysql_mutex_lock(&LOCK_lock_db); if (!--creating_table && creating_database) - pthread_cond_signal(&COND_refresh); - pthread_mutex_unlock(&LOCK_lock_db); + mysql_cond_signal(&COND_refresh); + mysql_mutex_unlock(&LOCK_lock_db); DBUG_RETURN(result); } @@ -4267,7 +4267,7 @@ void wait_while_table_is_used(THD *thd, TABLE *table, table->s->table_name.str, (ulong) table->s, table->db_stat, table->s->version)); - safe_mutex_assert_owner(&LOCK_open); + mysql_mutex_assert_owner(&LOCK_open); (void) table->file->extra(function); /* Mark all tables that are in use as 'old' */ @@ -4352,22 +4352,22 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, uint key_length; key_length= create_table_def_key(thd, key, table_list, 0); - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); if (!(share= (get_table_share(thd, table_list, key, key_length, 0, &error)))) { - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(0); // Can't open frm file } if (open_table_from_share(thd, share, "", 0, 0, 0, &tmp_table, FALSE)) { release_table_share(share, RELEASE_NORMAL); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(0); // Out of memory } table= &tmp_table; - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } /* A MERGE table must not come here. */ @@ -4421,9 +4421,9 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, /* If we could open the table, close it */ if (table_list->table) { - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); close_cached_table(thd, table); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } if (lock_and_wait_for_table_name(thd,table_list)) { @@ -4432,27 +4432,27 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, } if (my_rename(from, tmp, MYF(MY_WME))) { - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); unlock_table_name(thd, table_list); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); error= send_check_errmsg(thd, table_list, "repair", "Failed renaming data file"); goto end; } if (mysql_truncate(thd, table_list, 1)) { - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); unlock_table_name(thd, table_list); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); error= send_check_errmsg(thd, table_list, "repair", "Failed generating table from .frm file"); goto end; } if (my_rename(tmp, from, MYF(MY_WME))) { - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); unlock_table_name(thd, table_list); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); error= send_check_errmsg(thd, table_list, "repair", "Failed restoring .MYD file"); goto end; @@ -4462,23 +4462,23 @@ static int prepare_for_repair(THD *thd, TABLE_LIST *table_list, Now we should be able to open the partially repaired table to finish the repair in the handler later on. */ - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); if (reopen_name_locked_table(thd, table_list, TRUE)) { unlock_table_name(thd, table_list); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); error= send_check_errmsg(thd, table_list, "repair", "Failed to open partially repaired table"); goto end; } - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); end: if (table == &tmp_table) { - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); closefrm(table, 1); // Free allocated memory - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } DBUG_RETURN(error); } @@ -4705,7 +4705,7 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, if (lock_type == TL_WRITE && table->table->s->version) { DBUG_PRINT("admin", ("removing table from cache")); - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); const char *old_message=thd->enter_cond(&COND_refresh, &LOCK_open, "Waiting to get writelock"); mysql_lock_abort(thd,table->table, TRUE); @@ -4968,10 +4968,10 @@ send_result_message: table->table->file->info(HA_STATUS_CONST); else { - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); remove_table_from_cache(thd, table->table->s->db.str, table->table->s->table_name.str, RTFC_NO_FLAG); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } /* May be something modified consequently we have to invalidate cache */ query_cache_invalidate3(thd, table->table, 0); @@ -5274,12 +5274,12 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, Also some engines (e.g. NDB cluster) require that LOCK_open should be held during the call to ha_create_table(). See bug #28614 for more info. */ - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); if (src_table->schema_table) { if (mysql_create_like_schema_frm(thd, src_table, dst_path, create_info)) { - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); goto err; } } @@ -5289,7 +5289,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, my_error(ER_BAD_DB_ERROR,MYF(0),db); else my_error(ER_CANT_CREATE_FILE,MYF(0),dst_path,my_errno); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); goto err; } @@ -5318,7 +5318,7 @@ bool mysql_create_like_table(THD* thd, TABLE_LIST* table, TABLE_LIST* src_table, if (thd->variables.keep_files_on_create) create_info->options|= HA_CREATE_KEEP_FILES; err= ha_create_table(thd, dst_path, db, table_name, create_info, 1); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); if (create_info->options & HA_LEX_CREATE_TMP_TABLE) { @@ -5392,13 +5392,13 @@ binlog: of this function. */ table->table= name_lock; - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); if (reopen_name_locked_table(thd, table, FALSE)) { - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); goto err; } - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); int result __attribute__((unused))= store_create_info(thd, table, &query, @@ -5422,9 +5422,9 @@ binlog: err: if (name_lock) { - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); unlink_open_table(thd, name_lock, FALSE); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } DBUG_RETURN(res); } @@ -6501,7 +6501,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, if (wait_if_global_read_lock(thd,0,1)) DBUG_RETURN(TRUE); - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); if (lock_table_names(thd, table_list)) { error= 1; @@ -6523,7 +6523,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, unlock_table_names(thd, table_list, (TABLE_LIST*) 0); view_err: - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); start_waiting_global_read_lock(thd); DBUG_RETURN(error); } @@ -6684,17 +6684,17 @@ view_err: while the fact that the table is still open gives us protection from concurrent DDL statements. */ - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_EXECUTE_IF("sleep_alter_enable_indexes", my_sleep(6000000);); error= table->file->ha_enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); /* COND_refresh will be signaled in close_thread_tables() */ break; case DISABLE: - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); error=table->file->ha_disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE); /* COND_refresh will be signaled in close_thread_tables() */ break; @@ -6711,7 +6711,7 @@ view_err: table->alias); } - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); /* Unlike to the above case close_cached_table() below will remove ALL instances of TABLE from table cache (it will also remove table lock @@ -6777,7 +6777,7 @@ view_err: } if (name_lock) unlink_open_table(thd, name_lock, FALSE); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); table_list->table= NULL; // For query cache query_cache_invalidate3(thd, table_list, 0); DBUG_RETURN(error); @@ -7138,9 +7138,9 @@ view_err: } else { - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); thd_proc_info(thd, "manage keys"); alter_table_manage_keys(table, table->file->indexes_are_disabled(), alter_info->keys_onoff); @@ -7270,11 +7270,11 @@ view_err: intern_close_table(new_table); my_free(new_table,MYF(0)); } - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); if (error) { (void) quick_rm_table(new_db_type, new_db, tmp_name, FN_IS_TMP); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); goto err; } @@ -7407,7 +7407,7 @@ view_err: if (error) goto err_with_placeholders; } - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); thd_proc_info(thd, "end"); @@ -7454,10 +7454,10 @@ view_err: from the list of open tables and table cache. If we are not under LOCK TABLES we can rely on close_thread_tables() doing this job. */ - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); unlink_open_table(thd, table, FALSE); unlink_open_table(thd, name_lock, FALSE); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } end_temporary: @@ -7514,9 +7514,9 @@ err: } if (name_lock) { - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); unlink_open_table(thd, name_lock, FALSE); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } DBUG_RETURN(TRUE); @@ -7529,7 +7529,7 @@ err_with_placeholders: unlink_open_table(thd, table, FALSE); if (name_lock) unlink_open_table(thd, name_lock, FALSE); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(TRUE); } /* mysql_alter_table */ diff --git a/sql/sql_test.cc b/sql/sql_test.cc index d9beb77f546..af05f1199d4 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -80,7 +80,7 @@ void print_cached_tables(void) compile_time_assert(TL_WRITE_ONLY+1 == array_elements(lock_descriptions)); /* purecov: begin tested */ - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); puts("DB Table Version Thread Open Lock"); for (idx=unused=0 ; idx < open_cache.records ; idx++) @@ -116,7 +116,7 @@ void print_cached_tables(void) if (my_hash_check(&open_cache)) printf("Error: File hash table is corrupted\n"); fflush(stdout); - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); /* purecov: end */ return; } @@ -381,12 +381,12 @@ static void display_table_locks(void) DYNAMIC_ARRAY saved_table_locks; (void) my_init_dynamic_array(&saved_table_locks,sizeof(TABLE_LOCK_INFO),open_cache.records + 20,50); - pthread_mutex_lock(&THR_LOCK_lock); + mysql_mutex_lock(&THR_LOCK_lock); for (list= thr_lock_thread_list; list; list= list_rest(list)) { THR_LOCK *lock=(THR_LOCK*) list->data; - pthread_mutex_lock(&lock->mutex); + mysql_mutex_lock(&lock->mutex); push_locks_into_array(&saved_table_locks, lock->write.data, FALSE, "Locked - write"); push_locks_into_array(&saved_table_locks, lock->write_wait.data, TRUE, @@ -395,9 +395,9 @@ static void display_table_locks(void) "Locked - read"); push_locks_into_array(&saved_table_locks, lock->read_wait.data, TRUE, "Waiting - read"); - pthread_mutex_unlock(&lock->mutex); + mysql_mutex_unlock(&lock->mutex); } - pthread_mutex_unlock(&THR_LOCK_lock); + mysql_mutex_unlock(&THR_LOCK_lock); if (!saved_table_locks.elements) goto end; qsort((uchar*) dynamic_element(&saved_table_locks,0,TABLE_LOCK_INFO *),saved_table_locks.elements,sizeof(TABLE_LOCK_INFO),(qsort_cmp) dl_compare); @@ -473,7 +473,7 @@ void mysql_print_status() /* Print key cache status */ puts("\nKey caches:"); process_key_caches(print_key_cache_status); - pthread_mutex_lock(&LOCK_status); + mysql_mutex_lock(&LOCK_status); printf("\nhandler status:\n\ read_key: %10lu\n\ read_next: %10lu\n\ @@ -489,7 +489,7 @@ update: %10lu\n", tmp.ha_write_count, tmp.ha_delete_count, tmp.ha_update_count); - pthread_mutex_unlock(&LOCK_status); + mysql_mutex_unlock(&LOCK_status); printf("\nTable status:\n\ Opened tables: %10lu\n\ Open tables: %10lu\n\ diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index ecbb6473ec4..c895239064b 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -387,7 +387,7 @@ bool mysql_create_or_drop_trigger(THD *thd, TABLE_LIST *tables, bool create) !(need_start_waiting= !wait_if_global_read_lock(thd, 0, 1))) DBUG_RETURN(TRUE); - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); if (!create) { @@ -510,7 +510,7 @@ end: write_bin_log(thd, TRUE, stmt_query.ptr(), stmt_query.length()); } - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); if (need_start_waiting) start_waiting_global_read_lock(thd); @@ -1884,7 +1884,7 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db, old_table)-(char*)&key[0])+1; if (!is_table_name_exclusively_locked_by_this_thread(thd, key, key_length)) - safe_mutex_assert_owner(&LOCK_open); + mysql_mutex_assert_owner(&LOCK_open); #endif DBUG_ASSERT(my_strcasecmp(table_alias_charset, db, new_db) || diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 83341a53c3e..9d383dcd363 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -620,7 +620,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, res= TRUE; goto err; } - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); res= mysql_register_view(thd, view, mode); if (mysql_bin_log.is_open()) @@ -666,7 +666,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, buff.ptr(), buff.length(), FALSE, FALSE, errcode); } - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); if (mode != VIEW_CREATE_NEW) query_cache_invalidate3(thd, view, 0); start_waiting_global_read_lock(thd); @@ -1579,7 +1579,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) bool something_wrong= FALSE; DBUG_ENTER("mysql_drop_view"); - pthread_mutex_lock(&LOCK_open); + mysql_mutex_lock(&LOCK_open); for (view= views; view; view= view->next_local) { TABLE_SHARE *share; @@ -1656,7 +1656,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) write_bin_log(thd, !something_wrong, thd->query(), thd->query_length()); } - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); if (something_wrong) { diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index a73a39440d7..eea42904bb0 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -3141,7 +3141,7 @@ int ha_federated::real_connect() to establish Federated connection to guard against a trivial Denial of Service scenerio. */ - safe_mutex_assert_not_owner(&LOCK_open); + mysql_mutex_assert_not_owner(&LOCK_open); DBUG_ASSERT(mysql == NULL); From 0531f85e16223e30071e7e8ce40695fda3f2c235 Mon Sep 17 00:00:00 2001 From: Marc Alff Date: Fri, 11 Dec 2009 12:45:44 -0700 Subject: [PATCH 17/23] Merge cleanup --- include/my_pthread.h | 2 -- sql/ha_ndbcluster.cc | 2 +- sql/ha_ndbcluster_binlog.cc | 2 +- sql/lock.cc | 2 +- sql/mysqld.cc | 10 +++++----- sql/sql_base.cc | 18 +++++++++--------- sql/sql_delete.cc | 2 +- sql/sql_handler.cc | 3 ++- sql/sql_parse.cc | 2 +- sql/sql_rename.cc | 2 +- sql/sql_show.cc | 2 +- sql/sql_table.cc | 2 +- sql/sql_test.cc | 2 +- sql/sql_trigger.cc | 2 +- sql/sql_view.cc | 2 +- 15 files changed, 27 insertions(+), 28 deletions(-) diff --git a/include/my_pthread.h b/include/my_pthread.h index bfb5a2f67f4..0b59aad56f9 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -148,8 +148,6 @@ int pthread_join(pthread_t thread, void **value_ptr); #define pthread_detach_this_thread() #define pthread_condattr_init(A) #define pthread_condattr_destroy(A) -#define pthread_yield() SwitchToThread() - /* per the platform's documentation */ #define pthread_yield() Sleep(0) diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index b60b9463c6b..1103683b56c 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2003 MySQL AB +/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 diff --git a/sql/ha_ndbcluster_binlog.cc b/sql/ha_ndbcluster_binlog.cc index 285df1a3313..bdbb57224b0 100644 --- a/sql/ha_ndbcluster_binlog.cc +++ b/sql/ha_ndbcluster_binlog.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2003 MySQL AB +/* Copyright (C) 2000-2003 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 diff --git a/sql/lock.cc b/sql/lock.cc index 03524712259..e60259f6acc 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -1,4 +1,4 @@ -/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. 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 diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 899e5fbbe30..764d799f1f7 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1,4 +1,4 @@ -/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. 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 @@ -648,7 +648,7 @@ SHOW_COMP_OPTION have_profiling; pthread_key(MEM_ROOT**,THR_MALLOC); pthread_key(THD*, THR_THD); pthread_mutex_t LOCK_thread_count, - LOCK_mapped_file, LOCK_global_read_lock, + LOCK_mapped_file, LOCK_global_read_lock, LOCK_error_log, LOCK_uuid_generator, LOCK_crypt, LOCK_global_system_variables, @@ -964,9 +964,9 @@ static void close_connections(void) mysql_mutex_lock(&tmp->mysys_var->mutex); if (tmp->mysys_var->current_cond) { - mysql_mutex_lock(tmp->mysys_var->current_mutex); - mysql_cond_broadcast(tmp->mysys_var->current_cond); - mysql_mutex_unlock(tmp->mysys_var->current_mutex); + mysql_mutex_lock(tmp->mysys_var->current_mutex); + mysql_cond_broadcast(tmp->mysys_var->current_cond); + mysql_mutex_unlock(tmp->mysys_var->current_mutex); } mysql_mutex_unlock(&tmp->mysys_var->mutex); } diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 03cd9943dea..c5861af9c5d 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1,4 +1,4 @@ -/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. 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 @@ -994,7 +994,7 @@ bool close_cached_tables(THD *thd, TABLE_LIST *tables, bool have_lock, { found=1; DBUG_PRINT("signal", ("Waiting for COND_refresh")); - mysql_cond_wait(&COND_refresh, &LOCK_open); + mysql_cond_wait(&COND_refresh, &LOCK_open); break; } } @@ -2825,7 +2825,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, /* Avoid self-deadlocks by detecting self-dependencies. */ if (table->open_placeholder && table->in_use == thd) { - mysql_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); my_error(ER_UPDATE_TABLE_USED, MYF(0), table->s->table_name.str); DBUG_RETURN(0); } @@ -2866,7 +2866,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, } else { - mysql_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } /* There is a refresh in progress for this table. @@ -8503,15 +8503,15 @@ bool remove_table_from_cache(THD *thd, const char *db, const char *table_name, ! in_use->killed) { in_use->killed= THD::KILL_CONNECTION; - mysql_mutex_lock(&in_use->mysys_var->mutex); + mysql_mutex_lock(&in_use->mysys_var->mutex); if (in_use->mysys_var->current_cond) { - mysql_mutex_lock(in_use->mysys_var->current_mutex); + mysql_mutex_lock(in_use->mysys_var->current_mutex); signalled= 1; - mysql_cond_broadcast(in_use->mysys_var->current_cond); - mysql_mutex_unlock(in_use->mysys_var->current_mutex); + mysql_cond_broadcast(in_use->mysys_var->current_cond); + mysql_mutex_unlock(in_use->mysys_var->current_mutex); } - mysql_mutex_unlock(&in_use->mysys_var->mutex); + mysql_mutex_unlock(&in_use->mysys_var->mutex); } /* Now we must abort all tables locks used by this thread diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index d0988ea46f8..1b54f2a76e4 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000 MySQL AB +/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index b6c399d9908..5b45c35dd22 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -1,4 +1,5 @@ -/* Copyright (C) 2000-2004 MySQL AB +/* Copyright (C) 2000-2004 MySQL AB, 2008-2009 Sun Microsystems, Inc + 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. diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index f1cf6380a9b..bdadec180f5 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1,4 +1,4 @@ -/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. 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 diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 18ec7f76032..7c52a12c072 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2006 MySQL AB +/* Copyright (C) 2000-2006 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 2f6b60bbd0f..b91dfeec011 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -1,4 +1,4 @@ -/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. 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 diff --git a/sql/sql_table.cc b/sql/sql_table.cc index c04a0be7c2f..69de97847cf 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1,4 +1,4 @@ -/* Copyright 2000-2008 MySQL AB, 2008 Sun Microsystems, Inc. +/* Copyright 2000-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc. 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 diff --git a/sql/sql_test.cc b/sql/sql_test.cc index 56ca7111e86..ac1dae3197d 100644 --- a/sql/sql_test.cc +++ b/sql/sql_test.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2000-2006 MySQL AB +/* Copyright (C) 2000-2006 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 154e08aa3d4..4ab9bba03ae 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2004-2005 MySQL AB +/* Copyright (C) 2004-2005 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 8d2d03583de..f511cace885 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2004 MySQL AB +/* Copyright (C) 2004 MySQL AB, 2008-2009 Sun Microsystems, Inc 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 From 32b9defd3c7ca206dc314d044607c05b2f2501f5 Mon Sep 17 00:00:00 2001 From: Mikael Ronstrom Date: Mon, 14 Dec 2009 15:51:42 +0100 Subject: [PATCH 18/23] Fixed an issue where STOP SLAVE generated a warning to error log which test case couldn't handle, fixed by checking for io slave killed before checking for network error --- sql/slave.cc | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/sql/slave.cc b/sql/slave.cc index 96aa9890c89..ce5bb785792 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1219,6 +1219,8 @@ static int get_master_version_and_clock(MYSQL* mysql, Master_info* mi) mi->clock_diff_with_master= (long) (time((time_t*) 0) - strtoul(master_row[0], 0, 10)); } + else if (check_io_slave_killed(mi->io_thd, mi, NULL)) + goto slave_killed_err; else if (is_network_error(mysql_errno(mysql))) { mi->report(WARNING_LEVEL, mysql_errno(mysql), @@ -1271,7 +1273,9 @@ not always make sense; please check the manual before using it)."; } else if (mysql_errno(mysql)) { - if (is_network_error(mysql_errno(mysql))) + if (check_io_slave_killed(mi->io_thd, mi, NULL)) + goto slave_killed_err; + else if (is_network_error(mysql_errno(mysql))) { mi->report(WARNING_LEVEL, mysql_errno(mysql), "Get master SERVER_ID failed with error: %s", mysql_error(mysql)); @@ -1342,6 +1346,8 @@ be equal for the Statement-format replication to work"; goto err; } } + else if (check_io_slave_killed(mi->io_thd, mi, NULL)) + goto slave_killed_err; else if (is_network_error(mysql_errno(mysql))) { mi->report(WARNING_LEVEL, mysql_errno(mysql), @@ -1403,6 +1409,8 @@ be equal for the Statement-format replication to work"; goto err; } } + else if (check_io_slave_killed(mi->io_thd, mi, NULL)) + goto slave_killed_err; else if (is_network_error(mysql_errno(mysql))) { mi->report(WARNING_LEVEL, mysql_errno(mysql), @@ -1466,6 +1474,11 @@ network_err: if (master_res) mysql_free_result(master_res); DBUG_RETURN(2); + +slave_killed_err: + if (master_res) + mysql_free_result(master_res); + DBUG_RETURN(2); } /* @@ -2884,7 +2897,7 @@ connected: if (ret == 1) /* Fatal error */ goto err; - + if (ret == 2) { if (check_io_slave_killed(mi->io_thd, mi, "Slave I/O thread killed" From e74991d4a62a0064a4538e2edd8636a2d3855480 Mon Sep 17 00:00:00 2001 From: Mikael Ronstrom Date: Tue, 15 Dec 2009 15:40:08 +0100 Subject: [PATCH 19/23] Fixed atomic instruction headers for Windows and x86-gcc --- include/atomic/generic-msvc.h | 32 ++++++++++++++++++++++++++++---- include/atomic/x86-gcc.h | 6 ++++++ 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/include/atomic/generic-msvc.h b/include/atomic/generic-msvc.h index f1e1b0e88c9..e317e7dc4cc 100644 --- a/include/atomic/generic-msvc.h +++ b/include/atomic/generic-msvc.h @@ -37,18 +37,29 @@ C_MODE_START /*Visual Studio 2003 and earlier do not have prototypes for atomic intrinsics*/ LONG _InterlockedExchange (LONG volatile *Target,LONG Value); -LONG _InterlockedCompareExchange (LONG volatile *Target, LONG Value, LONG Comp); +LONGLONG _InterlockedExchange64 (LONGLONG volatile *Target,LONGLONG Value); +LONG _InterlockedCompareExchange (LONG volatile *Target, + LONG Value, LONG Comp); +LONGLONG _InterlockedCompareExchange64 (LONGLONG volatile *Target, + LONGLONG Value, LONGLONG Comp); LONG _InterlockedExchangeAdd (LONG volatile *Addend, LONG Value); +LONGLONG _InterlockedExchangeAdd64 (LONGLONG volatile *Addend, LONGLONG Value); C_MODE_END #pragma intrinsic(_InterlockedExchangeAdd) #pragma intrinsic(_InterlockedCompareExchange) #pragma intrinsic(_InterlockedExchange) +#pragma intrinsic(_InterlockedExchangeAdd64) +#pragma intrinsic(_InterlockedCompareExchange64) +#pragma intrinsic(_InterlockedExchange64) #endif #define InterlockedExchange _InterlockedExchange #define InterlockedExchangeAdd _InterlockedExchangeAdd #define InterlockedCompareExchange _InterlockedCompareExchange +#define InterlockedExchange64 _InterlockedExchange64 +#define InterlockedExchangeAdd64 _InterlockedExchangeAdd64 +#define InterlockedCompareExchange64 _InterlockedCompareExchange64 /* No need to do something special for InterlockedCompareExchangePointer as it is a #define to InterlockedCompareExchange. The same applies to @@ -57,10 +68,20 @@ C_MODE_END #endif /*_M_IX86*/ #define MY_ATOMIC_MODE "msvc-intrinsics" -#define IL_EXCHG_ADD32(X,Y) InterlockedExchangeAdd((volatile LONG *)(X),(Y)) -#define IL_COMP_EXCHG32(X,Y,Z) InterlockedCompareExchange((volatile LONG *)(X),(Y),(Z)) +#define IL_EXCHG_ADD32(X,Y) \ + InterlockedExchangeAdd((volatile LONG *)(X),(Y)) +#define IL_EXCHG_ADD64(X,Y) \ + InterlockedExchangeAdd64((volatile LONGLONG *)(X),(LONGLONG)(Y)) +#define IL_COMP_EXCHG32(X,Y,Z) \ + InterlockedCompareExchange((volatile LONG *)(X),(Y),(Z)) +#define IL_COMP_EXCHG64(X,Y,Z) \ + InterlockedCompareExchange64((volatile LONGLONG *)(X), \ + (LONGLONG)(Y),(LONGLONG)(Z)) #define IL_COMP_EXCHGptr InterlockedCompareExchangePointer -#define IL_EXCHG32(X,Y) InterlockedExchange((volatile LONG *)(X),(Y)) +#define IL_EXCHG32(X,Y) \ + InterlockedExchange((volatile LONG *)(X),(Y)) +#define IL_EXCHG64(X,Y) \ + InterlockedExchange64((volatile LONGLONG *)(X),(LONGLONG)(Y)) #define IL_EXCHGptr InterlockedExchangePointer #define make_atomic_add_body(S) \ v= IL_EXCHG_ADD ## S (a, v) @@ -108,9 +129,12 @@ static __inline int my_yield_processor() #else /* cleanup */ #undef IL_EXCHG_ADD32 +#undef IL_EXCHG_ADD64 #undef IL_COMP_EXCHG32 +#undef IL_COMP_EXCHG64 #undef IL_COMP_EXCHGptr #undef IL_EXCHG32 +#undef IL_EXCHG64 #undef IL_EXCHGptr #endif diff --git a/include/atomic/x86-gcc.h b/include/atomic/x86-gcc.h index e5e88fa58ff..f19a4a33f3c 100644 --- a/include/atomic/x86-gcc.h +++ b/include/atomic/x86-gcc.h @@ -22,6 +22,12 @@ architectures support double-word (128-bit) cas. */ +/* + No special support of 8 and 16 bit operations are implemented here + currently. +*/ +#undef MY_ATOMIC_HAS_8_AND_16 + #ifdef __x86_64__ # ifdef MY_ATOMIC_NO_XADD # define MY_ATOMIC_MODE "gcc-amd64" LOCK_prefix "-no-xadd" From 0d28ae37e5cc4a8a3d5e869345c471dc2ea92e96 Mon Sep 17 00:00:00 2001 From: Mikael Ronstrom Date: Tue, 15 Dec 2009 17:07:43 +0100 Subject: [PATCH 20/23] Fixed 64-bit atomics on Win x86 and removed support for 8 and 16-bit atomic operations --- include/atomic/generic-msvc.h | 13 +------------ include/my_atomic.h | 7 +++---- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/include/atomic/generic-msvc.h b/include/atomic/generic-msvc.h index e317e7dc4cc..77319aaa93c 100644 --- a/include/atomic/generic-msvc.h +++ b/include/atomic/generic-msvc.h @@ -37,29 +37,18 @@ C_MODE_START /*Visual Studio 2003 and earlier do not have prototypes for atomic intrinsics*/ LONG _InterlockedExchange (LONG volatile *Target,LONG Value); -LONGLONG _InterlockedExchange64 (LONGLONG volatile *Target,LONGLONG Value); -LONG _InterlockedCompareExchange (LONG volatile *Target, - LONG Value, LONG Comp); -LONGLONG _InterlockedCompareExchange64 (LONGLONG volatile *Target, - LONGLONG Value, LONGLONG Comp); +LONG _InterlockedCompareExchange (LONG volatile *Target, LONG Value, LONG Comp); LONG _InterlockedExchangeAdd (LONG volatile *Addend, LONG Value); -LONGLONG _InterlockedExchangeAdd64 (LONGLONG volatile *Addend, LONGLONG Value); C_MODE_END #pragma intrinsic(_InterlockedExchangeAdd) #pragma intrinsic(_InterlockedCompareExchange) #pragma intrinsic(_InterlockedExchange) -#pragma intrinsic(_InterlockedExchangeAdd64) -#pragma intrinsic(_InterlockedCompareExchange64) -#pragma intrinsic(_InterlockedExchange64) #endif #define InterlockedExchange _InterlockedExchange #define InterlockedExchangeAdd _InterlockedExchangeAdd #define InterlockedCompareExchange _InterlockedCompareExchange -#define InterlockedExchange64 _InterlockedExchange64 -#define InterlockedExchangeAdd64 _InterlockedExchangeAdd64 -#define InterlockedCompareExchange64 _InterlockedCompareExchange64 /* No need to do something special for InterlockedCompareExchangePointer as it is a #define to InterlockedCompareExchange. The same applies to diff --git a/include/my_atomic.h b/include/my_atomic.h index 4170e45fe8c..23c3dc749ab 100644 --- a/include/my_atomic.h +++ b/include/my_atomic.h @@ -56,11 +56,10 @@ #define intptr void * /** - On most platforms we implement 8-bit, 16-bit, 32-bit and "pointer" - operations. Thus the symbol below is defined by default; platforms - where we leave out 8-bit or 16-bit operations should undefine it. + Currently we don't support 8-bit and 16-bit operations. + It can be added later if needed. */ -#define MY_ATOMIC_HAS_8_16 1 +#undef MY_ATOMIC_HAS_8_16 #ifndef MY_ATOMIC_MODE_RWLOCKS /* From 6b0bb0506880d04d6a1d6cd5c6c03f2aebe4ca24 Mon Sep 17 00:00:00 2001 From: Mikael Ronstrom Date: Tue, 15 Dec 2009 18:12:49 +0100 Subject: [PATCH 21/23] Include windows.h in atomics framework for windows --- include/atomic/generic-msvc.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/atomic/generic-msvc.h b/include/atomic/generic-msvc.h index 77319aaa93c..4a50dc4a667 100644 --- a/include/atomic/generic-msvc.h +++ b/include/atomic/generic-msvc.h @@ -23,6 +23,7 @@ */ #undef MY_ATOMIC_HAS_8_16 +#include /* x86 compilers (both VS2003 or VS2005) never use instrinsics, but generate function calls to kernel32 instead, even in the optimized build. From 0fb1c286d762d94564edaa924de9769c599bc231 Mon Sep 17 00:00:00 2001 From: Mikael Ronstrom Date: Tue, 15 Dec 2009 22:15:48 +0100 Subject: [PATCH 22/23] Fixed complex gcc assembler issues with 64-bit operations on 32-bit platforms using PIC codes, commented x86-gcc.h a lot more --- include/atomic/x86-gcc.h | 75 ++++++++++++++++++++++++++++------------ 1 file changed, 52 insertions(+), 23 deletions(-) diff --git a/include/atomic/x86-gcc.h b/include/atomic/x86-gcc.h index f19a4a33f3c..32839e0a67d 100644 --- a/include/atomic/x86-gcc.h +++ b/include/atomic/x86-gcc.h @@ -59,39 +59,68 @@ asm volatile (LOCK_prefix "; cmpxchg %3, %0; setz %2;" \ : "+m" (*a), "+a" (*cmp), "=q" (ret): "r" (set)) -#define make_atomic_cas_bodyptr make_atomic_cas_body32 - -#ifndef __x86_64__ +#ifdef __x86_64__ #define make_atomic_add_body64 make_atomic_add_body32 #define make_atomic_cas_body64 make_atomic_cas_body32 -#else -#define make_atomic_add_body64 \ - int64 tmp=*a; \ - while (!my_atomic_cas64(a, &tmp, tmp+v)); \ - v=tmp; -#define make_atomic_cas_body64 \ - int32 ebx=(set & 0xFFFFFFFF), ecx=(set >> 32); \ - asm volatile (LOCK_prefix "; cmpxchg8b %0; setz %2;" \ - : "+m" (*a), "+A" (*cmp), "=q" (ret) \ - :"b" (ebx), "c" (ecx)) -#endif #define make_atomic_fas_body(S) \ asm volatile ("xchg %0, %1;" : "+r" (v) , "+m" (*a)) -#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_prefix here anyway to force memory barriers */ -#define make_atomic_load_body(S) \ - ret=0; \ - asm volatile (LOCK_prefix "; cmpxchg %2, %0" \ - : "+m" (*a), "+a" (ret): "r" (ret)) -#define make_atomic_store_body(S) \ +#define make_atomic_load_body(S) \ + ret=0; \ + asm volatile (LOCK_prefix "; cmpxchg %2, %0" \ + : "+m" (*a), "+a" (ret): "r" (ret)) +#define make_atomic_store_body(S) \ asm volatile ("; xchg %0, %1;" : "+m" (*a), "+r" (v)) + +#else +/* + Use default implementations of 64-bit operations since we solved + the 64-bit problem on 32-bit platforms for CAS, no need to solve it + once more for ADD, LOAD, STORE and FAS as well. + Since we already added add32 support, we need to define add64 + here, but we haven't defined fas, load and store at all, so + we can fallback on default implementations. +*/ +#define make_atomic_add_body64 \ + int64 tmp=*a; \ + while (!my_atomic_cas64(a, &tmp, tmp+v)); \ + v=tmp; + +/* + On some platforms (e.g. Mac OS X and Solaris) the ebx register + is held as a pointer to the global offset table. Thus we're not + allowed to use the b-register on those platforms when compiling + PIC code, to avoid this we push ebx and pop ebx and add a movl + instruction to avoid having ebx in the interface of the assembler + instruction. + + cmpxchg8b works on both 32-bit platforms and 64-bit platforms but + the code here is only used on 32-bit platforms, on 64-bit + platforms the much simpler make_atomic_cas_body32 will work + fine. +*/ +#define make_atomic_cas_body64 \ + int32 ebx=(set & 0xFFFFFFFF), ecx=(set >> 32); \ + asm volatile ("push %%ebx; movl %3, %%ebx;" \ + LOCK_prefix "; cmpxchg8b %0; setz %2; pop %%ebx"\ + : "+m" (*a), "+A" (*cmp), "=q" (ret) \ + :"m" (ebx), "c" (ecx)) +#endif + +/* + The implementation of make_atomic_cas_body32 is adaptable to + the OS word size, so on 64-bit platforms it will automatically + adapt to 64-bits and so it will work also on 64-bit platforms +*/ +#define make_atomic_cas_bodyptr make_atomic_cas_body32 + +#ifdef MY_ATOMIC_MODE_DUMMY +#define make_atomic_load_body(S) ret=*a +#define make_atomic_store_body(S) *a=v #endif #endif /* ATOMIC_X86_GCC_INCLUDED */ From a893a64e2342eb4d179db46c5f85d4c86c45a4ed Mon Sep 17 00:00:00 2001 From: Mikael Ronstrom Date: Wed, 16 Dec 2009 00:33:15 +0100 Subject: [PATCH 23/23] Fix for Windows atomics --- include/atomic/generic-msvc.h | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/include/atomic/generic-msvc.h b/include/atomic/generic-msvc.h index 4a50dc4a667..a84cde6b2c3 100644 --- a/include/atomic/generic-msvc.h +++ b/include/atomic/generic-msvc.h @@ -37,19 +37,17 @@ #else C_MODE_START /*Visual Studio 2003 and earlier do not have prototypes for atomic intrinsics*/ -LONG _InterlockedExchange (LONG volatile *Target,LONG Value); LONG _InterlockedCompareExchange (LONG volatile *Target, LONG Value, LONG Comp); -LONG _InterlockedExchangeAdd (LONG volatile *Addend, LONG Value); +LONGLONG _InterlockedCompareExchange64 (LONGLONG volatile *Target, + LONGLONG Value, LONGLONG Comp); C_MODE_END -#pragma intrinsic(_InterlockedExchangeAdd) #pragma intrinsic(_InterlockedCompareExchange) -#pragma intrinsic(_InterlockedExchange) +#pragma intrinsic(_InterlockedCompareExchange64) #endif -#define InterlockedExchange _InterlockedExchange -#define InterlockedExchangeAdd _InterlockedExchangeAdd #define InterlockedCompareExchange _InterlockedCompareExchange +#define InterlockedCompareExchange64 _InterlockedCompareExchange64 /* No need to do something special for InterlockedCompareExchangePointer as it is a #define to InterlockedCompareExchange. The same applies to @@ -58,33 +56,39 @@ C_MODE_END #endif /*_M_IX86*/ #define MY_ATOMIC_MODE "msvc-intrinsics" -#define IL_EXCHG_ADD32(X,Y) \ - InterlockedExchangeAdd((volatile LONG *)(X),(Y)) -#define IL_EXCHG_ADD64(X,Y) \ - InterlockedExchangeAdd64((volatile LONGLONG *)(X),(LONGLONG)(Y)) +/* Implement using CAS on WIN32 */ #define IL_COMP_EXCHG32(X,Y,Z) \ InterlockedCompareExchange((volatile LONG *)(X),(Y),(Z)) #define IL_COMP_EXCHG64(X,Y,Z) \ InterlockedCompareExchange64((volatile LONGLONG *)(X), \ (LONGLONG)(Y),(LONGLONG)(Z)) #define IL_COMP_EXCHGptr InterlockedCompareExchangePointer + +#define make_atomic_cas_body(S) \ + int ## S initial_cmp= *cmp; \ + int ## S initial_a= IL_COMP_EXCHG ## S (a, set, initial_cmp); \ + if (!(ret= (initial_a == initial_cmp))) *cmp= initial_a; + +#ifndef _M_IX86 +/* Use full set of optimised functions on WIN64 */ +#define IL_EXCHG_ADD32(X,Y) \ + InterlockedExchangeAdd((volatile LONG *)(X),(Y)) +#define IL_EXCHG_ADD64(X,Y) \ + InterlockedExchangeAdd64((volatile LONGLONG *)(X),(LONGLONG)(Y)) #define IL_EXCHG32(X,Y) \ InterlockedExchange((volatile LONG *)(X),(Y)) #define IL_EXCHG64(X,Y) \ InterlockedExchange64((volatile LONGLONG *)(X),(LONGLONG)(Y)) #define IL_EXCHGptr InterlockedExchangePointer + #define make_atomic_add_body(S) \ v= IL_EXCHG_ADD ## S (a, v) -#define make_atomic_cas_body(S) \ - int ## S initial_cmp= *cmp; \ - int ## S initial_a= IL_COMP_EXCHG ## S (a, set, initial_cmp); \ - if (!(ret= (initial_a == initial_cmp))) *cmp= initial_a; #define make_atomic_swap_body(S) \ v= IL_EXCHG ## S (a, v) #define make_atomic_load_body(S) \ ret= 0; /* avoid compiler warning */ \ ret= IL_COMP_EXCHG ## S (a, ret, ret); - +#endif /* my_yield_processor (equivalent of x86 PAUSE instruction) should be used to improve performance on hyperthreaded CPUs. Intel recommends to use it in