List:Commits« Previous MessageNext Message »
From:Alexander Nozdrin Date:December 4 2009 12:43pm
Subject:bzr push into mysql-5.6-next-mr-bugfixing branch (alik:2916 to 2917)
View as plain text  
 2917 Alexander Nozdrin	2009-12-04 [merge]
      Auto-merge from mysql-next-mr.

    added:
      include/mysql/psi/
      include/mysql/psi/mysql_file.h
      include/mysql/psi/mysql_thread.h
      include/mysql/psi/psi.h
      include/mysql/psi/psi_abi_v1.h
      include/mysql/psi/psi_abi_v1.h.pp
      include/mysql/psi/psi_abi_v2.h
      include/mysql/psi/psi_abi_v2.h.pp
    modified:
      Makefile.am
      include/Makefile.am
      include/my_global.h
      include/my_no_pthread.h
      include/my_pthread.h
      include/my_sys.h
      libmysql/Makefile.am
      libmysql/Makefile.shared
      mysys/my_static.c
      mysys/my_winthread.c
      strings/Makefile.am
 2916 Alexander Nozdrin	2009-12-03 [merge]
      Auto-merge from mysql-next-mr.

    added:
      mysql-test/include/check_ipv6.inc
      mysql-test/include/ipv6.inc
      mysql-test/include/ipv6_clients.inc
      mysql-test/include/rpl_ip_mix.inc
      mysql-test/include/rpl_ip_mix2.inc
      mysql-test/include/rpl_ipv6.inc
      mysql-test/r/ipv4_as_ipv6.result
      mysql-test/r/ipv4_as_ipv6_win.result
      mysql-test/r/ipv6.result
      mysql-test/r/ipv6_win.result
      mysql-test/suite/rpl/r/rpl_ip_mix.result
      mysql-test/suite/rpl/r/rpl_ip_mix2.result
      mysql-test/suite/rpl/r/rpl_ip_mix2_win.result
      mysql-test/suite/rpl/r/rpl_ip_mix_win.result
      mysql-test/suite/rpl/r/rpl_ipv4_as_ipv6.result
      mysql-test/suite/rpl/r/rpl_ipv4_as_ipv6_win.result
      mysql-test/suite/rpl/r/rpl_ipv6.result
      mysql-test/suite/rpl/r/rpl_ipv6_win.result
      mysql-test/suite/rpl/t/rpl_ip_mix.cnf
      mysql-test/suite/rpl/t/rpl_ip_mix.test
      mysql-test/suite/rpl/t/rpl_ip_mix2.cnf
      mysql-test/suite/rpl/t/rpl_ip_mix2.test
      mysql-test/suite/rpl/t/rpl_ip_mix2_win.cnf
      mysql-test/suite/rpl/t/rpl_ip_mix2_win.test
      mysql-test/suite/rpl/t/rpl_ip_mix_win.cnf
      mysql-test/suite/rpl/t/rpl_ip_mix_win.test
      mysql-test/suite/rpl/t/rpl_ipv4_as_ipv6.cnf
      mysql-test/suite/rpl/t/rpl_ipv4_as_ipv6.test
      mysql-test/suite/rpl/t/rpl_ipv4_as_ipv6_win.cnf
      mysql-test/suite/rpl/t/rpl_ipv4_as_ipv6_win.test
      mysql-test/suite/rpl/t/rpl_ipv6.cnf
      mysql-test/suite/rpl/t/rpl_ipv6.test
      mysql-test/suite/rpl/t/rpl_ipv6_win.cnf
      mysql-test/suite/rpl/t/rpl_ipv6_win.test
      mysql-test/t/ipv4_as_ipv6-master.opt
      mysql-test/t/ipv4_as_ipv6.test
      mysql-test/t/ipv4_as_ipv6_win-master.opt
      mysql-test/t/ipv4_as_ipv6_win.test
      mysql-test/t/ipv6-master.opt
      mysql-test/t/ipv6.test
      mysql-test/t/ipv6_win-master.opt
      mysql-test/t/ipv6_win.test
    modified:
      CMakeLists.txt
      configure.in
      include/config-win.h
      include/my_net.h
      include/violite.h
      mysql-test/t/skip_name_resolve.test
      scripts/mysql_system_tables_data.sql
      sql-common/client.c
      sql/client_settings.h
      sql/hostname.cc
      sql/mysql_priv.h
      sql/mysqld.cc
      sql/sql_acl.cc
      sql/sql_class.h
      sql/sql_connect.cc
      vio/vio.c
      vio/vio_priv.h
      vio/viosocket.c
=== modified file 'Makefile.am'
--- a/Makefile.am	2009-11-10 07:31:33 +0000
+++ b/Makefile.am	2009-12-01 00:49:15 +0000
@@ -269,11 +269,12 @@ test-full-qa:
 #
 
 API_PREPROCESSOR_HEADER = $(top_srcdir)/include/mysql/plugin.h \
-                           $(top_srcdir)/include/mysql.h
+			$(top_srcdir)/include/mysql.h \
+			$(top_srcdir)/include/mysql/psi/psi_abi_v1.h \
+			$(top_srcdir)/include/mysql/psi/psi_abi_v2.h
 
-TEST_PREPROCESSOR_HEADER = $(top_srcdir)/include/mysql/plugin.h \
-                            $(top_srcdir)/sql/mysql_priv.h \
-                            $(top_srcdir)/include/mysql.h
+TEST_PREPROCESSOR_HEADER = $(API_PREPROCESSOR_HEADER) \
+			$(top_srcdir)/sql/mysql_priv.h
 
 #
 # Rules for checking that the abi/api has not changed.

=== modified file 'include/Makefile.am'
--- a/include/Makefile.am	2009-11-24 23:36:31 +0000
+++ b/include/Makefile.am	2009-12-01 00:49:15 +0000
@@ -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
@@ -24,6 +24,8 @@ pkginclude_HEADERS =	$(HEADERS_ABI) my_d
 			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 \
@@ -38,13 +40,15 @@ noinst_HEADERS =	config-win.h config-net
 			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 \
+			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/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 \
+			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

=== modified file 'include/my_global.h'
--- a/include/my_global.h	2009-11-24 13:54:59 +0000
+++ b/include/my_global.h	2009-12-01 00:49:15 +0000
@@ -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
@@ -83,6 +83,16 @@
 #endif
 #endif /* _WIN32... */
 
+#ifdef EMBEDDED_LIBRARY
+#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
+#undef WITH_PERFSCHEMA_STORAGE_ENGINE
+#endif
+#endif /* EMBEDDED_LIBRARY */
+
+#ifdef WITH_PERFSCHEMA_STORAGE_ENGINE
+#define HAVE_PSI_INTERFACE
+#endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */
+
 /* Make it easier to add conditionl code for windows */
 #ifdef __WIN__
 #define IF_WIN(A,B) (A)

=== modified file 'include/my_no_pthread.h'
--- a/include/my_no_pthread.h	2009-09-23 21:32:31 +0000
+++ b/include/my_no_pthread.h	2009-12-01 00:49:15 +0000
@@ -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,5 +48,16 @@
 #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)
+
 #endif
 #endif /* MY_NO_PTHREAD_INCLUDED */

=== modified file 'include/my_pthread.h'
--- a/include/my_pthread.h	2009-11-24 19:39:05 +0000
+++ b/include/my_pthread.h	2009-12-01 00:49:15 +0000
@@ -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
@@ -99,7 +99,7 @@ struct timespec {
 
 
 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,
@@ -137,8 +137,8 @@ int pthread_join(pthread_t thread, void 
 #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 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)
 
 
@@ -630,6 +630,10 @@ 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;

=== modified file 'include/my_sys.h'
--- a/include/my_sys.h	2009-12-02 15:50:14 +0000
+++ b/include/my_sys.h	2009-12-04 12:39:09 +0000
@@ -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
@@ -1018,5 +1018,15 @@ void netware_reg_user(const char *ip, co
 		      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 */

=== added directory 'include/mysql/psi'
=== added file 'include/mysql/psi/mysql_file.h'
--- a/include/mysql/psi/mysql_file.h	1970-01-01 00:00:00 +0000
+++ b/include/mysql/psi/mysql_file.h	2009-12-01 00:49:15 +0000
@@ -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
+

=== added file 'include/mysql/psi/mysql_thread.h'
--- a/include/mysql/psi/mysql_thread.h	1970-01-01 00:00:00 +0000
+++ b/include/mysql/psi/mysql_thread.h	2009-12-01 00:49:15 +0000
@@ -0,0 +1,884 @@
+/* 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;
+};
+
+/**
+  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;
+
+/**
+  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.
+*/
+#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_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_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_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_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_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_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_cond_init(K, C, A)
+  Instrumented rwlock_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);
+}
+
+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);
+}
+
+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;
+}
+
+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;
+}
+
+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;
+}
+
+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;
+}
+
+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;
+}
+
+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
+

=== added file 'include/mysql/psi/psi.h'
--- a/include/mysql/psi/psi.h	1970-01-01 00:00:00 +0000
+++ b/include/mysql/psi/psi.h	2009-12-01 00:49:15 +0000
@@ -0,0 +1,1086 @@
+/* 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_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);
+
+/**
+  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 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 */
+

=== added file 'include/mysql/psi/psi_abi_v1.h'
--- a/include/mysql/psi/psi_abi_v1.h	1970-01-01 00:00:00 +0000
+++ b/include/mysql/psi/psi_abi_v1.h	2009-12-01 00:49:15 +0000
@@ -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"
+

=== added file 'include/mysql/psi/psi_abi_v1.h.pp'
--- a/include/mysql/psi/psi_abi_v1.h.pp	1970-01-01 00:00:00 +0000
+++ b/include/mysql/psi/psi_abi_v1.h.pp	2009-12-01 00:49:15 +0000
@@ -0,0 +1,242 @@
+#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 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;
+  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

=== added file 'include/mysql/psi/psi_abi_v2.h'
--- a/include/mysql/psi/psi_abi_v2.h	1970-01-01 00:00:00 +0000
+++ b/include/mysql/psi/psi_abi_v2.h	2009-12-01 00:49:15 +0000
@@ -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"
+

=== added file 'include/mysql/psi/psi_abi_v2.h.pp'
--- a/include/mysql/psi/psi_abi_v2.h.pp	1970-01-01 00:00:00 +0000
+++ b/include/mysql/psi/psi_abi_v2.h.pp	2009-12-01 00:49:15 +0000
@@ -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

=== modified file 'libmysql/Makefile.am'
--- a/libmysql/Makefile.am	2009-07-08 14:49:45 +0000
+++ b/libmysql/Makefile.am	2009-12-01 00:49:15 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2000-2004 MySQL AB
+# Copyright (C) 2000-2004 MySQL AB, 2008-2009 Sun Microsystems, Inc.
 # 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of version 2 GNU General Public License as
@@ -21,7 +21,9 @@
 # This file is public domain and comes with NO WARRANTY of any kind
 
 target =	libmysqlclient.la
-target_defs =	-DMYSQL_CLIENT_NO_THREADS -DDONT_USE_RAID @LIB_EXTRA_CCFLAGS@
+target_defs =	-DMYSQL_CLIENT_NO_THREADS -DDONT_USE_RAID \
+		-DDISABLE_MYSQL_THREAD_H @LIB_EXTRA_CCFLAGS@
+
 LIBS =		@CLIENT_LIBS@ 
 INCLUDES =	-I$(top_builddir)/include -I$(top_srcdir)/include \
 		$(openssl_includes) @ZLIB_INCLUDES@

=== modified file 'libmysql/Makefile.shared'
--- a/libmysql/Makefile.shared	2009-10-15 20:53:21 +0000
+++ b/libmysql/Makefile.shared	2009-12-01 00:49:15 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2000-2004 MySQL AB
+# Copyright (C) 2000-2004 MySQL AB, 2008-2009 Sun Microsystems, Inc.
 # 
 # This program is free software; you can redistribute it and/or modify
 # it under the terms of version 2 GNU General Public License as
@@ -68,7 +68,8 @@ mysysobjects1 =		my_init.lo my_static.lo
                         mf_iocache2.lo my_seek.lo my_sleep.lo \
 			my_pread.lo mf_cache.lo md5.lo sha1.lo \
 			my_getopt.lo my_gethostbyname.lo my_port.lo \
-                        my_rename.lo my_chsize.lo my_sync.lo my_getsystime.lo
+			my_rename.lo my_chsize.lo my_sync.lo \
+			my_getsystime.lo my_symlink2.lo mf_same.lo
 sqlobjects =		net.lo
 sql_cmn_objects =	pack.lo client.lo my_time.lo
 

=== modified file 'mysys/my_static.c'
--- a/mysys/my_static.c	2009-10-14 08:25:39 +0000
+++ b/mysys/my_static.c	2009-12-01 00:49:15 +0000
@@ -111,3 +111,31 @@ my_bool NEAR my_disable_async_io=0;
 my_bool NEAR my_disable_flush_key_blocks=0;
 my_bool NEAR my_disable_symlinks=0;
 my_bool NEAR mysys_uses_curses=0;
+
+/*
+  Note that PSI_hook and PSI_server are unconditionally
+  (no ifdef HAVE_PSI_INTERFACE) defined.
+  This is to ensure binary compatibility between the server and plugins,
+  in the case when:
+  - the server is not compiled with HAVE_PSI_INTERFACE
+  - a plugin is compiled with HAVE_PSI_INTERFACE
+  See the doxygen documentation for the performance schema.
+*/
+
+/**
+  Hook for the instrumentation interface.
+  Code implementing the instrumentation interface should register here.
+*/
+struct PSI_bootstrap *PSI_hook= NULL;
+
+/**
+  Instance of the instrumentation interface for the MySQL server.
+  @todo This is currently a global variable, which is handy when
+  compiling instrumented code that is bundled with the server.
+  When dynamic plugin are truly supported, this variable will need
+  to be replaced by a macro, so that each XYZ plugin can have it's own
+  xyz_psi_server variable, obtained from PSI_bootstrap::get_interface()
+  with the version used at compile time for plugin XYZ.
+*/
+PSI *PSI_server= NULL;
+

=== modified file 'mysys/my_winthread.c'
--- a/mysys/my_winthread.c	2009-09-30 15:40:12 +0000
+++ b/mysys/my_winthread.c	2009-12-01 00:49:15 +0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 MySQL AB
+/* Copyright (C) 2000 MySQL AB, 2008-2009 Sun Microsystems, Inc
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -63,8 +63,8 @@ static unsigned int __stdcall pthread_st
 }
 
 
-int pthread_create(pthread_t *thread_id, pthread_attr_t *attr,
-     pthread_handler func, void *param)
+int pthread_create(pthread_t *thread_id, const pthread_attr_t *attr,
+                   pthread_handler func, void *param)
 {
   uintptr_t handle;
   struct thread_start_parameter *par;

=== modified file 'strings/Makefile.am'
--- a/strings/Makefile.am	2009-03-24 13:58:52 +0000
+++ b/strings/Makefile.am	2009-12-01 00:49:15 +0000
@@ -1,4 +1,4 @@
-# Copyright (C) 2000-2006 MySQL AB
+# Copyright (C) 2000-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
@@ -15,7 +15,16 @@
 
 # This file is public domain and comes with NO WARRANTY of any kind
 
-INCLUDES =		-I$(top_builddir)/include -I$(top_srcdir)/include
+#
+# Note that the string library is built with #define THREAD,
+# which by default cause all the thread related code (my_pthread.h)
+# and therefore the associated instrumentation (mysql/psi/mysql_thread.h)
+# to be used.
+# Since the string code itself is not instrumented, we use
+# #define DISABLE_MYSQL_THREAD_H here to avoid unneeded dependencies.
+#
+
+INCLUDES = -I$(top_builddir)/include -I$(top_srcdir)/include -DDISABLE_MYSQL_THREAD_H
 pkglib_LIBRARIES =	libmystrings.a
 
 # Exact one of ASSEMBLER_X


Attachment: [text/bzr-bundle] bzr/alik@sun.com-20091204123909-9b475ggxitga3z6j.bundle
Thread
bzr push into mysql-5.6-next-mr-bugfixing branch (alik:2916 to 2917)Alexander Nozdrin4 Dec