summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorAlexey Kopytov <Alexey.Kopytov@Sun.com>2010-03-24 18:03:44 +0300
committerAlexey Kopytov <Alexey.Kopytov@Sun.com>2010-03-24 18:03:44 +0300
commitd95c1e3b470506c7df6dfce3fe6dc7e5b46930ee (patch)
tree9f13d4fcc3ac732dc94fe2cae446f6f8c2b4e02b /include
parentabc6846d5b1df4846c4ffc03f4c93c82f874dd96 (diff)
parentae715642f46d4ed9ea8b5dd9b5cc9f3cace7f437 (diff)
downloadmariadb-git-d95c1e3b470506c7df6dfce3fe6dc7e5b46930ee.tar.gz
Manual merge of mysql-trunk into mysql-trunk-merge.
Conflicts: Text conflict in client/mysqlbinlog.cc Text conflict in mysql-test/Makefile.am Text conflict in mysql-test/collections/default.daily Text conflict in mysql-test/r/mysqlbinlog_row_innodb.result Text conflict in mysql-test/suite/rpl/r/rpl_typeconv_innodb.result Text conflict in mysql-test/suite/rpl/t/rpl_get_master_version_and_clock.test Text conflict in mysql-test/suite/rpl/t/rpl_row_create_table.test Text conflict in mysql-test/suite/rpl/t/rpl_slave_skip.test Text conflict in mysql-test/suite/rpl/t/rpl_typeconv_innodb.test Text conflict in mysys/charset.c Text conflict in sql/field.cc Text conflict in sql/field.h Text conflict in sql/item.h Text conflict in sql/item_func.cc Text conflict in sql/log.cc Text conflict in sql/log_event.cc Text conflict in sql/log_event_old.cc Text conflict in sql/mysqld.cc Text conflict in sql/rpl_utility.cc Text conflict in sql/rpl_utility.h Text conflict in sql/set_var.cc Text conflict in sql/share/Makefile.am Text conflict in sql/sql_delete.cc Text conflict in sql/sql_plugin.cc Text conflict in sql/sql_select.cc Text conflict in sql/sql_table.cc Text conflict in storage/example/ha_example.h Text conflict in storage/federated/ha_federated.cc Text conflict in storage/myisammrg/ha_myisammrg.cc Text conflict in storage/myisammrg/myrg_open.c
Diffstat (limited to 'include')
-rw-r--r--include/CMakeLists.txt63
-rw-r--r--include/Makefile.am21
-rw-r--r--include/atomic/gcc_builtins.h5
-rw-r--r--include/atomic/generic-msvc.h134
-rw-r--r--include/atomic/nolock.h69
-rw-r--r--include/atomic/rwlock.h70
-rw-r--r--include/atomic/solaris.h206
-rw-r--r--include/atomic/x86-gcc.h104
-rw-r--r--include/atomic/x86-msvc.h96
-rw-r--r--include/config-netware.h3
-rw-r--r--include/config-win.h43
-rw-r--r--include/ft_global.h4
-rw-r--r--include/hash.h11
-rw-r--r--include/heap.h4
-rw-r--r--include/keycache.h14
-rw-r--r--include/lf.h268
-rw-r--r--include/m_ctype.h94
-rw-r--r--include/m_string.h118
-rw-r--r--include/my_alarm.h10
-rw-r--r--include/my_atomic.h276
-rw-r--r--include/my_base.h17
-rw-r--r--include/my_bitmap.h4
-rw-r--r--include/my_getopt.h51
-rw-r--r--include/my_global.h192
-rw-r--r--include/my_net.h16
-rw-r--r--include/my_no_pthread.h13
-rw-r--r--include/my_pthread.h205
-rw-r--r--include/my_rdtsc.h129
-rw-r--r--include/my_sys.h33
-rw-r--r--include/my_time.h6
-rw-r--r--include/myisam.h12
-rw-r--r--include/myisammrg.h4
-rw-r--r--include/mysql.h.pp4
-rw-r--r--include/mysql/plugin.h245
-rw-r--r--include/mysql/plugin.h.pp11
-rw-r--r--include/mysql/plugin_audit.h97
-rw-r--r--include/mysql/plugin_ftparser.h211
-rw-r--r--include/mysql/psi/mysql_file.h1398
-rw-r--r--include/mysql/psi/mysql_thread.h1164
-rw-r--r--include/mysql/psi/psi.h1091
-rw-r--r--include/mysql/psi/psi_abi_v1.h26
-rw-r--r--include/mysql/psi/psi_abi_v1.h.pp244
-rw-r--r--include/mysql/psi/psi_abi_v2.h26
-rw-r--r--include/mysql/psi/psi_abi_v2.h.pp92
-rw-r--r--include/mysql/service_my_snprintf.h2
-rw-r--r--include/mysql_com.h15
-rw-r--r--include/sslopt-longopts.h6
-rw-r--r--include/thr_alarm.h2
-rw-r--r--include/thr_lock.h24
-rw-r--r--include/typelib.h5
-rw-r--r--include/violite.h41
51 files changed, 6151 insertions, 848 deletions
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
new file mode 100644
index 00000000000..e2ef01b3b4c
--- /dev/null
+++ b/include/CMakeLists.txt
@@ -0,0 +1,63 @@
+# 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
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+SET(HEADERS_GEN_CONFIGURE
+${CMAKE_CURRENT_BINARY_DIR}/mysql_version.h
+${CMAKE_CURRENT_BINARY_DIR}/my_config.h
+${CMAKE_CURRENT_BINARY_DIR}/mysqld_ername.h
+${CMAKE_CURRENT_BINARY_DIR}/mysqld_error.h
+${CMAKE_CURRENT_BINARY_DIR}/sql_state.h
+)
+SET(HEADERS_ABI
+ mysql.h
+ mysql_com.h
+ mysql_time.h
+ my_list.h
+ my_alloc.h
+ typelib.h
+ mysql/plugin.h
+ mysql/plugin_audit.h
+ mysql/plugin_ftparser.h
+)
+
+SET(HEADERS
+ ${HEADERS_ABI}
+ my_dbug.h
+ m_string.h
+ my_sys.h
+ my_xml.h
+ mysql_embed.h
+ my_pthread.h
+ my_no_pthread.h
+ decimal.h
+ errmsg.h
+ my_global.h
+ my_net.h
+ my_getopt.h
+ sslopt-longopts.h
+ my_dir.h
+ sslopt-vars.h
+ sslopt-case.h
+ sql_common.h
+ keycache.h
+ m_ctype.h
+ my_attribute.h
+ ${HEADERS_GEN_CONFIGURE}
+)
+
+INSTALL(FILES ${HEADERS} DESTINATION ${INSTALL_INCLUDEDIR})
+INSTALL(DIRECTORY mysql/ DESTINATION ${INSTALL_INCLUDEDIR} FILES_MATCHING PATTERN "*.h")
+
+
diff --git a/include/Makefile.am b/include/Makefile.am
index 0a7a35bd6fa..1a0bc9c9df3 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -1,4 +1,4 @@
-# Copyright (C) 2000-2006 MySQL AB
+# Copyright (C) 2000-2006 MySQL AB, 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
@@ -19,18 +19,21 @@ BUILT_SOURCES = $(HEADERS_GEN_MAKE) link_sources probes_mysql_nodtrace.h
HEADERS_GEN_CONFIGURE = mysql_version.h
HEADERS_GEN_MAKE = my_config.h
HEADERS_ABI = mysql.h mysql_com.h mysql_time.h \
- my_list.h my_alloc.h typelib.h mysql/plugin.h
+ my_list.h my_alloc.h typelib.h mysql/plugin.h \
+ mysql/plugin_audit.h mysql/plugin_ftparser.h
pkginclude_HEADERS = $(HEADERS_ABI) my_dbug.h m_string.h my_sys.h \
my_xml.h mysql_embed.h mysql/services.h \
mysql/service_my_snprintf.h mysql/service_thd_alloc.h \
my_pthread.h my_no_pthread.h \
+ mysql/psi/psi.h mysql/psi/mysql_thread.h \
+ mysql/psi/mysql_file.h \
decimal.h errmsg.h my_global.h my_net.h \
my_getopt.h sslopt-longopts.h my_dir.h \
sslopt-vars.h sslopt-case.h sql_common.h keycache.h \
m_ctype.h my_attribute.h $(HEADERS_GEN_CONFIGURE) \
$(HEADERS_GEN_MAKE) probes_mysql.h probes_mysql_nodtrace.h
-noinst_HEADERS = config-win.h config-netware.h my_bit.h \
+noinst_HEADERS = config-win.h config-netware.h lf.h my_bit.h \
heap.h my_bitmap.h my_uctype.h \
myisam.h myisampack.h myisammrg.h ft_global.h\
mysys_err.h my_base.h help_start.h help_end.h \
@@ -38,12 +41,16 @@ noinst_HEADERS = config-win.h config-netware.h my_bit.h \
my_aes.h my_tree.h my_trie.h hash.h thr_alarm.h \
thr_lock.h t_ctype.h violite.h my_md5.h base64.h \
my_handler.h my_time.h service_versions.h \
+ my_rdtsc.h mysql/psi/psi_abi_v1.h mysql/psi/psi_abi_v2.h \
my_vle.h my_user.h my_atomic.h atomic/nolock.h \
- atomic/rwlock.h atomic/x86-gcc.h atomic/x86-msvc.h \
- atomic/solaris.h \
- atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h
+ atomic/rwlock.h atomic/x86-gcc.h atomic/generic-msvc.h \
+ atomic/gcc_builtins.h my_libwrap.h my_stacktrace.h \
+ atomic/solaris.h
-EXTRA_DIST = mysql.h.pp mysql/plugin.h.pp probes_mysql.d.base
+EXTRA_DIST = mysql.h.pp mysql/plugin.h.pp probes_mysql.d.base \
+ CMakeLists.txt \
+ mysql/psi/psi_abi_v1.h.pp \
+ mysql/psi/psi_abi_v2.h.pp
# Remove built files and the symlinked directories
CLEANFILES = $(BUILT_SOURCES) readline openssl probes_mysql.d probes_mysql_nodtrace.h
diff --git a/include/atomic/gcc_builtins.h b/include/atomic/gcc_builtins.h
index 01ebc38707e..100ff80cacd 100644
--- a/include/atomic/gcc_builtins.h
+++ b/include/atomic/gcc_builtins.h
@@ -18,7 +18,7 @@
#define make_atomic_add_body(S) \
v= __sync_fetch_and_add(a, v);
-#define make_atomic_swap_body(S) \
+#define make_atomic_fas_body(S) \
v= __sync_lock_test_and_set(a, v);
#define make_atomic_cas_body(S) \
int ## S sav; \
@@ -28,7 +28,10 @@
#ifdef MY_ATOMIC_MODE_DUMMY
#define make_atomic_load_body(S) ret= *a
#define make_atomic_store_body(S) *a= v
+#define MY_ATOMIC_MODE "gcc-builtins-up"
+
#else
+#define MY_ATOMIC_MODE "gcc-builtins-smp"
#define make_atomic_load_body(S) \
ret= __sync_fetch_and_or(a, 0);
#define make_atomic_store_body(S) \
diff --git a/include/atomic/generic-msvc.h b/include/atomic/generic-msvc.h
new file mode 100644
index 00000000000..a84cde6b2c3
--- /dev/null
+++ b/include/atomic/generic-msvc.h
@@ -0,0 +1,134 @@
+/* Copyright (C) 2006-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef _atomic_h_cleanup_
+#define _atomic_h_cleanup_ "atomic/generic-msvc.h"
+
+/*
+ We don't implement anything specific for MY_ATOMIC_MODE_DUMMY, always use
+ intrinsics.
+ 8 and 16-bit atomics are not implemented, but it can be done if necessary.
+*/
+#undef MY_ATOMIC_HAS_8_16
+
+#include <windows.h>
+/*
+ x86 compilers (both VS2003 or VS2005) never use instrinsics, but generate
+ function calls to kernel32 instead, even in the optimized build.
+ We force intrinsics as described in MSDN documentation for
+ _InterlockedCompareExchange.
+*/
+#ifdef _M_IX86
+
+#if (_MSC_VER >= 1500)
+#include <intrin.h>
+#else
+C_MODE_START
+/*Visual Studio 2003 and earlier do not have prototypes for atomic intrinsics*/
+LONG _InterlockedCompareExchange (LONG volatile *Target, LONG Value, LONG Comp);
+LONGLONG _InterlockedCompareExchange64 (LONGLONG volatile *Target,
+ LONGLONG Value, LONGLONG Comp);
+C_MODE_END
+
+#pragma intrinsic(_InterlockedCompareExchange)
+#pragma intrinsic(_InterlockedCompareExchange64)
+#endif
+
+#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
+ InterlockedExchangePointer.
+*/
+#endif /*_M_IX86*/
+
+#define MY_ATOMIC_MODE "msvc-intrinsics"
+/* Implement using CAS on WIN32 */
+#define IL_COMP_EXCHG32(X,Y,Z) \
+ InterlockedCompareExchange((volatile LONG *)(X),(Y),(Z))
+#define IL_COMP_EXCHG64(X,Y,Z) \
+ InterlockedCompareExchange64((volatile LONGLONG *)(X), \
+ (LONGLONG)(Y),(LONGLONG)(Z))
+#define IL_COMP_EXCHGptr InterlockedCompareExchangePointer
+
+#define make_atomic_cas_body(S) \
+ int ## S initial_cmp= *cmp; \
+ int ## S initial_a= IL_COMP_EXCHG ## S (a, set, initial_cmp); \
+ if (!(ret= (initial_a == initial_cmp))) *cmp= initial_a;
+
+#ifndef _M_IX86
+/* Use full set of optimised functions on WIN64 */
+#define IL_EXCHG_ADD32(X,Y) \
+ InterlockedExchangeAdd((volatile LONG *)(X),(Y))
+#define IL_EXCHG_ADD64(X,Y) \
+ InterlockedExchangeAdd64((volatile LONGLONG *)(X),(LONGLONG)(Y))
+#define IL_EXCHG32(X,Y) \
+ InterlockedExchange((volatile LONG *)(X),(Y))
+#define IL_EXCHG64(X,Y) \
+ InterlockedExchange64((volatile LONGLONG *)(X),(LONGLONG)(Y))
+#define IL_EXCHGptr InterlockedExchangePointer
+
+#define make_atomic_add_body(S) \
+ v= IL_EXCHG_ADD ## S (a, v)
+#define make_atomic_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
+ spin loops also on non-HT machines to reduce power consumption (see e.g
+ http://softwarecommunity.intel.com/articles/eng/2004.htm)
+
+ Running benchmarks for spinlocks implemented with InterlockedCompareExchange
+ and YieldProcessor shows that much better performance is achieved by calling
+ YieldProcessor in a loop - that is, yielding longer. On Intel boxes setting
+ loop count in the range 200-300 brought best results.
+ */
+#ifndef YIELD_LOOPS
+#define YIELD_LOOPS 200
+#endif
+
+static __inline int my_yield_processor()
+{
+ int i;
+ for(i=0; i<YIELD_LOOPS; i++)
+ {
+#if (_MSC_VER <= 1310)
+ /* On older compilers YieldProcessor is not available, use inline assembly*/
+ __asm { rep nop }
+#else
+ YieldProcessor();
+#endif
+ }
+ return 1;
+}
+
+#define LF_BACKOFF 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/nolock.h b/include/atomic/nolock.h
index d7d87167ade..5a0c41d9078 100644
--- a/include/atomic/nolock.h
+++ b/include/atomic/nolock.h
@@ -16,43 +16,46 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#if defined(__i386__) || defined(_M_IX86) || defined(HAVE_GCC_ATOMIC_BUILTINS)
+#if defined(__i386__) || defined(_MSC_VER) || defined(__x86_64__) \
+ || defined(HAVE_GCC_ATOMIC_BUILTINS) \
+ || defined(HAVE_SOLARIS_ATOMIC)
-#ifdef MY_ATOMIC_MODE_DUMMY
-# define LOCK ""
-#else
-# define LOCK "lock"
-#endif
-
-#ifdef HAVE_GCC_ATOMIC_BUILTINS
-#include "gcc_builtins.h"
-#elif __GNUC__
-#include "x86-gcc.h"
-#elif defined(_MSC_VER)
-#include "x86-msvc.h"
-#endif
-
-#elif defined(HAVE_SOLARIS_ATOMIC)
-
-#include "solaris.h"
-
-#endif /* __i386__ || _M_IX86 || HAVE_GCC_ATOMIC_BUILTINS */
-
-#if defined(make_atomic_cas_body) || defined(MY_ATOMICS_MADE)
+# ifdef MY_ATOMIC_MODE_DUMMY
+# define LOCK_prefix ""
+# else
+# define LOCK_prefix "lock"
+# endif
/*
- * We have atomics that require no locking
- */
-#define MY_ATOMIC_NOLOCK
-
-#ifdef __SUNPRO_C
-/*
- * Sun Studio 12 (and likely earlier) does not accept a typedef struct {}
- */
-typedef char my_atomic_rwlock_t;
-#else
-typedef struct { } my_atomic_rwlock_t;
+ We choose implementation as follows:
+ ------------------------------------
+ On Windows using Visual C++ the native implementation should be
+ preferrable. When using gcc we prefer the native x86 implementation,
+ we prefer the Solaris implementation before the gcc because of
+ stability preference, we choose gcc implementation if nothing else
+ works on gcc. If neither Visual C++ or gcc we still choose the
+ Solaris implementation on Solaris (mainly for SunStudio compiles.
+*/
+# if defined(_MSV_VER)
+# include "generic-msvc.h"
+# elif __GNUC__
+# if defined(__i386__) || defined(__x86_64__)
+# include "x86-gcc.h"
+# elif defined(HAVE_SOLARIS_ATOMIC)
+# include "solaris.h"
+# elif defined(HAVE_GCC_ATOMIC_BUILTINS)
+# include "gcc_builtins.h"
+# endif
+# elif defined(HAVE_SOLARIS_ATOMIC)
+# include "solaris.h"
+# endif
#endif
+#if defined(make_atomic_cas_body)
+/*
+ Type not used so minimal size (emptry struct has different size between C
+ and C++, zero-length array is gcc-specific).
+*/
+typedef char my_atomic_rwlock_t __attribute__ ((unused));
#define my_atomic_rwlock_destroy(name)
#define my_atomic_rwlock_init(name)
#define my_atomic_rwlock_rdlock(name)
diff --git a/include/atomic/rwlock.h b/include/atomic/rwlock.h
index 0ff4d16c545..a31f8ed6ca1 100644
--- a/include/atomic/rwlock.h
+++ b/include/atomic/rwlock.h
@@ -1,7 +1,7 @@
#ifndef ATOMIC_RWLOCK_INCLUDED
#define ATOMIC_RWLOCK_INCLUDED
-/* Copyright (C) 2006 MySQL AB
+/* Copyright (C) 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
@@ -16,7 +16,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-typedef struct {pthread_rwlock_t rw;} my_atomic_rwlock_t;
+#define MY_ATOMIC_MODE_RWLOCKS 1
#ifdef MY_ATOMIC_MODE_DUMMY
/*
@@ -26,6 +26,9 @@ typedef struct {pthread_rwlock_t rw;} my_atomic_rwlock_t;
implementations (another way is to run a UP build on an SMP box).
*/
#warning MY_ATOMIC_MODE_DUMMY and MY_ATOMIC_MODE_RWLOCKS are incompatible
+
+typedef char my_atomic_rwlock_t;
+
#define my_atomic_rwlock_destroy(name)
#define my_atomic_rwlock_init(name)
#define my_atomic_rwlock_rdlock(name)
@@ -33,18 +36,63 @@ typedef struct {pthread_rwlock_t rw;} my_atomic_rwlock_t;
#define my_atomic_rwlock_rdunlock(name)
#define my_atomic_rwlock_wrunlock(name)
#define MY_ATOMIC_MODE "dummy (non-atomic)"
-#else
-#define my_atomic_rwlock_destroy(name) pthread_rwlock_destroy(& (name)->rw)
-#define my_atomic_rwlock_init(name) pthread_rwlock_init(& (name)->rw, 0)
-#define my_atomic_rwlock_rdlock(name) pthread_rwlock_rdlock(& (name)->rw)
-#define my_atomic_rwlock_wrlock(name) pthread_rwlock_wrlock(& (name)->rw)
-#define my_atomic_rwlock_rdunlock(name) pthread_rwlock_unlock(& (name)->rw)
-#define my_atomic_rwlock_wrunlock(name) pthread_rwlock_unlock(& (name)->rw)
-#define MY_ATOMIC_MODE "rwlocks"
+#else /* not MY_ATOMIC_MODE_DUMMY */
+
+typedef struct {pthread_mutex_t rw;} my_atomic_rwlock_t;
+
+#ifndef SAFE_MUTEX
+
+/*
+ we're using read-write lock macros but map them to mutex locks, and they're
+ faster. Still, having semantically rich API we can change the
+ underlying implementation, if necessary.
+*/
+#define my_atomic_rwlock_destroy(name) pthread_mutex_destroy(& (name)->rw)
+#define my_atomic_rwlock_init(name) pthread_mutex_init(& (name)->rw, 0)
+#define my_atomic_rwlock_rdlock(name) pthread_mutex_lock(& (name)->rw)
+#define my_atomic_rwlock_wrlock(name) pthread_mutex_lock(& (name)->rw)
+#define my_atomic_rwlock_rdunlock(name) pthread_mutex_unlock(& (name)->rw)
+#define my_atomic_rwlock_wrunlock(name) pthread_mutex_unlock(& (name)->rw)
+
+#else /* SAFE_MUTEX */
+
+/*
+ SAFE_MUTEX pollutes the compiling name space with macros
+ that alter pthread_mutex_t, pthread_mutex_init, etc.
+ Atomic operations should never use the safe mutex wrappers.
+ Unfortunately, there is no way to have both:
+ - safe mutex macros expanding pthread_mutex_lock to safe_mutex_lock
+ - my_atomic macros expanding to unmodified pthread_mutex_lock
+ inlined in the same compilation unit.
+ So, in case of SAFE_MUTEX, a function call is required.
+ Given that SAFE_MUTEX is a debugging facility,
+ this extra function call is not a performance concern for
+ production builds.
+*/
+C_MODE_START
+extern void plain_pthread_mutex_init(safe_mutex_t *);
+extern void plain_pthread_mutex_destroy(safe_mutex_t *);
+extern void plain_pthread_mutex_lock(safe_mutex_t *);
+extern void plain_pthread_mutex_unlock(safe_mutex_t *);
+C_MODE_END
+
+#define my_atomic_rwlock_destroy(name) plain_pthread_mutex_destroy(&(name)->rw)
+#define my_atomic_rwlock_init(name) plain_pthread_mutex_init(&(name)->rw)
+#define my_atomic_rwlock_rdlock(name) plain_pthread_mutex_lock(&(name)->rw)
+#define my_atomic_rwlock_wrlock(name) plain_pthread_mutex_lock(&(name)->rw)
+#define my_atomic_rwlock_rdunlock(name) plain_pthread_mutex_unlock(&(name)->rw)
+#define my_atomic_rwlock_wrunlock(name) plain_pthread_mutex_unlock(&(name)->rw)
+
+#endif /* SAFE_MUTEX */
+
+#define MY_ATOMIC_MODE "mutex"
+#ifndef MY_ATOMIC_MODE_RWLOCKS
+#define MY_ATOMIC_MODE_RWLOCKS 1
+#endif
#endif
#define make_atomic_add_body(S) int ## S sav; sav= *a; *a+= v; v=sav;
-#define make_atomic_swap_body(S) int ## S sav; sav= *a; *a= v; v=sav;
+#define make_atomic_fas_body(S) int ## S sav; sav= *a; *a= v; v=sav;
#define make_atomic_cas_body(S) if ((ret= (*a == *cmp))) *a= set; else *cmp=*a;
#define make_atomic_load_body(S) ret= *a;
#define make_atomic_store_body(S) *a= v;
diff --git a/include/atomic/solaris.h b/include/atomic/solaris.h
index 4c51253d2d5..fc9f369c707 100644
--- a/include/atomic/solaris.h
+++ b/include/atomic/solaris.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008 MySQL AB
+/* Copyright (C) 2008 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
@@ -13,198 +13,54 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+#ifndef _atomic_h_cleanup_
+#define _atomic_h_cleanup_ "atomic/solaris.h"
+
#include <atomic.h>
#define MY_ATOMIC_MODE "solaris-atomic"
-/*
- * This is defined to indicate we fully define the my_atomic_* (inline)
- * functions here, so there is no need to "make" them in my_atomic.h
- * using make_atomic_* and make_atomic_*_body.
- */
-#define MY_ATOMICS_MADE
-
-STATIC_INLINE int
-my_atomic_cas8(int8 volatile *a, int8 *cmp, int8 set)
-{
- int ret;
- int8 sav;
- sav = (int8) atomic_cas_8((volatile uint8_t *)a, (uint8_t)*cmp,
- (uint8_t)set);
- if (! (ret = (sav == *cmp)))
- *cmp = sav;
- return ret;
-}
-
-STATIC_INLINE int
-my_atomic_cas16(int16 volatile *a, int16 *cmp, int16 set)
-{
- int ret;
- int16 sav;
- sav = (int16) atomic_cas_16((volatile uint16_t *)a, (uint16_t)*cmp,
- (uint16_t)set);
- if (! (ret = (sav == *cmp)))
- *cmp = sav;
- return ret;
-}
-
-STATIC_INLINE int
-my_atomic_cas32(int32 volatile *a, int32 *cmp, int32 set)
-{
- int ret;
- int32 sav;
- sav = (int32) atomic_cas_32((volatile uint32_t *)a, (uint32_t)*cmp,
- (uint32_t)set);
- if (! (ret = (sav == *cmp)))
- *cmp = sav;
- return ret;
-}
-
-STATIC_INLINE int
-my_atomic_casptr(void * volatile *a, void **cmp, void *set)
-{
- int ret;
- void *sav;
- sav = atomic_cas_ptr(a, *cmp, set);
- if (! (ret = (sav == *cmp)))
- *cmp = sav;
- return ret;
-}
+#define uintptr_t void *
+#define atomic_or_ptr_nv(X,Y) (void *)atomic_or_ulong_nv((volatile ulong_t *)X, Y)
-/* ------------------------------------------------------------------------ */
+#define make_atomic_cas_body(S) \
+ uint ## S ## _t sav; \
+ sav = atomic_cas_ ## S( \
+ (volatile uint ## S ## _t *)a, \
+ (uint ## S ## _t)*cmp, \
+ (uint ## S ## _t)set); \
+ if (! (ret= (sav == *cmp))) \
+ *cmp= sav;
-STATIC_INLINE int8
-my_atomic_add8(int8 volatile *a, int8 v)
-{
- int8 nv;
- nv = atomic_add_8_nv((volatile uint8_t *)a, v);
- return (nv - v);
-}
-
-STATIC_INLINE int16
-my_atomic_add16(int16 volatile *a, int16 v)
-{
- int16 nv;
- nv = atomic_add_16_nv((volatile uint16_t *)a, v);
- return (nv - v);
-}
-
-STATIC_INLINE int32
-my_atomic_add32(int32 volatile *a, int32 v)
-{
- int32 nv;
- nv = atomic_add_32_nv((volatile uint32_t *)a, v);
- return (nv - v);
-}
+#define make_atomic_add_body(S) \
+ int ## S nv; /* new value */ \
+ nv= atomic_add_ ## S ## _nv((volatile uint ## S ## _t *)a, v); \
+ v= nv - v
/* ------------------------------------------------------------------------ */
#ifdef MY_ATOMIC_MODE_DUMMY
-STATIC_INLINE int8
-my_atomic_load8(int8 volatile *a) { return (*a); }
-
-STATIC_INLINE int16
-my_atomic_load16(int16 volatile *a) { return (*a); }
-
-STATIC_INLINE int32
-my_atomic_load32(int32 volatile *a) { return (*a); }
-
-STATIC_INLINE void *
-my_atomic_loadptr(void * volatile *a) { return (*a); }
-
-/* ------------------------------------------------------------------------ */
-
-STATIC_INLINE void
-my_atomic_store8(int8 volatile *a, int8 v) { *a = v; }
+#define make_atomic_load_body(S) ret= *a
+#define make_atomic_store_body(S) *a= v
-STATIC_INLINE void
-my_atomic_store16(int16 volatile *a, int16 v) { *a = v; }
-
-STATIC_INLINE void
-my_atomic_store32(int32 volatile *a, int32 v) { *a = v; }
+#else /* MY_ATOMIC_MODE_DUMMY */
-STATIC_INLINE void
-my_atomic_storeptr(void * volatile *a, void *v) { *a = v; }
+#define make_atomic_load_body(S) \
+ ret= atomic_or_ ## S ## _nv((volatile uint ## S ## _t *)a, 0)
-/* ------------------------------------------------------------------------ */
+#define make_atomic_store_body(S) \
+ (void) atomic_swap_ ## S((volatile uint ## S ## _t *)a, (uint ## S ## _t)v)
-#else /* MY_ATOMIC_MODE_DUMMY */
+#endif
-STATIC_INLINE int8
-my_atomic_load8(int8 volatile *a)
-{
- return ((int8) atomic_or_8_nv((volatile uint8_t *)a, 0));
-}
-
-STATIC_INLINE int16
-my_atomic_load16(int16 volatile *a)
-{
- return ((int16) atomic_or_16_nv((volatile uint16_t *)a, 0));
-}
-
-STATIC_INLINE int32
-my_atomic_load32(int32 volatile *a)
-{
- return ((int32) atomic_or_32_nv((volatile uint32_t *)a, 0));
-}
-
-STATIC_INLINE void *
-my_atomic_loadptr(void * volatile *a)
-{
- return ((void *) atomic_or_ulong_nv((volatile ulong_t *)a, 0));
-}
+#define make_atomic_fas_body(S) \
+ v= atomic_swap_ ## S((volatile uint ## S ## _t *)a, (uint ## S ## _t)v)
-/* ------------------------------------------------------------------------ */
+#else /* cleanup */
-STATIC_INLINE void
-my_atomic_store8(int8 volatile *a, int8 v)
-{
- (void) atomic_swap_8((volatile uint8_t *)a, (uint8_t)v);
-}
-
-STATIC_INLINE void
-my_atomic_store16(int16 volatile *a, int16 v)
-{
- (void) atomic_swap_16((volatile uint16_t *)a, (uint16_t)v);
-}
-
-STATIC_INLINE void
-my_atomic_store32(int32 volatile *a, int32 v)
-{
- (void) atomic_swap_32((volatile uint32_t *)a, (uint32_t)v);
-}
-
-STATIC_INLINE void
-my_atomic_storeptr(void * volatile *a, void *v)
-{
- (void) atomic_swap_ptr(a, v);
-}
+#undef uintptr_t
+#undef atomic_or_ptr_nv
#endif
-/* ------------------------------------------------------------------------ */
-
-STATIC_INLINE int8
-my_atomic_swap8(int8 volatile *a, int8 v)
-{
- return ((int8) atomic_swap_8((volatile uint8_t *)a, (uint8_t)v));
-}
-
-STATIC_INLINE int16
-my_atomic_swap16(int16 volatile *a, int16 v)
-{
- return ((int16) atomic_swap_16((volatile uint16_t *)a, (uint16_t)v));
-}
-
-STATIC_INLINE int32
-my_atomic_swap32(int32 volatile *a, int32 v)
-{
- return ((int32) atomic_swap_32((volatile uint32_t *)a, (uint32_t)v));
-}
-
-STATIC_INLINE void *
-my_atomic_swapptr(void * volatile *a, void *v)
-{
- return (atomic_swap_ptr(a, v));
-}
diff --git a/include/atomic/x86-gcc.h b/include/atomic/x86-gcc.h
index c3029f9c1b4..61b94a48568 100644
--- a/include/atomic/x86-gcc.h
+++ b/include/atomic/x86-gcc.h
@@ -22,10 +22,24 @@
architectures support double-word (128-bit) cas.
*/
-#ifdef MY_ATOMIC_NO_XADD
-#define MY_ATOMIC_MODE "gcc-x86" LOCK "-no-xadd"
+/*
+ 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"
+# else
+# define MY_ATOMIC_MODE "gcc-amd64" LOCK_prefix
+# endif
#else
-#define MY_ATOMIC_MODE "gcc-x86" LOCK
+# ifdef MY_ATOMIC_NO_XADD
+# define MY_ATOMIC_MODE "gcc-x86" LOCK_prefix "-no-xadd"
+# else
+# define MY_ATOMIC_MODE "gcc-x86" LOCK_prefix
+# endif
#endif
/* fix -ansi errors while maintaining readability */
@@ -34,29 +48,79 @@
#endif
#ifndef MY_ATOMIC_NO_XADD
-#define make_atomic_add_body(S) \
- asm volatile (LOCK "; 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_swap_body(S) \
- asm volatile ("; xchg %0, %1;" : "+q" (v) , "+m" (*a))
-#define make_atomic_cas_body(S) \
- asm volatile (LOCK "; cmpxchg %3, %0; setz %2;" \
+
+#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 here anyway to force memory barriers
+ 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) \
+ 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_load_body(S) \
- ret=0; \
- asm volatile (LOCK "; cmpxchg %2, %0" \
- : "+m" (*a), "+a" (ret): "r" (ret))
-#define make_atomic_store_body(S) \
- asm volatile ("; xchg %0, %1;" : "+m" (*a) : "r" (v))
+#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), "=c" (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/atomic/x86-msvc.h b/include/atomic/x86-msvc.h
deleted file mode 100644
index c4885bb8451..00000000000
--- a/include/atomic/x86-msvc.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/* Copyright (C) 2006 MySQL AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; version 2 of the License.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-/*
- XXX 64-bit atomic operations can be implemented using
- cmpxchg8b, if necessary
-*/
-
-// Would it be better to use intrinsics ?
-// (InterlockedCompareExchange, InterlockedCompareExchange16
-// InterlockedExchangeAdd, InterlockedExchange)
-
-#ifndef _atomic_h_cleanup_
-#define _atomic_h_cleanup_ "atomic/x86-msvc.h"
-
-#define MY_ATOMIC_MODE "msvc-x86" LOCK
-
-#define make_atomic_add_body(S) \
- _asm { \
- _asm mov reg_ ## S, v \
- _asm LOCK xadd *a, reg_ ## S \
- _asm movzx v, reg_ ## S \
- }
-#define make_atomic_cas_body(S) \
- _asm { \
- _asm mov areg_ ## S, *cmp \
- _asm mov reg2_ ## S, set \
- _asm LOCK cmpxchg *a, reg2_ ## S \
- _asm mov *cmp, areg_ ## S \
- _asm setz al \
- _asm movzx ret, al \
- }
-#define make_atomic_swap_body(S) \
- _asm { \
- _asm mov reg_ ## S, v \
- _asm xchg *a, reg_ ## S \
- _asm mov v, reg_ ## S \
- }
-
-#ifdef MY_ATOMIC_MODE_DUMMY
-#define make_atomic_load_body(S) ret=*a
-#define make_atomic_store_body(S) *a=v
-#else
-/*
- Actually 32-bit reads/writes are always atomic on x86
- But we add LOCK here anyway to force memory barriers
-*/
-#define make_atomic_load_body(S) \
- _asm { \
- _asm mov areg_ ## S, 0 \
- _asm mov reg2_ ## S, areg_ ## S \
- _asm LOCK cmpxchg *a, reg2_ ## S \
- _asm mov ret, areg_ ## S \
- }
-#define make_atomic_store_body(S) \
- _asm { \
- _asm mov reg_ ## S, v \
- _asm xchg *a, reg_ ## S \
- }
-#endif
-
-#define reg_8 al
-#define reg_16 ax
-#define reg_32 eax
-#define areg_8 al
-#define areg_16 ax
-#define areg_32 eax
-#define reg2_8 bl
-#define reg2_16 bx
-#define reg2_32 ebx
-
-#else /* cleanup */
-
-#undef reg_8
-#undef reg_16
-#undef reg_32
-#undef areg_8
-#undef areg_16
-#undef areg_32
-#undef reg2_8
-#undef reg2_16
-#undef reg2_32
-#endif
-
diff --git a/include/config-netware.h b/include/config-netware.h
index 4b9e1437170..a4465ea177a 100644
--- a/include/config-netware.h
+++ b/include/config-netware.h
@@ -73,7 +73,6 @@ extern "C" {
#undef HAVE_FINITE
#undef HAVE_GETPWNAM
#undef HAVE_GETPWUID
-#undef HAVE_PTHREAD_SETSCHEDPARAM
#undef HAVE_READLINK
#undef HAVE_STPCPY
/* changes end */
@@ -101,7 +100,7 @@ extern "C" {
#define USE_OLD_FUNCTIONS 1
/* no case sensitivity */
-#define FN_NO_CASE_SENCE 1
+#define FN_NO_CASE_SENSE 1
/* the thread alarm is not used */
#define DONT_USE_THR_ALARM 1
diff --git a/include/config-win.h b/include/config-win.h
index 17a0bd4bcac..269ec0e925a 100644
--- a/include/config-win.h
+++ b/include/config-win.h
@@ -20,6 +20,13 @@
#define BIG_TABLES
+/*
+ Minimal version of Windows we should be able to run on.
+ Currently Windows XP.
+*/
+#define _WIN32_WINNT 0x0501
+
+
#if defined(_MSC_VER) && _MSC_VER >= 1400
/* Avoid endless warnings about sprintf() etc. being unsafe. */
#define _CRT_SECURE_NO_DEPRECATE 1
@@ -27,6 +34,7 @@
#include <sys/locking.h>
#include <winsock2.h>
+#include <Ws2tcpip.h>
#include <fcntl.h>
#include <io.h>
#include <malloc.h>
@@ -88,6 +96,12 @@
#define S_IROTH S_IREAD /* for my_lib */
+/* Winsock2 constant (Vista SDK and later)*/
+#define IPPROTO_IPV6 41
+#ifndef IPV6_V6ONLY
+#define IPV6_V6ONLY 27
+#endif
+
#ifdef __BORLANDC__
#define FILE_BINARY O_BINARY /* my_fopen in binary mode */
#define O_TEMPORARY 0
@@ -145,10 +159,21 @@ typedef __int64 os_off_t;
#ifdef _WIN64
typedef UINT_PTR rf_SetTimer;
#else
+typedef uint rf_SetTimer;
+#endif
+
#ifndef HAVE_SIZE_T
-typedef unsigned int size_t;
+#ifndef _SIZE_T_DEFINED
+typedef SIZE_T size_t;
+#define _SIZE_T_DEFINED
+#endif
+#endif
+
+#ifndef HAVE_SSIZE_T
+#ifndef _SSIZE_T_DEFINED
+typedef SSIZE_T ssize_t;
+#define _SSIZE_T_DEFINED
#endif
-typedef uint rf_SetTimer;
#endif
#define Socket_defined
@@ -293,10 +318,11 @@ inline ulonglong double2ulonglong(double d)
#define strcasecmp stricmp
#define strncasecmp strnicmp
-#ifdef NOT_USED
-#define HAVE_SNPRINTF /* Gave link error */
-#define _snprintf snprintf
-#endif
+#define HAVE_SNPRINTF 1
+#define snprintf _snprintf
+
+#define HAVE_SETENV 1
+#define setenv(VAR,VAL,X) _putenv_s(VAR,VAL)
#ifdef _MSC_VER
#define HAVE_LDIV /* The optimizer breaks in zortech for ldiv */
@@ -335,7 +361,7 @@ inline ulonglong double2ulonglong(double d)
#define FN_ROOTDIR "\\"
#define FN_DEVCHAR ':'
#define FN_NETWORK_DRIVES /* Uses \\ to indicate network drives */
-#define FN_NO_CASE_SENCE /* Files are not case-sensitive */
+#define FN_NO_CASE_SENSE /* Files are not case-sensitive */
#define OS_FILE_LIMIT UINT_MAX /* No limit*/
#define DO_NOT_REMOVE_THREAD_WRAPPERS
@@ -406,6 +432,9 @@ inline ulonglong double2ulonglong(double d)
#define HAVE_CHARSET_ucs2 1
#define HAVE_CHARSET_ujis 1
#define HAVE_CHARSET_utf8 1
+#define HAVE_CHARSET_utf8mb4 1
+#define HAVE_CHARSET_utf16 1
+#define HAVE_CHARSET_utf32 1
#define HAVE_UCA_COLLATIONS 1
#define HAVE_BOOL 1
diff --git a/include/ft_global.h b/include/ft_global.h
index 752371d6bc6..ad56bce678b 100644
--- a/include/ft_global.h
+++ b/include/ft_global.h
@@ -28,6 +28,8 @@ extern "C" {
#define HA_FT_MAXBYTELEN 254
#define HA_FT_MAXCHARLEN (HA_FT_MAXBYTELEN/3)
+#define DEFAULT_FTB_SYNTAX "+ -><()~*:\"\"&|"
+
typedef struct st_ft_info FT_INFO;
struct _ft_vft
{
@@ -51,7 +53,7 @@ extern const char *ft_precompiled_stopwords[];
extern ulong ft_min_word_len;
extern ulong ft_max_word_len;
extern ulong ft_query_expansion_limit;
-extern char ft_boolean_syntax[15];
+extern const char *ft_boolean_syntax;
extern struct st_mysql_ftparser ft_default_parser;
int ft_init_stopwords(void);
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/heap.h b/include/heap.h
index 4a1c7d419ed..27aefb5beda 100644
--- a/include/heap.h
+++ b/include/heap.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000,2004 MySQL AB
+/* Copyright (C) 2000-2004 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
@@ -148,7 +148,7 @@ typedef struct st_heap_share
char * name; /* Name of "memory-file" */
#ifdef THREAD
THR_LOCK lock;
- pthread_mutex_t intern_lock; /* Locking for use with _locking */
+ mysql_mutex_t intern_lock; /* Locking for use with _locking */
#endif
my_bool delete_on_close;
LIST open_list;
diff --git a/include/keycache.h b/include/keycache.h
index a6005bae878..baec7f40dcd 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
@@ -67,10 +67,10 @@ typedef struct st_key_cache
HASH_LINK *free_hash_list; /* list of free hash links */
BLOCK_LINK *free_block_list; /* list of free blocks */
BLOCK_LINK *block_root; /* memory for block links */
- uchar HUGE_PTR *block_mem; /* memory for block buffers */
+ 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
@@ -87,10 +87,10 @@ typedef struct st_key_cache
initializing the key cache.
*/
- ulonglong param_buff_size; /* size the memory allocated for the cache */
- ulong param_block_size; /* size of the blocks in the key cache */
- ulong param_division_limit; /* min. percentage of warm blocks */
- ulong param_age_threshold; /* determines when hot block is downgraded */
+ ulonglong param_buff_size; /* size the memory allocated for the cache */
+ ulonglong param_block_size; /* size of the blocks in the key cache */
+ ulonglong param_division_limit; /* min. percentage of warm blocks */
+ ulonglong param_age_threshold; /* determines when hot block is downgraded */
/* Statistics variables. These are reset in reset_key_cache_counters(). */
ulong global_blocks_changed; /* number of currently dirty blocks */
diff --git a/include/lf.h b/include/lf.h
new file mode 100644
index 00000000000..7e8f05f4ada
--- /dev/null
+++ b/include/lf.h
@@ -0,0 +1,268 @@
+/* Copyright (C) 2007-2008 MySQL AB, 2008-2009 Sun Microsystems, Inc.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef _lf_h
+#define _lf_h
+
+#include <my_atomic.h>
+
+C_MODE_START
+
+/*
+ Helpers to define both func() and _func(), where
+ func() is a _func() protected by my_atomic_rwlock_wrlock()
+*/
+
+#define lock_wrap(f, t, proto_args, args, lock) \
+t _ ## f proto_args; \
+static inline t f proto_args \
+{ \
+ t ret; \
+ my_atomic_rwlock_wrlock(lock); \
+ ret= _ ## f args; \
+ my_atomic_rwlock_wrunlock(lock); \
+ return ret; \
+}
+
+#define lock_wrap_void(f, proto_args, args, lock) \
+void _ ## f proto_args; \
+static inline void f proto_args \
+{ \
+ my_atomic_rwlock_wrlock(lock); \
+ _ ## f args; \
+ my_atomic_rwlock_wrunlock(lock); \
+}
+
+#define nolock_wrap(f, t, proto_args, args) \
+t _ ## f proto_args; \
+static inline t f proto_args \
+{ \
+ return _ ## f args; \
+}
+
+#define nolock_wrap_void(f, proto_args, args) \
+void _ ## f proto_args; \
+static inline void f proto_args \
+{ \
+ _ ## f args; \
+}
+
+/*
+ wait-free dynamic array, see lf_dynarray.c
+
+ 4 levels of 256 elements each mean 4311810304 elements in an array - it
+ should be enough for a while
+*/
+#define LF_DYNARRAY_LEVEL_LENGTH 256
+#define LF_DYNARRAY_LEVELS 4
+
+typedef struct {
+ void * volatile level[LF_DYNARRAY_LEVELS];
+ uint size_of_element;
+ my_atomic_rwlock_t lock;
+} LF_DYNARRAY;
+
+typedef int (*lf_dynarray_func)(void *, void *);
+
+void lf_dynarray_init(LF_DYNARRAY *array, uint element_size);
+void lf_dynarray_destroy(LF_DYNARRAY *array);
+
+nolock_wrap(lf_dynarray_value, void *,
+ (LF_DYNARRAY *array, uint idx),
+ (array, idx))
+lock_wrap(lf_dynarray_lvalue, void *,
+ (LF_DYNARRAY *array, uint idx),
+ (array, idx),
+ &array->lock)
+nolock_wrap(lf_dynarray_iterate, int,
+ (LF_DYNARRAY *array, lf_dynarray_func func, void *arg),
+ (array, func, arg))
+
+/*
+ pin manager for memory allocator, lf_alloc-pin.c
+*/
+
+#define LF_PINBOX_PINS 4
+#define LF_PURGATORY_SIZE 10
+
+typedef void lf_pinbox_free_func(void *, void *, void*);
+
+typedef struct {
+ LF_DYNARRAY pinarray;
+ lf_pinbox_free_func *free_func;
+ void *free_func_arg;
+ uint free_ptr_offset;
+ uint32 volatile pinstack_top_ver; /* this is a versioned pointer */
+ uint32 volatile pins_in_array; /* number of elements in array */
+} LF_PINBOX;
+
+typedef struct {
+ void * volatile pin[LF_PINBOX_PINS];
+ LF_PINBOX *pinbox;
+ void **stack_ends_here;
+ void *purgatory;
+ uint32 purgatory_count;
+ uint32 volatile link;
+/* we want sizeof(LF_PINS) to be 64 to avoid false sharing */
+#if SIZEOF_INT*2+SIZEOF_CHARP*(LF_PINBOX_PINS+3) != 64
+ char pad[64-sizeof(uint32)*2-sizeof(void*)*(LF_PINBOX_PINS+3)];
+#endif
+} LF_PINS;
+
+/*
+ shortcut macros to do an atomic_wrlock on a structure that uses pins
+ (e.g. lf_hash).
+*/
+#define lf_rwlock_by_pins(PINS) \
+ my_atomic_rwlock_wrlock(&(PINS)->pinbox->pinarray.lock)
+#define lf_rwunlock_by_pins(PINS) \
+ my_atomic_rwlock_wrunlock(&(PINS)->pinbox->pinarray.lock)
+
+/*
+ compile-time assert, to require "no less than N" pins
+ it's enough if it'll fail on at least one compiler, so
+ we'll enable it on GCC only, which supports zero-length arrays.
+*/
+#if defined(__GNUC__) && defined(MY_LF_EXTRA_DEBUG)
+#define LF_REQUIRE_PINS(N) \
+ static const char require_pins[LF_PINBOX_PINS-N] \
+ __attribute__ ((unused)); \
+ static const int LF_NUM_PINS_IN_THIS_FILE= N;
+#define _lf_pin(PINS, PIN, ADDR) \
+ ( \
+ assert(PIN < LF_NUM_PINS_IN_THIS_FILE), \
+ my_atomic_storeptr(&(PINS)->pin[PIN], (ADDR)) \
+ )
+#else
+#define LF_REQUIRE_PINS(N)
+#define _lf_pin(PINS, PIN, ADDR) my_atomic_storeptr(&(PINS)->pin[PIN], (ADDR))
+#endif
+
+#define _lf_unpin(PINS, PIN) _lf_pin(PINS, PIN, NULL)
+#define lf_pin(PINS, PIN, ADDR) \
+ do { \
+ lf_rwlock_by_pins(PINS); \
+ _lf_pin(PINS, PIN, ADDR); \
+ lf_rwunlock_by_pins(PINS); \
+ } while (0)
+#define lf_unpin(PINS, PIN) lf_pin(PINS, PIN, NULL)
+#define _lf_assert_pin(PINS, PIN) assert((PINS)->pin[PIN] != 0)
+#define _lf_assert_unpin(PINS, PIN) assert((PINS)->pin[PIN] == 0)
+
+void lf_pinbox_init(LF_PINBOX *pinbox, uint free_ptr_offset,
+ lf_pinbox_free_func *free_func, void * free_func_arg);
+void lf_pinbox_destroy(LF_PINBOX *pinbox);
+
+lock_wrap(lf_pinbox_get_pins, LF_PINS *,
+ (LF_PINBOX *pinbox),
+ (pinbox),
+ &pinbox->pinarray.lock)
+lock_wrap_void(lf_pinbox_put_pins,
+ (LF_PINS *pins),
+ (pins),
+ &pins->pinbox->pinarray.lock)
+lock_wrap_void(lf_pinbox_free,
+ (LF_PINS *pins, void *addr),
+ (pins, addr),
+ &pins->pinbox->pinarray.lock)
+
+/*
+ memory allocator, lf_alloc-pin.c
+*/
+
+typedef struct st_lf_allocator {
+ LF_PINBOX pinbox;
+ uchar * volatile top;
+ uint element_size;
+ uint32 volatile mallocs;
+ void (*constructor)(uchar *); /* called, when an object is malloc()'ed */
+ void (*destructor)(uchar *); /* called, when an object is free()'d */
+} LF_ALLOCATOR;
+
+void lf_alloc_init(LF_ALLOCATOR *allocator, uint size, uint free_ptr_offset);
+void lf_alloc_destroy(LF_ALLOCATOR *allocator);
+uint lf_alloc_pool_count(LF_ALLOCATOR *allocator);
+/*
+ shortcut macros to access underlying pinbox functions from an LF_ALLOCATOR
+ see _lf_pinbox_get_pins() and _lf_pinbox_put_pins()
+*/
+#define _lf_alloc_free(PINS, PTR) _lf_pinbox_free((PINS), (PTR))
+#define lf_alloc_free(PINS, PTR) lf_pinbox_free((PINS), (PTR))
+#define _lf_alloc_get_pins(A) _lf_pinbox_get_pins(&(A)->pinbox)
+#define lf_alloc_get_pins(A) lf_pinbox_get_pins(&(A)->pinbox)
+#define _lf_alloc_put_pins(PINS) _lf_pinbox_put_pins(PINS)
+#define lf_alloc_put_pins(PINS) lf_pinbox_put_pins(PINS)
+#define lf_alloc_direct_free(ALLOC, ADDR) my_free((uchar*)(ADDR), MYF(0))
+
+lock_wrap(lf_alloc_new, void *,
+ (LF_PINS *pins),
+ (pins),
+ &pins->pinbox->pinarray.lock)
+
+C_MODE_END
+
+/*
+ extendible hash, lf_hash.c
+*/
+#include <hash.h>
+
+C_MODE_START
+
+#define LF_HASH_UNIQUE 1
+
+/* lf_hash overhead per element (that is, sizeof(LF_SLIST) */
+extern const int LF_HASH_OVERHEAD;
+
+typedef struct {
+ LF_DYNARRAY array; /* hash itself */
+ LF_ALLOCATOR alloc; /* allocator for elements */
+ my_hash_get_key get_key; /* see HASH */
+ CHARSET_INFO *charset; /* see HASH */
+ uint key_offset, key_length; /* see HASH */
+ uint element_size; /* size of memcpy'ed area on insert */
+ uint flags; /* LF_HASH_UNIQUE, etc */
+ int32 volatile size; /* size of array */
+ int32 volatile count; /* number of elements in the hash */
+} LF_HASH;
+
+void lf_hash_init(LF_HASH *hash, uint element_size, uint flags,
+ uint key_offset, uint key_length, my_hash_get_key get_key,
+ CHARSET_INFO *charset);
+void lf_hash_destroy(LF_HASH *hash);
+int lf_hash_insert(LF_HASH *hash, LF_PINS *pins, const void *data);
+void *lf_hash_search(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen);
+int lf_hash_delete(LF_HASH *hash, LF_PINS *pins, const void *key, uint keylen);
+/*
+ shortcut macros to access underlying pinbox functions from an LF_HASH
+ see _lf_pinbox_get_pins() and _lf_pinbox_put_pins()
+*/
+#define _lf_hash_get_pins(HASH) _lf_alloc_get_pins(&(HASH)->alloc)
+#define lf_hash_get_pins(HASH) lf_alloc_get_pins(&(HASH)->alloc)
+#define _lf_hash_put_pins(PINS) _lf_pinbox_put_pins(PINS)
+#define lf_hash_put_pins(PINS) lf_pinbox_put_pins(PINS)
+#define lf_hash_search_unpin(PINS) lf_unpin((PINS), 2)
+/*
+ cleanup
+*/
+
+#undef lock_wrap_void
+#undef lock_wrap
+#undef nolock_wrap_void
+#undef nolock_wrap
+
+C_MODE_END
+
+#endif
+
diff --git a/include/m_ctype.h b/include/m_ctype.h
index 700f373d677..7c01ebe7e5a 100644
--- a/include/m_ctype.h
+++ b/include/m_ctype.h
@@ -38,11 +38,29 @@ extern "C" {
#define my_wc_t ulong
+#define MY_CS_REPLACEMENT_CHARACTER 0xFFFD
+
+/*
+ On i386 we store Unicode->CS conversion tables for
+ some character sets using Big-endian order,
+ to copy two bytes at onces.
+ This gives some performance improvement.
+*/
+#ifdef __i386__
+#define MB2(x) (((x) >> 8) + (((x) & 0xFF) << 8))
+#define MY_PUT_MB2(s, code) { *((uint16*)(s))= (code); }
+#else
+#define MB2(x) (x)
+#define MY_PUT_MB2(s, code) { (s)[0]= code >> 8; (s)[1]= code & 0xFF; }
+#endif
+
+
+
typedef struct unicase_info_st
{
- uint16 toupper;
- uint16 tolower;
- uint16 sort;
+ uint32 toupper;
+ uint32 tolower;
+ uint32 sort;
} MY_UNICASE_INFO;
@@ -81,13 +99,14 @@ extern MY_UNI_CTYPE my_uni_ctype[256];
#define MY_CS_BINSORT 16 /* if binary sort order */
#define MY_CS_PRIMARY 32 /* if primary collation */
#define MY_CS_STRNXFRM 64 /* if strnxfrm is used for sort */
-#define MY_CS_UNICODE 128 /* is a charset is full unicode */
+#define MY_CS_UNICODE 128 /* is a charset is BMP Unicode */
#define MY_CS_READY 256 /* if a charset is initialized */
#define MY_CS_AVAILABLE 512 /* If either compiled-in or loaded*/
#define MY_CS_CSSORT 1024 /* if case sensitive sort order */
#define MY_CS_HIDDEN 2048 /* don't display in SHOW */
#define MY_CS_PUREASCII 4096 /* if a charset is pure ascii */
#define MY_CS_NONASCII 8192 /* if not ASCII-compatible */
+#define MY_CS_UNICODE_SUPPLEMENT 16384 /* Non-BMP Unicode characters */
#define MY_CHARSET_UNDEFINED 0
/* Character repertoire flags */
@@ -95,7 +114,6 @@ extern MY_UNI_CTYPE my_uni_ctype[256];
#define MY_REPERTOIRE_EXTENDED 2 /* Extended characters: U+0080..U+FFFF */
#define MY_REPERTOIRE_UNICODE30 3 /* ASCII | EXTENDED: U+0000..U+FFFF */
-
typedef struct my_uni_idx_st
{
uint16 from;
@@ -287,10 +305,14 @@ typedef struct charset_info_st
extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_bin;
+extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_latin1;
+extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_filename;
+
extern CHARSET_INFO my_charset_big5_chinese_ci;
extern CHARSET_INFO my_charset_big5_bin;
extern CHARSET_INFO my_charset_cp932_japanese_ci;
extern CHARSET_INFO my_charset_cp932_bin;
+extern CHARSET_INFO my_charset_cp1250_czech_ci;
extern CHARSET_INFO my_charset_eucjpms_japanese_ci;
extern CHARSET_INFO my_charset_eucjpms_bin;
extern CHARSET_INFO my_charset_euckr_korean_ci;
@@ -299,7 +321,6 @@ extern CHARSET_INFO my_charset_gb2312_chinese_ci;
extern CHARSET_INFO my_charset_gb2312_bin;
extern CHARSET_INFO my_charset_gbk_chinese_ci;
extern CHARSET_INFO my_charset_gbk_bin;
-extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_latin1;
extern CHARSET_INFO my_charset_latin1_german2_ci;
extern CHARSET_INFO my_charset_latin1_bin;
extern CHARSET_INFO my_charset_latin2_czech_ci;
@@ -312,11 +333,22 @@ extern CHARSET_INFO my_charset_ucs2_bin;
extern CHARSET_INFO my_charset_ucs2_unicode_ci;
extern CHARSET_INFO my_charset_ujis_japanese_ci;
extern CHARSET_INFO my_charset_ujis_bin;
+extern CHARSET_INFO my_charset_utf16_bin;
+extern CHARSET_INFO my_charset_utf16_general_ci;
+extern CHARSET_INFO my_charset_utf16_unicode_ci;
+extern CHARSET_INFO my_charset_utf32_bin;
+extern CHARSET_INFO my_charset_utf32_general_ci;
+extern CHARSET_INFO my_charset_utf32_unicode_ci;
+
extern CHARSET_INFO my_charset_utf8_general_ci;
extern CHARSET_INFO my_charset_utf8_unicode_ci;
extern CHARSET_INFO my_charset_utf8_bin;
-extern CHARSET_INFO my_charset_cp1250_czech_ci;
-extern MYSQL_PLUGIN_IMPORT CHARSET_INFO my_charset_filename;
+extern CHARSET_INFO my_charset_utf8mb4_bin;
+extern CHARSET_INFO my_charset_utf8mb4_general_ci;
+extern CHARSET_INFO my_charset_utf8mb4_unicode_ci;
+#define MY_UTF8MB3 "utf8"
+#define MY_UTF8MB4 "utf8mb4"
+
/* declarations for simple charsets */
extern size_t my_strnxfrm_simple(CHARSET_INFO *, uchar *, size_t,
@@ -413,6 +445,19 @@ my_bool my_like_range_ucs2(CHARSET_INFO *cs,
char *min_str, char *max_str,
size_t *min_length, size_t *max_length);
+my_bool my_like_range_utf16(CHARSET_INFO *cs,
+ const char *ptr, size_t ptr_length,
+ pbool escape, pbool w_one, pbool w_many,
+ size_t res_length,
+ char *min_str, char *max_str,
+ size_t *min_length, size_t *max_length);
+
+my_bool my_like_range_utf32(CHARSET_INFO *cs,
+ const char *ptr, size_t ptr_length,
+ pbool escape, pbool w_one, pbool w_many,
+ size_t res_length,
+ char *min_str, char *max_str,
+ size_t *min_length, size_t *max_length);
int my_wildcmp_8bit(CHARSET_INFO *,
const char *str,const char *str_end,
@@ -439,6 +484,14 @@ extern size_t my_caseup_mb(CHARSET_INFO *, char *src, size_t srclen,
char *dst, size_t dstlen);
extern size_t my_casedn_mb(CHARSET_INFO *, char *src, size_t srclen,
char *dst, size_t dstlen);
+extern size_t my_caseup_mb_varlen(CHARSET_INFO *, char *src, size_t srclen,
+ char *dst, size_t dstlen);
+extern size_t my_casedn_mb_varlen(CHARSET_INFO *, char *src, size_t srclen,
+ char *dst, size_t dstlen);
+extern size_t my_caseup_ujis(CHARSET_INFO *, char *src, size_t srclen,
+ char *dst, size_t dstlen);
+extern size_t my_casedn_ujis(CHARSET_INFO *, char *src, size_t srclen,
+ char *dst, size_t dstlen);
extern int my_strcasecmp_mb(CHARSET_INFO * cs,const char *, const char *);
int my_wildcmp_mb(CHARSET_INFO *,
@@ -455,6 +508,31 @@ uint my_instr_mb(struct charset_info_st *,
const char *s, size_t s_length,
my_match_t *match, uint nmatch);
+int my_strnncoll_mb_bin(CHARSET_INFO * cs,
+ const uchar *s, size_t slen,
+ const uchar *t, size_t tlen,
+ my_bool t_is_prefix);
+
+int my_strnncollsp_mb_bin(CHARSET_INFO *cs,
+ const uchar *a, size_t a_length,
+ const uchar *b, size_t b_length,
+ my_bool diff_if_only_endspace_difference);
+
+int my_wildcmp_mb_bin(CHARSET_INFO *cs,
+ const char *str,const char *str_end,
+ const char *wildstr,const char *wildend,
+ int escape, int w_one, int w_many);
+
+int my_strcasecmp_mb_bin(CHARSET_INFO * cs __attribute__((unused)),
+ const char *s, const char *t);
+
+void my_hash_sort_mb_bin(CHARSET_INFO *cs __attribute__((unused)),
+ const uchar *key, size_t len,ulong *nr1, ulong *nr2);
+
+size_t my_strnxfrm_unicode(CHARSET_INFO *,
+ uchar *dst, size_t dstlen,
+ const uchar *src, size_t srclen);
+
int my_wildcmp_unicode(CHARSET_INFO *cs,
const char *str, const char *str_end,
const char *wildstr, const char *wildend,
diff --git a/include/m_string.h b/include/m_string.h
index fade3171da8..a118144d310 100644
--- a/include/m_string.h
+++ b/include/m_string.h
@@ -92,9 +92,6 @@ extern char *stpcpy(char *, const char *); /* For AIX with gcc 2.95.3 */
extern char NEAR _dig_vec_upper[];
extern char NEAR _dig_vec_lower[];
-/* Defined in strtod.c */
-extern const double log_10[309];
-
#ifndef strmov
#define strmov_overlapp(A,B) strmov(A,B)
#define strmake_overlapp(A,B,C) strmake(A,B,C)
@@ -196,8 +193,42 @@ extern char *strstr(const char *, const char *);
extern int is_prefix(const char *, const char *);
/* Conversion routines */
+typedef enum {
+ MY_GCVT_ARG_FLOAT,
+ MY_GCVT_ARG_DOUBLE
+} my_gcvt_arg_type;
+
double my_strtod(const char *str, char **end, int *error);
double my_atof(const char *nptr);
+size_t my_fcvt(double x, int precision, char *to, my_bool *error);
+size_t my_gcvt(double x, my_gcvt_arg_type type, int width, char *to,
+ my_bool *error);
+
+#define NOT_FIXED_DEC 31
+
+/*
+ The longest string my_fcvt can return is 311 + "precision" bytes.
+ Here we assume that we never cal my_fcvt() with precision >= NOT_FIXED_DEC
+ (+ 1 byte for the terminating '\0').
+*/
+#define FLOATING_POINT_BUFFER (311 + NOT_FIXED_DEC)
+
+/*
+ We want to use the 'e' format in some cases even if we have enough space
+ for the 'f' one just to mimic sprintf("%.15g") behavior for large integers,
+ and to improve it for numbers < 10^(-4).
+ That is, for |x| < 1 we require |x| >= 10^(-15), and for |x| > 1 we require
+ it to be integer and be <= 10^DBL_DIG for the 'f' format to be used.
+ We don't lose precision, but make cases like "1e200" or "0.00001" look nicer.
+*/
+#define MAX_DECPT_FOR_F_FORMAT DBL_DIG
+
+/*
+ The maximum possible field width for my_gcvt() conversion.
+ (DBL_DIG + 2) significant digits + sign + "." + ("e-NNN" or
+ MAX_DECPT_FOR_F_FORMAT zeros for cases when |x|<1 and the 'f' format is used).
+*/
+#define MY_GCVT_MAX_FIELD_WIDTH (DBL_DIG + 4 + max(5, MAX_DECPT_FOR_F_FORMAT)) \
extern char *llstr(longlong value,char *buff);
extern char *ullstr(longlong value,char *buff);
@@ -212,7 +243,7 @@ extern char *str2int(const char *src,int radix,long lower,long upper,
long *val);
longlong my_strtoll10(const char *nptr, char **endptr, int *error);
#if SIZEOF_LONG == SIZEOF_LONG_LONG
-#define longlong2str(A,B,C) int2str((A),(B),(C),1)
+#define ll2str(A,B,C,D) int2str((A),(B),(C),(D))
#define longlong10_to_str(A,B,C) int10_to_str((A),(B),(C))
#undef strtoll
#define strtoll(A,B,C) strtol((A),(B),(C))
@@ -225,7 +256,7 @@ longlong my_strtoll10(const char *nptr, char **endptr, int *error);
#endif
#else
#ifdef HAVE_LONG_LONG
-extern char *longlong2str(longlong val,char *dst,int radix);
+extern char *ll2str(longlong val,char *dst,int radix, int upcase);
extern char *longlong10_to_str(longlong val,char *dst,int radix);
#if (!defined(HAVE_STRTOULL) || defined(NO_STRTOLL_PROTO))
extern longlong strtoll(const char *str, char **ptr, int base);
@@ -233,6 +264,7 @@ extern ulonglong strtoull(const char *str, char **ptr, int base);
#endif
#endif
#endif
+#define longlong2str(A,B,C) ll2str((A),(B),(C),1)
/* my_vsnprintf.c */
@@ -257,4 +289,80 @@ typedef struct st_mysql_lex_string LEX_STRING;
#define USTRING_WITH_LEN(X) ((uchar*) X), ((size_t) (sizeof(X) - 1))
#define C_STRING_WITH_LEN(X) ((char *) (X)), ((size_t) (sizeof(X) - 1))
+struct st_mysql_const_lex_string
+{
+ const char *str;
+ size_t length;
+};
+typedef struct st_mysql_const_lex_string LEX_CSTRING;
+
+/* SPACE_INT is a word that contains only spaces */
+#if SIZEOF_INT == 4
+#define SPACE_INT 0x20202020
+#elif SIZEOF_INT == 8
+#define SPACE_INT 0x2020202020202020
+#else
+#error define the appropriate constant for a word full of spaces
+#endif
+
+/**
+ Skip trailing space.
+
+ On most systems reading memory in larger chunks (ideally equal to the size of
+ the chinks that the machine physically reads from memory) causes fewer memory
+ access loops and hence increased performance.
+ This is why the 'int' type is used : it's closest to that (according to how
+ it's defined in C).
+ So when we determine the amount of whitespace at the end of a string we do
+ the following :
+ 1. We divide the string into 3 zones :
+ a) from the start of the string (__start) to the first multiple
+ of sizeof(int) (__start_words)
+ b) from the end of the string (__end) to the last multiple of sizeof(int)
+ (__end_words)
+ c) a zone that is aligned to sizeof(int) and can be safely accessed
+ through an int *
+ 2. We start comparing backwards from (c) char-by-char. If all we find is
+ space then we continue
+ 3. If there are elements in zone (b) we compare them as unsigned ints to a
+ int mask (SPACE_INT) consisting of all spaces
+ 4. Finally we compare the remaining part (a) of the string char by char.
+ This covers for the last non-space unsigned int from 3. (if any)
+
+ This algorithm works well for relatively larger strings, but it will slow
+ the things down for smaller strings (because of the additional calculations
+ and checks compared to the naive method). Thus the barrier of length 20
+ is added.
+
+ @param ptr pointer to the input string
+ @param len the length of the string
+ @return the last non-space character
+*/
+
+static inline const uchar *skip_trailing_space(const uchar *ptr,size_t len)
+{
+ const uchar *end= ptr + len;
+
+ if (len > 20)
+ {
+ const uchar *end_words= (const uchar *)(intptr)
+ (((ulonglong)(intptr)end) / SIZEOF_INT * SIZEOF_INT);
+ const uchar *start_words= (const uchar *)(intptr)
+ ((((ulonglong)(intptr)ptr) + SIZEOF_INT - 1) / SIZEOF_INT * SIZEOF_INT);
+
+ DBUG_ASSERT(((ulonglong)(intptr)ptr) >= SIZEOF_INT);
+ if (end_words > ptr)
+ {
+ while (end > end_words && end[-1] == 0x20)
+ end--;
+ if (end[-1] == 0x20 && start_words < end_words)
+ while (end > start_words && ((unsigned *)end)[-1] == SPACE_INT)
+ end -= SIZEOF_INT;
+ }
+ }
+ while (end > ptr && end[-1] == 0x20)
+ end--;
+ return (end);
+}
+
#endif
diff --git a/include/my_alarm.h b/include/my_alarm.h
index 750135d64ed..dd2d5642f5f 100644
--- a/include/my_alarm.h
+++ b/include/my_alarm.h
@@ -33,15 +33,15 @@ extern ulong my_time_to_wait_for_lock;
#define ALARM_INIT my_have_got_alarm=0 ; \
alarm_old=(uint) alarm(MY_HOW_OFTEN_TO_ALARM); \
alarm_signal=signal(SIGALRM,my_set_alarm_variable);
-#define ALARM_END VOID(signal(SIGALRM,alarm_signal)); \
- VOID(alarm(alarm_old));
+#define ALARM_END (void) signal(SIGALRM,alarm_signal); \
+ (void) alarm(alarm_old);
#define ALARM_TEST my_have_got_alarm
#ifdef DONT_REMEMBER_SIGNAL
-#define ALARM_REINIT VOID(alarm(MY_HOW_OFTEN_TO_ALARM)); \
- VOID(signal(SIGALRM,my_set_alarm_variable));\
+#define ALARM_REINIT (void) alarm(MY_HOW_OFTEN_TO_ALARM); \
+ (void) signal(SIGALRM,my_set_alarm_variable);\
my_have_got_alarm=0;
#else
-#define ALARM_REINIT VOID(alarm((uint) MY_HOW_OFTEN_TO_ALARM)); \
+#define ALARM_REINIT (void) alarm((uint) MY_HOW_OFTEN_TO_ALARM); \
my_have_got_alarm=0;
#endif /* DONT_REMEMBER_SIGNAL */
#else
diff --git a/include/my_atomic.h b/include/my_atomic.h
index f5da6e6a0d9..8ba3e201730 100644
--- a/include/my_atomic.h
+++ b/include/my_atomic.h
@@ -16,9 +16,50 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+/*
+ This header defines five atomic operations:
+
+ my_atomic_add#(&var, what)
+ add 'what' to *var, and return the old value of *var
+
+ my_atomic_fas#(&var, what)
+ 'Fetch And Store'
+ store 'what' in *var, and return the old value of *var
+
+ my_atomic_cas#(&var, &old, new)
+ 'Compare And Swap'
+ if *var is equal to *old, then store 'new' in *var, and return TRUE
+ otherwise store *var in *old, and return FALSE
+
+ my_atomic_load#(&var)
+ return *var
+
+ my_atomic_store#(&var, what)
+ store 'what' in *var
+
+ '#' 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
+ enclosed in my_atomic_rwlock_rdlock(lock)/my_atomic_rwlock_rdunlock(lock)
+ or my_atomic_rwlock_wrlock(lock)/my_atomic_rwlock_wrunlock(lock).
+ Hint: if a code block makes intensive use of atomic ops, it make sense
+ to take/release rwlock once for the whole block, not for every statement.
+
+ 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.
+*/
+
#ifndef my_atomic_rwlock_init
#define intptr void *
+/**
+ Currently we don't support 8-bit and 16-bit operations.
+ It can be added later if needed.
+*/
+#undef MY_ATOMIC_HAS_8_16
#ifndef MY_ATOMIC_MODE_RWLOCKS
/*
@@ -27,124 +68,233 @@
#include "atomic/nolock.h"
#endif
-#ifndef MY_ATOMIC_NOLOCK
-/*
- * Have to use rw-locks for atomic ops
- */
+#ifndef make_atomic_cas_body
+/* nolock.h was not able to generate even a CAS function, fall back */
#include "atomic/rwlock.h"
#endif
-#ifndef MY_ATOMICS_MADE
-
+/* define missing functions by using the already generated ones */
#ifndef make_atomic_add_body
-#define make_atomic_add_body(S) \
+#define make_atomic_add_body(S) \
int ## S tmp=*a; \
- while (!my_atomic_cas ## S(a, &tmp, tmp+v)); \
+ while (!my_atomic_cas ## S(a, &tmp, tmp+v)) ; \
v=tmp;
#endif
+#ifndef make_atomic_fas_body
+#define make_atomic_fas_body(S) \
+ int ## S tmp=*a; \
+ while (!my_atomic_cas ## S(a, &tmp, v)) ; \
+ v=tmp;
+#endif
+#ifndef make_atomic_load_body
+#define make_atomic_load_body(S) \
+ ret= 0; /* avoid compiler warning */ \
+ (void)(my_atomic_cas ## S(a, &ret, ret));
+#endif
+#ifndef make_atomic_store_body
+#define make_atomic_store_body(S) \
+ (void)(my_atomic_fas ## S (a, v));
+#endif
+
+/*
+ transparent_union doesn't work in g++
+ Bug ?
+
+ Darwin's gcc doesn't want to put pointers in a transparent_union
+ when built with -arch ppc64. Complains:
+ warning: 'transparent_union' attribute ignored
+*/
+#if defined(__GNUC__) && !defined(__cplusplus) && \
+ ! (defined(__APPLE__) && (defined(_ARCH_PPC64) ||defined (_ARCH_PPC)))
+/*
+ we want to be able to use my_atomic_xxx functions with
+ both signed and unsigned integers. But gcc will issue a warning
+ "passing arg N of `my_atomic_XXX' as [un]signed due to prototype"
+ if the signedness of the argument doesn't match the prototype, or
+ "pointer targets in passing argument N of my_atomic_XXX differ in signedness"
+ if int* is used where uint* is expected (or vice versa).
+ Let's shut these warnings up
+*/
+#define make_transparent_unions(S) \
+ typedef union { \
+ int ## S i; \
+ uint ## S u; \
+ } U_ ## S __attribute__ ((transparent_union)); \
+ typedef union { \
+ int ## S volatile *i; \
+ uint ## S volatile *u; \
+ } Uv_ ## S __attribute__ ((transparent_union));
+#define uintptr intptr
+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
+#define a U_a.i
+#define cmp U_cmp.i
+#define v U_v.i
+#define set U_set.i
+#else
+#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
+#define U_v v
+#define U_set set
+#endif /* __GCC__ transparent_union magic */
#ifdef HAVE_INLINE
-#define make_atomic_add(S) \
-STATIC_INLINE int ## S my_atomic_add ## S( \
- int ## S volatile *a, int ## S v) \
-{ \
- make_atomic_add_body(S); \
- return v; \
+#define make_atomic_cas(S) \
+STATIC_INLINE int my_atomic_cas ## S(Uv_ ## S U_a, \
+ Uv_ ## S U_cmp, U_ ## S U_set) \
+{ \
+ int8 ret; \
+ make_atomic_cas_body(S); \
+ return ret; \
}
-#define make_atomic_swap(S) \
-STATIC_INLINE int ## S my_atomic_swap ## S( \
- int ## S volatile *a, int ## S v) \
-{ \
- make_atomic_swap_body(S); \
- return v; \
+#define make_atomic_add(S) \
+STATIC_INLINE int ## S my_atomic_add ## S( \
+ Uv_ ## S U_a, U_ ## S U_v) \
+{ \
+ make_atomic_add_body(S); \
+ return v; \
}
-#define make_atomic_cas(S) \
-STATIC_INLINE int my_atomic_cas ## S(int ## S volatile *a, \
- int ## S *cmp, int ## S set) \
-{ \
- int8 ret; \
- make_atomic_cas_body(S); \
- return ret; \
+#define make_atomic_fas(S) \
+STATIC_INLINE int ## S my_atomic_fas ## S( \
+ Uv_ ## S U_a, U_ ## S U_v) \
+{ \
+ make_atomic_fas_body(S); \
+ return v; \
}
-#define make_atomic_load(S) \
-STATIC_INLINE int ## S my_atomic_load ## S(int ## S volatile *a) \
-{ \
- int ## S ret; \
- make_atomic_load_body(S); \
- return ret; \
+#define make_atomic_load(S) \
+STATIC_INLINE int ## S my_atomic_load ## S(Uv_ ## S U_a) \
+{ \
+ int ## S ret; \
+ make_atomic_load_body(S); \
+ return ret; \
}
-#define make_atomic_store(S) \
-STATIC_INLINE void my_atomic_store ## S( \
- int ## S volatile *a, int ## S v) \
-{ \
- make_atomic_store_body(S); \
+#define make_atomic_store(S) \
+STATIC_INLINE void my_atomic_store ## S( \
+ Uv_ ## S U_a, U_ ## S U_v) \
+{ \
+ make_atomic_store_body(S); \
}
#else /* no inline functions */
-#define make_atomic_add(S) \
-extern int ## S my_atomic_add ## S(int ## S volatile *a, int ## S v);
+#define make_atomic_add(S) \
+extern int ## S my_atomic_add ## S(Uv_ ## S U_a, U_ ## S U_v);
-#define make_atomic_swap(S) \
-extern int ## S my_atomic_swap ## S(int ## S volatile *a, int ## S v);
+#define make_atomic_fas(S) \
+extern int ## S my_atomic_fas ## S(Uv_ ## S U_a, U_ ## S U_v);
-#define make_atomic_cas(S) \
-extern int my_atomic_cas ## S(int ## S volatile *a, int ## S *cmp, int ## S set);
+#define make_atomic_cas(S) \
+extern int my_atomic_cas ## S(Uv_ ## S U_a, Uv_ ## S U_cmp, U_ ## S U_set);
-#define make_atomic_load(S) \
-extern int ## S my_atomic_load ## S(int ## S volatile *a);
+#define make_atomic_load(S) \
+extern int ## S my_atomic_load ## S(Uv_ ## S U_a);
-#define make_atomic_store(S) \
-extern void my_atomic_store ## S(int ## S volatile *a, int ## S v);
+#define make_atomic_store(S) \
+extern void my_atomic_store ## S(Uv_ ## S U_a, U_ ## S U_v);
#endif /* HAVE_INLINE */
-make_atomic_cas( 8)
+#ifdef MY_ATOMIC_HAS_8_16
+make_atomic_cas(8)
make_atomic_cas(16)
+#endif
make_atomic_cas(32)
+make_atomic_cas(64)
make_atomic_cas(ptr)
-make_atomic_add( 8)
+#ifdef MY_ATOMIC_HAS_8_16
+make_atomic_add(8)
make_atomic_add(16)
+#endif
make_atomic_add(32)
+make_atomic_add(64)
-make_atomic_load( 8)
+#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)
-make_atomic_store( 8)
+#ifdef MY_ATOMIC_HAS_8_16
+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
+make_atomic_store(8)
make_atomic_store(16)
+#endif
make_atomic_store(32)
+make_atomic_store(64)
make_atomic_store(ptr)
-make_atomic_swap( 8)
-make_atomic_swap(16)
-make_atomic_swap(32)
-make_atomic_swap(ptr)
+#ifdef _atomic_h_cleanup_
+#include _atomic_h_cleanup_
+#undef _atomic_h_cleanup_
+#endif
+#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
+#undef v
+#undef set
+#undef U_a
+#undef U_cmp
+#undef U_v
+#undef U_set
#undef make_atomic_add
#undef make_atomic_cas
#undef make_atomic_load
#undef make_atomic_store
-#undef make_atomic_swap
+#undef make_atomic_fas
#undef make_atomic_add_body
#undef make_atomic_cas_body
#undef make_atomic_load_body
#undef make_atomic_store_body
-#undef make_atomic_swap_body
+#undef make_atomic_fas_body
#undef intptr
-#endif /* MY_ATOMICS_MADE */
-
-#ifdef _atomic_h_cleanup_
-#include _atomic_h_cleanup_
-#undef _atomic_h_cleanup_
+/*
+ the macro below defines (as an expression) the code that
+ will be run in spin-loops. Intel manuals recummend to have PAUSE there.
+ It is expected to be defined in include/atomic/ *.h files
+*/
+#ifndef LF_BACKOFF
+#define LF_BACKOFF (1)
#endif
#define MY_ATOMIC_OK 0
diff --git a/include/my_base.h b/include/my_base.h
index 70bd9b5e073..7766d4165a2 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -191,10 +191,11 @@ enum ha_extra_function {
/* Inform handler that we will do a rename */
HA_EXTRA_PREPARE_FOR_RENAME,
/*
- Orders MERGE handler to attach or detach its child tables. Used at
- begin and end of a statement.
+ Special actions for MERGE tables.
*/
+ HA_EXTRA_ADD_CHILDREN_LIST,
HA_EXTRA_ATTACH_CHILDREN,
+ HA_EXTRA_IS_ATTACHED_CHILDREN,
HA_EXTRA_DETACH_CHILDREN
};
@@ -272,20 +273,10 @@ enum ha_base_keytype {
#define HA_SPACE_PACK_USED 4 /* Test for if SPACE_PACK used */
#define HA_VAR_LENGTH_KEY 8
#define HA_NULL_PART_KEY 64
+#define HA_USES_COMMENT 4096
#define HA_USES_PARSER 16384 /* Fulltext index uses [pre]parser */
#define HA_USES_BLOCK_SIZE ((uint) 32768)
#define HA_SORT_ALLOWS_SAME 512 /* Intern bit when sorting records */
-#if MYSQL_VERSION_ID < 0x50200
-/*
- Key has a part that can have end space. If this is an unique key
- we have to handle it differently from other unique keys as we can find
- many matching rows for one key (because end space are not compared)
-*/
-#define HA_END_SPACE_KEY 0 /* was: 4096 */
-#else
-#error HA_END_SPACE_KEY is obsolete, please remove it
-#endif
-
/* These flags can be added to key-seg-flag */
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_getopt.h b/include/my_getopt.h
index 7cbad607aac..32380efe289 100644
--- a/include/my_getopt.h
+++ b/include/my_getopt.h
@@ -32,6 +32,7 @@ C_MODE_START
#define GET_ENUM 12
#define GET_SET 13
#define GET_DOUBLE 14
+#define GET_FLAGSET 15
#define GET_ASK_ADDR 128
#define GET_TYPE_MASK 127
@@ -42,24 +43,40 @@ struct st_typelib;
struct my_option
{
- const char *name; /* Name of the option */
- int id; /* unique id or short option */
- const char *comment; /* option comment, for autom. --help */
- uchar **value; /* The variable value */
- uchar **u_max_value; /* The user def. max variable value */
- struct st_typelib *typelib; /* Pointer to possible values */
- ulong var_type;
- enum get_opt_arg_type arg_type;
- longlong def_value; /* Default value */
- longlong min_value; /* Min allowed value */
- longlong max_value; /* Max allowed value */
- longlong sub_size; /* Subtract this from given value */
- long block_size; /* Value should be a mult. of this */
- void *app_type; /* To be used by an application */
+ const char *name; /**< Name of the option. name=NULL
+ marks the end of the my_option[]
+ array.
+ */
+ int id; /**< For 0<id<255 it's means one
+ character for a short option
+ (like -A), if >255 no short option
+ is created, but a long option still
+ can be identified uniquely in the
+ my_get_one_option() callback.
+ If an opton needs neither special
+ treatment in the my_get_one_option()
+ nor one-letter short equivalent
+ use id=0
+ */
+ const char *comment; /**< option comment, for autom. --help.
+ if it's NULL the option is not
+ visible in --help.
+ */
+ uchar **value; /**< A pointer to the variable value */
+ uchar **u_max_value; /**< The user def. max variable value */
+ struct st_typelib *typelib; /**< Pointer to possible values */
+ ulong var_type; /**< GET_BOOL, GET_ULL, etc */
+ enum get_opt_arg_type arg_type; /**< e.g. REQUIRED_ARG or OPT_ARG */
+ longlong def_value; /**< Default value */
+ longlong min_value; /**< Min allowed value (for numbers) */
+ longlong max_value; /**< Max allowed value (for numbers) */
+ longlong sub_size; /**< Unused */
+ long block_size; /**< Value should be a mult. of this (for numbers) */
+ void *app_type; /**< To be used by an application */
};
-typedef my_bool (* my_get_one_option) (int, const struct my_option *, char * );
-typedef void (* my_error_reporter) (enum loglevel level, const char *format, ... );
+typedef my_bool (*my_get_one_option) (int, const struct my_option *, char * );
+typedef void (*my_error_reporter) (enum loglevel level, const char *format, ... );
extern char *disabled_my_option;
extern my_bool my_getopt_print_errors;
@@ -78,6 +95,8 @@ ulonglong getopt_ull_limit_value(ulonglong num, const struct my_option *optp,
my_bool *fix);
longlong getopt_ll_limit_value(longlong, const struct my_option *,
my_bool *fix);
+double getopt_double_limit_value(double num, const struct my_option *optp,
+ my_bool *fix);
my_bool getopt_compare_strings(const char *s, const char *t, uint length);
C_MODE_END
diff --git a/include/my_global.h b/include/my_global.h
index d3d17721ea9..b4bc61e0a48 100644
--- a/include/my_global.h
+++ b/include/my_global.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000-2003 MySQL AB
+/* Copyright (C) 2000-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
@@ -68,8 +68,8 @@
#define C_MODE_END
#endif
-#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
-#include <config-win.h>
+#if defined(_WIN32)
+#include <my_config.h>
#elif defined(__NETWARE__)
#include <my_config.h>
#include <config-netware.h>
@@ -83,11 +83,39 @@
#endif
#endif /* _WIN32... */
-/* Make it easier to add conditionl code for windows */
+#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
+#define HAVE_PSI_INTERFACE
+#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
+
+/* Make it easier to add conditional code in _expressions_ */
#ifdef __WIN__
-#define IF_WIN(A,B) (A)
+#define IF_WIN(A,B) A
+#else
+#define IF_WIN(A,B) B
+#endif
+
+#ifdef __NETWARE__
+#define IF_NETWARE(A,B) A
+#else
+#define IF_NETWARE(A,B) B
+#endif
+
+#ifndef DBUG_OFF
+#define IF_DBUG(A,B) A
#else
-#define IF_WIN(A,B) (B)
+#define IF_DBUG(A,B) B
+#endif
+
+#ifdef HAVE_purify
+#define IF_PURIFY(A,B) A
+#else
+#define IF_PURIFY(A,B) B
+#endif
+
+#ifdef DISABLE_GRANT_OPTIONS
+#define IF_DISABLE_GRANT_OPTIONS(A,B) A
+#else
+#define IF_DISABLE_GRANT_OPTIONS(A,B) B
#endif
#ifndef EMBEDDED_LIBRARY
@@ -107,6 +135,49 @@
#define NETWARE_SET_SCREEN_MODE(A)
#endif
+#if defined (_WIN32)
+/*
+ off_t is 32 bit long. We do not use C runtime functions
+ with off_t but native Win32 file IO APIs, that work with
+ 64 bit offsets.
+*/
+#undef SIZEOF_OFF_T
+#define SIZEOF_OFF_T 8
+
+/*
+ Prevent inclusion of Windows GDI headers - they define symbol
+ ERROR that conflicts with mysql headers.
+*/
+#ifndef NOGDI
+#define NOGDI
+#endif
+
+/* Include common headers.*/
+#include <winsock2.h>
+#include <ws2tcpip.h> /* SOCKET */
+#include <io.h> /* access(), chmod() */
+#include <process.h> /* getpid() */
+
+#define sleep(a) Sleep((a)*1000)
+
+/* Define missing access() modes. */
+#define F_OK 0
+#define W_OK 2
+
+/* Define missing file locking constants. */
+#define F_RDLCK 1
+#define F_WRLCK 2
+#define F_UNLCK 3
+#define F_TO_EOF 0x3FFFFFFF
+
+/* Shared memory and named pipe connections are supported. */
+#define HAVE_SMEM 1
+#define HAVE_NAMED_PIPE 1
+#define shared_memory_buffer_length 16000
+#define default_shared_memory_base_name "MYSQL"
+#endif /* _WIN32*/
+
+
/* Workaround for _LARGE_FILES and _LARGE_FILE_API incompatibility on AIX */
#if defined(_AIX) && defined(_LARGE_FILE_API)
#undef _LARGE_FILE_API
@@ -239,6 +310,8 @@
#define inline_test_2(X) inline_test_1(X)
#if inline_test_2(inline) != 1
#define HAVE_INLINE
+#else
+#warning No "inline" support in C, all "static inline" functions will be instantiated in every .o file!!!
#endif
#undef inline_test_2
#undef inline_test_1
@@ -479,15 +552,17 @@ C_MODE_END
#define compile_time_assert(X) \
do \
{ \
- char compile_time_assert[(X) ? 1 : -1] \
- __attribute__ ((unused)); \
+ typedef char compile_time_assert[(X) ? 1 : -1]; \
} while(0)
#endif
/* Go around some bugs in different OS and compilers */
#if defined (HPUX11) && defined(_LARGEFILE_SOURCE)
+#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif
+#endif
+
#if defined(_HPUX_SOURCE) && defined(HAVE_SYS_STREAM_H)
#include <sys/stream.h> /* HPUX 10.20 defines ulong here. UGLY !!! */
#define HAVE_ULONG
@@ -542,17 +617,6 @@ extern "C" int madvise(void *addr, size_t len, int behav);
#define DONT_REMEMBER_SIGNAL
#endif
-/* Define void to stop lint from generating "null effekt" comments */
-#ifndef DONT_DEFINE_VOID
-#ifdef _lint
-int __void__;
-#define VOID(X) (__void__ = (int) (X))
-#else
-#undef VOID
-#define VOID(X) (X)
-#endif
-#endif /* DONT_DEFINE_VOID */
-
#if defined(_lint) || defined(FORCE_INIT_OF_VARS)
#define LINT_INIT(var) var=0 /* No uninitialize-warning */
#else
@@ -656,7 +720,9 @@ C_MODE_END
/* Some types that is different between systems */
typedef int File; /* File descriptor */
-#ifndef Socket_defined
+#ifdef _WIN32
+typedef SOCKET my_socket;
+#else
typedef int my_socket; /* File descriptor for sockets */
#define INVALID_SOCKET -1
#endif
@@ -744,8 +810,16 @@ typedef SOCKET_SIZE_TYPE size_socket;
#define FN_CURLIB '.' /* ./ is used as abbrev for current dir */
#define FN_PARENTDIR ".." /* Parent directory; Must be a string */
-#ifndef FN_LIBCHAR
+#ifdef _WIN32
+#define FN_LIBCHAR '\\'
+#define FN_LIBCHAR2 '/'
+#define FN_ROOTDIR "\\"
+#define FN_DEVCHAR ':'
+#define FN_NETWORK_DRIVES /* Uses \\ to indicate network drives */
+#define FN_NO_CASE_SENCE /* Files are not case-sensitive */
+#else
#define FN_LIBCHAR '/'
+#define FN_LIBCHAR2 '/'
#define FN_ROOTDIR "/"
#endif
@@ -788,7 +862,7 @@ typedef SOCKET_SIZE_TYPE size_socket;
#endif
/* #define EXT_IN_LIBNAME */
-/* #define FN_NO_CASE_SENCE */
+/* #define FN_NO_CASE_SENSE */
/* #define FN_UPPER_CASE TRUE */
/*
@@ -811,7 +885,7 @@ typedef SOCKET_SIZE_TYPE size_socket;
/* Typical record cash */
#define RECORD_CACHE_SIZE (uint) (64*1024-MALLOC_OVERHEAD)
/* Typical key cash */
-#define KEY_CACHE_SIZE (uint) (8*1024*1024-MALLOC_OVERHEAD)
+#define KEY_CACHE_SIZE (uint) (8*1024*1024)
/* Default size of a key cache block */
#define KEY_CACHE_BLOCK_SIZE (uint) 1024
@@ -828,6 +902,31 @@ typedef SOCKET_SIZE_TYPE size_socket;
#undef remove /* Crashes MySQL on SCO 5.0.0 */
#ifndef __WIN__
#define closesocket(A) close(A)
+#endif
+
+#if (_MSC_VER)
+#if !defined(_WIN64)
+inline double my_ulonglong2double(unsigned long long value)
+{
+ long long nr=(long long) value;
+ if (nr >= 0)
+ return (double) nr;
+ return (18446744073709551616.0 + (double) nr);
+}
+#define ulonglong2double my_ulonglong2double
+#define my_off_t2double my_ulonglong2double
+#endif /* _WIN64 */
+inline unsigned long long my_double2ulonglong(double d)
+{
+ double t= d - (double) 0x8000000000000000ULL;
+
+ if (t >= 0)
+ return ((unsigned long long) t) + 0x8000000000000000ULL;
+ return (unsigned long long) d;
+}
+#define double2ulonglong my_double2ulonglong
+#endif
+
#ifndef ulonglong2double
#define ulonglong2double(A) ((double) (ulonglong) (A))
#define my_off_t2double(A) ((double) (my_off_t) (A))
@@ -835,7 +934,6 @@ typedef SOCKET_SIZE_TYPE size_socket;
#ifndef double2ulonglong
#define double2ulonglong(A) ((ulonglong) (double) (A))
#endif
-#endif
#ifndef offsetof
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
@@ -877,6 +975,8 @@ typedef SOCKET_SIZE_TYPE size_socket;
#endif
#endif /* defined (HAVE_LONG_LONG) && !defined(ULONGLONG_MAX)*/
+#define INT_MIN64 (~0x7FFFFFFFFFFFFFFFLL)
+#define INT_MAX64 0x7FFFFFFFFFFFFFFFLL
#define INT_MIN32 (~0x7FFFFFFFL)
#define INT_MAX32 0x7FFFFFFFL
#define UINT_MAX32 0xFFFFFFFFL
@@ -1092,15 +1192,18 @@ typedef long long intptr;
#define SYSTEM_SIZEOF_OFF_T SIZEOF_OFF_T
#endif /* USE_RAID */
+#if defined(_WIN32)
+typedef unsigned long long my_off_t;
+typedef unsigned long long os_off_t;
+#else
+typedef off_t os_off_t;
#if SIZEOF_OFF_T > 4
typedef ulonglong my_off_t;
#else
typedef unsigned long my_off_t;
#endif
+#endif /*_WIN32*/
#define MY_FILEPOS_ERROR (~(my_off_t) 0)
-#if !defined(__WIN__)
-typedef off_t os_off_t;
-#endif
#if defined(__WIN__)
#define socket_errno WSAGetLastError()
@@ -1127,9 +1230,6 @@ typedef uint8 int7; /* Most effective integer 0 <= x <= 127 */
typedef short int15; /* Most effective integer 0 <= x <= 32767 */
typedef int myf; /* Type of MyFlags in my_funcs */
typedef char my_bool; /* Small bool */
-#if !defined(bool) && (!defined(HAVE_BOOL) || !defined(__cplusplus))
-typedef char bool; /* Ordinary boolean values 0 1 */
-#endif
/* Macros for converting *constants* to the right type */
#define INT8(v) (int8) (v)
#define INT16(v) (int16) (v)
@@ -1522,12 +1622,15 @@ do { doubleget_union _tmp; \
#define NO_EMBEDDED_ACCESS_CHECKS
#endif
-#ifdef HAVE_DLOPEN
-#if defined(__WIN__)
-#define dlsym(lib, name) GetProcAddress((HMODULE)lib, name)
+#if defined(_WIN32)
+#define dlsym(lib, name) (void*)GetProcAddress((HMODULE)lib, name)
#define dlopen(libname, unused) LoadLibraryEx(libname, NULL, 0)
#define dlclose(lib) FreeLibrary((HMODULE)lib)
-#elif defined(HAVE_DLFCN_H)
+#define HAVE_DLOPEN
+#endif
+
+#ifdef HAVE_DLOPEN
+#if defined(HAVE_DLFCN_H)
#include <dlfcn.h>
#endif
#endif
@@ -1572,7 +1675,7 @@ inline void operator delete[](void*, void*) { /* Do nothing */ }
#if !defined(max)
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
-#endif
+#endif
/*
Only Linux is known to need an explicit sync of the directory to make sure a
file creation/deletion/renaming in(from,to) this directory durable.
@@ -1585,6 +1688,25 @@ inline void operator delete[](void*, void*) { /* Do nothing */ }
#define bool In_C_you_should_use_my_bool_instead()
#endif
+/* Provide __func__ macro definition for platforms that miss it. */
+#if __STDC_VERSION__ < 199901L
+# if __GNUC__ >= 2
+# define __func__ __FUNCTION__
+# else
+# define __func__ "<unknown>"
+# endif
+#elif defined(_MSC_VER)
+# if _MSC_VER < 1300
+# define __func__ "<unknown>"
+# else
+# define __func__ __FUNCTION__
+# endif
+#elif defined(__BORLANDC__)
+# define __func__ __FUNC__
+#else
+# define __func__ "<unknown>"
+#endif
+
#ifndef HAVE_RINT
/**
All integers up to this number can be represented exactly as double precision
diff --git a/include/my_net.h b/include/my_net.h
index 3af79ea3db5..18fb3db8e88 100644
--- a/include/my_net.h
+++ b/include/my_net.h
@@ -43,7 +43,7 @@ C_MODE_START
#include <sys/ioctl.h>
#endif
-#if !defined(__WIN__) && !defined(HAVE_BROKEN_NETINET_INCLUDES) && !defined(__BEOS__) && !defined(__NETWARE__)
+#if !defined(__WIN__) && !defined(HAVE_BROKEN_NETINET_INCLUDES) && !defined(__NETWARE__)
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
@@ -73,11 +73,6 @@ C_MODE_START
#define in_addr_t uint32
#endif
-/* On some operating systems (e.g. Solaris) INADDR_NONE is not defined */
-#ifndef INADDR_NONE
-#define INADDR_NONE -1 /* Error value from inet_addr */
-#endif
-
/* Thread safe or portable version of some functions */
void my_inet_ntoa(struct in_addr in, char *buf);
@@ -86,9 +81,6 @@ void my_inet_ntoa(struct in_addr in, char *buf);
Handling of gethostbyname_r()
*/
-#if !defined(HPUX10)
-struct hostent;
-#endif /* HPUX */
#if !defined(HAVE_GETHOSTBYNAME_R)
struct hostent *my_gethostbyname_r(const char *name,
struct hostent *result, char *buffer,
@@ -118,11 +110,5 @@ struct hostent *my_gethostbyname_r(const char *name,
#define GETHOSTBYNAME_BUFF_SIZE 2048
#endif
-/* On SCO you get a link error when refering to h_errno */
-#ifdef SCO
-#undef h_errno
-#define h_errno errno
-#endif
-
C_MODE_END
#endif
diff --git a/include/my_no_pthread.h b/include/my_no_pthread.h
index b7e47e9b765..a805a9151f8 100644
--- a/include/my_no_pthread.h
+++ b/include/my_no_pthread.h
@@ -1,7 +1,7 @@
#ifndef MY_NO_PTHREAD_INCLUDED
#define MY_NO_PTHREAD_INCLUDED
-/* 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
@@ -48,6 +48,17 @@
#define rw_unlock(A)
#define rwlock_destroy(A)
+#define mysql_mutex_init(A, B, C) do {} while (0)
+#define mysql_mutex_lock(A) do {} while (0)
+#define mysql_mutex_unlock(A) do {} while (0)
+#define mysql_mutex_destroy(A) do {} while (0)
+
+#define mysql_rwlock_init(A, B, C) do {} while (0)
+#define mysql_rwlock_rdlock(A) do {} while (0)
+#define mysql_rwlock_wrlock(A) do {} while (0)
+#define mysql_rwlock_unlock(A) do {} while (0)
+#define mysql_rwlock_destroy(A) do {} while (0)
+
typedef int my_pthread_once_t;
#define MY_PTHREAD_ONCE_INIT 0
#define MY_PTHREAD_ONCE_DONE 1
diff --git a/include/my_pthread.h b/include/my_pthread.h
index 9e0be6b779e..0b55c70b0fa 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (C) 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
@@ -35,7 +35,6 @@ typedef DWORD pthread_t;
typedef struct thread_attr {
DWORD dwStackSize ;
DWORD dwCreatingFlag ;
- int priority ;
} pthread_attr_t ;
typedef struct { int dummy; } pthread_condattr_t;
@@ -103,9 +102,22 @@ struct timespec {
(ABSTIME).max_timeout_msec= (long)((NSEC)/1000000); \
}
+/**
+ Compare two timespec structs.
+
+ @retval 1 If TS1 ends after TS2.
+
+ @retval 0 If TS1 is equal to TS2.
+
+ @retval -1 If TS1 ends before TS2.
+*/
+#define cmp_timespec(TS1, TS2) \
+ ((TS1.tv.i64 > TS2.tv.i64) ? 1 : \
+ ((TS1.tv.i64 < TS2.tv.i64) ? -1 : 0))
+
int win_pthread_mutex_trylock(pthread_mutex_t *mutex);
-int pthread_create(pthread_t *,pthread_attr_t *,pthread_handler,void *);
+int pthread_create(pthread_t *, const pthread_attr_t *, pthread_handler, void *);
int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr);
int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex);
int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
@@ -115,7 +127,6 @@ int pthread_cond_broadcast(pthread_cond_t *cond);
int pthread_cond_destroy(pthread_cond_t *cond);
int pthread_attr_init(pthread_attr_t *connect_att);
int pthread_attr_setstacksize(pthread_attr_t *connect_att,DWORD stack);
-int pthread_attr_setprio(pthread_attr_t *connect_att,int priority);
int pthread_attr_destroy(pthread_attr_t *connect_att);
int my_pthread_once(my_pthread_once_t *once_control,void (*init_routine)(void));
struct tm *localtime_r(const time_t *timep,struct tm *tmp);
@@ -123,9 +134,11 @@ struct tm *gmtime_r(const time_t *timep,struct tm *tmp);
void pthread_exit(void *a);
int pthread_join(pthread_t thread, void **value_ptr);
+int pthread_cancel(pthread_t thread);
-
+#ifndef ETIMEDOUT
#define ETIMEDOUT 145 /* Win32 doesn't have this */
+#endif
#define HAVE_LOCALTIME_R 1
#define _REENTRANT 1
#define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1
@@ -145,21 +158,19 @@ int pthread_join(pthread_t thread, void **value_ptr);
#define pthread_mutex_init(A,B) (InitializeCriticalSection(A),0)
#define pthread_mutex_lock(A) (EnterCriticalSection(A),0)
#define pthread_mutex_trylock(A) win_pthread_mutex_trylock((A))
-#define pthread_mutex_unlock(A) LeaveCriticalSection(A)
-#define pthread_mutex_destroy(A) DeleteCriticalSection(A)
-#define my_pthread_setprio(A,B) SetThreadPriority(GetCurrentThread(), (B))
+#define pthread_mutex_unlock(A) (LeaveCriticalSection(A), 0)
+#define pthread_mutex_destroy(A) (DeleteCriticalSection(A), 0)
#define pthread_kill(A,B) pthread_dummy((A) ? 0 : ESRCH)
/* Dummy defines for easier code */
#define pthread_attr_setdetachstate(A,B) pthread_dummy(0)
-#define my_pthread_attr_setprio(A,B) pthread_attr_setprio(A,B)
#define pthread_attr_setscope(A,B)
#define pthread_detach_this_thread()
#define pthread_condattr_init(A)
#define pthread_condattr_destroy(A)
-
-#define my_pthread_getprio(thread_id) pthread_dummy(0)
+#define pthread_yield() SwitchToThread()
+#define my_sigset(A,B) signal(A,B)
#else /* Normal threads */
@@ -187,8 +198,6 @@ void my_pthread_exit(void *status);
#define pthread_exit(A) my_pthread_exit(A)
#endif
-extern int my_pthread_getprio(pthread_t thread_id);
-
#define pthread_key(T,V) pthread_key_t V
#define my_pthread_getspecific_ptr(T,V) my_pthread_getspecific(T,(V))
#define my_pthread_setspecific_ptr(T,V) pthread_setspecific(T,(void*) (V))
@@ -264,32 +273,6 @@ int sigwait(sigset_t *setp, int *sigp); /* Use our implemention */
#define my_sigset(A,B) signal((A),(B))
#endif
-#ifndef my_pthread_setprio
-#if defined(HAVE_PTHREAD_SETPRIO_NP) /* FSU threads */
-#define my_pthread_setprio(A,B) pthread_setprio_np((A),(B))
-#elif defined(HAVE_PTHREAD_SETPRIO)
-#define my_pthread_setprio(A,B) pthread_setprio((A),(B))
-#elif defined(HAVE_PTHREAD_SETSCHEDPRIO) && !defined (__GNUC__)
-/*
- Workaround for bug on Solaris where pthread.h have bug in GNU
- version of pthread.h => configure says yes, header files says
- no. So not used with gcc and issue is Solaris only, so will
- be used on Solaris using SunStudio.
-*/
-#define my_pthread_setprio(A,B) pthread_setschedprio((A),(B))
-#else
-extern void my_pthread_setprio(pthread_t thread_id,int prior);
-#endif
-#endif
-
-#ifndef my_pthread_attr_setprio
-#ifdef HAVE_PTHREAD_ATTR_SETPRIO
-#define my_pthread_attr_setprio(A,B) pthread_attr_setprio((A),(B))
-#else
-extern void my_pthread_attr_setprio(pthread_attr_t *attr, int priority);
-#endif
-#endif
-
#if !defined(HAVE_PTHREAD_ATTR_SETSCOPE) || defined(HAVE_DEC_3_2_THREADS)
#define pthread_attr_setscope(A,B)
#undef HAVE_GETHOSTBYADDR_R /* No definition */
@@ -395,6 +378,17 @@ void my_pthread_attr_getstacksize(pthread_attr_t *attrib, size_t *size);
int my_pthread_mutex_trylock(pthread_mutex_t *mutex);
#endif
+#if !defined(HAVE_PTHREAD_YIELD_ONE_ARG) && !defined(HAVE_PTHREAD_YIELD_ZERO_ARG)
+/* no pthread_yield() available */
+#ifdef HAVE_SCHED_YIELD
+#define pthread_yield() sched_yield()
+#elif defined(HAVE_PTHREAD_YIELD_NP) /* can be Mac OS X */
+#define pthread_yield() pthread_yield_np()
+#elif defined(HAVE_THR_YIELD)
+#define pthread_yield() thr_yield()
+#endif
+#endif
+
/*
The defines set_timespec and set_timespec_nsec should be used
for calculating an absolute time at which
@@ -436,6 +430,33 @@ int my_pthread_mutex_trylock(pthread_mutex_t *mutex);
#endif /* !set_timespec_nsec */
#endif /* HAVE_TIMESPEC_TS_SEC */
+/**
+ Compare two timespec structs.
+
+ @retval 1 If TS1 ends after TS2.
+
+ @retval 0 If TS1 is equal to TS2.
+
+ @retval -1 If TS1 ends before TS2.
+*/
+#ifdef HAVE_TIMESPEC_TS_SEC
+#ifndef cmp_timespec
+#define cmp_timespec(TS1, TS2) \
+ ((TS1.ts_sec > TS2.ts_sec || \
+ (TS1.ts_sec == TS2.ts_sec && TS1.ts_nsec > TS2.ts_nsec)) ? 1 : \
+ ((TS1.ts_sec < TS2.ts_sec || \
+ (TS1.ts_sec == TS2.ts_sec && TS1.ts_nsec < TS2.ts_nsec)) ? -1 : 0))
+#endif /* !cmp_timespec */
+#else
+#ifndef cmp_timespec
+#define cmp_timespec(TS1, TS2) \
+ ((TS1.tv_sec > TS2.tv_sec || \
+ (TS1.tv_sec == TS2.tv_sec && TS1.tv_nsec > TS2.tv_nsec)) ? 1 : \
+ ((TS1.tv_sec < TS2.tv_sec || \
+ (TS1.tv_sec == TS2.tv_sec && TS1.tv_nsec < TS2.tv_nsec)) ? -1 : 0))
+#endif /* !cmp_timespec */
+#endif /* HAVE_TIMESPEC_TS_SEC */
+
/* safe_mutex adds checking to mutex for easier debugging */
#if defined(__NETWARE__) && !defined(SAFE_MUTEX_DETECT_DESTROY)
@@ -579,30 +600,76 @@ int my_pthread_fastmutex_lock(my_pthread_fastmutex_t *mp);
#define my_rwlock_init(A,B) rwlock_init((A),USYNC_THREAD,0)
#else
/* Use our own version of read/write locks */
-typedef struct _my_rw_lock_t {
- pthread_mutex_t lock; /* lock for structure */
- pthread_cond_t readers; /* waiting readers */
- pthread_cond_t writers; /* waiting writers */
- int state; /* -1:writer,0:free,>0:readers */
- int waiters; /* number of waiting writers */
-} my_rw_lock_t;
-
+#define NEED_MY_RW_LOCK 1
#define rw_lock_t my_rw_lock_t
+#define my_rwlock_init(A,B) my_rw_init((A), 0)
#define rw_rdlock(A) my_rw_rdlock((A))
#define rw_wrlock(A) my_rw_wrlock((A))
#define rw_tryrdlock(A) my_rw_tryrdlock((A))
#define rw_trywrlock(A) my_rw_trywrlock((A))
#define rw_unlock(A) my_rw_unlock((A))
-#define rwlock_destroy(A) my_rwlock_destroy((A))
+#define rwlock_destroy(A) my_rw_destroy((A))
+#endif /* USE_MUTEX_INSTEAD_OF_RW_LOCKS */
+
+
+/*
+ Portable read-write locks which prefer readers.
-extern int my_rwlock_init(my_rw_lock_t *, void *);
-extern int my_rwlock_destroy(my_rw_lock_t *);
+ Required by some algorithms in order to provide correctness.
+*/
+
+#if defined(HAVE_PTHREAD_RWLOCK_RDLOCK) && defined(HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP)
+/*
+ On systems which have a way to specify that readers should
+ be preferred through attribute mechanism (e.g. Linux) we use
+ system implementation of read/write locks.
+*/
+#define rw_pr_lock_t pthread_rwlock_t
+extern int rw_pr_init(rw_pr_lock_t *);
+#define rw_pr_rdlock(A) pthread_rwlock_rdlock(A)
+#define rw_pr_wrlock(A) pthread_rwlock_wrlock(A)
+#define rw_pr_tryrdlock(A) pthread_rwlock_tryrdlock(A)
+#define rw_pr_trywrlock(A) pthread_rwlock_trywrlock(A)
+#define rw_pr_unlock(A) pthread_rwlock_unlock(A)
+#define rw_pr_destroy(A) pthread_rwlock_destroy(A)
+#else
+/* Otherwise we have to use our own implementation of read/write locks. */
+#define NEED_MY_RW_LOCK 1
+struct st_my_rw_lock_t;
+#define rw_pr_lock_t my_rw_lock_t
+extern int rw_pr_init(struct st_my_rw_lock_t *);
+#define rw_pr_rdlock(A) my_rw_rdlock((A))
+#define rw_pr_wrlock(A) my_rw_wrlock((A))
+#define rw_pr_tryrdlock(A) my_rw_tryrdlock((A))
+#define rw_pr_trywrlock(A) my_rw_trywrlock((A))
+#define rw_pr_unlock(A) my_rw_unlock((A))
+#define rw_pr_destroy(A) my_rw_destroy((A))
+#endif /* defined(HAVE_PTHREAD_RWLOCK_RDLOCK) && defined(HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP) */
+
+
+#ifdef NEED_MY_RW_LOCK
+/*
+ On systems which don't support native read/write locks, or don't support
+ read/write locks which prefer readers we have to use own implementation.
+*/
+typedef struct st_my_rw_lock_t {
+ pthread_mutex_t lock; /* lock for structure */
+ pthread_cond_t readers; /* waiting readers */
+ pthread_cond_t writers; /* waiting writers */
+ int state; /* -1:writer,0:free,>0:readers */
+ int waiters; /* number of waiting writers */
+ my_bool prefer_readers;
+} my_rw_lock_t;
+
+extern int my_rw_init(my_rw_lock_t *, my_bool *);
+extern int my_rw_destroy(my_rw_lock_t *);
extern int my_rw_rdlock(my_rw_lock_t *);
extern int my_rw_wrlock(my_rw_lock_t *);
extern int my_rw_unlock(my_rw_lock_t *);
extern int my_rw_tryrdlock(my_rw_lock_t *);
extern int my_rw_trywrlock(my_rw_lock_t *);
-#endif /* USE_MUTEX_INSTEAD_OF_RW_LOCKS */
+#endif /* NEED_MY_RW_LOCK */
+
#define GETHOSTBYADDR_BUFF_SIZE 2048
@@ -636,6 +703,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);
@@ -659,13 +728,17 @@ extern int pthread_dummy(int);
#endif
#endif
+#include <mysql/psi/mysql_thread.h>
+
+#define INSTRUMENT_ME 0
+
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;
@@ -673,6 +746,7 @@ struct st_my_thread_var
my_bool init;
struct st_my_thread_var *next,**prev;
void *opt_info;
+ void *stack_ends_here;
#ifndef DBUG_OFF
void *dbug;
char name[THREAD_NAME_SIZE+1];
@@ -709,23 +783,30 @@ extern uint thd_lib_detected;
Warning:
When compiling without threads, this file is not included.
See the *other* declarations of thread_safe_xxx in include/my_global.h
-
- Second warning:
- See include/config-win.h, for yet another implementation.
*/
#ifdef THREAD
#ifndef thread_safe_increment
+#ifdef _WIN32
+#define thread_safe_increment(V,L) InterlockedIncrement((long*) &(V))
+#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
#ifndef thread_safe_add
+#ifdef _WIN32
+#define thread_safe_add(V,C,L) InterlockedExchangeAdd((long*) &(V),(C))
+#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_rdtsc.h b/include/my_rdtsc.h
new file mode 100644
index 00000000000..81bc1aafb58
--- /dev/null
+++ b/include/my_rdtsc.h
@@ -0,0 +1,129 @@
+/* Copyright (C) 2008, 2009 Sun Microsystems, Inc
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/*
+ rdtsc3 -- multi-platform timer code
+ pgulutzan@mysql.com, 2005-08-29
+ modified 2008-11-02
+*/
+
+#ifndef MY_RDTSC_H
+#define MY_RDTSC_H
+
+/**
+ Characteristics of a timer.
+*/
+struct my_timer_unit_info
+{
+ /** Routine used for the timer. */
+ ulonglong routine;
+ /** Overhead of the timer. */
+ ulonglong overhead;
+ /** Frequency of the timer. */
+ ulonglong frequency;
+ /** Resolution of the timer. */
+ ulonglong resolution;
+};
+
+/**
+ Characteristics of all the supported timers.
+ @sa my_timer_init().
+*/
+struct my_timer_info
+{
+ /** Characteristics of the cycle timer. */
+ struct my_timer_unit_info cycles;
+ /** Characteristics of the nanosecond timer. */
+ struct my_timer_unit_info nanoseconds;
+ /** Characteristics of the microsecond timer. */
+ struct my_timer_unit_info microseconds;
+ /** Characteristics of the millisecond timer. */
+ struct my_timer_unit_info milliseconds;
+ /** Characteristics of the tick timer. */
+ struct my_timer_unit_info ticks;
+};
+
+typedef struct my_timer_info MY_TIMER_INFO;
+
+C_MODE_START
+
+/**
+ A cycle timer.
+ @return the current timer value, in cycles.
+*/
+ulonglong my_timer_cycles(void);
+
+/**
+ A namoseconds timer.
+ @return the current timer value, in nanoseconds.
+*/
+ulonglong my_timer_nanoseconds(void);
+
+/**
+ A microseconds timer.
+ @return the current timer value, in microseconds.
+*/
+ulonglong my_timer_microseconds(void);
+
+/**
+ A millisecond timer.
+ @return the current timer value, in milliseconds.
+*/
+ulonglong my_timer_milliseconds(void);
+
+/**
+ A ticks timer.
+ @return the current timer value, in ticks.
+*/
+ulonglong my_timer_ticks(void);
+
+/**
+ Timer initialization function.
+ @param [out] mti the timer characteristics.
+*/
+void my_timer_init(MY_TIMER_INFO *mti);
+
+C_MODE_END
+
+#define MY_TIMER_ROUTINE_ASM_X86 1
+#define MY_TIMER_ROUTINE_ASM_X86_64 2
+#define MY_TIMER_ROUTINE_RDTSCLL 3
+#define MY_TIMER_ROUTINE_ASM_X86_WIN 4
+#define MY_TIMER_ROUTINE_RDTSC 5
+#define MY_TIMER_ROUTINE_ASM_IA64 6
+#define MY_TIMER_ROUTINE_ASM_PPC 7
+#define MY_TIMER_ROUTINE_SGI_CYCLE 8
+#define MY_TIMER_ROUTINE_GETHRTIME 9
+#define MY_TIMER_ROUTINE_READ_REAL_TIME 10
+#define MY_TIMER_ROUTINE_CLOCK_GETTIME 11
+#define MY_TIMER_ROUTINE_NXGETTIME 12
+#define MY_TIMER_ROUTINE_GETTIMEOFDAY 13
+#define MY_TIMER_ROUTINE_QUERYPERFORMANCECOUNTER 14
+#define MY_TIMER_ROUTINE_GETTICKCOUNT 15
+#define MY_TIMER_ROUTINE_TIME 16
+#define MY_TIMER_ROUTINE_TIMES 17
+#define MY_TIMER_ROUTINE_FTIME 18
+#define MY_TIMER_ROUTINE_ASM_PPC64 19
+#define MY_TIMER_ROUTINE_ASM_SUNPRO_SPARC64 20
+#define MY_TIMER_ROUTINE_ASM_SUNPRO_SPARC32 21
+#define MY_TIMER_ROUTINE_ASM_SUNPRO_I386 22
+#define MY_TIMER_ROUTINE_ASM_GCC_SPARC64 23
+#define MY_TIMER_ROUTINE_ASM_GCC_SPARC32 24
+#define MY_TIMER_ROUTINE_MACH_ABSOLUTE_TIME 25
+#define MY_TIMER_ROUTINE_GETSYSTEMTIMEASFILETIME 26
+#define MY_TIMER_ROUTINE_ASM_SUNPRO_X86_64 27
+
+#endif
+
diff --git a/include/my_sys.h b/include/my_sys.h
index 9676217a0d1..8e56ef27c2d 100644
--- a/include/my_sys.h
+++ b/include/my_sys.h
@@ -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
@@ -34,6 +34,9 @@ extern int NEAR my_errno; /* Last error in mysys */
#include <m_ctype.h> /* for CHARSET_INFO */
#include <stdarg.h>
#include <typelib.h>
+#ifdef _WIN32
+#include <malloc.h> /*for alloca*/
+#endif
#define MYSYS_PROGRAM_USES_CURSES() { error_handler_hook = my_message_curses; mysys_uses_curses=1; }
#define MYSYS_PROGRAM_DONT_USE_CURSES() { error_handler_hook = my_message_no_curses; mysys_uses_curses=0;}
@@ -60,7 +63,7 @@ extern int NEAR my_errno; /* Last error in mysys */
#define MY_WME 16 /* Write message on error */
#define MY_WAIT_IF_FULL 32 /* Wait and try again if disk full error */
#define MY_IGNORE_BADFD 32 /* my_sync: ignore 'bad descriptor' errors */
-#define MY_SYNC_DIR 1024 /* my_create/delete/rename: sync directory */
+#define MY_SYNC_DIR 8192 /* my_create/delete/rename: sync directory */
#define MY_RAID 64 /* Support for RAID */
#define MY_FULL_IO 512 /* For my_read - loop intil I/O is complete */
#define MY_DONT_CHECK_FILESIZE 128 /* Option to init_io_cache() */
@@ -235,6 +238,9 @@ extern void (*fatal_error_handler_hook)(uint my_err, const char *str,
extern uint my_file_limit;
extern ulong my_thread_stack_size;
+extern const char *(*proc_info_hook)(void *, const char *, const char *,
+ const char *, const unsigned int);
+
#ifdef HAVE_LARGE_PAGES
extern my_bool my_use_large_pages;
extern uint my_large_page_size;
@@ -338,7 +344,7 @@ struct st_my_file_info
#endif
enum file_type type;
#if defined(THREAD) && !defined(HAVE_PREAD) && !defined(_WIN32)
- pthread_mutex_t mutex;
+ mysql_mutex_t mutex;
#endif
};
@@ -358,7 +364,7 @@ typedef struct st_my_tmpdir
char **list;
uint cur, max;
#ifdef THREAD
- pthread_mutex_t mutex;
+ mysql_mutex_t mutex;
#endif
} MY_TMPDIR;
@@ -374,9 +380,9 @@ typedef int (*IO_CACHE_CALLBACK)(struct st_io_cache*);
#ifdef THREAD
typedef struct st_io_cache_share
{
- pthread_mutex_t mutex; /* To sync on reads into buffer. */
- pthread_cond_t cond; /* To wait for signals. */
- pthread_cond_t cond_writer; /* For a synchronized writer. */
+ mysql_mutex_t mutex; /* To sync on reads into buffer. */
+ mysql_cond_t cond; /* To wait for signals. */
+ mysql_cond_t cond_writer; /* For a synchronized writer. */
/* Offset in file corresponding to the first byte of buffer. */
my_off_t pos_in_file;
/* If a synchronized write cache is the source of the data. */
@@ -437,7 +443,7 @@ typedef struct st_io_cache /* Used when cacheing files */
The lock is for append buffer used in SEQ_READ_APPEND cache
need mutex copying from append buffer to read buffer.
*/
- pthread_mutex_t append_buffer_lock;
+ mysql_mutex_t append_buffer_lock;
/*
The following is used when several threads are reading the
same file in parallel. They are synchronized on disk
@@ -691,6 +697,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);
@@ -1017,5 +1024,15 @@ void netware_reg_user(const char *ip, const char *user,
const char *application);
#endif
+#include <mysql/psi/psi.h>
+
+#ifdef HAVE_PSI_INTERFACE
+extern MYSQL_PLUGIN_IMPORT struct PSI_bootstrap *PSI_hook;
+void my_init_mysys_psi_keys(void);
+#endif
+
+struct st_mysql_file;
+extern struct st_mysql_file *mysql_stdin;
+
C_MODE_END
#endif /* _my_sys_h */
diff --git a/include/my_time.h b/include/my_time.h
index 58995f1bf62..829cb706bb6 100644
--- a/include/my_time.h
+++ b/include/my_time.h
@@ -74,12 +74,12 @@ typedef long my_time_t;
TIME_MAX_MINUTE * 60L + TIME_MAX_SECOND)
my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date,
- ulong flags, int *was_cut);
+ ulonglong flags, int *was_cut);
enum enum_mysql_timestamp_type
str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time,
- uint flags, int *was_cut);
+ ulonglong flags, int *was_cut);
longlong number_to_datetime(longlong nr, MYSQL_TIME *time_res,
- uint flags, int *was_cut);
+ ulonglong flags, int *was_cut);
ulonglong TIME_to_ulonglong_datetime(const MYSQL_TIME *);
ulonglong TIME_to_ulonglong_date(const MYSQL_TIME *);
ulonglong TIME_to_ulonglong_time(const MYSQL_TIME *);
diff --git a/include/myisam.h b/include/myisam.h
index 6592a2da177..d590a29c1b3 100644
--- a/include/myisam.h
+++ b/include/myisam.h
@@ -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
@@ -251,7 +251,7 @@ typedef struct st_columndef /* column information */
extern char * myisam_log_filename; /* Name of logfile */
extern ulong myisam_block_size;
-extern ulong myisam_concurrent_insert;
+extern uint myisam_concurrent_insert;
extern my_bool myisam_flush,myisam_delay_key_write,myisam_single_user;
extern my_off_t myisam_max_temp_length;
extern ulong myisam_bulk_insert_tree_size, myisam_data_pointer_size;
@@ -260,7 +260,7 @@ extern ulong myisam_bulk_insert_tree_size, myisam_data_pointer_size;
/* which is normally forbidden */
extern int (*myisam_test_invalid_symlink)(const char *filename);
extern ulonglong myisam_mmap_size, myisam_mmap_used;
-extern pthread_mutex_t THR_LOCK_myisam_mmap;
+extern mysql_mutex_t THR_LOCK_myisam_mmap;
/* Prototypes for myisam-functions */
@@ -436,7 +436,7 @@ typedef struct st_mi_check_param
const char *op_name;
enum_mi_stats_method stats_method;
#ifdef THREAD
- pthread_mutex_t print_msg_mutex;
+ mysql_mutex_t print_msg_mutex;
my_bool need_print_msg_lock;
#endif
} MI_CHECK;
@@ -463,8 +463,8 @@ typedef struct st_sort_info
/* sync things */
uint got_error, threads_running;
#ifdef THREAD
- pthread_mutex_t mutex;
- pthread_cond_t cond;
+ mysql_mutex_t mutex;
+ mysql_cond_t cond;
#endif
} SORT_INFO;
diff --git a/include/myisammrg.h b/include/myisammrg.h
index 31ce3fa47b8..3277510705b 100644
--- a/include/myisammrg.h
+++ b/include/myisammrg.h
@@ -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
@@ -75,7 +75,7 @@ typedef struct st_myrg_info
LIST open_list;
QUEUE by_key;
ulong *rec_per_key_part; /* for sql optimizing */
- pthread_mutex_t mutex;
+ mysql_mutex_t mutex;
} MYRG_INFO;
diff --git a/include/mysql.h.pp b/include/mysql.h.pp
index 0ea1d0974c2..4fef9e9ec0b 100644
--- a/include/mysql.h.pp
+++ b/include/mysql.h.pp
@@ -233,6 +233,10 @@ extern void make_type(char *to,unsigned int nr,TYPELIB *typelib);
extern const char *get_type(TYPELIB *typelib,unsigned int nr);
extern TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from);
extern TYPELIB sql_protocol_typelib;
+my_ulonglong find_set_from_flags(const TYPELIB *lib, uint default_name,
+ my_ulonglong cur_set, my_ulonglong default_set,
+ const char *str, uint length,
+ char **err_pos, uint *err_len);
typedef struct st_mysql_rows {
struct st_mysql_rows *next;
MYSQL_ROW data;
diff --git a/include/mysql/plugin.h b/include/mysql/plugin.h
index c56045f920f..567734c1d5c 100644
--- a/include/mysql/plugin.h
+++ b/include/mysql/plugin.h
@@ -18,10 +18,25 @@
/*
On Windows, exports from DLL need to be declared
-*/
-#if (defined(_WIN32) && defined(MYSQL_DYNAMIC_PLUGIN))
-#define MYSQL_PLUGIN_EXPORT extern "C" __declspec(dllexport)
-#else
+ Also, plugin needs to be declared as extern "C" because MSVC
+ unlike other compilers, uses C++ mangling for variables not only
+ for functions.
+*/
+#if defined(_MSC_VER)
+#if defined(MYSQL_DYNAMIC_PLUGIN)
+ #ifdef __cplusplus
+ #define MYSQL_PLUGIN_EXPORT extern "C" __declspec(dllexport)
+ #else
+ #define MYSQL_PLUGIN_EXPORT __declspec(dllexport)
+ #endif
+#else /* MYSQL_DYNAMIC_PLUGIN */
+ #ifdef __cplusplus
+ #define MYSQL_PLUGIN_EXPORT extern "C"
+ #else
+ #define MYSQL_PLUGIN_EXPORT
+ #endif
+#endif /*MYSQL_DYNAMIC_PLUGIN */
+#else /*_MSC_VER */
#define MYSQL_PLUGIN_EXPORT
#endif
@@ -88,9 +103,9 @@ typedef struct st_mysql_xid MYSQL_XID;
#ifndef MYSQL_DYNAMIC_PLUGIN
#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \
-int VERSION= MYSQL_PLUGIN_INTERFACE_VERSION; \
-int PSIZE= sizeof(struct st_mysql_plugin); \
-struct st_mysql_plugin DECLS[]= {
+MYSQL_PLUGIN_EXPORT int VERSION= MYSQL_PLUGIN_INTERFACE_VERSION; \
+MYSQL_PLUGIN_EXPORT int PSIZE= sizeof(struct st_mysql_plugin); \
+MYSQL_PLUGIN_EXPORT struct st_mysql_plugin DECLS[]= {
#else
#define __MYSQL_DECLARE_PLUGIN(NAME, VERSION, PSIZE, DECLS) \
MYSQL_PLUGIN_EXPORT int _mysql_plugin_interface_version_= MYSQL_PLUGIN_INTERFACE_VERSION; \
@@ -404,205 +419,43 @@ struct st_mysql_plugin
/*************************************************************************
API for Full-text parser plugin. (MYSQL_FTPARSER_PLUGIN)
*/
+#include "plugin_ftparser.h"
-#define MYSQL_FTPARSER_INTERFACE_VERSION 0x0100
-
-/* Parsing modes. Set in MYSQL_FTPARSER_PARAM::mode */
-enum enum_ftparser_mode
-{
-/*
- Fast and simple mode. This mode is used for indexing, and natural
- language queries.
-
- The parser is expected to return only those words that go into the
- index. Stopwords or too short/long words should not be returned. The
- 'boolean_info' argument of mysql_add_word() does not have to be set.
-*/
- MYSQL_FTPARSER_SIMPLE_MODE= 0,
-
-/*
- Parse with stopwords mode. This mode is used in boolean searches for
- "phrase matching."
-
- The parser is not allowed to ignore words in this mode. Every word
- should be returned, including stopwords and words that are too short
- or long. The 'boolean_info' argument of mysql_add_word() does not
- have to be set.
+/*************************************************************************
+ API for Storage Engine plugin. (MYSQL_DAEMON_PLUGIN)
*/
- MYSQL_FTPARSER_WITH_STOPWORDS= 1,
-/*
- Parse in boolean mode. This mode is used to parse a boolean query string.
-
- The parser should provide a valid MYSQL_FTPARSER_BOOLEAN_INFO
- structure in the 'boolean_info' argument to mysql_add_word().
- Usually that means that the parser should recognize boolean operators
- in the parsing stream and set appropriate fields in
- MYSQL_FTPARSER_BOOLEAN_INFO structure accordingly. As for
- MYSQL_FTPARSER_WITH_STOPWORDS mode, no word should be ignored.
- Instead, use FT_TOKEN_STOPWORD for the token type of such a word.
-*/
- MYSQL_FTPARSER_FULL_BOOLEAN_INFO= 2
-};
+/* handlertons of different MySQL releases are incompatible */
+#define MYSQL_DAEMON_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
/*
- Token types for boolean mode searching (used for the type member of
- MYSQL_FTPARSER_BOOLEAN_INFO struct)
-
- FT_TOKEN_EOF: End of data.
- FT_TOKEN_WORD: Regular word.
- FT_TOKEN_LEFT_PAREN: Left parenthesis (start of group/sub-expression).
- FT_TOKEN_RIGHT_PAREN: Right parenthesis (end of group/sub-expression).
- FT_TOKEN_STOPWORD: Stopword.
+ Here we define only the descriptor structure, that is referred from
+ st_mysql_plugin.
*/
-enum enum_ft_token_type
+struct st_mysql_daemon
{
- FT_TOKEN_EOF= 0,
- FT_TOKEN_WORD= 1,
- FT_TOKEN_LEFT_PAREN= 2,
- FT_TOKEN_RIGHT_PAREN= 3,
- FT_TOKEN_STOPWORD= 4
+ int interface_version;
};
-/*
- This structure is used in boolean search mode only. It conveys
- boolean-mode metadata to the MySQL search engine for every word in
- the search query. A valid instance of this structure must be filled
- in by the plugin parser and passed as an argument in the call to
- mysql_add_word (the callback function in the MYSQL_FTPARSER_PARAM
- structure) when a query is parsed in boolean mode.
-
- type: The token type. Should be one of the enum_ft_token_type values.
-
- yesno: Whether the word must be present for a match to occur:
- >0 Must be present
- <0 Must not be present
- 0 Neither; the word is optional but its presence increases the relevance
- With the default settings of the ft_boolean_syntax system variable,
- >0 corresponds to the '+' operator, <0 corrresponds to the '-' operator,
- and 0 means neither operator was used.
-
- weight_adjust: A weighting factor that determines how much a match
- for the word counts. Positive values increase, negative - decrease the
- relative word's importance in the query.
-
- wasign: The sign of the word's weight in the query. If it's non-negative
- the match for the word will increase document relevance, if it's
- negative - decrease (the word becomes a "noise word", the less of it the
- better).
-
- trunc: Corresponds to the '*' operator in the default setting of the
- ft_boolean_syntax system variable.
-*/
-
-typedef struct st_mysql_ftparser_boolean_info
-{
- enum enum_ft_token_type type;
- int yesno;
- int weight_adjust;
- char wasign;
- char trunc;
- /* These are parser state and must be removed. */
- char prev;
- char *quot;
-} MYSQL_FTPARSER_BOOLEAN_INFO;
-
-/*
- The following flag means that buffer with a string (document, word)
- may be overwritten by the caller before the end of the parsing (that is
- before st_mysql_ftparser::deinit() call). If one needs the string
- to survive between two successive calls of the parsing function, she
- needs to save a copy of it. The flag may be set by MySQL before calling
- st_mysql_ftparser::parse(), or it may be set by a plugin before calling
- st_mysql_ftparser_param::mysql_parse() or
- st_mysql_ftparser_param::mysql_add_word().
-*/
-#define MYSQL_FTFLAGS_NEED_COPY 1
-
-/*
- An argument of the full-text parser plugin. This structure is
- filled in by MySQL server and passed to the parsing function of the
- plugin as an in/out parameter.
-
- mysql_parse: A pointer to the built-in parser implementation of the
- server. It's set by the server and can be used by the parser plugin
- to invoke the MySQL default parser. If plugin's role is to extract
- textual data from .doc, .pdf or .xml content, it might extract
- plaintext from the content, and then pass the text to the default
- MySQL parser to be parsed.
- mysql_add_word: A server callback to add a new word. When parsing
- a document, the server sets this to point at a function that adds
- the word to MySQL full-text index. When parsing a search query,
- this function will add the new word to the list of words to search
- for. The boolean_info argument can be NULL for all cases except
- when mode is MYSQL_FTPARSER_FULL_BOOLEAN_INFO.
-
- ftparser_state: A generic pointer. The plugin can set it to point
- to information to be used internally for its own purposes.
-
- mysql_ftparam: This is set by the server. It is used by MySQL functions
- called via mysql_parse() and mysql_add_word() callback. The plugin
- should not modify it.
-
- cs: Information about the character set of the document or query string.
-
- doc: A pointer to the document or query string to be parsed.
-
- length: Length of the document or query string, in bytes.
-
- flags: See MYSQL_FTFLAGS_* constants above.
-
- mode: The parsing mode. With boolean operators, with stopwords, or
- nothing. See enum_ftparser_mode above.
+/*************************************************************************
+ API for I_S plugin. (MYSQL_INFORMATION_SCHEMA_PLUGIN)
*/
-typedef struct st_mysql_ftparser_param
-{
- int (*mysql_parse)(struct st_mysql_ftparser_param *,
- char *doc, int doc_len);
- int (*mysql_add_word)(struct st_mysql_ftparser_param *,
- char *word, int word_len,
- MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
- void *ftparser_state;
- void *mysql_ftparam;
- struct charset_info_st *cs;
- char *doc;
- int length;
- int flags;
- enum enum_ftparser_mode mode;
-} MYSQL_FTPARSER_PARAM;
+/* handlertons of different MySQL releases are incompatible */
+#define MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
/*
- Full-text parser descriptor.
-
- interface_version is, e.g., MYSQL_FTPARSER_INTERFACE_VERSION.
- The parsing, initialization, and deinitialization functions are
- invoked per SQL statement for which the parser is used.
+ Here we define only the descriptor structure, that is referred from
+ st_mysql_plugin.
*/
-struct st_mysql_ftparser
+struct st_mysql_information_schema
{
int interface_version;
- int (*parse)(MYSQL_FTPARSER_PARAM *param);
- int (*init)(MYSQL_FTPARSER_PARAM *param);
- int (*deinit)(MYSQL_FTPARSER_PARAM *param);
};
-/*************************************************************************
- API for Storage Engine plugin. (MYSQL_DAEMON_PLUGIN)
-*/
-
-/* handlertons of different MySQL releases are incompatible */
-#define MYSQL_DAEMON_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
-
-/*************************************************************************
- API for I_S plugin. (MYSQL_INFORMATION_SCHEMA_PLUGIN)
-*/
-
-/* handlertons of different MySQL releases are incompatible */
-#define MYSQL_INFORMATION_SCHEMA_INTERFACE_VERSION (MYSQL_VERSION_ID << 8)
/*************************************************************************
API for Storage Engine plugin. (MYSQL_STORAGE_ENGINE_PLUGIN)
@@ -624,25 +477,6 @@ struct st_mysql_storage_engine
struct handlerton;
-/*
- Here we define only the descriptor structure, that is referred from
- st_mysql_plugin.
-*/
-
-struct st_mysql_daemon
-{
- int interface_version;
-};
-
-/*
- Here we define only the descriptor structure, that is referred from
- st_mysql_plugin.
-*/
-
-struct st_mysql_information_schema
-{
- int interface_version;
-};
/*
API for Replication plugin. (MYSQL_REPLICATION_PLUGIN)
@@ -656,7 +490,7 @@ struct st_mysql_information_schema
int interface_version;
};
-/*
+/*************************************************************************
st_mysql_value struct for reading values from mysqld.
Used by server variables framework to parse user-provided values.
Will be used for arguments when implementing UDFs.
@@ -676,6 +510,7 @@ struct st_mysql_value
const char *(*val_str)(struct st_mysql_value *, char *buffer, int *length);
int (*val_real)(struct st_mysql_value *, double *realbuf);
int (*val_int)(struct st_mysql_value *, long long *intbuf);
+ int (*is_unsigned)(struct st_mysql_value *);
};
diff --git a/include/mysql/plugin.h.pp b/include/mysql/plugin.h.pp
index b7dd7bc0032..5dad31bd008 100644
--- a/include/mysql/plugin.h.pp
+++ b/include/mysql/plugin.h.pp
@@ -76,6 +76,8 @@ struct st_mysql_plugin
struct st_mysql_sys_var **system_vars;
void * __reserved1;
};
+#include "plugin_ftparser.h"
+#include "plugin.h"
enum enum_ftparser_mode
{
MYSQL_FTPARSER_SIMPLE_MODE= 0,
@@ -122,19 +124,19 @@ struct st_mysql_ftparser
int (*init)(MYSQL_FTPARSER_PARAM *param);
int (*deinit)(MYSQL_FTPARSER_PARAM *param);
};
-struct st_mysql_storage_engine
+struct st_mysql_daemon
{
int interface_version;
};
-struct handlerton;
-struct st_mysql_daemon
+struct st_mysql_information_schema
{
int interface_version;
};
-struct st_mysql_information_schema
+struct st_mysql_storage_engine
{
int interface_version;
};
+struct handlerton;
struct Mysql_replication {
int interface_version;
};
@@ -144,6 +146,7 @@ struct st_mysql_value
const char *(*val_str)(struct st_mysql_value *, char *buffer, int *length);
int (*val_real)(struct st_mysql_value *, double *realbuf);
int (*val_int)(struct st_mysql_value *, long long *intbuf);
+ int (*is_unsigned)(struct st_mysql_value *);
};
int thd_in_lock_tables(const void* thd);
int thd_tablespace_op(const void* thd);
diff --git a/include/mysql/plugin_audit.h b/include/mysql/plugin_audit.h
new file mode 100644
index 00000000000..8932767075d
--- /dev/null
+++ b/include/mysql/plugin_audit.h
@@ -0,0 +1,97 @@
+/* Copyright (C) 2007 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef _my_audit_h
+#define _my_audit_h
+
+/*************************************************************************
+ API for Audit plugin. (MYSQL_AUDIT_PLUGIN)
+*/
+
+#include "plugin.h"
+
+#define MYSQL_AUDIT_CLASS_MASK_SIZE 1
+
+#define MYSQL_AUDIT_INTERFACE_VERSION 0x0100
+
+/*
+ The first word in every event class struct indicates the specific
+ class of the event.
+*/
+struct mysql_event
+{
+ int event_class;
+};
+
+
+/*************************************************************************
+ AUDIT CLASS : GENERAL
+
+ LOG events occurs before emitting to the general query log.
+ ERROR events occur before transmitting errors to the user.
+ RESULT events occur after transmitting a resultset to the user.
+*/
+
+#define MYSQL_AUDIT_GENERAL_CLASS 0
+#define MYSQL_AUDIT_GENERAL_CLASSMASK (1 << MYSQL_AUDIT_GENERAL_CLASS)
+#define MYSQL_AUDIT_GENERAL_LOG 0
+#define MYSQL_AUDIT_GENERAL_ERROR 1
+#define MYSQL_AUDIT_GENERAL_RESULT 2
+
+struct mysql_event_general
+{
+ int event_class;
+ int general_error_code;
+ unsigned long general_thread_id;
+ const char *general_user;
+ unsigned int general_user_length;
+ const char *general_command;
+ unsigned int general_command_length;
+ const char *general_query;
+ unsigned int general_query_length;
+ struct charset_info_st *general_charset;
+ unsigned long long general_time;
+ unsigned long long general_rows;
+};
+
+
+/*************************************************************************
+ Here we define the descriptor structure, that is referred from
+ st_mysql_plugin.
+
+ release_thd() event occurs when the event class consumer is to be
+ disassociated from the specified THD. This would typically occur
+ before some operation which may require sleeping - such as when
+ waiting for the next query from the client.
+
+ event_notify() is invoked whenever an event occurs which is of any
+ class for which the plugin has interest. The first word of the
+ mysql_event argument indicates the specific event class and the
+ remainder of the structure is as required for that class.
+
+ class_mask is an array of bits used to indicate what event classes
+ that this plugin wants to receive.
+*/
+
+struct st_mysql_audit
+{
+ int interface_version;
+ void (*release_thd)(MYSQL_THD);
+ void (*event_notify)(MYSQL_THD, const struct mysql_event *);
+ unsigned long class_mask[MYSQL_AUDIT_CLASS_MASK_SIZE];
+};
+
+
+#endif
diff --git a/include/mysql/plugin_ftparser.h b/include/mysql/plugin_ftparser.h
new file mode 100644
index 00000000000..7f9bde3a6a0
--- /dev/null
+++ b/include/mysql/plugin_ftparser.h
@@ -0,0 +1,211 @@
+/* Copyright (C) 2005 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef _my_plugin_ftparser_h
+#define _my_plugin_ftparser_h
+#include "plugin.h"
+
+/*************************************************************************
+ API for Full-text parser plugin. (MYSQL_FTPARSER_PLUGIN)
+*/
+
+#define MYSQL_FTPARSER_INTERFACE_VERSION 0x0100
+
+/* Parsing modes. Set in MYSQL_FTPARSER_PARAM::mode */
+enum enum_ftparser_mode
+{
+/*
+ Fast and simple mode. This mode is used for indexing, and natural
+ language queries.
+
+ The parser is expected to return only those words that go into the
+ index. Stopwords or too short/long words should not be returned. The
+ 'boolean_info' argument of mysql_add_word() does not have to be set.
+*/
+ MYSQL_FTPARSER_SIMPLE_MODE= 0,
+
+/*
+ Parse with stopwords mode. This mode is used in boolean searches for
+ "phrase matching."
+
+ The parser is not allowed to ignore words in this mode. Every word
+ should be returned, including stopwords and words that are too short
+ or long. The 'boolean_info' argument of mysql_add_word() does not
+ have to be set.
+*/
+ MYSQL_FTPARSER_WITH_STOPWORDS= 1,
+
+/*
+ Parse in boolean mode. This mode is used to parse a boolean query string.
+
+ The parser should provide a valid MYSQL_FTPARSER_BOOLEAN_INFO
+ structure in the 'boolean_info' argument to mysql_add_word().
+ Usually that means that the parser should recognize boolean operators
+ in the parsing stream and set appropriate fields in
+ MYSQL_FTPARSER_BOOLEAN_INFO structure accordingly. As for
+ MYSQL_FTPARSER_WITH_STOPWORDS mode, no word should be ignored.
+ Instead, use FT_TOKEN_STOPWORD for the token type of such a word.
+*/
+ MYSQL_FTPARSER_FULL_BOOLEAN_INFO= 2
+};
+
+/*
+ Token types for boolean mode searching (used for the type member of
+ MYSQL_FTPARSER_BOOLEAN_INFO struct)
+
+ FT_TOKEN_EOF: End of data.
+ FT_TOKEN_WORD: Regular word.
+ FT_TOKEN_LEFT_PAREN: Left parenthesis (start of group/sub-expression).
+ FT_TOKEN_RIGHT_PAREN: Right parenthesis (end of group/sub-expression).
+ FT_TOKEN_STOPWORD: Stopword.
+*/
+
+enum enum_ft_token_type
+{
+ FT_TOKEN_EOF= 0,
+ FT_TOKEN_WORD= 1,
+ FT_TOKEN_LEFT_PAREN= 2,
+ FT_TOKEN_RIGHT_PAREN= 3,
+ FT_TOKEN_STOPWORD= 4
+};
+
+/*
+ This structure is used in boolean search mode only. It conveys
+ boolean-mode metadata to the MySQL search engine for every word in
+ the search query. A valid instance of this structure must be filled
+ in by the plugin parser and passed as an argument in the call to
+ mysql_add_word (the callback function in the MYSQL_FTPARSER_PARAM
+ structure) when a query is parsed in boolean mode.
+
+ type: The token type. Should be one of the enum_ft_token_type values.
+
+ yesno: Whether the word must be present for a match to occur:
+ >0 Must be present
+ <0 Must not be present
+ 0 Neither; the word is optional but its presence increases the relevance
+ With the default settings of the ft_boolean_syntax system variable,
+ >0 corresponds to the '+' operator, <0 corrresponds to the '-' operator,
+ and 0 means neither operator was used.
+
+ weight_adjust: A weighting factor that determines how much a match
+ for the word counts. Positive values increase, negative - decrease the
+ relative word's importance in the query.
+
+ wasign: The sign of the word's weight in the query. If it's non-negative
+ the match for the word will increase document relevance, if it's
+ negative - decrease (the word becomes a "noise word", the less of it the
+ better).
+
+ trunc: Corresponds to the '*' operator in the default setting of the
+ ft_boolean_syntax system variable.
+*/
+
+typedef struct st_mysql_ftparser_boolean_info
+{
+ enum enum_ft_token_type type;
+ int yesno;
+ int weight_adjust;
+ char wasign;
+ char trunc;
+ /* These are parser state and must be removed. */
+ char prev;
+ char *quot;
+} MYSQL_FTPARSER_BOOLEAN_INFO;
+
+/*
+ The following flag means that buffer with a string (document, word)
+ may be overwritten by the caller before the end of the parsing (that is
+ before st_mysql_ftparser::deinit() call). If one needs the string
+ to survive between two successive calls of the parsing function, she
+ needs to save a copy of it. The flag may be set by MySQL before calling
+ st_mysql_ftparser::parse(), or it may be set by a plugin before calling
+ st_mysql_ftparser_param::mysql_parse() or
+ st_mysql_ftparser_param::mysql_add_word().
+*/
+#define MYSQL_FTFLAGS_NEED_COPY 1
+
+/*
+ An argument of the full-text parser plugin. This structure is
+ filled in by MySQL server and passed to the parsing function of the
+ plugin as an in/out parameter.
+
+ mysql_parse: A pointer to the built-in parser implementation of the
+ server. It's set by the server and can be used by the parser plugin
+ to invoke the MySQL default parser. If plugin's role is to extract
+ textual data from .doc, .pdf or .xml content, it might extract
+ plaintext from the content, and then pass the text to the default
+ MySQL parser to be parsed.
+
+ mysql_add_word: A server callback to add a new word. When parsing
+ a document, the server sets this to point at a function that adds
+ the word to MySQL full-text index. When parsing a search query,
+ this function will add the new word to the list of words to search
+ for. The boolean_info argument can be NULL for all cases except
+ when mode is MYSQL_FTPARSER_FULL_BOOLEAN_INFO.
+
+ ftparser_state: A generic pointer. The plugin can set it to point
+ to information to be used internally for its own purposes.
+
+ mysql_ftparam: This is set by the server. It is used by MySQL functions
+ called via mysql_parse() and mysql_add_word() callback. The plugin
+ should not modify it.
+
+ cs: Information about the character set of the document or query string.
+
+ doc: A pointer to the document or query string to be parsed.
+
+ length: Length of the document or query string, in bytes.
+
+ flags: See MYSQL_FTFLAGS_* constants above.
+
+ mode: The parsing mode. With boolean operators, with stopwords, or
+ nothing. See enum_ftparser_mode above.
+*/
+
+typedef struct st_mysql_ftparser_param
+{
+ int (*mysql_parse)(struct st_mysql_ftparser_param *,
+ char *doc, int doc_len);
+ int (*mysql_add_word)(struct st_mysql_ftparser_param *,
+ char *word, int word_len,
+ MYSQL_FTPARSER_BOOLEAN_INFO *boolean_info);
+ void *ftparser_state;
+ void *mysql_ftparam;
+ struct charset_info_st *cs;
+ char *doc;
+ int length;
+ int flags;
+ enum enum_ftparser_mode mode;
+} MYSQL_FTPARSER_PARAM;
+
+/*
+ Full-text parser descriptor.
+
+ interface_version is, e.g., MYSQL_FTPARSER_INTERFACE_VERSION.
+ The parsing, initialization, and deinitialization functions are
+ invoked per SQL statement for which the parser is used.
+*/
+
+struct st_mysql_ftparser
+{
+ int interface_version;
+ int (*parse)(MYSQL_FTPARSER_PARAM *param);
+ int (*init)(MYSQL_FTPARSER_PARAM *param);
+ int (*deinit)(MYSQL_FTPARSER_PARAM *param);
+};
+
+
+#endif
+
diff --git a/include/mysql/psi/mysql_file.h b/include/mysql/psi/mysql_file.h
new file mode 100644
index 00000000000..18220a8dd4e
--- /dev/null
+++ b/include/mysql/psi/mysql_file.h
@@ -0,0 +1,1398 @@
+/* Copyright (C) 2008-2009 Sun Microsystems, Inc
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef MYSQL_FILE_H
+#define MYSQL_FILE_H
+
+/* For strlen() */
+#include <string.h>
+/* For MY_STAT */
+#include <my_dir.h>
+
+/**
+ @file mysql/psi/mysql_file.h
+ Instrumentation helpers for mysys file io.
+ This header file provides the necessary declarations
+ to use the mysys file API with the performance schema instrumentation.
+ In some compilers (SunStudio), 'static inline' functions, when declared
+ but not used, are not optimized away (because they are unused) by default,
+ so that including a static inline function from a header file does
+ create unwanted dependencies, causing unresolved symbols at link time.
+ Other compilers, like gcc, optimize these dependencies by default.
+
+ Since the instrumented APIs declared here are wrapper on top
+ of mysys file io APIs, including mysql/psi/mysql_file.h assumes that
+ the dependency on my_sys already exists.
+*/
+
+#include "mysql/psi/psi.h"
+
+/**
+ @defgroup File_instrumentation File Instrumentation
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ @def mysql_file_fgets(P1, P2, F)
+ Instrumented fgets.
+ @c mysql_file_fgets is a replacement for @c fgets.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_fgets(P1, P2, F) \
+ inline_mysql_file_fgets(__FILE__, __LINE__, P1, P2, F)
+#else
+ #define mysql_file_fgets(P1, P2, F) \
+ inline_mysql_file_fgets(P1, P2, F)
+#endif
+
+/**
+ @def mysql_file_fgetc(F)
+ Instrumented fgetc.
+ @c mysql_file_fgetc is a replacement for @c fgetc.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_fgetc(F) inline_mysql_file_fgetc(__FILE__, __LINE__, F)
+#else
+ #define mysql_file_fgetc(F) inline_mysql_file_fgetc(F)
+#endif
+
+/**
+ @def mysql_file_fputs(P1, F)
+ Instrumented fputs.
+ @c mysql_file_fputs is a replacement for @c fputs.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_fputs(P1, F) \
+ inline_mysql_file_fputs(__FILE__, __LINE__, P1, F)
+#else
+ #define mysql_file_fputs(P1, F)\
+ inline_mysql_file_fputs(P1, F)
+#endif
+
+/**
+ @def mysql_file_fputc(P1, F)
+ Instrumented fputc.
+ @c mysql_file_fputc is a replacement for @c fputc.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_fputc(P1, F) \
+ inline_mysql_file_fputc(__FILE__, __LINE__, P1, F)
+#else
+ #define mysql_file_fputc(P1, F) \
+ inline_mysql_file_fputc(P1, F)
+#endif
+
+/**
+ @def mysql_file_fprintf
+ Instrumented fprintf.
+ @c mysql_file_fprintf is a replacement for @c fprintf.
+*/
+#define mysql_file_fprintf inline_mysql_file_fprintf
+
+/**
+ @def mysql_file_vfprintf(F, P1, P2)
+ Instrumented vfprintf.
+ @c mysql_file_vfprintf is a replacement for @c vfprintf.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_vfprintf(F, P1, P2) \
+ inline_mysql_file_vfprintf(__FILE__, __LINE__, F, P1, P2)
+#else
+ #define mysql_file_vfprintf(F, P1, P2) \
+ inline_mysql_file_vfprintf(F, P1, P2)
+#endif
+
+/**
+ @def mysql_file_fflush(F, P1, P2)
+ Instrumented fflush.
+ @c mysql_file_fflush is a replacement for @c fflush.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_fflush(F) \
+ inline_mysql_file_fflush(__FILE__, __LINE__, F)
+#else
+ #define mysql_file_fflush(F) \
+ inline_mysql_file_fflush(F)
+#endif
+
+/**
+ @def mysql_file_feof(F)
+ Instrumented feof.
+ @c mysql_file_feof is a replacement for @c feof.
+*/
+#define mysql_file_feof(F) inline_mysql_file_feof(F)
+
+/**
+ @def mysql_file_fstat(FN, S, FL)
+ Instrumented fstat.
+ @c mysql_file_fstat is a replacement for @c my_fstat.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_fstat(FN, S, FL) \
+ inline_mysql_file_fstat(__FILE__, __LINE__, FN, S, FL)
+#else
+ #define mysql_file_fstat(FN, S, FL) \
+ inline_mysql_file_fstat(FN, S, FL)
+#endif
+
+/**
+ @def mysql_file_stat(K, FN, S, FL)
+ Instrumented stat.
+ @c mysql_file_stat is a replacement for @c my_stat.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_stat(K, FN, S, FL) \
+ inline_mysql_file_stat(K, __FILE__, __LINE__, FN, S, FL)
+#else
+ #define mysql_file_stat(K, FN, S, FL) \
+ inline_mysql_file_stat(FN, S, FL)
+#endif
+
+/**
+ @def mysql_file_chsize(F, P1, P2, P3)
+ Instrumented chsize.
+ @c mysql_file_chsize is a replacement for @c my_chsize.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_chsize(F, P1, P2, P3) \
+ inline_mysql_file_chsize(__FILE__, __LINE__, F, P1, P2, P3)
+#else
+ #define mysql_file_chsize(F, P1, P2, P3) \
+ inline_mysql_file_chsize(F, P1, P2, P3)
+#endif
+
+/**
+ @def mysql_file_fopen(K, N, F1, F2)
+ Instrumented fopen.
+ @c mysql_file_fopen is a replacement for @c my_fopen.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_fopen(K, N, F1, F2) \
+ inline_mysql_file_fopen(K, __FILE__, __LINE__, N, F1, F2)
+#else
+ #define mysql_file_fopen(K, N, F1, F2) \
+ inline_mysql_file_fopen(N, F1, F2)
+#endif
+
+/**
+ @def mysql_file_fclose(FD, FL)
+ Instrumented fclose.
+ @c mysql_file_fclose is a replacement for @c my_fclose.
+ Without the instrumentation, this call will have the same behavior as the
+ undocumented and possibly platform specific my_fclose(NULL, ...) behavior.
+ With the instrumentation, mysql_fclose(NULL, ...) will safely return 0,
+ which is an extension compared to my_fclose and is therefore compliant.
+ mysql_fclose is on purpose *not* implementing
+ @code DBUG_ASSERT(file != NULL) @endcode,
+ since doing so could introduce regressions.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_fclose(FD, FL) \
+ inline_mysql_file_fclose(__FILE__, __LINE__, FD, FL)
+#else
+ #define mysql_file_fclose(FD, FL) \
+ inline_mysql_file_fclose(FD, FL)
+#endif
+
+/**
+ @def mysql_file_fread(FD, P1, P2, P3)
+ Instrumented fread.
+ @c mysql_file_fread is a replacement for @c my_fread.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_fread(FD, P1, P2, P3) \
+ inline_mysql_file_fread(__FILE__, __LINE__, FD, P1, P2, P3)
+#else
+ #define mysql_file_fread(FD, P1, P2, P3) \
+ inline_mysql_file_fread(FD, P1, P2, P3)
+#endif
+
+/**
+ @def mysql_file_fwrite(FD, P1, P2, P3)
+ Instrumented fwrite.
+ @c mysql_file_fwrite is a replacement for @c my_fwrite.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_fwrite(FD, P1, P2, P3) \
+ inline_mysql_file_fwrite(__FILE__, __LINE__, FD, P1, P2, P3)
+#else
+ #define mysql_file_fwrite(FD, P1, P2, P3) \
+ inline_mysql_file_fwrite(FD, P1, P2, P3)
+#endif
+
+/**
+ @def mysql_file_fseek(FD, P, W, F)
+ Instrumented fseek.
+ @c mysql_file_fseek is a replacement for @c my_fseek.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_fseek(FD, P, W, F) \
+ inline_mysql_file_fseek(__FILE__, __LINE__, FD, P, W, F)
+#else
+ #define mysql_file_fseek(FD, P, W, F) \
+ inline_mysql_file_fseek(FD, P, W, F)
+#endif
+
+/**
+ @def mysql_file_ftell(FD, F)
+ Instrumented ftell.
+ @c mysql_file_ftell is a replacement for @c my_ftell.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_ftell(FD, F) \
+ inline_mysql_file_ftell(__FILE__, __LINE__, FD, F)
+#else
+ #define mysql_file_ftell(FD, F) \
+ inline_mysql_file_ftell(FD, F)
+#endif
+
+/**
+ @def mysql_file_create(K, N, F1, F2, F3)
+ Instrumented create.
+ @c mysql_file_create is a replacement for @c my_create.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_create(K, N, F1, F2, F3) \
+ inline_mysql_file_create(K, __FILE__, __LINE__, N, F1, F2, F3)
+#else
+ #define mysql_file_create(K, N, F1, F2, F3) \
+ inline_mysql_file_create(N, F1, F2, F3)
+#endif
+
+/**
+ @def mysql_file_create_temp(K, T, D, P, M, F)
+ Instrumented create_temp_file.
+ @c mysql_file_create_temp is a replacement for @c create_temp_file.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_create_temp(K, T, D, P, M, F) \
+ inline_mysql_file_create_temp(K, T, D, P, M, F)
+#else
+ #define mysql_file_create_temp(K, T, D, P, M, F) \
+ inline_mysql_file_create_temp(T, D, P, M, F)
+#endif
+
+/**
+ @def mysql_file_open(K, N, F1, F2)
+ Instrumented open.
+ @c mysql_file_open is a replacement for @c my_open.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_open(K, N, F1, F2) \
+ inline_mysql_file_open(K, __FILE__, __LINE__, N, F1, F2)
+#else
+ #define mysql_file_open(K, N, F1, F2) \
+ inline_mysql_file_open(N, F1, F2)
+#endif
+
+/**
+ @def mysql_file_close(FD, F)
+ Instrumented close.
+ @c mysql_file_close is a replacement for @c my_close.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_close(FD, F) \
+ inline_mysql_file_close(__FILE__, __LINE__, FD, F)
+#else
+ #define mysql_file_close(FD, F) \
+ inline_mysql_file_close(FD, F)
+#endif
+
+/**
+ @def mysql_file_read(FD, B, S, F)
+ Instrumented read.
+ @c mysql_read is a replacement for @c my_read.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_read(FD, B, S, F) \
+ inline_mysql_file_read(__FILE__, __LINE__, FD, B, S, F)
+#else
+ #define mysql_file_read(FD, B, S, F) \
+ inline_mysql_file_read(FD, B, S, F)
+#endif
+
+/**
+ @def mysql_file_write(FD, B, S, F)
+ Instrumented write.
+ @c mysql_file_write is a replacement for @c my_write.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_write(FD, B, S, F) \
+ inline_mysql_file_write(__FILE__, __LINE__, FD, B, S, F)
+#else
+ #define mysql_file_write(FD, B, S, F) \
+ inline_mysql_file_write(FD, B, S, F)
+#endif
+
+/**
+ @def mysql_file_pread(FD, B, S, O, F)
+ Instrumented pread.
+ @c mysql_pread is a replacement for @c my_pread.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_pread(FD, B, S, O, F) \
+ inline_mysql_file_pread(__FILE__, __LINE__, FD, B, S, O, F)
+#else
+ #define mysql_file_pread(FD, B, S, O, F) \
+ inline_mysql_file_pread(FD, B, S, O, F)
+#endif
+
+/**
+ @def mysql_file_pwrite(FD, B, S, O, F)
+ Instrumented pwrite.
+ @c mysql_file_pwrite is a replacement for @c my_pwrite.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_pwrite(FD, B, S, O, F) \
+ inline_mysql_file_pwrite(__FILE__, __LINE__, FD, B, S, O, F)
+#else
+ #define mysql_file_pwrite(FD, B, S, O, F) \
+ inline_mysql_file_pwrite(FD, B, S, O, F)
+#endif
+
+/**
+ @def mysql_file_seek(FD, P, W, F)
+ Instrumented seek.
+ @c mysql_file_seek is a replacement for @c my_seek.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_seek(FD, P, W, F) \
+ inline_mysql_file_seek(__FILE__, __LINE__, FD, P, W, F)
+#else
+ #define mysql_file_seek(FD, P, W, F) \
+ inline_mysql_file_seek(FD, P, W, F)
+#endif
+
+/**
+ @def mysql_file_tell(FD, F)
+ Instrumented tell.
+ @c mysql_file_tell is a replacement for @c my_tell.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_tell(FD, F) \
+ inline_mysql_file_tell(__FILE__, __LINE__, FD, F)
+#else
+ #define mysql_file_tell(FD, F) \
+ inline_mysql_file_tell(FD, F)
+#endif
+
+/**
+ @def mysql_file_delete(K, P1, P2)
+ Instrumented delete.
+ @c mysql_file_delete is a replacement for @c my_delete.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_delete(K, P1, P2) \
+ inline_mysql_file_delete(K, __FILE__, __LINE__, P1, P2)
+#else
+ #define mysql_file_delete(K, P1, P2) \
+ inline_mysql_file_delete(P1, P2)
+#endif
+
+/**
+ @def mysql_file_rename(K, P1, P2, P3)
+ Instrumented rename.
+ @c mysql_file_rename is a replacement for @c my_rename.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_rename(K, P1, P2, P3) \
+ inline_mysql_file_rename(K, __FILE__, __LINE__, P1, P2, P3)
+#else
+ #define mysql_file_rename(K, P1, P2, P3) \
+ inline_mysql_file_rename(P1, P2, P3)
+#endif
+
+/**
+ @def mysql_file_create_with_symlink(K, P1, P2, P3, P4, P5)
+ Instrumented create with symbolic link.
+ @c mysql_file_create_with_symlink is a replacement
+ for @c my_create_with_symlink.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_create_with_symlink(K, P1, P2, P3, P4, P5) \
+ inline_mysql_file_create_with_symlink(K, __FILE__, __LINE__, \
+ P1, P2, P3, P4, P5)
+#else
+ #define mysql_file_create_with_symlink(K, P1, P2, P3, P4, P5) \
+ inline_mysql_file_create_with_symlink(P1, P2, P3, P4, P5)
+#endif
+
+/**
+ @def mysql_file_delete_with_symlink(K, P1, P2)
+ Instrumented delete with symbolic link.
+ @c mysql_file_delete_with_symlink is a replacement
+ for @c my_delete_with_symlink.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_delete_with_symlink(K, P1, P2) \
+ inline_mysql_file_delete_with_symlink(K, __FILE__, __LINE__, P1, P2)
+#else
+ #define mysql_file_delete_with_symlink(K, P1, P2) \
+ inline_mysql_file_delete_with_symlink(P1, P2)
+#endif
+
+/**
+ @def mysql_file_rename_with_symlink(K, P1, P2, P3)
+ Instrumented rename with symbolic link.
+ @c mysql_file_rename_with_symlink is a replacement
+ for @c my_rename_with_symlink.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_rename_with_symlink(K, P1, P2, P3) \
+ inline_mysql_file_rename_with_symlink(K, __FILE__, __LINE__, P1, P2, P3)
+#else
+ #define mysql_file_rename_with_symlink(K, P1, P2, P3) \
+ inline_mysql_file_rename_with_symlink(P1, P2, P3)
+#endif
+
+/**
+ @def mysql_file_sync(P1, P2)
+ Instrumented file sync.
+ @c mysql_file_sync is a replacement for @c my_sync.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_file_sync(P1, P2) \
+ inline_mysql_file_sync(__FILE__, __LINE__, P1, P2)
+#else
+ #define mysql_file_sync(P1, P2) \
+ inline_mysql_file_sync(P1, P2)
+#endif
+
+/**
+ An instrumented FILE structure.
+ @sa MYSQL_FILE
+*/
+struct st_mysql_file
+{
+ /** The real file. */
+ FILE *m_file;
+ /**
+ The instrumentation hook.
+ Note that this hook is not conditionally defined,
+ for binary compatibility of the @c MYSQL_FILE interface.
+ */
+ struct PSI_file *m_psi;
+};
+
+/**
+ Type of an instrumented file.
+ @c MYSQL_FILE is a drop-in replacement for @c FILE.
+ @sa mysql_file_open
+*/
+typedef struct st_mysql_file MYSQL_FILE;
+
+static inline char *
+inline_mysql_file_fgets(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ char *str, int size, MYSQL_FILE *file)
+{
+ char *result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_READ);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) size, src_file, src_line);
+ }
+#endif
+ result= fgets(str, size, file->m_file);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, result ? strlen(result) : 0);
+#endif
+ return result;
+}
+
+static inline int
+inline_mysql_file_fgetc(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_READ);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 1, src_file, src_line);
+ }
+#endif
+ result= fgetc(file->m_file);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 1);
+#endif
+ return result;
+}
+
+static inline int
+inline_mysql_file_fputs(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ const char *str, MYSQL_FILE *file)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ size_t bytes= 0;
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ {
+ bytes= str ? strlen(str) : 0;
+ PSI_server->start_file_wait(locker, bytes, src_file, src_line);
+ }
+ }
+#endif
+ result= fputs(str, file->m_file);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, bytes);
+#endif
+ return result;
+}
+
+static inline int
+inline_mysql_file_fputc(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ char c, MYSQL_FILE *file)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 1, src_file, src_line);
+ }
+#endif
+ result= fputc(c, file->m_file);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 1);
+#endif
+ return result;
+}
+
+static inline int
+inline_mysql_file_fprintf(MYSQL_FILE *file, const char *format, ...)
+{
+ /*
+ TODO: figure out how to pass src_file and src_line from the caller.
+ */
+ int result;
+ va_list args;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, __FILE__, __LINE__);
+ }
+#endif
+ va_start(args, format);
+ result= vfprintf(file->m_file, format, args);
+ va_end(args);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) result);
+#endif
+ return result;
+}
+
+static inline int
+inline_mysql_file_vfprintf(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, const char *format, va_list args)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= vfprintf(file->m_file, format, args);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) result);
+#endif
+ return result;
+}
+
+static inline int
+inline_mysql_file_fflush(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_FLUSH);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= fflush(file->m_file);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline int inline_mysql_file_feof(MYSQL_FILE *file)
+{
+ /* Not instrumented, there is no wait involved */
+ return feof(file->m_file);
+}
+
+static inline int
+inline_mysql_file_fstat(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ int filenr, MY_STAT *stat_area, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_descriptor_locker(filenr,
+ PSI_FILE_FSTAT);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_fstat(filenr, stat_area, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline MY_STAT *
+inline_mysql_file_stat(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *path, MY_STAT *stat_area, myf flags)
+{
+ MY_STAT *result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_STAT,
+ path, &locker);
+ if (likely(locker != NULL))
+ PSI_server->start_file_open_wait(locker, src_file, src_line);
+ }
+#endif
+ result= my_stat(path, stat_area, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline int
+inline_mysql_file_chsize(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, my_off_t newlength, int filler, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_descriptor_locker(file,
+ PSI_FILE_CHSIZE);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) newlength, src_file,
+ src_line);
+ }
+#endif
+ result= my_chsize(file, newlength, filler, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) newlength);
+#endif
+ return result;
+}
+
+static inline MYSQL_FILE*
+inline_mysql_file_fopen(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *filename, int flags, myf myFlags)
+{
+ MYSQL_FILE *that;
+ that= (MYSQL_FILE*) my_malloc(sizeof(MYSQL_FILE), MYF(MY_WME));
+ if (likely(that != NULL))
+ {
+ that->m_psi= NULL;
+ {
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_name_locker
+ (key, PSI_FILE_STREAM_OPEN, filename, that);
+ if (likely(locker != NULL))
+ that->m_psi= PSI_server->start_file_open_wait(locker, src_file,
+ src_line);
+ }
+#endif
+ that->m_file= my_fopen(filename, flags, myFlags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_open_wait(locker);
+#endif
+ if (unlikely(that->m_file == NULL))
+ {
+ my_free(that, MYF(0));
+ return NULL;
+ }
+ }
+ }
+ return that;
+}
+
+static inline int
+inline_mysql_file_fclose(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, myf flags)
+{
+ int result= 0;
+ if (likely(file != NULL))
+ {
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ DBUG_ASSERT(file != NULL);
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_STREAM_CLOSE);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_fclose(file->m_file, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ my_free(file, MYF(0));
+ }
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_fread(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, uchar *buffer, size_t count, myf flags)
+{
+ size_t result= 0;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_READ);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, count, src_file, src_line);
+ }
+#endif
+ result= my_fread(file->m_file, buffer, count, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ {
+ size_t bytes_read;
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_read= (result == 0) ? count : 0;
+ else
+ bytes_read= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_server->end_file_wait(locker, bytes_read);
+ }
+#endif
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_fwrite(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, const uchar *buffer, size_t count, myf flags)
+{
+ size_t result= 0;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, count, src_file, src_line);
+ }
+#endif
+ result= my_fwrite(file->m_file, buffer, count, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ {
+ size_t bytes_written;
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_written= (result == 0) ? count : 0;
+ else
+ bytes_written= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_server->end_file_wait(locker, bytes_written);
+ }
+#endif
+ return result;
+}
+
+static inline my_off_t
+inline_mysql_file_fseek(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, my_off_t pos, int whence, myf flags)
+{
+ my_off_t result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_SEEK);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_fseek(file->m_file, pos, whence, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline my_off_t
+inline_mysql_file_ftell(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, myf flags)
+{
+ my_off_t result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server && file->m_psi))
+ {
+ locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+ PSI_FILE_TELL);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_ftell(file->m_file, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline File
+inline_mysql_file_create(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *filename, int create_flags, int access_flags, myf myFlags)
+{
+ File file;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_CREATE,
+ filename, &locker);
+ if (likely(locker != NULL))
+ PSI_server->start_file_open_wait(locker, src_file, src_line);
+ }
+#endif
+ file= my_create(filename, create_flags, access_flags, myFlags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_open_wait_and_bind_to_descriptor(locker, file);
+#endif
+ return file;
+}
+
+static inline File
+inline_mysql_file_create_temp(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_file_key key,
+#endif
+ char *to, const char *dir, const char *pfx, int mode, myf myFlags)
+{
+ File file;
+ /*
+ TODO: This event is instrumented, but not timed.
+ The problem is that the file name is now known
+ before the create_temp_file call.
+ */
+ file= create_temp_file(to, dir, pfx, mode, myFlags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(PSI_server != NULL))
+ PSI_server->create_file(key, to, file);
+#endif
+ return file;
+}
+
+static inline File
+inline_mysql_file_open(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *filename, int flags, myf myFlags)
+{
+ File file;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_OPEN,
+ filename, &locker);
+ if (likely(locker != NULL))
+ PSI_server->start_file_open_wait(locker, src_file, src_line);
+ }
+#endif
+ file= my_open(filename, flags, myFlags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_open_wait_and_bind_to_descriptor(locker, file);
+#endif
+ return file;
+}
+
+static inline int
+inline_mysql_file_close(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_descriptor_locker(file,
+ PSI_FILE_CLOSE);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_close(file, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_read(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, uchar *buffer, size_t count, myf flags)
+{
+ size_t result= 0;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_descriptor_locker(file,
+ PSI_FILE_READ);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, count, src_file, src_line);
+ }
+#endif
+ result= my_read(file, buffer, count, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ {
+ size_t bytes_read;
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_read= (result == 0) ? count : 0;
+ else
+ bytes_read= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_server->end_file_wait(locker, bytes_read);
+ }
+#endif
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_write(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, const uchar *buffer, size_t count, myf flags)
+{
+ size_t result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_descriptor_locker(file,
+ PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, count, src_file, src_line);
+ }
+#endif
+ result= my_write(file, buffer, count, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ {
+ size_t bytes_written;
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_written= (result == 0) ? count : 0;
+ else
+ bytes_written= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_server->end_file_wait(locker, bytes_written);
+ }
+#endif
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_pread(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, uchar *buffer, size_t count, my_off_t offset, myf flags)
+{
+ size_t result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_descriptor_locker(file, PSI_FILE_READ);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, count, src_file, src_line);
+ }
+#endif
+ result= my_pread(file, buffer, count, offset, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ {
+ size_t bytes_read;
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_read= (result == 0) ? count : 0;
+ else
+ bytes_read= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_server->end_file_wait(locker, bytes_read);
+ }
+#endif
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_pwrite(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, const uchar *buffer, size_t count, my_off_t offset, myf flags)
+{
+ size_t result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_descriptor_locker(file,
+ PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, count, src_file, src_line);
+ }
+#endif
+ result= my_pwrite(file, buffer, count, offset, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ {
+ size_t bytes_written;
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_written= (result == 0) ? count : 0;
+ else
+ bytes_written= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_server->end_file_wait(locker, bytes_written);
+ }
+#endif
+ return result;
+}
+
+static inline my_off_t
+inline_mysql_file_seek(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, my_off_t pos, int whence, myf flags)
+{
+ my_off_t result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_descriptor_locker(file, PSI_FILE_SEEK);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_seek(file, pos, whence, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline my_off_t
+inline_mysql_file_tell(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, myf flags)
+{
+ my_off_t result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_descriptor_locker(file, PSI_FILE_TELL);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_tell(file, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline int
+inline_mysql_file_delete(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *name, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_DELETE,
+ name, &locker);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_delete(name, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline int
+inline_mysql_file_rename(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *from, const char *to, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_RENAME,
+ to, &locker);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_rename(from, to, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline File
+inline_mysql_file_create_with_symlink(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *linkname, const char *filename, int create_flags,
+ int access_flags, myf flags)
+{
+ File file;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_CREATE,
+ filename, &locker);
+ if (likely(locker != NULL))
+ PSI_server->start_file_open_wait(locker, src_file, src_line);
+ }
+#endif
+ file= my_create_with_symlink(linkname, filename, create_flags, access_flags,
+ flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_open_wait_and_bind_to_descriptor(locker, file);
+#endif
+ return file;
+}
+
+static inline int
+inline_mysql_file_delete_with_symlink(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *name, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_DELETE,
+ name, &locker);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_delete_with_symlink(name, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline int
+inline_mysql_file_rename_with_symlink(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *from, const char *to, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_RENAME,
+ to, &locker);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_rename_with_symlink(from, to, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+static inline int
+inline_mysql_file_sync(
+#ifdef HAVE_PSI_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File fd, myf flags)
+{
+ int result= 0;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_file_locker *locker= NULL;
+ if (likely(PSI_server != NULL))
+ {
+ locker= PSI_server->get_thread_file_descriptor_locker(fd, PSI_FILE_SYNC);
+ if (likely(locker != NULL))
+ PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
+ }
+#endif
+ result= my_sync(fd, flags);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_file_wait(locker, (size_t) 0);
+#endif
+ return result;
+}
+
+/** @} (end of group File_instrumentation) */
+
+#endif
+
diff --git a/include/mysql/psi/mysql_thread.h b/include/mysql/psi/mysql_thread.h
new file mode 100644
index 00000000000..4e839c7cf6a
--- /dev/null
+++ b/include/mysql/psi/mysql_thread.h
@@ -0,0 +1,1164 @@
+/* Copyright (C) 2008-2009 Sun Microsystems, Inc
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef MYSQL_THREAD_H
+#define MYSQL_THREAD_H
+
+/**
+ @file mysql/psi/mysql_thread.h
+ Instrumentation helpers for mysys threads, mutexes,
+ read write locks and conditions.
+ This header file provides the necessary declarations
+ to use the mysys thread API with the performance schema instrumentation.
+ In some compilers (SunStudio), 'static inline' functions, when declared
+ but not used, are not optimized away (because they are unused) by default,
+ so that including a static inline function from a header file does
+ create unwanted dependencies, causing unresolved symbols at link time.
+ Other compilers, like gcc, optimize these dependencies by default.
+
+ Since the instrumented APIs declared here are wrapper on top
+ of my_pthread / safemutex / etc APIs,
+ including mysql/psi/mysql_thread.h assumes that
+ the dependency on my_pthread and safemutex already exists.
+*/
+/*
+ Note: there are several orthogonal dimensions here.
+
+ Dimension 1: Instrumentation
+ HAVE_PSI_INTERFACE is defined when the instrumentation is compiled in.
+ This may happen both in debug or production builds.
+
+ Dimension 2: Debug
+ SAFE_MUTEX is defined when debug is compiled in.
+ This may happen both with and without instrumentation.
+
+ Dimension 3: Platform
+ Mutexes are implemented with one of:
+ - the pthread library
+ - fast mutexes
+ - window apis
+ This is implemented by various macro definitions in my_pthread.h
+
+ This causes complexity with '#ifdef'-ery that can't be avoided.
+*/
+
+#include "mysql/psi/psi.h"
+
+/**
+ @defgroup Thread_instrumentation Thread Instrumentation
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ An instrumented mutex structure.
+ @sa mysql_mutex_t
+*/
+struct st_mysql_mutex
+{
+ /** The real mutex. */
+ pthread_mutex_t m_mutex;
+ /**
+ The instrumentation hook.
+ Note that this hook is not conditionally defined,
+ for binary compatibility of the @c mysql_mutex_t interface.
+ */
+ struct PSI_mutex *m_psi;
+};
+
+/**
+ Type of an instrumented mutex.
+ @c mysql_mutex_t is a drop-in replacement for @c pthread_mutex_t.
+ @sa mysql_mutex_assert_owner
+ @sa mysql_mutex_assert_not_owner
+ @sa mysql_mutex_init
+ @sa mysql_mutex_lock
+ @sa mysql_mutex_unlock
+ @sa mysql_mutex_destroy
+*/
+typedef struct st_mysql_mutex mysql_mutex_t;
+
+/**
+ An instrumented rwlock structure.
+ @sa mysql_rwlock_t
+*/
+struct st_mysql_rwlock
+{
+ /** The real rwlock */
+ rw_lock_t m_rwlock;
+ /**
+ The instrumentation hook.
+ Note that this hook is not conditionally defined,
+ for binary compatibility of the @c mysql_rwlock_t interface.
+ */
+ struct PSI_rwlock *m_psi;
+};
+
+/**
+ An instrumented prlock structure.
+ @sa mysql_prlock_t
+*/
+struct st_mysql_prlock
+{
+ /** The real prlock */
+ rw_pr_lock_t m_prlock;
+ /**
+ The instrumentation hook.
+ Note that this hook is not conditionally defined,
+ for binary compatibility of the @c mysql_rwlock_t interface.
+ */
+ struct PSI_rwlock *m_psi;
+};
+
+/**
+ Type of an instrumented rwlock.
+ @c mysql_rwlock_t is a drop-in replacement for @c pthread_rwlock_t.
+ @sa mysql_rwlock_init
+ @sa mysql_rwlock_rdlock
+ @sa mysql_rwlock_tryrdlock
+ @sa mysql_rwlock_wrlock
+ @sa mysql_rwlock_trywrlock
+ @sa mysql_rwlock_unlock
+ @sa mysql_rwlock_destroy
+*/
+typedef struct st_mysql_rwlock mysql_rwlock_t;
+
+/**
+ Type of an instrumented prlock.
+ A prlock is a read write lock that 'prefers readers' (pr).
+ @c mysql_prlock_t is a drop-in replacement for @c rw_pr_lock_t.
+ @sa mysql_prlock_init
+ @sa mysql_prlock_rdlock
+ @sa mysql_prlock_tryrdlock
+ @sa mysql_prlock_wrlock
+ @sa mysql_prlock_trywrlock
+ @sa mysql_prlock_unlock
+ @sa mysql_prlock_destroy
+*/
+typedef struct st_mysql_prlock mysql_prlock_t;
+
+/**
+ An instrumented cond structure.
+ @sa mysql_cond_t
+*/
+struct st_mysql_cond
+{
+ /** The real condition */
+ pthread_cond_t m_cond;
+ /**
+ The instrumentation hook.
+ Note that this hook is not conditionally defined,
+ for binary compatibility of the @c mysql_cond_t interface.
+ */
+ struct PSI_cond *m_psi;
+};
+
+/**
+ Type of an instrumented condition.
+ @c mysql_cond_t is a drop-in replacement for @c pthread_cond_t.
+ @sa mysql_cond_init
+ @sa mysql_cond_wait
+ @sa mysql_cond_timedwait
+ @sa mysql_cond_signal
+ @sa mysql_cond_broadcast
+ @sa mysql_cond_destroy
+*/
+typedef struct st_mysql_cond mysql_cond_t;
+
+/*
+ Consider the following code:
+ static inline void foo() { bar(); }
+ when foo() is never called.
+
+ With gcc, foo() is a local static function, so the dependencies
+ are optimized away at compile time, and there is no dependency on bar().
+ With other compilers (HP, Sun Studio), the function foo() implementation
+ is compiled, and bar() needs to be present to link.
+
+ Due to the existing header dependencies in MySQL code, this header file
+ is sometime used when it is not needed, which in turn cause link failures
+ on some platforms.
+ The proper fix would be to cut these extra dependencies in the calling code.
+ DISABLE_MYSQL_THREAD_H is a work around to limit dependencies.
+ DISABLE_MYSQL_PRLOCK_H is similar, and is used to disable specifically
+ the prlock wrappers.
+*/
+#ifndef DISABLE_MYSQL_THREAD_H
+
+/**
+ @def mysql_mutex_assert_owner(M)
+ Wrapper, to use safe_mutex_assert_owner with instrumented mutexes.
+ @c mysql_mutex_assert_owner is a drop-in replacement
+ for @c safe_mutex_assert_owner.
+*/
+#define mysql_mutex_assert_owner(M) \
+ safe_mutex_assert_owner(&(M)->m_mutex)
+
+/**
+ @def mysql_mutex_assert_not_owner(M)
+ Wrapper, to use safe_mutex_assert_not_owner with instrumented mutexes.
+ @c mysql_mutex_assert_not_owner is a drop-in replacement
+ for @c safe_mutex_assert_not_owner.
+*/
+#define mysql_mutex_assert_not_owner(M) \
+ safe_mutex_assert_not_owner(&(M)->m_mutex)
+
+/**
+ @def mysql_mutex_init(K, M, A)
+ Instrumented mutex_init.
+ @c mysql_mutex_init is a replacement for @c pthread_mutex_init.
+ @param K The PSI_mutex_key for this instrumented mutex
+ @param M The mutex to initialize
+ @param A Mutex attributes
+*/
+
+#ifdef HAVE_PSI_INTERFACE
+ #ifdef SAFE_MUTEX
+ #define mysql_mutex_init(K, M, A) \
+ inline_mysql_mutex_init(K, M, A, __FILE__, __LINE__)
+ #else
+ #define mysql_mutex_init(K, M, A) \
+ inline_mysql_mutex_init(K, M, A)
+ #endif
+#else
+ #ifdef SAFE_MUTEX
+ #define mysql_mutex_init(K, M, A) \
+ inline_mysql_mutex_init(M, A, __FILE__, __LINE__)
+ #else
+ #define mysql_mutex_init(K, M, A) \
+ inline_mysql_mutex_init(M, A)
+ #endif
+#endif
+
+/**
+ @def mysql_mutex_destroy(M)
+ Instrumented mutex_destroy.
+ @c mysql_mutex_destroy is a drop-in replacement
+ for @c pthread_mutex_destroy.
+*/
+#ifdef SAFE_MUTEX
+ #define mysql_mutex_destroy(M) \
+ inline_mysql_mutex_destroy(M, __FILE__, __LINE__)
+#else
+ #define mysql_mutex_destroy(M) \
+ inline_mysql_mutex_destroy(M)
+#endif
+
+/**
+ @def mysql_mutex_lock(M)
+ Instrumented mutex_lock.
+ @c mysql_mutex_lock is a drop-in replacement for @c pthread_mutex_lock.
+ @param M The mutex to lock
+*/
+
+#if defined(SAFE_MUTEX) || defined (HAVE_PSI_INTERFACE)
+ #define mysql_mutex_lock(M) \
+ inline_mysql_mutex_lock(M, __FILE__, __LINE__)
+#else
+ #define mysql_mutex_lock(M) \
+ inline_mysql_mutex_lock(M)
+#endif
+
+/**
+ @def mysql_mutex_trylock(M)
+ Instrumented mutex_lock.
+ @c mysql_mutex_trylock is a drop-in replacement
+ for @c pthread_mutex_trylock.
+*/
+
+#if defined(SAFE_MUTEX) || defined (HAVE_PSI_INTERFACE)
+ #define mysql_mutex_trylock(M) \
+ inline_mysql_mutex_trylock(M, __FILE__, __LINE__)
+#else
+ #define mysql_mutex_trylock(M) \
+ inline_mysql_mutex_trylock(M)
+#endif
+
+/**
+ @def mysql_mutex_unlock(M)
+ Instrumented mutex_unlock.
+ @c mysql_mutex_unlock is a drop-in replacement for @c pthread_mutex_unlock.
+*/
+#ifdef SAFE_MUTEX
+ #define mysql_mutex_unlock(M) \
+ inline_mysql_mutex_unlock(M, __FILE__, __LINE__)
+#else
+ #define mysql_mutex_unlock(M) \
+ inline_mysql_mutex_unlock(M)
+#endif
+
+/**
+ @def mysql_rwlock_init(K, RW)
+ Instrumented rwlock_init.
+ @c mysql_rwlock_init is a replacement for @c pthread_rwlock_init.
+ Note that pthread_rwlockattr_t is not supported in MySQL.
+ @param K The PSI_rwlock_key for this instrumented rwlock
+ @param RW The rwlock to initialize
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_rwlock_init(K, RW) inline_mysql_rwlock_init(K, RW)
+#else
+ #define mysql_rwlock_init(K, RW) inline_mysql_rwlock_init(RW)
+#endif
+
+/**
+ @def mysql_prlock_init(K, RW)
+ Instrumented rw_pr_init.
+ @c mysql_prlock_init is a replacement for @c rw_pr_init.
+ @param K The PSI_rwlock_key for this instrumented prlock
+ @param RW The prlock to initialize
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_prlock_init(K, RW) inline_mysql_prlock_init(K, RW)
+#else
+ #define mysql_prlock_init(K, RW) inline_mysql_prlock_init(RW)
+#endif
+
+/**
+ @def mysql_rwlock_destroy(RW)
+ Instrumented rwlock_destroy.
+ @c mysql_rwlock_destroy is a drop-in replacement
+ for @c pthread_rwlock_destroy.
+*/
+#define mysql_rwlock_destroy(RW) inline_mysql_rwlock_destroy(RW)
+
+/**
+ @def mysql_prlock_destroy(RW)
+ Instrumented rw_pr_destroy.
+ @c mysql_prlock_destroy is a drop-in replacement
+ for @c rw_pr_destroy.
+*/
+#define mysql_prlock_destroy(RW) inline_mysql_prlock_destroy(RW)
+
+/**
+ @def mysql_rwlock_rdlock(RW)
+ Instrumented rwlock_rdlock.
+ @c mysql_rwlock_rdlock is a drop-in replacement
+ for @c pthread_rwlock_rdlock.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_rwlock_rdlock(RW) \
+ inline_mysql_rwlock_rdlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_rwlock_rdlock(RW) \
+ inline_mysql_rwlock_rdlock(RW)
+#endif
+
+/**
+ @def mysql_prlock_rdlock(RW)
+ Instrumented rw_pr_rdlock.
+ @c mysql_prlock_rdlock is a drop-in replacement
+ for @c rw_pr_rdlock.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_prlock_rdlock(RW) \
+ inline_mysql_prlock_rdlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_prlock_rdlock(RW) \
+ inline_mysql_prlock_rdlock(RW)
+#endif
+
+/**
+ @def mysql_rwlock_wrlock(RW)
+ Instrumented rwlock_wrlock.
+ @c mysql_rwlock_wrlock is a drop-in replacement
+ for @c pthread_rwlock_wrlock.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_rwlock_wrlock(RW) \
+ inline_mysql_rwlock_wrlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_rwlock_wrlock(RW) \
+ inline_mysql_rwlock_wrlock(RW)
+#endif
+
+/**
+ @def mysql_prlock_wrlock(RW)
+ Instrumented rw_pr_wrlock.
+ @c mysql_prlock_wrlock is a drop-in replacement
+ for @c rw_pr_wrlock.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_prlock_wrlock(RW) \
+ inline_mysql_prlock_wrlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_prlock_wrlock(RW) \
+ inline_mysql_prlock_wrlock(RW)
+#endif
+
+/**
+ @def mysql_rwlock_tryrdlock(RW)
+ Instrumented rwlock_tryrdlock.
+ @c mysql_rwlock_tryrdlock is a drop-in replacement
+ for @c pthread_rwlock_tryrdlock.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_rwlock_tryrdlock(RW) \
+ inline_mysql_rwlock_tryrdlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_rwlock_tryrdlock(RW) \
+ inline_mysql_rwlock_tryrdlock(RW)
+#endif
+
+/**
+ @def mysql_prlock_tryrdlock(RW)
+ Instrumented rw_pr_tryrdlock.
+ @c mysql_prlock_tryrdlock is a drop-in replacement
+ for @c rw_pr_tryrdlock.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_prlock_tryrdlock(RW) \
+ inline_mysql_prlock_tryrdlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_prlock_tryrdlock(RW) \
+ inline_mysql_prlock_tryrdlock(RW)
+#endif
+
+/**
+ @def mysql_rwlock_trywrlock(RW)
+ Instrumented rwlock_trywrlock.
+ @c mysql_rwlock_trywrlock is a drop-in replacement
+ for @c pthread_rwlock_trywrlock.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_rwlock_trywrlock(RW) \
+ inline_mysql_rwlock_trywrlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_rwlock_trywrlock(RW) \
+ inline_mysql_rwlock_trywrlock(RW)
+#endif
+
+/**
+ @def mysql_prlock_trywrlock(RW)
+ Instrumented rw_pr_trywrlock.
+ @c mysql_prlock_trywrlock is a drop-in replacement
+ for @c rw_pr_trywrlock.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_prlock_trywrlock(RW) \
+ inline_mysql_prlock_trywrlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_prlock_trywrlock(RW) \
+ inline_mysql_prlock_trywrlock(RW)
+#endif
+
+/**
+ @def mysql_rwlock_unlock(RW)
+ Instrumented rwlock_unlock.
+ @c mysql_rwlock_unlock is a drop-in replacement
+ for @c pthread_rwlock_unlock.
+*/
+#define mysql_rwlock_unlock(RW) inline_mysql_rwlock_unlock(RW)
+
+/**
+ @def mysql_prlock_unlock(RW)
+ Instrumented rw_pr_unlock.
+ @c mysql_prlock_unlock is a drop-in replacement
+ for @c rw_pr_unlock.
+*/
+#define mysql_prlock_unlock(RW) inline_mysql_prlock_unlock(RW)
+
+/**
+ @def mysql_cond_init(K, C, A)
+ Instrumented cond_init.
+ @c mysql_cond_init is a replacement for @c pthread_cond_init.
+ @param C The cond to initialize
+ @param K The PSI_cond_key for this instrumented cond
+ @param A Condition attributes
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_cond_init(K, C, A) inline_mysql_cond_init(K, C, A)
+#else
+ #define mysql_cond_init(K, C, A) inline_mysql_cond_init(C, A)
+#endif
+
+/**
+ @def mysql_cond_destroy(C)
+ Instrumented cond_destroy.
+ @c mysql_cond_destroy is a drop-in replacement for @c pthread_cond_destroy.
+*/
+#define mysql_cond_destroy(C) inline_mysql_cond_destroy(C)
+
+/**
+ @def mysql_cond_wait(C)
+ Instrumented cond_wait.
+ @c mysql_cond_wait is a drop-in replacement for @c pthread_cond_wait.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_cond_wait(C, M) \
+ inline_mysql_cond_wait(C, M, __FILE__, __LINE__)
+#else
+ #define mysql_cond_wait(C, M) \
+ inline_mysql_cond_wait(C, M)
+#endif
+
+/**
+ @def mysql_cond_timedwait(C, M, W)
+ Instrumented cond_timedwait.
+ @c mysql_cond_timedwait is a drop-in replacement
+ for @c pthread_cond_timedwait.
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_cond_timedwait(C, M, W) \
+ inline_mysql_cond_timedwait(C, M, W, __FILE__, __LINE__)
+#else
+ #define mysql_cond_timedwait(C, M, W) \
+ inline_mysql_cond_timedwait(C, M, W)
+#endif
+
+/**
+ @def mysql_cond_signal(C)
+ Instrumented cond_signal.
+ @c mysql_cond_signal is a drop-in replacement for @c pthread_cond_signal.
+*/
+#define mysql_cond_signal(C) inline_mysql_cond_signal(C)
+
+/**
+ @def mysql_cond_broadcast(C)
+ Instrumented cond_broadcast.
+ @c mysql_cond_broadcast is a drop-in replacement
+ for @c pthread_cond_broadcast.
+*/
+#define mysql_cond_broadcast(C) inline_mysql_cond_broadcast(C)
+
+
+/**
+ @def mysql_thread_create(K, P1, P2, P3, P4)
+ Instrumented pthread_create.
+ This function creates both the thread instrumentation and a thread.
+ @c mysql_thread_create is a replacement for @c pthread_create.
+ The parameter P4 (or, if it is NULL, P1) will be used as the
+ instrumented thread "indentity".
+ Providing a P1 / P4 parameter with a different value for each call
+ will on average improve performances, since this thread identity value
+ is used internally to randomize access to data and prevent contention.
+ This is optional, and the improvement is not guaranteed, only statistical.
+ @param K The PSI_thread_key for this instrumented thread
+ @param P1 pthread_create parameter 1
+ @param P2 pthread_create parameter 2
+ @param P3 pthread_create parameter 3
+ @param P4 pthread_create parameter 4
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_thread_create(K, P1, P2, P3, P4) \
+ inline_mysql_thread_create(K, P1, P2, P3, P4)
+#else
+ #define mysql_thread_create(K, P1, P2, P3, P4) \
+ pthread_create(P1, P2, P3, P4)
+#endif
+
+/**
+ @def mysql_thread_set_psi_id(I)
+ Set the thread indentifier for the instrumentation.
+ @param I The thread identifier
+*/
+#ifdef HAVE_PSI_INTERFACE
+ #define mysql_thread_set_psi_id(I) inline_mysql_thread_set_psi_id(I)
+#else
+ #define mysql_thread_set_psi_id(I) do {} while (0)
+#endif
+
+static inline int inline_mysql_mutex_init(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_mutex_key key,
+#endif
+ mysql_mutex_t *that,
+ const pthread_mutexattr_t *attr
+#ifdef SAFE_MUTEX
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+#ifdef HAVE_PSI_INTERFACE
+ that->m_psi= PSI_server ? PSI_server->init_mutex(key, &that->m_mutex)
+ : NULL;
+#else
+ that->m_psi= NULL;
+#endif
+#ifdef SAFE_MUTEX
+ return safe_mutex_init(&that->m_mutex, attr, src_file, src_line);
+#else
+ return pthread_mutex_init(&that->m_mutex, attr);
+#endif
+}
+
+static inline int inline_mysql_mutex_destroy(
+ mysql_mutex_t *that
+#ifdef SAFE_MUTEX
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(PSI_server && that->m_psi))
+ {
+ PSI_server->destroy_mutex(that->m_psi);
+ that->m_psi= NULL;
+ }
+#endif
+#ifdef SAFE_MUTEX
+ return safe_mutex_destroy(&that->m_mutex, src_file, src_line);
+#else
+ return pthread_mutex_destroy(&that->m_mutex);
+#endif
+}
+
+static inline int inline_mysql_mutex_lock(
+ mysql_mutex_t *that
+#if defined(SAFE_MUTEX) || defined (HAVE_PSI_INTERFACE)
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_mutex_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_mutex_locker(that->m_psi, PSI_MUTEX_LOCK);
+ if (likely(locker != NULL))
+ PSI_server->start_mutex_wait(locker, src_file, src_line);
+ }
+#endif
+#ifdef SAFE_MUTEX
+ result= safe_mutex_lock(&that->m_mutex, FALSE, src_file, src_line);
+#else
+ result= pthread_mutex_lock(&that->m_mutex);
+#endif
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_mutex_wait(locker, result);
+#endif
+ return result;
+}
+
+static inline int inline_mysql_mutex_trylock(
+ mysql_mutex_t *that
+#if defined(SAFE_MUTEX) || defined (HAVE_PSI_INTERFACE)
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_mutex_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_mutex_locker(that->m_psi, PSI_MUTEX_TRYLOCK);
+ if (likely(locker != NULL))
+ PSI_server->start_mutex_wait(locker, src_file, src_line);
+ }
+#endif
+#ifdef SAFE_MUTEX
+ result= safe_mutex_lock(&that->m_mutex, TRUE, src_file, src_line);
+#else
+ result= pthread_mutex_trylock(&that->m_mutex);
+#endif
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_mutex_wait(locker, result);
+#endif
+ return result;
+}
+
+static inline int inline_mysql_mutex_unlock(
+ mysql_mutex_t *that
+#ifdef SAFE_MUTEX
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_thread *thread;
+ if (likely(PSI_server && that->m_psi))
+ {
+ thread= PSI_server->get_thread();
+ if (likely(thread != NULL))
+ PSI_server->unlock_mutex(thread, that->m_psi);
+ }
+#endif
+#ifdef SAFE_MUTEX
+ result= safe_mutex_unlock(&that->m_mutex, src_file, src_line);
+#else
+ result= pthread_mutex_unlock(&that->m_mutex);
+#endif
+ return result;
+}
+
+static inline int inline_mysql_rwlock_init(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_rwlock_key key,
+#endif
+ mysql_rwlock_t *that)
+{
+#ifdef HAVE_PSI_INTERFACE
+ that->m_psi= (PSI_server ? PSI_server->init_rwlock(key, &that->m_rwlock)
+ : NULL);
+#else
+ that->m_psi= NULL;
+#endif
+ /*
+ pthread_rwlockattr_t is not used in MySQL.
+ */
+ return my_rwlock_init(&that->m_rwlock, NULL);
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_init(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_rwlock_key key,
+#endif
+ mysql_prlock_t *that)
+{
+#ifdef HAVE_PSI_INTERFACE
+ that->m_psi= (PSI_server ? PSI_server->init_rwlock(key, &that->m_prlock)
+ : NULL);
+#else
+ that->m_psi= NULL;
+#endif
+ return rw_pr_init(&that->m_prlock);
+}
+#endif
+
+static inline int inline_mysql_rwlock_destroy(
+ mysql_rwlock_t *that)
+{
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(PSI_server && that->m_psi))
+ {
+ PSI_server->destroy_rwlock(that->m_psi);
+ that->m_psi= NULL;
+ }
+#endif
+ return rwlock_destroy(&that->m_rwlock);
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_destroy(
+ mysql_prlock_t *that)
+{
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(PSI_server && that->m_psi))
+ {
+ PSI_server->destroy_rwlock(that->m_psi);
+ that->m_psi= NULL;
+ }
+#endif
+ return rw_pr_destroy(&that->m_prlock);
+}
+#endif
+
+static inline int inline_mysql_rwlock_rdlock(
+ mysql_rwlock_t *that
+#ifdef HAVE_PSI_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_rwlock_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+ PSI_RWLOCK_READLOCK);
+ if (likely(locker != NULL))
+ PSI_server->start_rwlock_rdwait(locker, src_file, src_line);
+ }
+#endif
+ result= rw_rdlock(&that->m_rwlock);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_rwlock_rdwait(locker, result);
+#endif
+ return result;
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_rdlock(
+ mysql_prlock_t *that
+#ifdef HAVE_PSI_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_rwlock_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+ PSI_RWLOCK_READLOCK);
+ if (likely(locker != NULL))
+ PSI_server->start_rwlock_rdwait(locker, src_file, src_line);
+ }
+#endif
+ result= rw_pr_rdlock(&that->m_prlock);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_rwlock_rdwait(locker, result);
+#endif
+ return result;
+}
+#endif
+
+static inline int inline_mysql_rwlock_wrlock(
+ mysql_rwlock_t *that
+#ifdef HAVE_PSI_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_rwlock_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+ PSI_RWLOCK_WRITELOCK);
+ if (likely(locker != NULL))
+ PSI_server->start_rwlock_wrwait(locker, src_file, src_line);
+ }
+#endif
+ result= rw_wrlock(&that->m_rwlock);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_rwlock_wrwait(locker, result);
+#endif
+ return result;
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_wrlock(
+ mysql_prlock_t *that
+#ifdef HAVE_PSI_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_rwlock_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+ PSI_RWLOCK_WRITELOCK);
+ if (likely(locker != NULL))
+ PSI_server->start_rwlock_wrwait(locker, src_file, src_line);
+ }
+#endif
+ result= rw_pr_wrlock(&that->m_prlock);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_rwlock_wrwait(locker, result);
+#endif
+ return result;
+}
+#endif
+
+static inline int inline_mysql_rwlock_tryrdlock(
+ mysql_rwlock_t *that
+#ifdef HAVE_PSI_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_rwlock_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+ PSI_RWLOCK_TRYREADLOCK);
+ if (likely(locker != NULL))
+ PSI_server->start_rwlock_rdwait(locker, src_file, src_line);
+ }
+#endif
+ result= rw_tryrdlock(&that->m_rwlock);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_rwlock_rdwait(locker, result);
+#endif
+ return result;
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_tryrdlock(
+ mysql_prlock_t *that
+#ifdef HAVE_PSI_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_rwlock_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+ PSI_RWLOCK_TRYREADLOCK);
+ if (likely(locker != NULL))
+ PSI_server->start_rwlock_rdwait(locker, src_file, src_line);
+ }
+#endif
+ result= rw_pr_tryrdlock(&that->m_prlock);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_rwlock_rdwait(locker, result);
+#endif
+ return result;
+}
+#endif
+
+static inline int inline_mysql_rwlock_trywrlock(
+ mysql_rwlock_t *that
+#ifdef HAVE_PSI_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_rwlock_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+ PSI_RWLOCK_TRYWRITELOCK);
+ if (likely(locker != NULL))
+ PSI_server->start_rwlock_wrwait(locker, src_file, src_line);
+ }
+#endif
+ result= rw_trywrlock(&that->m_rwlock);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_rwlock_wrwait(locker, result);
+#endif
+ return result;
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_trywrlock(
+ mysql_prlock_t *that
+#ifdef HAVE_PSI_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_rwlock_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+ PSI_RWLOCK_TRYWRITELOCK);
+ if (likely(locker != NULL))
+ PSI_server->start_rwlock_wrwait(locker, src_file, src_line);
+ }
+#endif
+ result= rw_pr_trywrlock(&that->m_prlock);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_rwlock_wrwait(locker, result);
+#endif
+ return result;
+}
+#endif
+
+static inline int inline_mysql_rwlock_unlock(
+ mysql_rwlock_t *that)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_thread *thread;
+ if (likely(PSI_server && that->m_psi))
+ {
+ thread= PSI_server->get_thread();
+ if (likely(thread != NULL))
+ PSI_server->unlock_rwlock(thread, that->m_psi);
+ }
+#endif
+ result= rw_unlock(&that->m_rwlock);
+ return result;
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_unlock(
+ mysql_prlock_t *that)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_thread *thread;
+ if (likely(PSI_server && that->m_psi))
+ {
+ thread= PSI_server->get_thread();
+ if (likely(thread != NULL))
+ PSI_server->unlock_rwlock(thread, that->m_psi);
+ }
+#endif
+ result= rw_pr_unlock(&that->m_prlock);
+ return result;
+}
+#endif
+
+static inline int inline_mysql_cond_init(
+#ifdef HAVE_PSI_INTERFACE
+ PSI_cond_key key,
+#endif
+ mysql_cond_t *that,
+ const pthread_condattr_t *attr)
+{
+#ifdef HAVE_PSI_INTERFACE
+ that->m_psi= (PSI_server ? PSI_server->init_cond(key, &that->m_cond)
+ : NULL);
+#else
+ that->m_psi= NULL;
+#endif
+ return pthread_cond_init(&that->m_cond, attr);
+}
+
+static inline int inline_mysql_cond_destroy(
+ mysql_cond_t *that)
+{
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(PSI_server && that->m_psi))
+ {
+ PSI_server->destroy_cond(that->m_psi);
+ that->m_psi= NULL;
+ }
+#endif
+ return pthread_cond_destroy(&that->m_cond);
+}
+
+static inline int inline_mysql_cond_wait(
+ mysql_cond_t *that,
+ mysql_mutex_t *mutex
+#ifdef HAVE_PSI_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_cond_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_cond_locker(that->m_psi, mutex->m_psi,
+ PSI_COND_WAIT);
+ if (likely(locker != NULL))
+ PSI_server->start_cond_wait(locker, src_file, src_line);
+ }
+#endif
+ result= pthread_cond_wait(&that->m_cond, &mutex->m_mutex);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_cond_wait(locker, result);
+#endif
+ return result;
+}
+
+static inline int inline_mysql_cond_timedwait(
+ mysql_cond_t *that,
+ mysql_mutex_t *mutex,
+ struct timespec *abstime
+#ifdef HAVE_PSI_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_cond_locker *locker= NULL;
+ if (likely(PSI_server && that->m_psi))
+ {
+ locker= PSI_server->get_thread_cond_locker(that->m_psi, mutex->m_psi,
+ PSI_COND_TIMEDWAIT);
+ if (likely(locker != NULL))
+ PSI_server->start_cond_wait(locker, src_file, src_line);
+ }
+#endif
+ result= pthread_cond_timedwait(&that->m_cond, &mutex->m_mutex, abstime);
+#ifdef HAVE_PSI_INTERFACE
+ if (likely(locker != NULL))
+ PSI_server->end_cond_wait(locker, result);
+#endif
+ return result;
+}
+
+static inline int inline_mysql_cond_signal(
+ mysql_cond_t *that)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_thread *thread;
+ if (likely(PSI_server && that->m_psi))
+ {
+ thread= PSI_server->get_thread();
+ if (likely(thread != NULL))
+ PSI_server->signal_cond(thread, that->m_psi);
+ }
+#endif
+ result= pthread_cond_signal(&that->m_cond);
+ return result;
+}
+
+static inline int inline_mysql_cond_broadcast(
+ mysql_cond_t *that)
+{
+ int result;
+#ifdef HAVE_PSI_INTERFACE
+ struct PSI_thread *thread;
+ if (likely(PSI_server && that->m_psi))
+ {
+ thread= PSI_server->get_thread();
+ if (likely(thread != NULL))
+ PSI_server->broadcast_cond(thread, that->m_psi);
+ }
+#endif
+ result= pthread_cond_broadcast(&that->m_cond);
+ return result;
+}
+
+#ifdef HAVE_PSI_INTERFACE
+static inline int inline_mysql_thread_create(
+ PSI_thread_key key,
+ pthread_t *thread, const pthread_attr_t *attr,
+ void *(*start_routine)(void*), void *arg)
+{
+ int result;
+ if (likely(PSI_server != NULL))
+ result= PSI_server->spawn_thread(key, thread, attr, start_routine, arg);
+ else
+ result= pthread_create(thread, attr, start_routine, arg);
+ return result;
+}
+
+static inline void inline_mysql_thread_set_psi_id(ulong id)
+{
+ if (likely(PSI_server != NULL))
+ {
+ struct PSI_thread *psi= PSI_server->get_thread();
+ if (likely(psi != NULL))
+ PSI_server->set_thread_id(psi, id);
+ }
+}
+#endif
+
+#endif /* DISABLE_MYSQL_THREAD_H */
+
+/** @} (end of group Thread_instrumentation) */
+
+#endif
+
diff --git a/include/mysql/psi/psi.h b/include/mysql/psi/psi.h
new file mode 100644
index 00000000000..51446fa83a5
--- /dev/null
+++ b/include/mysql/psi/psi.h
@@ -0,0 +1,1091 @@
+/* Copyright (C) 2008-2010 Sun Microsystems, Inc
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef MYSQL_PERFORMANCE_SCHEMA_INTERFACE_H
+#define MYSQL_PERFORMANCE_SCHEMA_INTERFACE_H
+
+#ifndef _global_h
+/*
+ Make sure a .c or .cc file contains an include to my_global.h first.
+ When this include is missing, all the #ifdef HAVE_XXX have no effect,
+ and the resulting binary won't build, or won't link,
+ or will crash at runtime
+ since various structures will have different binary definitions.
+*/
+#error "You must include my_global.h in the code for the build to be correct."
+#endif
+
+C_MODE_START
+
+/**
+ @file mysql/psi/psi.h
+ Performance schema instrumentation interface.
+
+ @defgroup Instrumentation_interface Instrumentation Interface
+ @ingroup Performance_schema
+ @{
+*/
+
+/**
+ Interface for an instrumented mutex.
+ This is an opaque structure.
+*/
+struct PSI_mutex;
+
+/**
+ Interface for an instrumented rwlock.
+ This is an opaque structure.
+*/
+struct PSI_rwlock;
+
+/**
+ Interface for an instrumented condition.
+ This is an opaque structure.
+*/
+struct PSI_cond;
+
+/**
+ Interface for an instrumented table share.
+ This is an opaque structure.
+*/
+struct PSI_table_share;
+
+/**
+ Interface for an instrumented table handle.
+ This is an opaque structure.
+*/
+struct PSI_table;
+
+/**
+ Interface for an instrumented thread.
+ This is an opaque structure.
+*/
+struct PSI_thread;
+
+/**
+ Interface for an instrumented file handle.
+ This is an opaque structure.
+*/
+struct PSI_file;
+
+/** Entry point for the performance schema interface. */
+struct PSI_bootstrap
+{
+ /**
+ ABI interface finder.
+ Calling this method with an interface version number returns either
+ an instance of the ABI for this version, or NULL.
+ @param version the interface version number to find
+ @return a versioned interface (PSI_v1, PSI_v2 or PSI)
+ @sa PSI_VERSION_1
+ @sa PSI_v1
+ @sa PSI_VERSION_2
+ @sa PSI_v2
+ @sa PSI_CURRENT_VERSION
+ @sa PSI
+ */
+ void* (*get_interface)(int version);
+};
+
+#ifdef HAVE_PSI_INTERFACE
+
+/**
+ @def PSI_VERSION_1
+ Performance Schema Interface number for version 1.
+ This version is supported.
+*/
+#define PSI_VERSION_1 1
+
+/**
+ @def PSI_VERSION_2
+ Performance Schema Interface number for version 2.
+ This version is not implemented, it's a placeholder.
+*/
+#define PSI_VERSION_2 2
+
+/**
+ @def PSI_CURRENT_VERSION
+ Performance Schema Interface number for the most recent version.
+ The most current version is @c PSI_VERSION_1
+*/
+#define PSI_CURRENT_VERSION 1
+
+#ifndef USE_PSI_2
+#ifndef USE_PSI_1
+#define USE_PSI_1
+#endif
+#endif
+
+/**
+ Interface for an instrumented mutex operation.
+ This is an opaque structure.
+*/
+struct PSI_mutex_locker;
+
+/**
+ Interface for an instrumented rwlock operation.
+ This is an opaque structure.
+*/
+
+struct PSI_rwlock_locker;
+/**
+ Interface for an instrumented condition operation.
+ This is an opaque structure.
+*/
+
+struct PSI_cond_locker;
+
+/**
+ Interface for an instrumented file operation.
+ This is an opaque structure.
+*/
+struct PSI_file_locker;
+
+/** Operation performed on an instrumented mutex. */
+enum PSI_mutex_operation
+{
+ /** Lock. */
+ PSI_MUTEX_LOCK= 0,
+ /** Lock attempt. */
+ PSI_MUTEX_TRYLOCK= 1
+};
+
+/** Operation performed on an instrumented rwlock. */
+enum PSI_rwlock_operation
+{
+ /** Read lock. */
+ PSI_RWLOCK_READLOCK= 0,
+ /** Write lock. */
+ PSI_RWLOCK_WRITELOCK= 1,
+ /** Read lock attempt. */
+ PSI_RWLOCK_TRYREADLOCK= 2,
+ /** Write lock attempt. */
+ PSI_RWLOCK_TRYWRITELOCK= 3
+};
+
+/** Operation performed on an instrumented condition. */
+enum PSI_cond_operation
+{
+ /** Wait. */
+ PSI_COND_WAIT= 0,
+ /** Wait, with timeout. */
+ PSI_COND_TIMEDWAIT= 1
+};
+
+/** Operation performed on an instrumented file. */
+enum PSI_file_operation
+{
+ /** File creation, as in @c create(). */
+ PSI_FILE_CREATE= 0,
+ /** Temporary file creation, as in @c create_temp_file(). */
+ PSI_FILE_CREATE_TMP= 1,
+ /** File open, as in @c open(). */
+ PSI_FILE_OPEN= 2,
+ /** File open, as in @c fopen(). */
+ PSI_FILE_STREAM_OPEN= 3,
+ /** File close, as in @c close(). */
+ PSI_FILE_CLOSE= 4,
+ /** File close, as in @c fclose(). */
+ PSI_FILE_STREAM_CLOSE= 5,
+ /**
+ Generic file read, such as @c fgets(), @c fgetc(), @c fread(), @c read(),
+ @c pread().
+ */
+ PSI_FILE_READ= 6,
+ /**
+ Generic file write, such as @c fputs(), @c fputc(), @c fprintf(),
+ @c vfprintf(), @c fwrite(), @c write(), @c pwrite().
+ */
+ PSI_FILE_WRITE= 7,
+ /** Generic file seek, such as @c fseek() or @c seek(). */
+ PSI_FILE_SEEK= 8,
+ /** Generic file tell, such as @c ftell() or @c tell(). */
+ PSI_FILE_TELL= 9,
+ /** File flush, as in @c fflush(). */
+ PSI_FILE_FLUSH= 10,
+ /** File stat, as in @c stat(). */
+ PSI_FILE_STAT= 11,
+ /** File stat, as in @c fstat(). */
+ PSI_FILE_FSTAT= 12,
+ /** File chsize, as in @c my_chsize(). */
+ PSI_FILE_CHSIZE= 13,
+ /** File delete, such as @c my_delete() or @c my_delete_with_symlink(). */
+ PSI_FILE_DELETE= 14,
+ /** File rename, such as @c my_rename() or @c my_rename_with_symlink(). */
+ PSI_FILE_RENAME= 15,
+ /** File sync, as in @c fsync() or @c my_sync(). */
+ PSI_FILE_SYNC= 16
+};
+
+/**
+ Interface for an instrumented table operation.
+ This is an opaque structure.
+*/
+struct PSI_table_locker;
+
+/**
+ Instrumented mutex key.
+ To instrument a mutex, a mutex key must be obtained using @c register_mutex.
+ Using a zero key always disable the instrumentation.
+*/
+typedef unsigned int PSI_mutex_key;
+
+/**
+ Instrumented rwlock key.
+ To instrument a rwlock, a rwlock key must be obtained
+ using @c register_rwlock.
+ Using a zero key always disable the instrumentation.
+*/
+typedef unsigned int PSI_rwlock_key;
+
+/**
+ Instrumented cond key.
+ To instrument a condition, a condition key must be obtained
+ using @c register_cond.
+ Using a zero key always disable the instrumentation.
+*/
+typedef unsigned int PSI_cond_key;
+
+/**
+ Instrumented thread key.
+ To instrument a thread, a thread key must be obtained
+ using @c register_thread.
+ Using a zero key always disable the instrumentation.
+*/
+typedef unsigned int PSI_thread_key;
+
+/**
+ Instrumented file key.
+ To instrument a file, a file key must be obtained using @c register_file.
+ Using a zero key always disable the instrumentation.
+*/
+typedef unsigned int PSI_file_key;
+
+/**
+ @def USE_PSI_1
+ Define USE_PSI_1 to use the interface version 1.
+*/
+
+/**
+ @def USE_PSI_2
+ Define USE_PSI_2 to use the interface version 2.
+*/
+
+/**
+ @def HAVE_PSI_1
+ Define HAVE_PSI_1 if the interface version 1 needs to be compiled in.
+*/
+
+/**
+ @def HAVE_PSI_2
+ Define HAVE_PSI_2 if the interface version 2 needs to be compiled in.
+*/
+
+/**
+ Global flag.
+ This flag indicate that an instrumentation point is a global variable,
+ or a singleton.
+*/
+#define PSI_FLAG_GLOBAL (1 << 0)
+
+#ifdef USE_PSI_1
+#define HAVE_PSI_1
+#endif
+
+#ifdef HAVE_PSI_1
+
+/**
+ @defgroup Group_PSI_v1 Application Binary Interface, version 1
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ Mutex information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented mutex.
+*/
+struct PSI_mutex_info_v1
+{
+ /**
+ Pointer to the key assigned to the registered mutex.
+ */
+ PSI_mutex_key *m_key;
+ /**
+ The name of the mutex to register.
+ */
+ const char *m_name;
+ /**
+ The flags of the mutex to register.
+ @sa PSI_FLAG_GLOBAL
+ */
+ int m_flags;
+};
+
+/**
+ Rwlock information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented rwlock.
+*/
+struct PSI_rwlock_info_v1
+{
+ /**
+ Pointer to the key assigned to the registered rwlock.
+ */
+ PSI_rwlock_key *m_key;
+ /**
+ The name of the rwlock to register.
+ */
+ const char *m_name;
+ /**
+ The flags of the rwlock to register.
+ @sa PSI_FLAG_GLOBAL
+ */
+ int m_flags;
+};
+
+/**
+ Condition information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented cond.
+*/
+struct PSI_cond_info_v1
+{
+ /**
+ Pointer to the key assigned to the registered cond.
+ */
+ PSI_cond_key *m_key;
+ /**
+ The name of the cond to register.
+ */
+ const char *m_name;
+ /**
+ The flags of the cond to register.
+ @sa PSI_FLAG_GLOBAL
+ */
+ int m_flags;
+};
+
+/**
+ Thread instrument information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented thread.
+*/
+struct PSI_thread_info_v1
+{
+ /**
+ Pointer to the key assigned to the registered thread.
+ */
+ PSI_thread_key *m_key;
+ /**
+ The name of the thread instrument to register.
+ */
+ const char *m_name;
+ /**
+ The flags of the thread to register.
+ @sa PSI_FLAG_GLOBAL
+ */
+ int m_flags;
+};
+
+/**
+ File instrument information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented file.
+*/
+struct PSI_file_info_v1
+{
+ /**
+ Pointer to the key assigned to the registered file.
+ */
+ PSI_file_key *m_key;
+ /**
+ The name of the file instrument to register.
+ */
+ const char *m_name;
+ /**
+ The flags of the file instrument to register.
+ @sa PSI_FLAG_GLOBAL
+ */
+ int m_flags;
+};
+
+/* Using typedef to make reuse between PSI_v1 and PSI_v2 easier later. */
+
+/**
+ Mutex registration API.
+ @param category a category name (typically a plugin name)
+ @param info an array of mutex info to register
+ @param count the size of the info array
+*/
+typedef void (*register_mutex_v1_t)
+ (const char *category, struct PSI_mutex_info_v1 *info, int count);
+
+/**
+ Rwlock registration API.
+ @param category a category name (typically a plugin name)
+ @param info an array of rwlock info to register
+ @param count the size of the info array
+*/
+typedef void (*register_rwlock_v1_t)
+ (const char *category, struct PSI_rwlock_info_v1 *info, int count);
+
+/**
+ Cond registration API.
+ @param category a category name (typically a plugin name)
+ @param info an array of cond info to register
+ @param count the size of the info array
+*/
+typedef void (*register_cond_v1_t)
+ (const char *category, struct PSI_cond_info_v1 *info, int count);
+
+/**
+ Thread registration API.
+ @param category a category name (typically a plugin name)
+ @param info an array of thread info to register
+ @param count the size of the info array
+*/
+typedef void (*register_thread_v1_t)
+ (const char *category, struct PSI_thread_info_v1 *info, int count);
+
+/**
+ File registration API.
+ @param category a category name (typically a plugin name)
+ @param info an array of file info to register
+ @param count the size of the info array
+*/
+typedef void (*register_file_v1_t)
+ (const char *category, struct PSI_file_info_v1 *info, int count);
+
+/**
+ Mutex instrumentation initialisation API.
+ @param key the registered mutex key
+ @param identity the address of the mutex itself
+ @return an instrumented mutex
+*/
+typedef struct PSI_mutex* (*init_mutex_v1_t)
+ (PSI_mutex_key key, const void *identity);
+
+/**
+ Mutex instrumentation destruction API.
+ @param mutex the mutex to destroy
+*/
+typedef void (*destroy_mutex_v1_t)(struct PSI_mutex *mutex);
+
+/**
+ Rwlock instrumentation initialisation API.
+ @param key the registered rwlock key
+ @param identity the address of the rwlock itself
+ @return an instrumented rwlock
+*/
+typedef struct PSI_rwlock* (*init_rwlock_v1_t)
+ (PSI_rwlock_key key, const void *identity);
+
+/**
+ Rwlock instrumentation destruction API.
+ @param rwlock the rwlock to destroy
+*/
+typedef void (*destroy_rwlock_v1_t)(struct PSI_rwlock *rwlock);
+
+/**
+ Cond instrumentation initialisation API.
+ @param key the registered key
+ @param identity the address of the rwlock itself
+ @return an instrumented cond
+*/
+typedef struct PSI_cond* (*init_cond_v1_t)
+ (PSI_cond_key key, const void *identity);
+
+/**
+ Cond instrumentation destruction API.
+ @param cond the rcond to destroy
+*/
+typedef void (*destroy_cond_v1_t)(struct PSI_cond *cond);
+
+/**
+ Acquire a table info by name.
+ @param schema_name name of the table schema
+ @param schema_name_length length of schema_name
+ @param table_name name of the table
+ @param table_name_length length of table_name
+ @param identity table identity pointer, typically the table share
+ @return a table info, or NULL if the table is not instrumented
+*/
+typedef struct PSI_table_share* (*get_table_share_v1_t)
+ (const char *schema_name, int schema_name_length, const char *table_name,
+ int table_name_length, const void *identity);
+
+/**
+ Release a table share.
+ @param info the table share to release
+*/
+typedef void (*release_table_share_v1_t)(struct PSI_table_share *share);
+
+/**
+ Open an instrumentation table handle.
+ @param share the table to open
+ @param identity table handle identity
+ @return a table handle, or NULL
+*/
+typedef struct PSI_table* (*open_table_v1_t)
+ (struct PSI_table_share *share, const void *identity);
+
+/**
+ Close an instrumentation table handle.
+ Note that the table handle is invalid after this call.
+ @param table the table handle to close
+*/
+typedef void (*close_table_v1_t)(struct PSI_table *table);
+
+/**
+ Create a file instrumentation for a created file.
+ This method does not create the file itself, but is used to notify the
+ instrumentation interface that a file was just created.
+ @param key the file instrumentation key for this file
+ @param name the file name
+ @param file the file handle
+*/
+typedef void (*create_file_v1_t)(PSI_file_key key, const char *name,
+ File file);
+
+/**
+ Spawn a thread.
+ This method creates a new thread, with instrumentation.
+ @param key the instrumentation key for this thread
+ @param thread the resulting thread
+ @param attr the thread attributes
+ @param start_routine the thread start routine
+ @param arg the thread start routine argument
+*/
+typedef int (*spawn_thread_v1_t)(PSI_thread_key key,
+ pthread_t *thread,
+ const pthread_attr_t *attr,
+ void *(*start_routine)(void*), void *arg);
+
+/**
+ Create instrumentation for a thread.
+ @param key the registered key
+ @param identity an address typical of the thread
+ @return an instrumented thread
+*/
+typedef struct PSI_thread* (*new_thread_v1_t)
+ (PSI_thread_key key, const void *identity, ulong thread_id);
+
+/**
+ Assign an id to an instrumented thread.
+ @param thread the instrumented thread
+ @param id the id to assign
+*/
+typedef void (*set_thread_id_v1_t)(struct PSI_thread *thread,
+ unsigned long id);
+
+/**
+ Get the instrumentation for the running thread.
+ For this function to return a result,
+ the thread instrumentation must have been attached to the
+ running thread using @c set_thread()
+ @return the instrumentation for the running thread
+*/
+typedef struct PSI_thread* (*get_thread_v1_t)(void);
+
+/**
+ Attach a thread instrumentation to the running thread.
+ In case of thread pools, this method should be called when
+ a worker thread picks a work item and runs it.
+ Also, this method should be called if the instrumented code does not
+ keep the pointer returned by @c new_thread() and relies on @c get_thread()
+ instead.
+ @param thread the thread instrumentation
+*/
+typedef void (*set_thread_v1_t)(struct PSI_thread *thread);
+
+/** Delete the current thread instrumentation. */
+typedef void (*delete_current_thread_v1_t)(void);
+
+/** Delete a thread instrumentation. */
+typedef void (*delete_thread_v1_t)(struct PSI_thread *thread);
+
+/**
+ Get a mutex instrumentation locker.
+ @param mutex the instrumented mutex to lock
+ @return a mutex locker, or NULL
+*/
+typedef struct PSI_mutex_locker* (*get_thread_mutex_locker_v1_t)
+ (struct PSI_mutex *mutex, enum PSI_mutex_operation op);
+
+/**
+ Get a rwlock instrumentation locker.
+ @param rwlock the instrumented rwlock to lock
+ @return a rwlock locker, or NULL
+*/
+typedef struct PSI_rwlock_locker* (*get_thread_rwlock_locker_v1_t)
+ (struct PSI_rwlock *rwlock, enum PSI_rwlock_operation op);
+
+/**
+ Get a cond instrumentation locker.
+ @param cond the instrumented condition to wait on
+ @param mutex the instrumented mutex associated with the condition
+ @return a condition locker, or NULL
+*/
+typedef struct PSI_cond_locker* (*get_thread_cond_locker_v1_t)
+ (struct PSI_cond *cond, struct PSI_mutex *mutex,
+ enum PSI_cond_operation op);
+
+/**
+ Get a table instrumentation locker.
+ @param table the instrumented table to lock
+ @return a table locker, or NULL
+*/
+typedef struct PSI_table_locker* (*get_thread_table_locker_v1_t)
+ (struct PSI_table *table);
+
+/**
+ Get a file instrumentation locker, for opening or creating a file.
+ @param key the file instrumentation key
+ @param op the operation to perform
+ @param name the file name
+ @param identity a pointer representative of this file.
+ @return a file locker, or NULL
+*/
+typedef struct PSI_file_locker* (*get_thread_file_name_locker_v1_t)
+ (PSI_file_key key, enum PSI_file_operation op, const char *name,
+ const void *identity);
+
+/**
+ Get a file stream instrumentation locker.
+ @param file the file stream to access
+ @param op the operation to perform
+ @return a file locker, or NULL
+*/
+typedef struct PSI_file_locker* (*get_thread_file_stream_locker_v1_t)
+ (struct PSI_file *file, enum PSI_file_operation op);
+
+/**
+ Get a file instrumentation locker.
+ @param file the file descriptor to access
+ @param op the operation to perform
+ @return a file locker, or NULL
+*/
+typedef struct PSI_file_locker* (*get_thread_file_descriptor_locker_v1_t)
+ (File file, enum PSI_file_operation op);
+
+/**
+ Record a mutex instrumentation unlock event.
+ @param thread the running thread instrumentation
+ @param mutex the mutex instrumentation
+*/
+typedef void (*unlock_mutex_v1_t)
+ (struct PSI_thread *thread, struct PSI_mutex *mutex);
+
+/**
+ Record a rwlock instrumentation unlock event.
+ @param thread the running thread instrumentation
+ @param rwlock the rwlock instrumentation
+*/
+typedef void (*unlock_rwlock_v1_t)
+ (struct PSI_thread *thread, struct PSI_rwlock *rwlock);
+
+/**
+ Record a condition instrumentation signal event.
+ @param thread the running thread instrumentation
+ @param cond the cond instrumentation
+*/
+typedef void (*signal_cond_v1_t)
+ (struct PSI_thread *thread, struct PSI_cond *cond);
+
+/**
+ Record a condition instrumentation broadcast event.
+ @param thread the running thread instrumentation
+ @param cond the cond instrumentation
+*/
+typedef void (*broadcast_cond_v1_t)
+ (struct PSI_thread *thread, struct PSI_cond *cond);
+
+/**
+ Record a mutex instrumentation wait start event.
+ @param locker a thread locker for the running thread
+*/
+typedef void (*start_mutex_wait_v1_t)
+ (struct PSI_mutex_locker *locker, const char *src_file, uint src_line);
+
+/**
+ Record a mutex instrumentation wait end event.
+ @param locker a thread locker for the running thread
+ @param rc the wait operation return code
+*/
+typedef void (*end_mutex_wait_v1_t)
+ (struct PSI_mutex_locker *locker, int rc);
+
+/**
+ Record a rwlock instrumentation read wait start event.
+ @param locker a thread locker for the running thread
+ @param must must block: 1 for lock, 0 for trylock
+*/
+typedef void (*start_rwlock_rdwait_v1_t)
+ (struct PSI_rwlock_locker *locker, const char *src_file, uint src_line);
+
+/**
+ Record a rwlock instrumentation read wait end event.
+ @param locker a thread locker for the running thread
+ @param rc the wait operation return code
+*/
+typedef void (*end_rwlock_rdwait_v1_t)
+ (struct PSI_rwlock_locker *locker, int rc);
+
+/**
+ Record a rwlock instrumentation write wait start event.
+ @param locker a thread locker for the running thread
+ @param must must block: 1 for lock, 0 for trylock
+*/
+typedef void (*start_rwlock_wrwait_v1_t)
+ (struct PSI_rwlock_locker *locker, const char *src_file, uint src_line);
+
+/**
+ Record a rwlock instrumentation write wait end event.
+ @param locker a thread locker for the running thread
+ @param rc the wait operation return code
+*/
+typedef void (*end_rwlock_wrwait_v1_t)
+ (struct PSI_rwlock_locker *locker, int rc);
+
+/**
+ Record a condition instrumentation wait start event.
+ @param locker a thread locker for the running thread
+ @param must must block: 1 for wait, 0 for timedwait
+*/
+typedef void (*start_cond_wait_v1_t)
+ (struct PSI_cond_locker *locker, const char *src_file, uint src_line);
+
+/**
+ Record a condition instrumentation wait end event.
+ @param locker a thread locker for the running thread
+ @param rc the wait operation return code
+*/
+typedef void (*end_cond_wait_v1_t)
+ (struct PSI_cond_locker *locker, int rc);
+
+/**
+ Record a table instrumentation wait start event.
+ @param locker a table locker for the running thread
+ @param file the source file name
+ @param line the source line number
+*/
+typedef void (*start_table_wait_v1_t)
+ (struct PSI_table_locker *locker, const char *src_file, uint src_line);
+
+/**
+ Record a table instrumentation wait end event.
+ @param locker a table locker for the running thread
+*/
+typedef void (*end_table_wait_v1_t)(struct PSI_table_locker *locker);
+
+/**
+ Start a file instrumentation open operation.
+ @param locker the file locker
+ @param op the operation to perform
+ @param src_file the source file name
+ @param src_line the source line number
+ @return an instrumented file handle
+*/
+typedef struct PSI_file* (*start_file_open_wait_v1_t)
+ (struct PSI_file_locker *locker, const char *src_file, uint src_line);
+
+/**
+ End a file instrumentation open operation, for file streams.
+ @param locker the file locker.
+*/
+typedef void (*end_file_open_wait_v1_t)(struct PSI_file_locker *locker);
+
+/**
+ End a file instrumentation open operation, for non stream files.
+ @param locker the file locker.
+ @param file the file number assigned by open() or create() for this file.
+*/
+typedef void (*end_file_open_wait_and_bind_to_descriptor_v1_t)
+ (struct PSI_file_locker *locker, File file);
+
+/**
+ Record a file instrumentation start event.
+ @param locker a file locker for the running thread
+ @param op file operation to be performed
+ @param count the number of bytes requested, or 0 if not applicable
+ @param src_file the source file name
+ @param src_line the source line number
+*/
+typedef void (*start_file_wait_v1_t)
+ (struct PSI_file_locker *locker, size_t count,
+ const char *src_file, uint src_line);
+
+/**
+ Record a file instrumentation end event.
+ Note that for file close operations, the instrumented file handle
+ associated with the file (which was provided to obtain a locker)
+ is invalid after this call.
+ @param locker a file locker for the running thread
+ @param count the number of bytes actually used in the operation,
+ or 0 if not applicable, or -1 if the operation failed
+ @sa get_thread_file_name_locker
+ @sa get_thread_file_stream_locker
+ @sa get_thread_file_descriptor_locker
+*/
+typedef void (*end_file_wait_v1_t)
+ (struct PSI_file_locker *locker, size_t count);
+
+/**
+ Performance Schema Interface, version 1.
+ @since PSI_VERSION_1
+*/
+struct PSI_v1
+{
+ /** @sa register_mutex_v1_t. */
+ register_mutex_v1_t register_mutex;
+ /** @sa register_rwlock_v1_t. */
+ register_rwlock_v1_t register_rwlock;
+ /** @sa register_cond_v1_t. */
+ register_cond_v1_t register_cond;
+ /** @sa register_thread_v1_t. */
+ register_thread_v1_t register_thread;
+ /** @sa register_file_v1_t. */
+ register_file_v1_t register_file;
+ /** @sa init_mutex_v1_t. */
+ init_mutex_v1_t init_mutex;
+ /** @sa destroy_mutex_v1_t. */
+ destroy_mutex_v1_t destroy_mutex;
+ /** @sa init_rwlock_v1_t. */
+ init_rwlock_v1_t init_rwlock;
+ /** @sa destroy_rwlock_v1_t. */
+ destroy_rwlock_v1_t destroy_rwlock;
+ /** @sa init_cond_v1_t. */
+ init_cond_v1_t init_cond;
+ /** @sa destroy_cond_v1_t. */
+ destroy_cond_v1_t destroy_cond;
+ /** @sa get_table_share_v1_t. */
+ get_table_share_v1_t get_table_share;
+ /** @sa release_table_share_v1_t. */
+ release_table_share_v1_t release_table_share;
+ /** @sa open_table_v1_t. */
+ open_table_v1_t open_table;
+ /** @sa close_table_v1_t. */
+ close_table_v1_t close_table;
+ /** @sa create_file_v1_t. */
+ create_file_v1_t create_file;
+ /** @sa spawn_thread_v1_t. */
+ spawn_thread_v1_t spawn_thread;
+ /** @sa new_thread_v1_t. */
+ new_thread_v1_t new_thread;
+ /** @sa set_thread_id_v1_t. */
+ set_thread_id_v1_t set_thread_id;
+ /** @sa get_thread_v1_t. */
+ get_thread_v1_t get_thread;
+ /** @sa set_thread_v1_t. */
+ set_thread_v1_t set_thread;
+ /** @sa delete_current_thread_v1_t. */
+ delete_current_thread_v1_t delete_current_thread;
+ /** @sa delete_thread_v1_t. */
+ delete_thread_v1_t delete_thread;
+ /** @sa get_thread_mutex_locker_v1_t. */
+ get_thread_mutex_locker_v1_t get_thread_mutex_locker;
+ /** @sa get_thread_rwlock_locker_v1_t. */
+ get_thread_rwlock_locker_v1_t get_thread_rwlock_locker;
+ /** @sa get_thread_cond_locker_v1_t. */
+ get_thread_cond_locker_v1_t get_thread_cond_locker;
+ /** @sa get_thread_table_locker_v1_t. */
+ get_thread_table_locker_v1_t get_thread_table_locker;
+ /** @sa get_thread_file_name_locker_v1_t. */
+ get_thread_file_name_locker_v1_t get_thread_file_name_locker;
+ /** @sa get_thread_file_stream_locker_v1_t. */
+ get_thread_file_stream_locker_v1_t get_thread_file_stream_locker;
+ /** @sa get_thread_file_descriptor_locker_v1_t. */
+ get_thread_file_descriptor_locker_v1_t get_thread_file_descriptor_locker;
+ /** @sa unlock_mutex_v1_t. */
+ unlock_mutex_v1_t unlock_mutex;
+ /** @sa unlock_rwlock_v1_t. */
+ unlock_rwlock_v1_t unlock_rwlock;
+ /** @sa signal_cond_v1_t. */
+ signal_cond_v1_t signal_cond;
+ /** @sa broadcast_cond_v1_t. */
+ broadcast_cond_v1_t broadcast_cond;
+ /** @sa start_mutex_wait_v1_t. */
+ start_mutex_wait_v1_t start_mutex_wait;
+ /** @sa end_mutex_wait_v1_t. */
+ end_mutex_wait_v1_t end_mutex_wait;
+ /** @sa start_rwlock_rdwait_v1_t. */
+ start_rwlock_rdwait_v1_t start_rwlock_rdwait;
+ /** @sa end_rwlock_rdwait_v1_t. */
+ end_rwlock_rdwait_v1_t end_rwlock_rdwait;
+ /** @sa start_rwlock_wrwait_v1_t. */
+ start_rwlock_wrwait_v1_t start_rwlock_wrwait;
+ /** @sa end_rwlock_wrwait_v1_t. */
+ end_rwlock_wrwait_v1_t end_rwlock_wrwait;
+ /** @sa start_cond_wait_v1_t. */
+ start_cond_wait_v1_t start_cond_wait;
+ /** @sa end_cond_wait_v1_t. */
+ end_cond_wait_v1_t end_cond_wait;
+ /** @sa start_table_wait_v1_t. */
+ start_table_wait_v1_t start_table_wait;
+ /** @sa end_table_wait_v1_t. */
+ end_table_wait_v1_t end_table_wait;
+ /** @sa start_file_open_wait_v1_t. */
+ start_file_open_wait_v1_t start_file_open_wait;
+ /** @sa end_file_open_wait_v1_t. */
+ end_file_open_wait_v1_t end_file_open_wait;
+ /** @sa end_file_open_wait_and_bind_to_descriptor_v1_t. */
+ end_file_open_wait_and_bind_to_descriptor_v1_t
+ end_file_open_wait_and_bind_to_descriptor;
+ /** @sa start_file_wait_v1_t. */
+ start_file_wait_v1_t start_file_wait;
+ /** @sa end_file_wait_v1_t. */
+ end_file_wait_v1_t end_file_wait;
+};
+
+/** @} (end of group Group_PSI_v1) */
+
+#endif /* HAVE_PSI_1 */
+
+#ifdef USE_PSI_2
+#define HAVE_PSI_2
+#endif
+
+#ifdef HAVE_PSI_2
+
+/**
+ @defgroup Group_PSI_v2 Application Binary Interface, version 2
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ Performance Schema Interface, version 2.
+ This is a placeholder, this interface is not defined yet.
+ @since PSI_VERSION_2
+*/
+struct PSI_v2
+{
+ /** Placeholder */
+ int placeholder;
+ /* ... extended interface ... */
+};
+
+/** Placeholder */
+struct PSI_mutex_info_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_rwlock_info_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_cond_info_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_thread_info_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_file_info_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** @} (end of group Group_PSI_v2) */
+
+#endif /* HAVE_PSI_2 */
+
+/**
+ @typedef PSI
+ The instrumentation interface for the current version.
+ @sa PSI_CURRENT_VERSION
+*/
+
+/**
+ @typedef PSI_mutex_info
+ The mutex information structure for the current version.
+*/
+
+/**
+ @typedef PSI_rwlock_info
+ The rwlock information structure for the current version.
+*/
+
+/**
+ @typedef PSI_cond_info
+ The cond information structure for the current version.
+*/
+
+/**
+ @typedef PSI_thread_info
+ The thread information structure for the current version.
+*/
+
+/**
+ @typedef PSI_file_info
+ The file information structure for the current version.
+*/
+
+/* Export the required version */
+#ifdef USE_PSI_1
+typedef struct PSI_v1 PSI;
+typedef struct PSI_mutex_info_v1 PSI_mutex_info;
+typedef struct PSI_rwlock_info_v1 PSI_rwlock_info;
+typedef struct PSI_cond_info_v1 PSI_cond_info;
+typedef struct PSI_thread_info_v1 PSI_thread_info;
+typedef struct PSI_file_info_v1 PSI_file_info;
+#endif
+
+#ifdef USE_PSI_2
+typedef struct PSI_v2 PSI;
+typedef struct PSI_mutex_info_v2 PSI_mutex_info;
+typedef struct PSI_rwlock_info_v2 PSI_rwlock_info;
+typedef struct PSI_cond_info_v2 PSI_cond_info;
+typedef struct PSI_thread_info_v2 PSI_thread_info;
+typedef struct PSI_file_info_v2 PSI_file_info;
+#endif
+
+#else /* HAVE_PSI_INTERFACE */
+
+/**
+ Dummy structure, used to declare PSI_server when no instrumentation
+ is available.
+ The content does not matter, since PSI_server will be NULL.
+*/
+struct PSI_none
+{
+ int opaque;
+};
+typedef struct PSI_none PSI;
+
+#endif /* HAVE_PSI_INTERFACE */
+
+extern MYSQL_PLUGIN_IMPORT PSI *PSI_server;
+
+/** @} */
+
+C_MODE_END
+#endif /* MYSQL_PERFORMANCE_SCHEMA_INTERFACE_H */
+
diff --git a/include/mysql/psi/psi_abi_v1.h b/include/mysql/psi/psi_abi_v1.h
new file mode 100644
index 00000000000..c9dfd031668
--- /dev/null
+++ b/include/mysql/psi/psi_abi_v1.h
@@ -0,0 +1,26 @@
+/* Copyright (C) 2008-2009 Sun Microsystems, Inc
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file mysql/psi/psi_abi_v1.h
+ ABI check for mysql/psi/psi.h, when using PSI_VERSION_1.
+ This file is only used to automate detection of changes between versions.
+ Do not include this file, include mysql/psi/psi.h instead.
+*/
+#define USE_PSI_1
+#define HAVE_PSI_INTERFACE
+#define _global_h
+#include "mysql/psi/psi.h"
+
diff --git a/include/mysql/psi/psi_abi_v1.h.pp b/include/mysql/psi/psi_abi_v1.h.pp
new file mode 100644
index 00000000000..6ecd0f3098d
--- /dev/null
+++ b/include/mysql/psi/psi_abi_v1.h.pp
@@ -0,0 +1,244 @@
+#include "mysql/psi/psi.h"
+C_MODE_START
+struct PSI_mutex;
+struct PSI_rwlock;
+struct PSI_cond;
+struct PSI_table_share;
+struct PSI_table;
+struct PSI_thread;
+struct PSI_file;
+struct PSI_bootstrap
+{
+ void* (*get_interface)(int version);
+};
+struct PSI_mutex_locker;
+struct PSI_rwlock_locker;
+struct PSI_cond_locker;
+struct PSI_file_locker;
+enum PSI_mutex_operation
+{
+ PSI_MUTEX_LOCK= 0,
+ PSI_MUTEX_TRYLOCK= 1
+};
+enum PSI_rwlock_operation
+{
+ PSI_RWLOCK_READLOCK= 0,
+ PSI_RWLOCK_WRITELOCK= 1,
+ PSI_RWLOCK_TRYREADLOCK= 2,
+ PSI_RWLOCK_TRYWRITELOCK= 3
+};
+enum PSI_cond_operation
+{
+ PSI_COND_WAIT= 0,
+ PSI_COND_TIMEDWAIT= 1
+};
+enum PSI_file_operation
+{
+ PSI_FILE_CREATE= 0,
+ PSI_FILE_CREATE_TMP= 1,
+ PSI_FILE_OPEN= 2,
+ PSI_FILE_STREAM_OPEN= 3,
+ PSI_FILE_CLOSE= 4,
+ PSI_FILE_STREAM_CLOSE= 5,
+ PSI_FILE_READ= 6,
+ PSI_FILE_WRITE= 7,
+ PSI_FILE_SEEK= 8,
+ PSI_FILE_TELL= 9,
+ PSI_FILE_FLUSH= 10,
+ PSI_FILE_STAT= 11,
+ PSI_FILE_FSTAT= 12,
+ PSI_FILE_CHSIZE= 13,
+ PSI_FILE_DELETE= 14,
+ PSI_FILE_RENAME= 15,
+ PSI_FILE_SYNC= 16
+};
+struct PSI_table_locker;
+typedef unsigned int PSI_mutex_key;
+typedef unsigned int PSI_rwlock_key;
+typedef unsigned int PSI_cond_key;
+typedef unsigned int PSI_thread_key;
+typedef unsigned int PSI_file_key;
+struct PSI_mutex_info_v1
+{
+ PSI_mutex_key *m_key;
+ const char *m_name;
+ int m_flags;
+};
+struct PSI_rwlock_info_v1
+{
+ PSI_rwlock_key *m_key;
+ const char *m_name;
+ int m_flags;
+};
+struct PSI_cond_info_v1
+{
+ PSI_cond_key *m_key;
+ const char *m_name;
+ int m_flags;
+};
+struct PSI_thread_info_v1
+{
+ PSI_thread_key *m_key;
+ const char *m_name;
+ int m_flags;
+};
+struct PSI_file_info_v1
+{
+ PSI_file_key *m_key;
+ const char *m_name;
+ int m_flags;
+};
+typedef void (*register_mutex_v1_t)
+ (const char *category, struct PSI_mutex_info_v1 *info, int count);
+typedef void (*register_rwlock_v1_t)
+ (const char *category, struct PSI_rwlock_info_v1 *info, int count);
+typedef void (*register_cond_v1_t)
+ (const char *category, struct PSI_cond_info_v1 *info, int count);
+typedef void (*register_thread_v1_t)
+ (const char *category, struct PSI_thread_info_v1 *info, int count);
+typedef void (*register_file_v1_t)
+ (const char *category, struct PSI_file_info_v1 *info, int count);
+typedef struct PSI_mutex* (*init_mutex_v1_t)
+ (PSI_mutex_key key, const void *identity);
+typedef void (*destroy_mutex_v1_t)(struct PSI_mutex *mutex);
+typedef struct PSI_rwlock* (*init_rwlock_v1_t)
+ (PSI_rwlock_key key, const void *identity);
+typedef void (*destroy_rwlock_v1_t)(struct PSI_rwlock *rwlock);
+typedef struct PSI_cond* (*init_cond_v1_t)
+ (PSI_cond_key key, const void *identity);
+typedef void (*destroy_cond_v1_t)(struct PSI_cond *cond);
+typedef struct PSI_table_share* (*get_table_share_v1_t)
+ (const char *schema_name, int schema_name_length, const char *table_name,
+ int table_name_length, const void *identity);
+typedef void (*release_table_share_v1_t)(struct PSI_table_share *share);
+typedef struct PSI_table* (*open_table_v1_t)
+ (struct PSI_table_share *share, const void *identity);
+typedef void (*close_table_v1_t)(struct PSI_table *table);
+typedef void (*create_file_v1_t)(PSI_file_key key, const char *name,
+ File file);
+typedef int (*spawn_thread_v1_t)(PSI_thread_key key,
+ pthread_t *thread,
+ const pthread_attr_t *attr,
+ void *(*start_routine)(void*), void *arg);
+typedef struct PSI_thread* (*new_thread_v1_t)
+ (PSI_thread_key key, const void *identity, ulong thread_id);
+typedef void (*set_thread_id_v1_t)(struct PSI_thread *thread,
+ unsigned long id);
+typedef struct PSI_thread* (*get_thread_v1_t)(void);
+typedef void (*set_thread_v1_t)(struct PSI_thread *thread);
+typedef void (*delete_current_thread_v1_t)(void);
+typedef void (*delete_thread_v1_t)(struct PSI_thread *thread);
+typedef struct PSI_mutex_locker* (*get_thread_mutex_locker_v1_t)
+ (struct PSI_mutex *mutex, enum PSI_mutex_operation op);
+typedef struct PSI_rwlock_locker* (*get_thread_rwlock_locker_v1_t)
+ (struct PSI_rwlock *rwlock, enum PSI_rwlock_operation op);
+typedef struct PSI_cond_locker* (*get_thread_cond_locker_v1_t)
+ (struct PSI_cond *cond, struct PSI_mutex *mutex,
+ enum PSI_cond_operation op);
+typedef struct PSI_table_locker* (*get_thread_table_locker_v1_t)
+ (struct PSI_table *table);
+typedef struct PSI_file_locker* (*get_thread_file_name_locker_v1_t)
+ (PSI_file_key key, enum PSI_file_operation op, const char *name,
+ const void *identity);
+typedef struct PSI_file_locker* (*get_thread_file_stream_locker_v1_t)
+ (struct PSI_file *file, enum PSI_file_operation op);
+typedef struct PSI_file_locker* (*get_thread_file_descriptor_locker_v1_t)
+ (File file, enum PSI_file_operation op);
+typedef void (*unlock_mutex_v1_t)
+ (struct PSI_thread *thread, struct PSI_mutex *mutex);
+typedef void (*unlock_rwlock_v1_t)
+ (struct PSI_thread *thread, struct PSI_rwlock *rwlock);
+typedef void (*signal_cond_v1_t)
+ (struct PSI_thread *thread, struct PSI_cond *cond);
+typedef void (*broadcast_cond_v1_t)
+ (struct PSI_thread *thread, struct PSI_cond *cond);
+typedef void (*start_mutex_wait_v1_t)
+ (struct PSI_mutex_locker *locker, const char *src_file, uint src_line);
+typedef void (*end_mutex_wait_v1_t)
+ (struct PSI_mutex_locker *locker, int rc);
+typedef void (*start_rwlock_rdwait_v1_t)
+ (struct PSI_rwlock_locker *locker, const char *src_file, uint src_line);
+typedef void (*end_rwlock_rdwait_v1_t)
+ (struct PSI_rwlock_locker *locker, int rc);
+typedef void (*start_rwlock_wrwait_v1_t)
+ (struct PSI_rwlock_locker *locker, const char *src_file, uint src_line);
+typedef void (*end_rwlock_wrwait_v1_t)
+ (struct PSI_rwlock_locker *locker, int rc);
+typedef void (*start_cond_wait_v1_t)
+ (struct PSI_cond_locker *locker, const char *src_file, uint src_line);
+typedef void (*end_cond_wait_v1_t)
+ (struct PSI_cond_locker *locker, int rc);
+typedef void (*start_table_wait_v1_t)
+ (struct PSI_table_locker *locker, const char *src_file, uint src_line);
+typedef void (*end_table_wait_v1_t)(struct PSI_table_locker *locker);
+typedef struct PSI_file* (*start_file_open_wait_v1_t)
+ (struct PSI_file_locker *locker, const char *src_file, uint src_line);
+typedef void (*end_file_open_wait_v1_t)(struct PSI_file_locker *locker);
+typedef void (*end_file_open_wait_and_bind_to_descriptor_v1_t)
+ (struct PSI_file_locker *locker, File file);
+typedef void (*start_file_wait_v1_t)
+ (struct PSI_file_locker *locker, size_t count,
+ const char *src_file, uint src_line);
+typedef void (*end_file_wait_v1_t)
+ (struct PSI_file_locker *locker, size_t count);
+struct PSI_v1
+{
+ register_mutex_v1_t register_mutex;
+ register_rwlock_v1_t register_rwlock;
+ register_cond_v1_t register_cond;
+ register_thread_v1_t register_thread;
+ register_file_v1_t register_file;
+ init_mutex_v1_t init_mutex;
+ destroy_mutex_v1_t destroy_mutex;
+ init_rwlock_v1_t init_rwlock;
+ destroy_rwlock_v1_t destroy_rwlock;
+ init_cond_v1_t init_cond;
+ destroy_cond_v1_t destroy_cond;
+ get_table_share_v1_t get_table_share;
+ release_table_share_v1_t release_table_share;
+ open_table_v1_t open_table;
+ close_table_v1_t close_table;
+ create_file_v1_t create_file;
+ spawn_thread_v1_t spawn_thread;
+ new_thread_v1_t new_thread;
+ set_thread_id_v1_t set_thread_id;
+ get_thread_v1_t get_thread;
+ set_thread_v1_t set_thread;
+ delete_current_thread_v1_t delete_current_thread;
+ delete_thread_v1_t delete_thread;
+ get_thread_mutex_locker_v1_t get_thread_mutex_locker;
+ get_thread_rwlock_locker_v1_t get_thread_rwlock_locker;
+ get_thread_cond_locker_v1_t get_thread_cond_locker;
+ get_thread_table_locker_v1_t get_thread_table_locker;
+ get_thread_file_name_locker_v1_t get_thread_file_name_locker;
+ get_thread_file_stream_locker_v1_t get_thread_file_stream_locker;
+ get_thread_file_descriptor_locker_v1_t get_thread_file_descriptor_locker;
+ unlock_mutex_v1_t unlock_mutex;
+ unlock_rwlock_v1_t unlock_rwlock;
+ signal_cond_v1_t signal_cond;
+ broadcast_cond_v1_t broadcast_cond;
+ start_mutex_wait_v1_t start_mutex_wait;
+ end_mutex_wait_v1_t end_mutex_wait;
+ start_rwlock_rdwait_v1_t start_rwlock_rdwait;
+ end_rwlock_rdwait_v1_t end_rwlock_rdwait;
+ start_rwlock_wrwait_v1_t start_rwlock_wrwait;
+ end_rwlock_wrwait_v1_t end_rwlock_wrwait;
+ start_cond_wait_v1_t start_cond_wait;
+ end_cond_wait_v1_t end_cond_wait;
+ start_table_wait_v1_t start_table_wait;
+ end_table_wait_v1_t end_table_wait;
+ start_file_open_wait_v1_t start_file_open_wait;
+ end_file_open_wait_v1_t end_file_open_wait;
+ end_file_open_wait_and_bind_to_descriptor_v1_t
+ end_file_open_wait_and_bind_to_descriptor;
+ start_file_wait_v1_t start_file_wait;
+ end_file_wait_v1_t end_file_wait;
+};
+typedef struct PSI_v1 PSI;
+typedef struct PSI_mutex_info_v1 PSI_mutex_info;
+typedef struct PSI_rwlock_info_v1 PSI_rwlock_info;
+typedef struct PSI_cond_info_v1 PSI_cond_info;
+typedef struct PSI_thread_info_v1 PSI_thread_info;
+typedef struct PSI_file_info_v1 PSI_file_info;
+extern MYSQL_PLUGIN_IMPORT PSI *PSI_server;
+C_MODE_END
diff --git a/include/mysql/psi/psi_abi_v2.h b/include/mysql/psi/psi_abi_v2.h
new file mode 100644
index 00000000000..e720c4c2b7c
--- /dev/null
+++ b/include/mysql/psi/psi_abi_v2.h
@@ -0,0 +1,26 @@
+/* Copyright (C) 2008-2009 Sun Microsystems, Inc
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+/**
+ @file mysql/psi/psi_abi_v1.h
+ ABI check for mysql/psi/psi.h, when using PSI_VERSION_2.
+ This file is only used to automate detection of changes between versions.
+ Do not include this file, include mysql/psi/psi.h instead.
+*/
+#define USE_PSI_2
+#define HAVE_PSI_INTERFACE
+#define _global_h
+#include "mysql/psi/psi.h"
+
diff --git a/include/mysql/psi/psi_abi_v2.h.pp b/include/mysql/psi/psi_abi_v2.h.pp
new file mode 100644
index 00000000000..b32415a59b4
--- /dev/null
+++ b/include/mysql/psi/psi_abi_v2.h.pp
@@ -0,0 +1,92 @@
+#include "mysql/psi/psi.h"
+C_MODE_START
+struct PSI_mutex;
+struct PSI_rwlock;
+struct PSI_cond;
+struct PSI_table_share;
+struct PSI_table;
+struct PSI_thread;
+struct PSI_file;
+struct PSI_bootstrap
+{
+ void* (*get_interface)(int version);
+};
+struct PSI_mutex_locker;
+struct PSI_rwlock_locker;
+struct PSI_cond_locker;
+struct PSI_file_locker;
+enum PSI_mutex_operation
+{
+ PSI_MUTEX_LOCK= 0,
+ PSI_MUTEX_TRYLOCK= 1
+};
+enum PSI_rwlock_operation
+{
+ PSI_RWLOCK_READLOCK= 0,
+ PSI_RWLOCK_WRITELOCK= 1,
+ PSI_RWLOCK_TRYREADLOCK= 2,
+ PSI_RWLOCK_TRYWRITELOCK= 3
+};
+enum PSI_cond_operation
+{
+ PSI_COND_WAIT= 0,
+ PSI_COND_TIMEDWAIT= 1
+};
+enum PSI_file_operation
+{
+ PSI_FILE_CREATE= 0,
+ PSI_FILE_CREATE_TMP= 1,
+ PSI_FILE_OPEN= 2,
+ PSI_FILE_STREAM_OPEN= 3,
+ PSI_FILE_CLOSE= 4,
+ PSI_FILE_STREAM_CLOSE= 5,
+ PSI_FILE_READ= 6,
+ PSI_FILE_WRITE= 7,
+ PSI_FILE_SEEK= 8,
+ PSI_FILE_TELL= 9,
+ PSI_FILE_FLUSH= 10,
+ PSI_FILE_STAT= 11,
+ PSI_FILE_FSTAT= 12,
+ PSI_FILE_CHSIZE= 13,
+ PSI_FILE_DELETE= 14,
+ PSI_FILE_RENAME= 15,
+ PSI_FILE_SYNC= 16
+};
+struct PSI_table_locker;
+typedef unsigned int PSI_mutex_key;
+typedef unsigned int PSI_rwlock_key;
+typedef unsigned int PSI_cond_key;
+typedef unsigned int PSI_thread_key;
+typedef unsigned int PSI_file_key;
+struct PSI_v2
+{
+ int placeholder;
+};
+struct PSI_mutex_info_v2
+{
+ int placeholder;
+};
+struct PSI_rwlock_info_v2
+{
+ int placeholder;
+};
+struct PSI_cond_info_v2
+{
+ int placeholder;
+};
+struct PSI_thread_info_v2
+{
+ int placeholder;
+};
+struct PSI_file_info_v2
+{
+ int placeholder;
+};
+typedef struct PSI_v2 PSI;
+typedef struct PSI_mutex_info_v2 PSI_mutex_info;
+typedef struct PSI_rwlock_info_v2 PSI_rwlock_info;
+typedef struct PSI_cond_info_v2 PSI_cond_info;
+typedef struct PSI_thread_info_v2 PSI_thread_info;
+typedef struct PSI_file_info_v2 PSI_file_info;
+extern MYSQL_PLUGIN_IMPORT PSI *PSI_server;
+C_MODE_END
diff --git a/include/mysql/service_my_snprintf.h b/include/mysql/service_my_snprintf.h
index ad344864c34..9e5fe7f9c9f 100644
--- a/include/mysql/service_my_snprintf.h
+++ b/include/mysql/service_my_snprintf.h
@@ -53,7 +53,7 @@
<length modifier> can be 'l', 'll', or 'z'.
Supported formats are 's' (null pointer is accepted, printed as
- "(null)"), 'b' (extension, see below), 'c', 'd', 'u', 'x',
+ "(null)"), 'b' (extension, see below), 'c', 'd', 'u', 'x', 'o',
'X', 'p' (works as 0x%x).
Standard syntax for positional arguments $n is supported.
diff --git a/include/mysql_com.h b/include/mysql_com.h
index 345ecd5dd93..e4e34141d43 100644
--- a/include/mysql_com.h
+++ b/include/mysql_com.h
@@ -33,6 +33,14 @@
#define SQLSTATE_LENGTH 5
/*
+ Maximum length of comments
+*/
+#define TABLE_COMMENT_INLINE_MAXLEN 180 /* pre 6.0: 60 characters */
+#define TABLE_COMMENT_MAXLEN 2048
+#define COLUMN_COMMENT_MAXLEN 1024
+#define INDEX_COMMENT_MAXLEN 1024
+
+/*
USER_HOST_BUFF_SIZE -- length of string buffer, that is enough to contain
username and hostname parts of the user identifier with trailing zero in
MySQL standard format:
@@ -117,6 +125,12 @@ enum enum_server_command
thread */
#define REFRESH_MASTER 128 /* Remove all bin logs in the index
and truncate the index */
+#define REFRESH_ERROR_LOG 256 /* Rotate only the erorr log */
+#define REFRESH_ENGINE_LOG 512 /* Flush all storage engine logs */
+#define REFRESH_BINARY_LOG 1024 /* Flush the binary log */
+#define REFRESH_RELAY_LOG 2048 /* Flush the relay log */
+#define REFRESH_GENERAL_LOG 4096 /* Flush the general log */
+#define REFRESH_SLOW_LOG 8192 /* Flush the slow query log */
/* The following can't be set with mysql_refresh() */
#define REFRESH_READ_LOCK 16384 /* Lock tables for read */
@@ -524,4 +538,5 @@ uchar *net_store_length(uchar *pkg, ulonglong length);
#define MYSQL_STMT_HEADER 4
#define MYSQL_LONG_DATA_HEADER 6
+#define NOT_FIXED_DEC 31
#endif
diff --git a/include/sslopt-longopts.h b/include/sslopt-longopts.h
index eae1424238b..b98e72e298e 100644
--- a/include/sslopt-longopts.h
+++ b/include/sslopt-longopts.h
@@ -19,8 +19,8 @@
#ifdef HAVE_OPENSSL
{"ssl", OPT_SSL_SSL,
- "Enable SSL for connection (automatically enabled with other flags). Disable with --skip-ssl.",
- (uchar **) &opt_use_ssl, (uchar **) &opt_use_ssl, 0, GET_BOOL, NO_ARG, 0, 0, 0,
+ "Enable SSL for connection (automatically enabled with other flags).",
+ (uchar **) &opt_use_ssl, (uchar **) &opt_use_ssl, 0, GET_BOOL, OPT_ARG, 0, 0, 0,
0, 0, 0},
{"ssl-ca", OPT_SSL_CA,
"CA file in PEM format (check OpenSSL docs, implies --ssl).",
@@ -43,7 +43,7 @@
{"ssl-verify-server-cert", OPT_SSL_VERIFY_SERVER_CERT,
"Verify server's \"Common Name\" in its cert against hostname used when connecting. This option is disabled by default.",
(uchar **) &opt_ssl_verify_server_cert, (uchar **) &opt_ssl_verify_server_cert,
- 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0},
+ 0, GET_BOOL, OPT_ARG, 0, 0, 0, 0, 0, 0},
#endif
#endif /* HAVE_OPENSSL */
#endif /* SSLOPT_LONGOPTS_INCLUDED */
diff --git a/include/thr_alarm.h b/include/thr_alarm.h
index fb906039269..8d7f5bcdee0 100644
--- a/include/thr_alarm.h
+++ b/include/thr_alarm.h
@@ -64,7 +64,7 @@ typedef my_bool ALARM;
#if defined(__WIN__)
typedef struct st_thr_alarm_entry
{
- rf_SetTimer crono;
+ UINT_PTR crono;
} thr_alarm_entry;
#else /* System with posix threads */
diff --git a/include/thr_lock.h b/include/thr_lock.h
index fb70c57c0e7..1f4072ca0c5 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
@@ -83,7 +83,6 @@ enum enum_thr_lock_result { THR_LOCK_SUCCESS= 0, THR_LOCK_ABORTED= 1,
extern ulong max_write_lock_count;
-extern ulong table_lock_wait_timeout;
extern my_bool thr_lock_inited;
extern enum thr_lock_type thr_upgraded_concurrent_insert_lock;
@@ -115,10 +114,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 +127,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 +144,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)
@@ -155,19 +155,25 @@ void thr_lock_data_init(THR_LOCK *lock,THR_LOCK_DATA *data,
void *status_param);
enum enum_thr_lock_result thr_lock(THR_LOCK_DATA *data,
THR_LOCK_OWNER *owner,
- enum thr_lock_type lock_type);
+ enum thr_lock_type lock_type,
+ ulong lock_wait_timeout);
void thr_unlock(THR_LOCK_DATA *data);
enum enum_thr_lock_result thr_multi_lock(THR_LOCK_DATA **data,
- uint count, THR_LOCK_OWNER *owner);
+ uint count, THR_LOCK_OWNER *owner,
+ ulong lock_wait_timeout);
void thr_multi_unlock(THR_LOCK_DATA **data,uint count);
+void
+thr_lock_merge_status(THR_LOCK_DATA **data, uint count);
void thr_abort_locks(THR_LOCK *lock, my_bool upgrade_lock);
my_bool thr_abort_locks_for_thread(THR_LOCK *lock, my_thread_id thread);
void thr_print_locks(void); /* For debugging */
my_bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data,
- enum thr_lock_type new_lock_type);
+ enum thr_lock_type new_lock_type,
+ ulong lock_wait_timeout);
void thr_downgrade_write_lock(THR_LOCK_DATA *data,
enum thr_lock_type new_lock_type);
-my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data);
+my_bool thr_reschedule_write_lock(THR_LOCK_DATA *data,
+ ulong lock_wait_timeout);
#ifdef __cplusplus
}
#endif
diff --git a/include/typelib.h b/include/typelib.h
index 46106d1bdab..c6a7f7a42e9 100644
--- a/include/typelib.h
+++ b/include/typelib.h
@@ -36,4 +36,9 @@ extern TYPELIB *copy_typelib(MEM_ROOT *root, TYPELIB *from);
extern TYPELIB sql_protocol_typelib;
+my_ulonglong find_set_from_flags(const TYPELIB *lib, uint default_name,
+ my_ulonglong cur_set, my_ulonglong default_set,
+ const char *str, uint length,
+ char **err_pos, uint *err_len);
+
#endif /* _typelib_h */
diff --git a/include/violite.h b/include/violite.h
index 1eef3ef5730..34dc6511b3d 100644
--- a/include/violite.h
+++ b/include/violite.h
@@ -51,9 +51,6 @@ Vio* vio_new_win32shared_memory(HANDLE handle_file_map,
HANDLE event_client_wrote,
HANDLE event_client_read,
HANDLE event_conn_closed);
-size_t vio_read_pipe(Vio *vio, uchar * buf, size_t size);
-size_t vio_write_pipe(Vio *vio, const uchar * buf, size_t size);
-int vio_close_pipe(Vio * vio);
#else
#define HANDLE void *
#endif /* __WIN__ */
@@ -84,10 +81,18 @@ int vio_errno(Vio*vio);
/* Get socket number */
my_socket vio_fd(Vio*vio);
/* Remote peer's address and name in text form */
-my_bool vio_peer_addr(Vio* vio, char *buf, uint16 *port);
-/* Remotes in_addr */
-void vio_in_addr(Vio *vio, struct in_addr *in);
-my_bool vio_poll_read(Vio *vio,uint timeout);
+my_bool vio_peer_addr(Vio *vio, char *buf, uint16 *port, size_t buflen);
+my_bool vio_poll_read(Vio *vio, uint timeout);
+my_bool vio_is_connected(Vio *vio);
+ssize_t vio_pending(Vio *vio);
+
+my_bool vio_get_normalized_ip_string(const struct sockaddr *addr, int addr_length,
+ char *ip_string, size_t ip_string_size);
+
+int vio_getnameinfo(const struct sockaddr *sa,
+ char *hostname, size_t hostname_size,
+ char *port, size_t port_size,
+ int flags);
#ifdef HAVE_OPENSSL
#include <openssl/opensslv.h>
@@ -136,12 +141,6 @@ struct st_VioSSLFd
void free_vio_ssl_acceptor_fd(struct st_VioSSLFd *fd);
#endif /* HAVE_OPENSSL */
-#ifdef HAVE_SMEM
-size_t vio_read_shared_memory(Vio *vio, uchar * buf, size_t size);
-size_t vio_write_shared_memory(Vio *vio, const uchar * buf, size_t size);
-int vio_close_shared_memory(Vio * vio);
-#endif
-
void vio_end(void);
#ifdef __cplusplus
@@ -161,9 +160,10 @@ void vio_end(void);
#define vio_should_retry(vio) (vio)->should_retry(vio)
#define vio_was_interrupted(vio) (vio)->was_interrupted(vio)
#define vio_close(vio) ((vio)->vioclose)(vio)
-#define vio_peer_addr(vio, buf, prt) (vio)->peer_addr(vio, buf, prt)
-#define vio_in_addr(vio, in) (vio)->in_addr(vio, in)
+#define vio_peer_addr(vio, buf, prt, buflen) (vio)->peer_addr(vio, buf, prt, buflen)
#define vio_timeout(vio, which, seconds) (vio)->timeout(vio, which, seconds)
+#define vio_poll_read(vio, timeout) (vio)->poll_read(vio, timeout)
+#define vio_is_connected(vio) (vio)->is_connected(vio)
#endif /* !defined(DONT_MAP_VIO) */
/* This enumerator is used in parser - should be always visible */
@@ -185,8 +185,9 @@ struct st_vio
HANDLE hPipe;
my_bool localhost; /* Are we from localhost? */
int fcntl_mode; /* Buffered fcntl(sd,F_GETFL) */
- struct sockaddr_in local; /* Local internet address */
- struct sockaddr_in remote; /* Remote internet address */
+ struct sockaddr_storage local; /* Local internet address */
+ struct sockaddr_storage remote; /* Remote internet address */
+ int addrLen; /* Length of remote address */
enum enum_vio_type type; /* Type of connection */
char desc[30]; /* String description */
char *read_buffer; /* buffer for vio_read_buff */
@@ -202,12 +203,14 @@ struct st_vio
my_bool (*is_blocking)(Vio*);
int (*viokeepalive)(Vio*, my_bool);
int (*fastsend)(Vio*);
- my_bool (*peer_addr)(Vio*, char *, uint16*);
- void (*in_addr)(Vio*, struct in_addr*);
+ my_bool (*peer_addr)(Vio*, char *, uint16*, size_t);
+ void (*in_addr)(Vio*, struct sockaddr_storage*);
my_bool (*should_retry)(Vio*);
my_bool (*was_interrupted)(Vio*);
int (*vioclose)(Vio*);
void (*timeout)(Vio*, unsigned int which, unsigned int timeout);
+ my_bool (*poll_read)(Vio *vio, uint timeout);
+ my_bool (*is_connected)(Vio*);
#ifdef HAVE_OPENSSL
void *ssl_arg;
#endif