diff options
author | Vladislav Vaintroub <vvaintroub@linux-rbsx> | 2009-12-19 03:21:49 +0100 |
---|---|---|
committer | Vladislav Vaintroub <vvaintroub@linux-rbsx> | 2009-12-19 03:21:49 +0100 |
commit | 9c9cc49060f17415763b1d634aa6770ed63824c4 (patch) | |
tree | 9ccfada701764a2476975250d029acbe812b12b1 | |
parent | 54c5a4beefefb8047a3fb1f0259d38e5e8bb664e (diff) | |
parent | 92630be0ee81604ec47cb8c7e9ab016e5449dc4d (diff) | |
download | mariadb-git-9c9cc49060f17415763b1d634aa6770ed63824c4.tar.gz |
merge
83 files changed, 1887 insertions, 1037 deletions
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 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 980cfd9b3ea..57fa5b6a0f1 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 @@ -643,8 +643,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 9920cfc1904..9c665e6d76a 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -3837,8 +3837,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])) @@ -3855,8 +3859,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])) @@ -4257,10 +4265,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/config.h.cmake b/config.h.cmake index e4dd2541f92..13068a310ab 100644 --- a/config.h.cmake +++ b/config.h.cmake @@ -492,6 +492,7 @@ #cmakedefine HAVE_LARGE_PAGES 1 #cmakedefine HUGETLB_USE_PROC_MEMINFO 1 #cmakedefine NO_FCNTL_NONBLOCK 1 +#cmakedefine NO_ALARM 1 #cmakedefine _LARGE_FILES 1 #cmakedefine _LARGEFILE_SOURCE 1 diff --git a/configure.cmake b/configure.cmake index 84a1b5f1dfb..828c277c1dc 100644 --- a/configure.cmake +++ b/configure.cmake @@ -273,7 +273,7 @@ IF(UNIX) IF(NOT LIBM) MY_SEARCH_LIBS(__infinity m LIBM) ENDIF() - MY_SEARCH_LIBS(gethostbyname_r "nsl_r;nsl" LIBNLS) + MY_SEARCH_LIBS(gethostbyname_r "nsl_r;nsl" LIBNSL) MY_SEARCH_LIBS(bind "bind;socket" LIBBIND) MY_SEARCH_LIBS(crypt crypt LIBCRYPT) MY_SEARCH_LIBS(setsockopt socket LIBSOCKET) @@ -285,7 +285,7 @@ IF(UNIX) FIND_PACKAGE(Threads) SET(CMAKE_REQUIRED_LIBRARIES - ${LIBM} ${LIBNLS} ${LIBBIND} ${LIBCRYPT} ${LIBSOCKET} ${LIBDL} ${CMAKE_THREAD_LIBS_INIT} ${LIBRT}) + ${LIBM} ${LIBNSL} ${LIBBIND} ${LIBCRYPT} ${LIBSOCKET} ${LIBDL} ${CMAKE_THREAD_LIBS_INIT} ${LIBRT}) LIST(REMOVE_DUPLICATES CMAKE_REQUIRED_LIBRARIES) LINK_LIBRARIES(${CMAKE_THREAD_LIBS_INIT}) @@ -1136,6 +1136,50 @@ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS") ENDIF() ENDIF() +# Use of ALARMs to wakeup on timeout on sockets +# +# This feature makes use of a mutex and is a scalability hog we +# try to avoid using. However we need support for SO_SNDTIMEO and +# SO_RCVTIMEO socket options for this to work. So we will check +# if this feature is supported by a simple TRY_RUN macro. However +# on some OS's there is support for setting those variables but +# they are silently ignored. For those OS's we will not attempt +# to use SO_SNDTIMEO and SO_RCVTIMEO even if it is said to work. +# See Bug#29093 for the problem with SO_SND/RCVTIMEO on HP/UX. +# To use alarm is simple, simply avoid setting anything. + +IF(WIN32) + SET(HAVE_SOCKET_TIMEOUT 1) +ELSEIF(CMAKE_SYSTEM MATCHES "HP") + SET(HAVE_SOCKET_TIMEOUT 0) +ELSEIF(CMAKE_CROSSCOMPILING) + SET(HAVE_SOCKET_TIMEOUT 0) +ELSE() +SET(CMAKE_REQUIRED_LIBRARIES ${LIBNSL} ${LIBSOCKET}) +CHECK_C_SOURCE_RUNS( +" + #include <sys/types.h> + #include <sys/socket.h> + #include <sys/time.h> + + int main() + { + 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; + } +" HAVE_SOCKET_TIMEOUT) +ENDIF() + +SET(NO_ALARM "${HAVE_SOCKET_TIMEOUT}" CACHE BOOL + "No need to use alarm to implement socket timeout") +MARK_AS_ADVANCED(NO_ALARM) + IF(CMAKE_SYSTEM_NAME STREQUAL "AIX" OR CMAKE_SYSTEM_NAME STREQUAL "OS400") # xlC oddity - it complains about same inline function defined multiple times # in different compilation units diff --git a/configure.in b/configure.in index 5bf230ab034..b5ebddcb68f 100644 --- a/configure.in +++ b/configure.in @@ -880,9 +880,73 @@ AC_CHECK_DECLS(MHA_MAPSIZE_VA, #include <sys/mman.h> ] ) +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 <sys/types.h> + #include <sys/socket.h> + #include <sys/time.h> + ]],[[ + 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]) + AC_DEFINE([SIGNAL_WITH_VIO_CLOSE], [1], [Need to use vio close for kill connection]) fi +AC_MSG_RESULT($use_alarm) #-------------------------------------------------------------------- # Check for IPv6 support diff --git a/include/atomic/generic-msvc.h b/include/atomic/generic-msvc.h index f1e1b0e88c9..a84cde6b2c3 100644 --- a/include/atomic/generic-msvc.h +++ b/include/atomic/generic-msvc.h @@ -23,6 +23,7 @@ */ #undef MY_ATOMIC_HAS_8_16 +#include <windows.h> /* x86 compilers (both VS2003 or VS2005) never use instrinsics, but generate function calls to kernel32 instead, even in the optimized build. @@ -36,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 @@ -57,23 +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_COMP_EXCHG32(X,Y,Z) InterlockedCompareExchange((volatile LONG *)(X),(Y),(Z)) +/* 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 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; + +#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_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 @@ -108,9 +123,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 59090bc26b7..32839e0a67d 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" @@ -42,29 +48,79 @@ #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)) -#ifdef MY_ATOMIC_MODE_DUMMY -#define make_atomic_load_body(S) ret=*a -#define make_atomic_store_body(S) *a=v -#else +#ifdef __x86_64__ +#define make_atomic_add_body64 make_atomic_add_body32 +#define make_atomic_cas_body64 make_atomic_cas_body32 + +#define make_atomic_fas_body(S) \ + asm volatile ("xchg %0, %1;" : "+r" (v) , "+m" (*a)) + /* 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 */ diff --git a/include/hash.h b/include/hash.h index d870e17c341..515c764214d 100644 --- a/include/hash.h +++ b/include/hash.h @@ -30,6 +30,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 *); @@ -60,8 +61,18 @@ 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, + my_hash_value_type hash_value, + 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, + my_hash_value_type 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/include/keycache.h b/include/keycache.h index 1ffb1dbb71f..7222208d6df 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 *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_atomic.h b/include/my_atomic.h index 95868e4b810..df1fc7c38ad 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 @@ -49,18 +49,17 @@ On architectures where these operations are really atomic, rwlocks will be optimized away. 8- and 16-bit atomics aren't implemented for windows (see generic-msvc.h), - but can be added, if necessary. + but can be added, if necessary. */ #ifndef my_atomic_rwlock_init #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 /* @@ -130,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 @@ -141,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 @@ -218,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 @@ -225,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 @@ -238,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 @@ -245,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_ @@ -255,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_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_global.h b/include/my_global.h index 5c3a7044c4c..9898d060e8a 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -954,6 +954,8 @@ inline unsigned long long my_double2ulonglong(double d) #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/include/my_pthread.h b/include/my_pthread.h index 6e3763b6181..51dd9c72c79 100644 --- a/include/my_pthread.h +++ b/include/my_pthread.h @@ -608,6 +608,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); @@ -638,10 +640,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; @@ -694,9 +696,9 @@ extern uint thd_lib_detected; #define thread_safe_decrement(V,L) InterlockedDecrement((long*) &(V)) #else #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 #endif @@ -706,9 +708,9 @@ extern uint thd_lib_detected; #define thread_safe_sub(V,C,L) InterlockedExchangeAdd((long*) &(V),-(long) (C)) #else #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 #endif diff --git a/include/my_sys.h b/include/my_sys.h index 690649892a7..12ff5a329f7 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -341,7 +341,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 }; @@ -361,7 +361,7 @@ typedef struct st_my_tmpdir char **list; uint cur, max; #ifdef THREAD - pthread_mutex_t mutex; + mysql_mutex_t mutex; #endif } MY_TMPDIR; @@ -377,9 +377,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. */ @@ -440,7 +440,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 @@ -694,6 +694,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/CMakeLists.txt b/mysys/CMakeLists.txt index d055b0af8a9..c035a2f0b49 100755 --- a/mysys/CMakeLists.txt +++ b/mysys/CMakeLists.txt @@ -64,5 +64,5 @@ IF(UNIX) ENDIF() ADD_CONVENIENCE_LIBRARY(mysys ${MYSYS_SOURCES}) TARGET_LINK_LIBRARIES(mysys dbug strings ${ZLIB_LIBRARY} - ${LIBNLS} ${LIBM} ${LIBRT}) + ${LIBNSL} ${LIBM} ${LIBRT}) DTRACE_INSTRUMENT(mysys) diff --git a/mysys/charset.c b/mysys/charset.c index e216f665092..f05e8c71297 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 @@ -342,10 +342,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; @@ -424,7 +424,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)); @@ -447,7 +447,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; } @@ -510,7 +510,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 */ { @@ -532,7 +532,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 f7c18ed83eb..8c7dfe12047 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 @@ -687,7 +687,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; @@ -727,10 +727,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 */ @@ -920,11 +920,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/hash.c b/mysys/hash.c index 6996b045d1c..5fa804ce7ce 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); @@ -214,6 +217,21 @@ 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, + my_hash_value_type 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); +} + +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); +} /* Search after a record based on a key @@ -224,14 +242,25 @@ 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, + my_hash_value_type 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 { @@ -331,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 *UNINIT_VAR(ptr_to_rec),*UNINIT_VAR(ptr_to_rec2); HASH_LINK *data,*empty,*UNINIT_VAR(gpos),*UNINIT_VAR(gpos2),*pos; @@ -467,7 +497,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/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 <N> add #define MAX_THREADS <N> - - 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 <T> 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 0b774975851..f5854043459 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 b9f385d83a9..ea12f73fe3d 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 @@ -171,7 +171,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) { @@ -179,7 +179,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,28 +59,35 @@ static ulong atoi_octal(const char *str) return (ulong) tmp; } - -/* - Init my_sys functions and my_sys variabels - - SYNOPSIS - my_init() - - RETURN - 0 ok - 1 Couldn't initialize environment +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_init(void) +my_bool my_basic_init(void) { - char * str; - if (my_init_done) + if (my_basic_init_done) return 0; - my_init_done=1; + 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; @@ -94,6 +103,38 @@ my_bool my_init(void) #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 + + SYNOPSIS + my_init() + + RETURN + 0 ok + 1 Couldn't initialize environment +*/ + +my_bool my_init(void) +{ + char * str; + if (my_init_done) + return 0; + my_init_done= 1; + + if (my_basic_init()) + return 1; + +#ifdef THREAD + if (my_thread_global_init()) + return 1; #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 23cc24d2fcb..84c457da4c9 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 <my_no_pthread.h> #endif /* THREAD */ diff --git a/mysys/ptr_cmp.c b/mysys/ptr_cmp.c index 24ab6a1ea9c..2005e3eb2b7 100644 --- a/mysys/ptr_cmp.c +++ b/mysys/ptr_cmp.c @@ -22,16 +22,39 @@ #include "mysys_priv.h" #include <myisampack.h> +#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 + * 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 <string.h> + +static int native_compare(size_t *length, unsigned char **a, unsigned char **b) +{ + return memcmp(*a, *b, *length); +} + +#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 /* 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 TARGET_OS_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 /* TARGET_OS_SOLARIS */ } 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 <my_global.h> #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 c2e329e1fe4..eb8d7465025 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 @@ -63,7 +63,7 @@ static int gettimeofday(struct timeval *tv, void *tz) * ******************************************************************************/ -ActiveTranx::ActiveTranx(pthread_mutex_t *lock, +ActiveTranx::ActiveTranx(mysql_mutex_t *lock, unsigned long trace_level) : Trace(trace_level), num_entries_(max_connections << 1), /* Transaction hash table size @@ -377,8 +377,10 @@ int ReplSemiSyncMaster::initObject() setTraceLevel(rpl_semi_sync_master_trace_level); /* 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(); @@ -453,8 +455,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_; @@ -462,17 +464,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) @@ -481,8 +483,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 bfb1cb74cd0..1a951fa0ba2 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. @@ -44,7 +50,7 @@ private: TranxNode **trx_htb_; /* A hash table on active 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(); @@ -69,7 +75,7 @@ private: } public: - ActiveTranx(pthread_mutex_t *lock, unsigned long trace_level); + ActiveTranx(mysql_mutex_t *lock, unsigned long trace_level); ~ActiveTranx(); /* Insert an active transaction node with the specified position. @@ -118,14 +124,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/event_scheduler.cc b/sql/event_scheduler.cc index d9ca161f260..31bb3d39b85 100644 --- a/sql/event_scheduler.cc +++ b/sql/event_scheduler.cc @@ -132,9 +132,8 @@ post_init_event_thread(THD *thd) pthread_mutex_lock(&LOCK_thread_count); threads.append(thd); thread_count++; - thread_running++; + inc_thread_running(); pthread_mutex_unlock(&LOCK_thread_count); - return FALSE; } @@ -156,7 +155,7 @@ deinit_event_thread(THD *thd) DBUG_PRINT("exit", ("Event thread finishing")); pthread_mutex_lock(&LOCK_thread_count); thread_count--; - thread_running--; + dec_thread_running(); delete thd; pthread_cond_broadcast(&COND_thread_count); pthread_mutex_unlock(&LOCK_thread_count); @@ -417,7 +416,7 @@ Event_scheduler::start() net_end(&new_thd->net); pthread_mutex_lock(&LOCK_thread_count); thread_count--; - thread_running--; + dec_thread_running(); delete new_thd; pthread_cond_broadcast(&COND_thread_count); pthread_mutex_unlock(&LOCK_thread_count); @@ -550,7 +549,7 @@ error: net_end(&new_thd->net); pthread_mutex_lock(&LOCK_thread_count); thread_count--; - thread_running--; + dec_thread_running(); delete new_thd; pthread_cond_broadcast(&COND_thread_count); pthread_mutex_unlock(&LOCK_thread_count); diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index a9cc37f3162..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 @@ -6909,7 +6909,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(); @@ -6919,7 +6919,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); } @@ -7071,7 +7071,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 */ @@ -7089,7 +7089,7 @@ int ndbcluster_find_all_files(THD *thd) TRUE); } #endif - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); } } while (unhandled && retries); @@ -7182,19 +7182,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; @@ -7251,10 +7251,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 @@ -7303,7 +7303,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<char> it2(create_list); while ((file_name_str=it2++)) @@ -7318,7 +7318,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); @@ -8246,7 +8246,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 a22ce976351..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 @@ -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 691af708d51..6f14e69e101 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 @@ -3282,7 +3282,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 @@ -3293,7 +3293,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; } @@ -3301,7 +3301,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)) @@ -3318,7 +3318,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); @@ -3333,12 +3333,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; @@ -3350,7 +3374,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); } } @@ -3359,7 +3383,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; } @@ -3402,7 +3426,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) { @@ -3420,7 +3444,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++; @@ -3436,7 +3460,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; } @@ -3452,19 +3476,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 @@ -3482,8 +3506,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; @@ -3499,7 +3523,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. */ @@ -3542,11 +3566,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); } @@ -3569,13 +3593,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 } @@ -3625,13 +3649,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); } @@ -3662,7 +3686,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())))) @@ -3683,7 +3707,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); } @@ -3789,7 +3813,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; @@ -3803,13 +3827,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; @@ -3824,13 +3848,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 } @@ -5758,10 +5782,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; @@ -5777,10 +5801,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..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 @@ -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/log_event.cc b/sql/log_event.cc index cc2b4667115..10b4ecd3f7b 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -3055,10 +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); - pthread_mutex_lock(&LOCK_thread_count); - thd->query_id = next_query_id(); - pthread_mutex_unlock(&LOCK_thread_count); + 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())); @@ -4580,9 +4577,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); - pthread_mutex_lock(&LOCK_thread_count); - thd->query_id = next_query_id(); - pthread_mutex_unlock(&LOCK_thread_count); + thd->set_query_id(next_query_id()); thd->warning_info->opt_clear_warning_info(thd->query_id); TABLE_LIST tables; @@ -8071,9 +8066,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. */ - pthread_mutex_lock(&LOCK_thread_count); - thd->query_id= next_query_id(); - pthread_mutex_unlock(&LOCK_thread_count); + 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/mysql_priv.h b/sql/mysql_priv.h index bed60aaa494..3ddaf114673 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -53,6 +53,7 @@ #include "sql_array.h" #include "sql_plugin.h" #include "scheduler.h" +#include <my_atomic.h> #include <mysql/psi/mysql_file.h> #ifndef __WIN__ #include <netdb.h> @@ -89,11 +90,60 @@ 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; +extern my_atomic_rwlock_t thread_running_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; + 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; +} + +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); +} + +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); +} + +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; +} /* useful constants */ extern MYSQL_PLUGIN_IMPORT const key_map key_map_empty; @@ -1498,8 +1548,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); @@ -1955,7 +2005,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; @@ -1988,13 +2038,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; @@ -2004,7 +2056,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<THD> threads; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 367b427aaae..a208a95d863 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 @@ -524,7 +524,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; @@ -540,6 +541,8 @@ 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; +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; @@ -647,14 +650,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 +673,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 +964,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 @@ -1369,6 +1375,8 @@ 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); + 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; @@ -1410,17 +1418,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 +1456,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); @@ -3592,16 +3600,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); @@ -3631,7 +3643,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); @@ -7782,6 +7794,8 @@ 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); + 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"; @@ -8924,7 +8938,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); @@ -8938,7 +8952,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/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" 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/slave.cc b/sql/slave.cc index 6d78d44f6f2..6876734d746 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -1206,6 +1206,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), @@ -1258,7 +1260,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)); @@ -1329,6 +1333,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), @@ -1390,6 +1396,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), @@ -1453,6 +1461,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); } static bool wait_for_relay_log_space(Relay_log_info* rli) @@ -2678,7 +2691,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" diff --git a/sql/sp_cache.cc b/sql/sp_cache.cc index 0da5e44b846..e8604baf466 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; @@ -81,12 +81,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/sp_head.cc b/sql/sp_head.cc index 542db282700..3f7d812384c 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1335,7 +1335,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; @@ -2745,9 +2745,7 @@ sp_lex_keeper::reset_lex_and_exec_core(THD *thd, uint *nextp, */ thd->lex= m_lex; - pthread_mutex_lock(&LOCK_thread_count); - thd->query_id= next_query_id(); - pthread_mutex_unlock(&LOCK_thread_count); + thd->set_query_id(next_query_id()); if (thd->prelocked_mode == NON_PRELOCKED) { diff --git a/sql/sql_base.cc b/sql/sql_base.cc index c67c3266e59..ee264ec3de6 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 @@ -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); } @@ -2098,7 +2098,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); /* @@ -2167,14 +2167,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); } } @@ -2190,7 +2190,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; @@ -2200,7 +2200,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 @@ -2213,12 +2213,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; } @@ -2289,7 +2289,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); @@ -2369,7 +2369,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 @@ -2429,24 +2429,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); } @@ -2478,7 +2478,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; @@ -2555,6 +2555,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; + my_hash_value_type hash_value; HASH_SEARCH_STATE state; DBUG_ENTER("open_table"); @@ -2700,15 +2701,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); } } /* @@ -2741,7 +2742,8 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, on disk. */ - pthread_mutex_lock(&LOCK_open); + hash_value= my_calc_hash(&open_cache, (uchar*) key, key_length); + mysql_mutex_lock(&LOCK_open); /* If it's the first table from a list of tables used in a query, @@ -2759,7 +2761,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); } @@ -2783,8 +2785,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*) my_hash_first(&open_cache, (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*) my_hash_next(&open_cache, (uchar*) key, key_length, &state)) @@ -2825,7 +2830,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); } @@ -2866,7 +2871,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. @@ -2907,7 +2912,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); } @@ -2918,7 +2923,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); } /* @@ -2929,7 +2934,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. */ @@ -2938,7 +2943,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); } @@ -2947,7 +2952,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) @@ -2960,7 +2965,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", @@ -2969,14 +2974,14 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, if (my_hash_insert(&open_cache,(uchar*) table)) { my_free(table, MYF(0)); - (void) pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); DBUG_RETURN(NULL); } } 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 */ @@ -3180,7 +3185,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) { @@ -3319,7 +3324,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) { /* @@ -3582,7 +3587,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; @@ -3590,7 +3595,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 @@ -3601,7 +3606,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); } @@ -3754,7 +3759,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 */ /* @@ -3878,7 +3883,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, @@ -4007,7 +4012,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, @@ -4030,7 +4035,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) @@ -8434,10 +8439,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); } @@ -8508,15 +8513,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 @@ -8573,7 +8578,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; @@ -8588,7 +8593,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; @@ -8734,12 +8739,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); } @@ -8761,10 +8766,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); @@ -8803,7 +8808,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) ; @@ -8824,14 +8829,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 @@ -8861,7 +8866,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; } @@ -9100,7 +9105,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; /* @@ -9116,7 +9121,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 94329bbcd28..019c22d9dd2 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -962,9 +962,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; @@ -1023,9 +1023,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; } @@ -1164,7 +1164,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; /* @@ -1188,11 +1188,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; } @@ -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 19b3059fa03..2a332341cb7 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; } @@ -2319,10 +2319,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_db.cc b/sql/sql_db.cc index 51098987e81..f1b631915c1 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)) { @@ -757,7 +783,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); @@ -788,7 +814,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 @@ -835,7 +861,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); @@ -887,7 +913,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 @@ -909,9 +935,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); @@ -1047,7 +1073,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); @@ -1173,7 +1199,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; } @@ -1251,7 +1277,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); } @@ -1328,7 +1354,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; } @@ -1735,18 +1761,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; } @@ -1763,7 +1789,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) @@ -1771,8 +1797,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); } @@ -1780,7 +1806,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; } @@ -1909,7 +1935,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 '\' @@ -1965,7 +1991,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); } @@ -1993,14 +2019,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 c59e7dd5873..ab898950a1d 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 @@ -1170,10 +1170,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: @@ -1187,15 +1187,15 @@ end: if (!error) 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..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. @@ -143,14 +144,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 +776,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 9dc25f8dc51..8a303d62b4f 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 @@ -904,7 +904,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 */ @@ -1763,8 +1763,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; @@ -1796,9 +1796,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 ? @@ -1814,9 +1814,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; @@ -1833,18 +1833,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; } @@ -1865,7 +1865,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<Delayed_insert> it(delayed_threads); Delayed_insert *di; while ((di= it++)) @@ -1877,7 +1877,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; } @@ -1947,7 +1947,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. @@ -1973,14 +1973,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); @@ -1991,9 +1992,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) { @@ -2016,16 +2017,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()); @@ -2036,7 +2037,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()); } @@ -2072,10 +2073,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) @@ -2162,7 +2163,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); } @@ -2181,9 +2182,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) @@ -2258,15 +2259,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); } @@ -2279,14 +2280,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; } @@ -2295,7 +2296,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<Delayed_insert> it(delayed_threads); Delayed_insert *di; @@ -2304,7 +2305,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) { /* @@ -2312,15 +2313,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 } @@ -2342,15 +2343,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 */ @@ -2409,7 +2412,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 */ @@ -2423,12 +2426,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 } @@ -2448,15 +2451,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 @@ -2469,12 +2472,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); @@ -2499,7 +2502,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) { @@ -2519,7 +2522,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(). @@ -2528,10 +2531,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: @@ -2560,14 +2563,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); @@ -2614,7 +2617,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(); @@ -2647,12 +2650,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; @@ -2771,7 +2774,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 @@ -2793,9 +2796,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 */ @@ -2814,15 +2817,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 @@ -2848,7 +2851,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: @@ -2872,7 +2875,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 */ @@ -3535,7 +3538,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, @@ -3544,7 +3547,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 501234e9ba9..0774e373908 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 @@ -482,7 +482,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(); @@ -493,7 +493,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 @@ -915,29 +914,29 @@ 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(); - 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(); + { + 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->set_query_id(query_id); } - - thread_running++; + inc_thread_running(); /* TODO: set thd->lex->sql_command to SQLCOM_END here */ - pthread_mutex_unlock(&LOCK_thread_count); /** Clear the set of flags that are expected to be cleared at the @@ -1165,16 +1164,13 @@ 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); - pthread_mutex_lock(&LOCK_thread_count); + 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 */ - pthread_mutex_unlock(&LOCK_thread_count); mysql_parse(thd, beginning_of_next_stmt, length, &end_of_stmt); } @@ -1488,9 +1484,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; - pthread_mutex_lock(&LOCK_thread_count); // For process list - thread_running--; - pthread_mutex_unlock(&LOCK_thread_count); + dec_thread_running(); 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)); @@ -2081,11 +2075,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 062d2fb701c..248f226be9c 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -6258,7 +6258,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; @@ -6272,7 +6272,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); } } @@ -6296,9 +6296,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 d15c97de912..4d60caf2931 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1371,10 +1371,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 e85e730db5b..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 @@ -134,10 +134,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; } @@ -173,7 +173,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); if (!silent && !error) { @@ -185,9 +185,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 8c8d0166b38..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 @@ -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); } @@ -7218,7 +7218,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. @@ -7228,7 +7228,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 e06659a549c..c4904feffa6 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 @@ -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; @@ -1871,7 +1871,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 @@ -1892,14 +1892,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); } @@ -2070,7 +2070,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()) @@ -2153,10 +2153,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); } @@ -3872,7 +3872,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)) @@ -4016,7 +4016,7 @@ bool mysql_create_table_no_lock(THD *thd, error= write_create_table_bin_log(thd, create_info, internal_tmp_table); unlock_and_end: - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); err: thd_proc_info(thd, "After create"); @@ -4049,21 +4049,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)) { @@ -4100,14 +4100,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); } @@ -4268,7 +4268,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' */ @@ -4353,22 +4353,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. */ @@ -4422,9 +4422,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)) { @@ -4433,27 +4433,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; @@ -4463,23 +4463,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); } @@ -4706,7 +4706,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); @@ -4969,10 +4969,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); @@ -5275,12 +5275,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; } } @@ -5290,7 +5290,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; } @@ -5319,7 +5319,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) { @@ -5393,13 +5393,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); /* The condition avoids a crash as described in BUG#48506. Other @@ -5433,9 +5433,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); } @@ -6552,7 +6552,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; @@ -6576,7 +6576,7 @@ view_err_unlock: 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); } @@ -6737,17 +6737,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; @@ -6764,7 +6764,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 @@ -6831,7 +6831,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); @@ -7192,9 +7192,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); @@ -7325,11 +7325,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; } @@ -7462,7 +7462,7 @@ view_err: if (error) goto err_with_placeholders; } - pthread_mutex_unlock(&LOCK_open); + mysql_mutex_unlock(&LOCK_open); thd_proc_info(thd, "end"); @@ -7510,10 +7510,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: @@ -7570,9 +7570,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); @@ -7585,7 +7585,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 f95d19f099e..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 @@ -79,7 +79,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++) @@ -115,7 +115,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; } @@ -380,12 +380,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, @@ -394,9 +394,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); @@ -472,7 +472,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\ @@ -488,7 +488,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 96af74df072..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 @@ -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: result= 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 f65c5dc54c1..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 @@ -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()) @@ -667,7 +667,7 @@ bool mysql_create_view(THD *thd, TABLE_LIST *views, res= TRUE; } - 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); @@ -1581,7 +1581,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; @@ -1659,7 +1659,7 @@ bool mysql_drop_view(THD *thd, TABLE_LIST *views, enum_drop_mode drop_mode) something_wrong= 1; } - 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); diff --git a/unittest/mysys/my_atomic-t.c b/unittest/mysys/my_atomic-t.c index 1a558e8cb73..9853d3cf964 100644 --- a/unittest/mysys/my_atomic-t.c +++ b/unittest/mysys/my_atomic-t.c @@ -48,6 +48,34 @@ pthread_handler_t test_atomic_add(void *arg) 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 bad @@ -128,7 +156,7 @@ pthread_handler_t test_atomic_cas(void *arg) void do_tests() { - plan(4); + plan(6); bad= my_atomic_initialize(); ok(!bad, "my_atomic_initialize() returned %d", bad); @@ -142,5 +170,14 @@ void do_tests() 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); + my_atomic_rwlock_destroy(&rwl); } |