summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorSergei Golubchik <sergii@pisem.net>2014-05-07 10:02:35 +0200
committerSergei Golubchik <sergii@pisem.net>2014-05-07 10:02:35 +0200
commit7226287c066228a216217c43c48f3a0a833d9909 (patch)
tree5f1d80b69a78398cc05a0c4ba5eda4a566d344c3 /include
parent06d874ba90bec42c17ee1af0103a87d6b50730cd (diff)
downloadmariadb-git-7226287c066228a216217c43c48f3a0a833d9909.tar.gz
perfschema 5.6.10 initial commit.
include/mysql/psi/*
Diffstat (limited to 'include')
-rw-r--r--include/mysql/psi/mysql_file.h1421
-rw-r--r--include/mysql/psi/mysql_idle.h92
-rw-r--r--include/mysql/psi/mysql_socket.h1161
-rw-r--r--include/mysql/psi/mysql_stage.h72
-rw-r--r--include/mysql/psi/mysql_statement.h230
-rw-r--r--include/mysql/psi/mysql_table.h189
-rw-r--r--include/mysql/psi/mysql_thread.h1268
-rw-r--r--include/mysql/psi/psi.h2431
-rw-r--r--include/mysql/psi/psi_abi_v0.h24
-rw-r--r--include/mysql/psi/psi_abi_v0.h.pp47
-rw-r--r--include/mysql/psi/psi_abi_v1.h26
-rw-r--r--include/mysql/psi/psi_abi_v1.h.pp634
-rw-r--r--include/mysql/psi/psi_abi_v2.h26
-rw-r--r--include/mysql/psi/psi_abi_v2.h.pp214
14 files changed, 7835 insertions, 0 deletions
diff --git a/include/mysql/psi/mysql_file.h b/include/mysql/psi/mysql_file.h
new file mode 100644
index 00000000000..c226258f462
--- /dev/null
+++ b/include/mysql/psi/mysql_file.h
@@ -0,0 +1,1421 @@
+/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+
+ 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,
+ 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
+
+#ifndef MYSQL_FILE_H
+#define MYSQL_FILE_H
+
+#include <my_global.h>
+
+/* For strlen() */
+#include <string.h>
+/* For MY_STAT */
+#include <my_dir.h>
+/* For my_chsize */
+#include <my_sys.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_register(P1, P2, P3)
+ File registration.
+*/
+#define mysql_file_register(P1, P2, P3) \
+ inline_mysql_file_register(P1, P2, P3)
+
+/**
+ @def mysql_file_fgets(P1, P2, F)
+ Instrumented fgets.
+ @c mysql_file_fgets is a replacement for @c fgets.
+*/
+#ifdef HAVE_PSI_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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_FILE_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 void inline_mysql_file_register(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *category,
+ PSI_file_info *info,
+ int count
+#else
+ const char *category __attribute__ ((unused)),
+ void *info __attribute__ ((unused)),
+ int count __attribute__ ((unused))
+#endif
+)
+{
+#ifdef HAVE_PSI_FILE_INTERFACE
+ PSI_FILE_CALL(register_file)(category, info, count);
+#endif
+}
+
+static inline char *
+inline_mysql_file_fgets(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ char *str, int size, MYSQL_FILE *file)
+{
+ char *result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker)
+ (&state, file->m_psi, PSI_FILE_READ);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) size, src_file, src_line);
+ result= fgets(str, size, file->m_file);
+ PSI_FILE_CALL(end_file_wait)(locker, result ? strlen(result) : 0);
+ return result;
+ }
+#endif
+
+ result= fgets(str, size, file->m_file);
+ return result;
+}
+
+static inline int
+inline_mysql_file_fgetc(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file)
+{
+ int result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker)
+ (&state, file->m_psi, PSI_FILE_READ);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 1, src_file, src_line);
+ result= fgetc(file->m_file);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) 1);
+ return result;
+ }
+#endif
+
+ result= fgetc(file->m_file);
+ return result;
+}
+
+static inline int
+inline_mysql_file_fputs(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ const char *str, MYSQL_FILE *file)
+{
+ int result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ size_t bytes;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker)
+ (&state, file->m_psi, PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ {
+ bytes= str ? strlen(str) : 0;
+ PSI_FILE_CALL(start_file_wait)(locker, bytes, src_file, src_line);
+ result= fputs(str, file->m_file);
+ PSI_FILE_CALL(end_file_wait)(locker, bytes);
+ return result;
+ }
+#endif
+
+ result= fputs(str, file->m_file);
+ return result;
+}
+
+static inline int
+inline_mysql_file_fputc(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ char c, MYSQL_FILE *file)
+{
+ int result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker)
+ (&state, file->m_psi, PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 1, src_file, src_line);
+ result= fputc(c, file->m_file);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) 1);
+ return result;
+ }
+#endif
+
+ result= fputc(c, file->m_file);
+ 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_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker)
+ (&state, file->m_psi, PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, __FILE__, __LINE__);
+ va_start(args, format);
+ result= vfprintf(file->m_file, format, args);
+ va_end(args);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) result);
+ return result;
+ }
+#endif
+
+ va_start(args, format);
+ result= vfprintf(file->m_file, format, args);
+ va_end(args);
+ return result;
+}
+
+static inline int
+inline_mysql_file_vfprintf(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, const char *format, va_list args)
+{
+ int result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker)
+ (&state, file->m_psi, PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, src_file, src_line);
+ result= vfprintf(file->m_file, format, args);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) result);
+ return result;
+ }
+#endif
+
+ result= vfprintf(file->m_file, format, args);
+ return result;
+}
+
+static inline int
+inline_mysql_file_fflush(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file)
+{
+ int result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker)
+ (&state, file->m_psi, PSI_FILE_FLUSH);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, src_file, src_line);
+ result= fflush(file->m_file);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) 0);
+ return result;
+ }
+#endif
+
+ result= fflush(file->m_file);
+ 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_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ int filenr, MY_STAT *stat_area, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_descriptor_locker)
+ (&state, filenr, PSI_FILE_FSTAT);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, src_file, src_line);
+ result= my_fstat(filenr, stat_area, flags);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) 0);
+ return result;
+ }
+#endif
+
+ result= my_fstat(filenr, stat_area, flags);
+ return result;
+}
+
+static inline MY_STAT *
+inline_mysql_file_stat(
+#ifdef HAVE_PSI_FILE_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_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_name_locker)
+ (&state, key, PSI_FILE_STAT, path, &locker);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_open_wait)(locker, src_file, src_line);
+ result= my_stat(path, stat_area, flags);
+ PSI_FILE_CALL(end_file_open_wait)(locker, result);
+ return result;
+ }
+#endif
+
+ result= my_stat(path, stat_area, flags);
+ return result;
+}
+
+static inline int
+inline_mysql_file_chsize(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, my_off_t newlength, int filler, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_descriptor_locker)
+ (&state, file, PSI_FILE_CHSIZE);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) newlength, src_file,
+ src_line);
+ result= my_chsize(file, newlength, filler, flags);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) newlength);
+ return result;
+ }
+#endif
+
+ result= my_chsize(file, newlength, filler, flags);
+ return result;
+}
+
+static inline MYSQL_FILE*
+inline_mysql_file_fopen(
+#ifdef HAVE_PSI_FILE_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))
+ {
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_name_locker)
+ (&state, key, PSI_FILE_STREAM_OPEN, filename, that);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_open_wait)
+ (locker, src_file, src_line);
+ that->m_file= my_fopen(filename, flags, myFlags);
+ that->m_psi= PSI_FILE_CALL(end_file_open_wait)(locker, that->m_file);
+ if (unlikely(that->m_file == NULL))
+ {
+ my_free(that);
+ return NULL;
+ }
+ return that;
+ }
+#endif
+
+ that->m_psi= NULL;
+ that->m_file= my_fopen(filename, flags, myFlags);
+ if (unlikely(that->m_file == NULL))
+ {
+ my_free(that);
+ return NULL;
+ }
+ }
+ return that;
+}
+
+static inline int
+inline_mysql_file_fclose(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, myf flags)
+{
+ int result= 0;
+ if (likely(file != NULL))
+ {
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker)
+ (&state, file->m_psi, PSI_FILE_STREAM_CLOSE);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_close_wait)(locker, src_file, src_line);
+ result= my_fclose(file->m_file, flags);
+ PSI_FILE_CALL(end_file_close_wait)(locker, result);
+ my_free(file);
+ return result;
+ }
+#endif
+
+ result= my_fclose(file->m_file, flags);
+ my_free(file);
+ }
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_fread(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, uchar *buffer, size_t count, myf flags)
+{
+ size_t result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ size_t bytes_read;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker)
+ (&state, file->m_psi, PSI_FILE_READ);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, count, src_file, src_line);
+ result= my_fread(file->m_file, buffer, count, flags);
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_read= (result == 0) ? count : 0;
+ else
+ bytes_read= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_FILE_CALL(end_file_wait)(locker, bytes_read);
+ return result;
+ }
+#endif
+
+ result= my_fread(file->m_file, buffer, count, flags);
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_fwrite(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, const uchar *buffer, size_t count, myf flags)
+{
+ size_t result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ size_t bytes_written;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker)
+ (&state, file->m_psi, PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, count, src_file, src_line);
+ result= my_fwrite(file->m_file, buffer, count, flags);
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_written= (result == 0) ? count : 0;
+ else
+ bytes_written= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_FILE_CALL(end_file_wait)(locker, bytes_written);
+ return result;
+ }
+#endif
+
+ result= my_fwrite(file->m_file, buffer, count, flags);
+ return result;
+}
+
+static inline my_off_t
+inline_mysql_file_fseek(
+#ifdef HAVE_PSI_FILE_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_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker)
+ (&state, file->m_psi, PSI_FILE_SEEK);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, src_file, src_line);
+ result= my_fseek(file->m_file, pos, whence, flags);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) 0);
+ return result;
+ }
+#endif
+
+ result= my_fseek(file->m_file, pos, whence, flags);
+ return result;
+}
+
+static inline my_off_t
+inline_mysql_file_ftell(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_FILE *file, myf flags)
+{
+ my_off_t result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_stream_locker)
+ (&state, file->m_psi, PSI_FILE_TELL);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, src_file, src_line);
+ result= my_ftell(file->m_file, flags);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) 0);
+ return result;
+ }
+#endif
+
+ result= my_ftell(file->m_file, flags);
+ return result;
+}
+
+static inline File
+inline_mysql_file_create(
+#ifdef HAVE_PSI_FILE_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_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_name_locker)
+ (&state, key, PSI_FILE_CREATE, filename, &locker);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_open_wait)(locker, src_file, src_line);
+ file= my_create(filename, create_flags, access_flags, myFlags);
+ PSI_FILE_CALL(end_file_open_wait_and_bind_to_descriptor)(locker, file);
+ return file;
+ }
+#endif
+
+ file= my_create(filename, create_flags, access_flags, myFlags);
+ return file;
+}
+
+static inline File
+inline_mysql_file_create_temp(
+#ifdef HAVE_PSI_FILE_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_FILE_INTERFACE
+ PSI_FILE_CALL(create_file)(key, to, file);
+#endif
+ return file;
+}
+
+static inline File
+inline_mysql_file_open(
+#ifdef HAVE_PSI_FILE_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_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_name_locker)
+ (&state, key, PSI_FILE_OPEN, filename, &locker);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_open_wait)(locker, src_file, src_line);
+ file= my_open(filename, flags, myFlags);
+ PSI_FILE_CALL(end_file_open_wait_and_bind_to_descriptor)(locker, file);
+ return file;
+ }
+#endif
+
+ file= my_open(filename, flags, myFlags);
+ return file;
+}
+
+static inline int
+inline_mysql_file_close(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_descriptor_locker)
+ (&state, file, PSI_FILE_CLOSE);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_close_wait)(locker, src_file, src_line);
+ result= my_close(file, flags);
+ PSI_FILE_CALL(end_file_close_wait)(locker, result);
+ return result;
+ }
+#endif
+
+ result= my_close(file, flags);
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_read(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, uchar *buffer, size_t count, myf flags)
+{
+ size_t result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ size_t bytes_read;
+ locker= PSI_FILE_CALL(get_thread_file_descriptor_locker)
+ (&state, file, PSI_FILE_READ);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, count, src_file, src_line);
+ result= my_read(file, buffer, count, flags);
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_read= (result == 0) ? count : 0;
+ else
+ bytes_read= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_FILE_CALL(end_file_wait)(locker, bytes_read);
+ return result;
+ }
+#endif
+
+ result= my_read(file, buffer, count, flags);
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_write(
+#ifdef HAVE_PSI_FILE_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_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ size_t bytes_written;
+ locker= PSI_FILE_CALL(get_thread_file_descriptor_locker)
+ (&state, file, PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, count, src_file, src_line);
+ result= my_write(file, buffer, count, flags);
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_written= (result == 0) ? count : 0;
+ else
+ bytes_written= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_FILE_CALL(end_file_wait)(locker, bytes_written);
+ return result;
+ }
+#endif
+
+ result= my_write(file, buffer, count, flags);
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_pread(
+#ifdef HAVE_PSI_FILE_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_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ size_t bytes_read;
+ locker= PSI_FILE_CALL(get_thread_file_descriptor_locker)
+ (&state, file, PSI_FILE_READ);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, count, src_file, src_line);
+ result= my_pread(file, buffer, count, offset, flags);
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_read= (result == 0) ? count : 0;
+ else
+ bytes_read= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_FILE_CALL(end_file_wait)(locker, bytes_read);
+ return result;
+ }
+#endif
+
+ result= my_pread(file, buffer, count, offset, flags);
+ return result;
+}
+
+static inline size_t
+inline_mysql_file_pwrite(
+#ifdef HAVE_PSI_FILE_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_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ size_t bytes_written;
+ locker= PSI_FILE_CALL(get_thread_file_descriptor_locker)
+ (&state, file, PSI_FILE_WRITE);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, count, src_file, src_line);
+ result= my_pwrite(file, buffer, count, offset, flags);
+ if (flags & (MY_NABP | MY_FNABP))
+ bytes_written= (result == 0) ? count : 0;
+ else
+ bytes_written= (result != MY_FILE_ERROR) ? result : 0;
+ PSI_FILE_CALL(end_file_wait)(locker, bytes_written);
+ return result;
+ }
+#endif
+
+ result= my_pwrite(file, buffer, count, offset, flags);
+ return result;
+}
+
+static inline my_off_t
+inline_mysql_file_seek(
+#ifdef HAVE_PSI_FILE_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_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_descriptor_locker)
+ (&state, file, PSI_FILE_SEEK);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, src_file, src_line);
+ result= my_seek(file, pos, whence, flags);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) 0);
+ return result;
+ }
+#endif
+
+ result= my_seek(file, pos, whence, flags);
+ return result;
+}
+
+static inline my_off_t
+inline_mysql_file_tell(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File file, myf flags)
+{
+ my_off_t result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_descriptor_locker)
+ (&state, file, PSI_FILE_TELL);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, src_file, src_line);
+ result= my_tell(file, flags);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) 0);
+ return result;
+ }
+#endif
+
+ result= my_tell(file, flags);
+ return result;
+}
+
+static inline int
+inline_mysql_file_delete(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *name, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_name_locker)
+ (&state, key, PSI_FILE_DELETE, name, &locker);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_close_wait)(locker, src_file, src_line);
+ result= my_delete(name, flags);
+ PSI_FILE_CALL(end_file_close_wait)(locker, result);
+ return result;
+ }
+#endif
+
+ result= my_delete(name, flags);
+ return result;
+}
+
+static inline int
+inline_mysql_file_rename(
+#ifdef HAVE_PSI_FILE_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_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_name_locker)
+ (&state, key, PSI_FILE_RENAME, to, &locker);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, src_file, src_line);
+ result= my_rename(from, to, flags);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) 0);
+ return result;
+ }
+#endif
+
+ result= my_rename(from, to, flags);
+ return result;
+}
+
+static inline File
+inline_mysql_file_create_with_symlink(
+#ifdef HAVE_PSI_FILE_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_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_name_locker)
+ (&state, key, PSI_FILE_CREATE, filename, &locker);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_open_wait)(locker, src_file, src_line);
+ file= my_create_with_symlink(linkname, filename, create_flags, access_flags,
+ flags);
+ PSI_FILE_CALL(end_file_open_wait_and_bind_to_descriptor)(locker, file);
+ return file;
+ }
+#endif
+
+ file= my_create_with_symlink(linkname, filename, create_flags, access_flags,
+ flags);
+ return file;
+}
+
+static inline int
+inline_mysql_file_delete_with_symlink(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ PSI_file_key key, const char *src_file, uint src_line,
+#endif
+ const char *name, myf flags)
+{
+ int result;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_name_locker)
+ (&state, key, PSI_FILE_DELETE, name, &locker);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_close_wait)(locker, src_file, src_line);
+ result= my_delete_with_symlink(name, flags);
+ PSI_FILE_CALL(end_file_close_wait)(locker, result);
+ return result;
+ }
+#endif
+
+ result= my_delete_with_symlink(name, flags);
+ return result;
+}
+
+static inline int
+inline_mysql_file_rename_with_symlink(
+#ifdef HAVE_PSI_FILE_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_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_name_locker)
+ (&state, key, PSI_FILE_RENAME, to, &locker);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, src_file, src_line);
+ result= my_rename_with_symlink(from, to, flags);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) 0);
+ return result;
+ }
+#endif
+
+ result= my_rename_with_symlink(from, to, flags);
+ return result;
+}
+
+static inline int
+inline_mysql_file_sync(
+#ifdef HAVE_PSI_FILE_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ File fd, myf flags)
+{
+ int result= 0;
+#ifdef HAVE_PSI_FILE_INTERFACE
+ struct PSI_file_locker *locker;
+ PSI_file_locker_state state;
+ locker= PSI_FILE_CALL(get_thread_file_descriptor_locker)
+ (&state, fd, PSI_FILE_SYNC);
+ if (likely(locker != NULL))
+ {
+ PSI_FILE_CALL(start_file_wait)(locker, (size_t) 0, src_file, src_line);
+ result= my_sync(fd, flags);
+ PSI_FILE_CALL(end_file_wait)(locker, (size_t) 0);
+ return result;
+ }
+#endif
+
+ result= my_sync(fd, flags);
+ return result;
+}
+
+/** @} (end of group File_instrumentation) */
+
+#endif
+
diff --git a/include/mysql/psi/mysql_idle.h b/include/mysql/psi/mysql_idle.h
new file mode 100644
index 00000000000..c53d0ceb8c7
--- /dev/null
+++ b/include/mysql/psi/mysql_idle.h
@@ -0,0 +1,92 @@
+/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+ 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,
+ 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
+
+#ifndef MYSQL_IDLE_H
+#define MYSQL_IDLE_H
+
+/**
+ @file mysql/psi/mysql_idle.h
+ Instrumentation helpers for idle waits.
+*/
+
+#include "mysql/psi/psi.h"
+
+/**
+ @defgroup Idle_instrumentation Idle Instrumentation
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ @def MYSQL_START_IDLE_WAIT
+ Instrumentation helper for table io_waits.
+ This instrumentation marks the start of a wait event.
+ @param LOCKER the locker
+ @param STATE the locker state
+ @sa MYSQL_END_IDLE_WAIT.
+*/
+#ifdef HAVE_PSI_IDLE_INTERFACE
+ #define MYSQL_START_IDLE_WAIT(LOCKER, STATE) \
+ LOCKER= inline_mysql_start_idle_wait(STATE, __FILE__, __LINE__)
+#else
+ #define MYSQL_START_IDLE_WAIT(LOCKER, STATE) \
+ do {} while (0)
+#endif
+
+/**
+ @def MYSQL_END_IDLE_WAIT
+ Instrumentation helper for idle waits.
+ This instrumentation marks the end of a wait event.
+ @param LOCKER the locker
+ @sa MYSQL_START_IDLE_WAIT.
+*/
+#ifdef HAVE_PSI_IDLE_INTERFACE
+ #define MYSQL_END_IDLE_WAIT(LOCKER) \
+ inline_mysql_end_idle_wait(LOCKER)
+#else
+ #define MYSQL_END_IDLE_WAIT(LOCKER) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_IDLE_INTERFACE
+/**
+ Instrumentation calls for MYSQL_START_IDLE_WAIT.
+ @sa MYSQL_END_IDLE_WAIT.
+*/
+static inline struct PSI_idle_locker *
+inline_mysql_start_idle_wait(PSI_idle_locker_state *state,
+ const char *src_file, int src_line)
+{
+ struct PSI_idle_locker *locker;
+ locker= PSI_IDLE_CALL(start_idle_wait)(state, src_file, src_line);
+ return locker;
+}
+
+/**
+ Instrumentation calls for MYSQL_END_IDLE_WAIT.
+ @sa MYSQL_START_IDLE_WAIT.
+*/
+static inline void
+inline_mysql_end_idle_wait(struct PSI_idle_locker *locker)
+{
+ if (likely(locker != NULL))
+ PSI_IDLE_CALL(end_idle_wait)(locker);
+}
+#endif
+
+/** @} (end of group Idle_instrumentation) */
+
+#endif
+
diff --git a/include/mysql/psi/mysql_socket.h b/include/mysql/psi/mysql_socket.h
new file mode 100644
index 00000000000..e1d56539f85
--- /dev/null
+++ b/include/mysql/psi/mysql_socket.h
@@ -0,0 +1,1161 @@
+/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; version 2 of the
+License.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+02110-1301 USA
+*/
+
+#ifndef MYSQL_SOCKET_H
+#define MYSQL_SOCKET_H
+
+/* For strlen() */
+#include <string.h>
+/* For MY_STAT */
+#include <my_dir.h>
+/* For my_chsize */
+#include <my_sys.h>
+/* For socket api */
+#ifdef __WIN__
+ #include <ws2def.h>
+ #include <winsock2.h>
+ #include <MSWSock.h>
+ #define SOCKBUF_T char
+#else
+ #include <netinet/in.h>
+ #define SOCKBUF_T void
+#endif
+/**
+ @file mysql/psi/mysql_socket.h
+[...]
+*/
+
+#include "mysql/psi/psi.h"
+
+/**
+ @defgroup Socket_instrumentation Socket Instrumentation
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ @def mysql_socket_register(P1, P2, P3)
+ Socket registration.
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_register(P1, P2, P3) \
+ inline_mysql_socket_register(P1, P2, P3)
+#else
+ #define mysql_socket_register(P1, P2, P3) \
+ do {} while (0)
+#endif
+
+struct st_mysql_socket
+{
+ /** The real socket descriptor. */
+ my_socket fd;
+
+ /**
+ The instrumentation hook.
+ Note that this hook is not conditionally defined,
+ for binary compatibility of the @c MYSQL_SOCKET interface.
+ */
+ struct PSI_socket *m_psi;
+};
+
+/**
+ An instrumented socket.
+ @c MYSQL_SOCKET is a replacement for @c my_socket.
+*/
+typedef struct st_mysql_socket MYSQL_SOCKET;
+
+
+/**
+ @def MYSQL_INVALID_SOCKET
+ MYSQL_SOCKET initial value.
+*/
+//MYSQL_SOCKET MYSQL_INVALID_SOCKET= {INVALID_SOCKET, NULL};
+#define MYSQL_INVALID_SOCKET mysql_socket_invalid()
+
+/**
+ MYSQL_SOCKET helper. Initialize instrumented socket.
+ @sa mysql_socket_getfd
+ @sa mysql_socket_setfd
+*/
+static inline MYSQL_SOCKET
+mysql_socket_invalid()
+{
+ MYSQL_SOCKET mysql_socket= {INVALID_SOCKET, NULL};
+ return mysql_socket;
+}
+
+/**
+ Set socket descriptor and address.
+ @param socket nstrumented socket
+ @param fd socket descriptor
+ @param addr unformatted socket address
+ @param adr_len length of socket addres
+*/
+
+static inline void
+mysql_socket_set_address(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ MYSQL_SOCKET socket,
+ const struct sockaddr *addr,
+ socklen_t addr_len
+#else
+ MYSQL_SOCKET socket __attribute__ ((unused)),
+ const struct sockaddr *addr __attribute__ ((unused)),
+ socklen_t addr_len __attribute__ ((unused))
+#endif
+)
+{
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (socket.m_psi != NULL)
+ PSI_SOCKET_CALL(set_socket_info)(socket.m_psi, NULL, addr, addr_len);
+#endif
+}
+
+/**
+ Set socket descriptor and address.
+ @param socket instrumented socket
+ @param thread instrumented owning thread
+*/
+static inline void
+mysql_socket_set_thread_owner(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+MYSQL_SOCKET socket
+#else
+MYSQL_SOCKET socket __attribute__ ((unused))
+#endif
+)
+{
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (socket.m_psi != NULL)
+ PSI_SOCKET_CALL(set_socket_thread_owner)(socket.m_psi);
+#endif
+}
+
+/**
+ MYSQL_SOCKET helper. Get socket descriptor.
+ @param mysql_socket Instrumented socket
+ @sa mysql_socket_setfd
+*/
+static inline my_socket
+mysql_socket_getfd(MYSQL_SOCKET mysql_socket)
+{
+ return mysql_socket.fd;
+}
+
+/**
+ MYSQL_SOCKET helper. Set socket descriptor.
+ @param mysql_socket Instrumented socket
+ @param fd Socket descriptor
+ @sa mysql_socket_getfd
+*/
+static inline void
+mysql_socket_setfd(MYSQL_SOCKET *mysql_socket, my_socket fd)
+{
+ if (likely(mysql_socket != NULL))
+ mysql_socket->fd= fd;
+}
+
+/**
+ @def MYSQL_SOCKET_WAIT_VARIABLES
+ Instrumentation helper for socket waits.
+ This instrumentation declares local variables.
+ Do not use a ';' after this macro
+ @param LOCKER locker
+ @param STATE locker state
+ @sa MYSQL_START_SOCKET_WAIT.
+ @sa MYSQL_END_SOCKET_WAIT.
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define MYSQL_SOCKET_WAIT_VARIABLES(LOCKER, STATE) \
+ struct PSI_socket_locker* LOCKER; \
+ PSI_socket_locker_state STATE;
+#else
+ #define MYSQL_SOCKET_WAIT_VARIABLES(LOCKER, STATE)
+#endif
+
+/**
+ @def MYSQL_START_SOCKET_WAIT
+ Instrumentation helper for socket waits.
+ This instrumentation marks the start of a wait event.
+ @param LOCKER locker
+ @param STATE locker state
+ @param SOCKET instrumented socket
+ @param OP The socket operation to be performed
+ @param FLAGS per-socket operation flags.
+ @param COUNT bytes to be written/read
+ @sa MYSQL_END_SOCKET_WAIT.
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define MYSQL_START_SOCKET_WAIT(LOCKER, STATE, SOCKET, OP, COUNT) \
+ LOCKER= inline_mysql_start_socket_wait(STATE, SOCKET, OP, COUNT,\
+ __FILE__, __LINE__)
+#else
+ #define MYSQL_START_SOCKET_WAIT(LOCKER, STATE, SOCKET, OP, COUNT) \
+ do {} while (0)
+#endif
+
+/**
+ @def MYSQL_END_SOCKET_WAIT
+ Instrumentation helper for socket waits.
+ This instrumentation marks the end of a wait event.
+ @param LOCKER locker
+ @param COUNT actual bytes written/read, or -1
+ @sa MYSQL_START_SOCKET_WAIT.
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define MYSQL_END_SOCKET_WAIT(LOCKER, COUNT) \
+ inline_mysql_end_socket_wait(LOCKER, COUNT)
+#else
+ #define MYSQL_END_SOCKET_WAIT(LOCKER, COUNT) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define MYSQL_SOCKET_SET_STATE(SOCKET, STATE) \
+ inline_mysql_socket_set_state(SOCKET, STATE)
+#else
+ #define MYSQL_SOCKET_SET_STATE(SOCKET, STATE) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+/**
+ Instrumentation calls for MYSQL_START_SOCKET_WAIT.
+ @sa MYSQL_START_SOCKET_WAIT.
+*/
+static inline struct PSI_socket_locker*
+inline_mysql_start_socket_wait(PSI_socket_locker_state *state,
+ MYSQL_SOCKET mysql_socket,
+ enum PSI_socket_operation op,
+ size_t byte_count,
+ const char *src_file, int src_line)
+{
+ struct PSI_socket_locker *locker;
+ if (mysql_socket.m_psi != NULL)
+ {
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (state, mysql_socket.m_psi, op, byte_count, src_file, src_line);
+ }
+ else
+ locker= NULL;
+ return locker;
+}
+
+/**
+ Instrumentation calls for MYSQL_END_SOCKET_WAIT.
+ @sa MYSQL_END_SOCKET_WAIT.
+*/
+static inline void
+inline_mysql_end_socket_wait(struct PSI_socket_locker *locker, size_t byte_count)
+{
+ if (locker != NULL)
+ PSI_SOCKET_CALL(end_socket_wait)(locker, byte_count);
+}
+
+/**
+ Set the state (IDLE, ACTIVE) of an instrumented socket.
+ @param socket the instrumented socket
+ @param state the new state
+ @sa PSI_socket_state
+*/
+static inline void
+inline_mysql_socket_set_state(MYSQL_SOCKET socket, enum PSI_socket_state state)
+{
+ if (socket.m_psi != NULL)
+ PSI_SOCKET_CALL(set_socket_state)(socket.m_psi, state);
+}
+#endif /* HAVE_PSI_SOCKET_INTERFACE */
+
+/**
+ @def mysql_socket_socket(K, D, T, P)
+ Create a socket.
+ @c mysql_socket_socket is a replacement for @c socket.
+ @param K PSI_socket_key for this instrumented socket
+ @param D Socket domain
+ @param T Protocol type
+ @param P Transport protocol
+*/
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_socket(K, D, T, P) \
+ inline_mysql_socket_socket(K, D, T, P)
+#else
+ #define mysql_socket_socket(K, D, T, P) \
+ inline_mysql_socket_socket(D, T, P)
+#endif
+
+/**
+ @def mysql_socket_bind(FD, AP, L)
+ Bind a socket to a local port number and IP address
+ @c mysql_socket_bind is a replacement for @c bind.
+ @param FD Instrumented socket descriptor returned by socket()
+ @param AP Pointer to local port number and IP address in sockaddr structure
+ @param L Length of sockaddr structure
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_bind(FD, AP, L) \
+ inline_mysql_socket_bind(__FILE__, __LINE__, FD, AP, L)
+#else
+ #define mysql_socket_bind(FD, AP, L) \
+ inline_mysql_socket_bind(FD, AP, L)
+#endif
+
+/**
+ @def mysql_socket_getsockname(FD, AP, LP)
+ Return port number and IP address of the local host
+ @c mysql_socket_getsockname is a replacement for @c getsockname.
+ @param FD Instrumented socket descriptor returned by socket()
+ @param A Pointer to returned address of local host in sockaddr structure
+ @param L Pointer to length of sockaddr structure
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_getsockname(FD, AP, LP) \
+ inline_mysql_socket_getsockname(__FILE__, __LINE__, FD, AP, LP)
+#else
+ #define mysql_socket_getsockname(FD, AP, LP) \
+ inline_mysql_socket_getsockname(FD, AP, LP)
+#endif
+
+/**
+ @def mysql_socket_connect(FD, AP, L)
+ Establish a connection to a remote host.
+ @c mysql_socket_connect is a replacement for @c connect.
+ @param FD Instrumented socket descriptor returned by socket()
+ @param AP Pointer to target address in sockaddr structure
+ @param L Length of sockaddr structure
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_connect(FD, AP, L) \
+ inline_mysql_socket_connect(__FILE__, __LINE__, FD, AP, L)
+#else
+ #define mysql_socket_connect(FD, AP, L) \
+ inline_mysql_socket_connect(FD, AP, L)
+#endif
+
+/**
+ @def mysql_socket_getpeername(FD, AP, LP)
+ Get port number and IP address of remote host that a socket is connected to.
+ @c mysql_socket_getpeername is a replacement for @c getpeername.
+ @param FD Instrumented socket descriptor returned by socket() or accept()
+ @param AP Pointer to returned address of remote host in sockaddr structure
+ @param LP Pointer to length of sockaddr structure
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_getpeername(FD, AP, LP) \
+ inline_mysql_socket_getpeername(__FILE__, __LINE__, FD, AP, LP)
+#else
+ #define mysql_socket_getpeername(FD, AP, LP) \
+ inline_mysql_socket_getpeername(FD, AP, LP)
+#endif
+
+/**
+ @def mysql_socket_send(FD, B, N, FL)
+ Send data from the buffer, B, to a connected socket.
+ @c mysql_socket_send is a replacement for @c send.
+ @param FD Instrumented socket descriptor returned by socket() or accept()
+ @param B Buffer to send
+ @param N Number of bytes to send
+ @param FL Control flags
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_send(FD, B, N, FL) \
+ inline_mysql_socket_send(__FILE__, __LINE__, FD, B, N, FL)
+#else
+ #define mysql_socket_send(FD, B, N, FL) \
+ inline_mysql_socket_send(FD, B, N, FL)
+#endif
+
+/**
+ @def mysql_socket_recv(FD, B, N, FL)
+ Receive data from a connected socket.
+ @c mysql_socket_recv is a replacement for @c recv.
+ @param FD Instrumented socket descriptor returned by socket() or accept()
+ @param B Buffer to receive to
+ @param N Maximum bytes to receive
+ @param FL Control flags
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_recv(FD, B, N, FL) \
+ inline_mysql_socket_recv(__FILE__, __LINE__, FD, B, N, FL)
+#else
+ #define mysql_socket_recv(FD, B, N, FL) \
+ inline_mysql_socket_recv(FD, B, N, FL)
+#endif
+
+/**
+ @def mysql_socket_sendto(FD, B, N, FL, AP, L)
+ Send data to a socket at the specified address.
+ @c mysql_socket_sendto is a replacement for @c sendto.
+ @param FD Instrumented socket descriptor returned by socket()
+ @param B Buffer to send
+ @param N Number of bytes to send
+ @param FL Control flags
+ @param AP Pointer to destination sockaddr structure
+ @param L Size of sockaddr structure
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_sendto(FD, B, N, FL, AP, L) \
+ inline_mysql_socket_sendto(__FILE__, __LINE__, FD, B, N, FL, AP, L)
+#else
+ #define mysql_socket_sendto(FD, B, N, FL, AP, L) \
+ inline_mysql_socket_sendto(FD, B, N, FL, AP, L)
+#endif
+
+/**
+ @def mysql_socket_recvfrom(FD, B, N, FL, AP, L)
+ Receive data from a socket and return source address information
+ @c mysql_socket_recvfrom is a replacement for @c recvfrom.
+ @param FD Instrumented socket descriptor returned by socket()
+ @param B Buffer to receive to
+ @param N Maximum bytes to receive
+ @param FL Control flags
+ @param AP Pointer to source address in sockaddr_storage structure
+ @param L Size of sockaddr_storage structure
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_recvfrom(FD, B, N, FL, AP, LP) \
+ inline_mysql_socket_recvfrom(__FILE__, __LINE__, FD, B, N, FL, AP, LP)
+#else
+ #define mysql_socket_recvfrom(FD, B, N, FL, AP, LP) \
+ inline_mysql_socket_recvfrom(FD, B, N, FL, AP, LP)
+#endif
+
+/**
+ @def mysql_socket_getsockopt(FD, LV, ON, OP, OL)
+ Get a socket option for the specified socket.
+ @c mysql_socket_getsockopt is a replacement for @c getsockopt.
+ @param FD Instrumented socket descriptor returned by socket()
+ @param LV Protocol level
+ @param ON Option to query
+ @param OP Buffer which will contain the value for the requested option
+ @param OL Pointer to length of OP
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_getsockopt(FD, LV, ON, OP, OL) \
+ inline_mysql_socket_getsockopt(__FILE__, __LINE__, FD, LV, ON, OP, OL)
+#else
+ #define mysql_socket_getsockopt(FD, LV, ON, OP, OL) \
+ inline_mysql_socket_getsockopt(FD, LV, ON, OP, OL)
+#endif
+
+/**
+ @def mysql_socket_setsockopt(FD, LV, ON, OP, OL)
+ Set a socket option for the specified socket.
+ @c mysql_socket_setsockopt is a replacement for @c setsockopt.
+ @param FD Instrumented socket descriptor returned by socket()
+ @param LV Protocol level
+ @param ON Option to modify
+ @param OP Buffer containing the value for the specified option
+ @param OL Pointer to length of OP
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_setsockopt(FD, LV, ON, OP, OL) \
+ inline_mysql_socket_setsockopt(__FILE__, __LINE__, FD, LV, ON, OP, OL)
+#else
+ #define mysql_socket_setsockopt(FD, LV, ON, OP, OL) \
+ inline_mysql_socket_setsockopt(FD, LV, ON, OP, OL)
+#endif
+
+/**
+ @def mysql_socket_listen(FD, N)
+ Set socket state to listen for an incoming connection.
+ @c mysql_socket_listen is a replacement for @c listen.
+ @param FD Instrumented socket descriptor, bound and connected
+ @param N Maximum number of pending connections allowed.
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_listen(FD, N) \
+ inline_mysql_socket_listen(__FILE__, __LINE__, FD, N)
+#else
+ #define mysql_socket_listen(FD, N) \
+ inline_mysql_socket_listen(FD, N)
+#endif
+
+/**
+ @def mysql_socket_accept(K, FD, AP, LP)
+ Accept a connection from any remote host; TCP only.
+ @c mysql_socket_accept is a replacement for @c accept.
+ @param K PSI_socket_key for this instrumented socket
+ @param FD Instrumented socket descriptor, bound and placed in a listen state
+ @param AP Pointer to sockaddr structure with returned IP address and port of connected host
+ @param LP Pointer to length of valid information in AP
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_accept(K, FD, AP, LP) \
+ inline_mysql_socket_accept(__FILE__, __LINE__, K, FD, AP, LP)
+#else
+ #define mysql_socket_accept(K, FD, AP, LP) \
+ inline_mysql_socket_accept(FD, AP, LP)
+#endif
+
+/**
+ @def mysql_socket_close(FD)
+ Close a socket and sever any connections.
+ @c mysql_socket_close is a replacement for @c close.
+ @param FD Instrumented socket descriptor returned by socket() or accept()
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_close(FD) \
+ inline_mysql_socket_close(__FILE__, __LINE__, FD)
+#else
+ #define mysql_socket_close(FD) \
+ inline_mysql_socket_close(FD)
+#endif
+
+/**
+ @def mysql_socket_shutdown(FD, H)
+ Disable receives and/or sends on a socket.
+ @c mysql_socket_shutdown is a replacement for @c shutdown.
+ @param FD Instrumented socket descriptor returned by socket() or accept()
+ @param H Specifies which operations to shutdown
+*/
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ #define mysql_socket_shutdown(FD, H) \
+ inline_mysql_socket_shutdown(__FILE__, __LINE__, FD, H)
+#else
+ #define mysql_socket_shutdown(FD, H) \
+ inline_mysql_socket_shutdown(FD, H)
+#endif
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+static inline void inline_mysql_socket_register(
+ const char *category,
+ PSI_socket_info *info,
+ int count)
+{
+ PSI_SOCKET_CALL(register_socket)(category, info, count);
+}
+#endif
+
+/** mysql_socket_socket */
+
+static inline MYSQL_SOCKET
+inline_mysql_socket_socket
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ PSI_socket_key key,
+#endif
+ int domain, int type, int protocol)
+{
+ MYSQL_SOCKET mysql_socket= MYSQL_INVALID_SOCKET;
+ mysql_socket.fd= socket(domain, type, protocol);
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (likely(mysql_socket.fd != INVALID_SOCKET))
+ {
+ mysql_socket.m_psi= PSI_SOCKET_CALL(init_socket)
+ (key, (const my_socket*)&mysql_socket.fd, NULL, 0);
+ }
+#endif
+ return mysql_socket;
+}
+
+/** mysql_socket_bind */
+
+static inline int
+inline_mysql_socket_bind
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, const struct sockaddr *addr, socklen_t len)
+{
+ int result;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (mysql_socket.m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_socket_locker_state state;
+ PSI_socket_locker *locker;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_BIND, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+ result= bind(mysql_socket.fd, addr, len);
+
+ /* Instrumentation end */
+ if (result == 0)
+ PSI_SOCKET_CALL(set_socket_info)(mysql_socket.m_psi, NULL, addr, len);
+
+ if (locker != NULL)
+ PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= bind(mysql_socket.fd, addr, len);
+ return result;
+}
+
+/** mysql_socket_getsockname */
+
+static inline int
+inline_mysql_socket_getsockname
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, struct sockaddr *addr, socklen_t *len)
+{
+ int result;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (mysql_socket.m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_BIND, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+ result= getsockname(mysql_socket.fd, addr, len);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= getsockname(mysql_socket.fd, addr, len);
+
+ return result;
+}
+
+/** mysql_socket_connect */
+
+static inline int
+inline_mysql_socket_connect
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, const struct sockaddr *addr, socklen_t len)
+{
+ int result;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (mysql_socket.m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_CONNECT, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+ result= connect(mysql_socket.fd, addr, len);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= connect(mysql_socket.fd, addr, len);
+
+ return result;
+}
+
+/** mysql_socket_getpeername */
+
+static inline int
+inline_mysql_socket_getpeername
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, struct sockaddr *addr, socklen_t *len)
+{
+ int result;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (mysql_socket.m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_BIND, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+ result= getpeername(mysql_socket.fd, addr, len);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= getpeername(mysql_socket.fd, addr, len);
+
+ return result;
+}
+
+/** mysql_socket_send */
+
+static inline ssize_t
+inline_mysql_socket_send
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, const SOCKBUF_T *buf, size_t n, int flags)
+{
+ ssize_t result;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (mysql_socket.m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_SEND, n, src_file, src_line);
+
+ /* Instrumented code */
+ result= send(mysql_socket.fd, buf, IF_WIN((int),) n, flags);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ {
+ size_t bytes_written;
+ bytes_written= (result > -1) ? result : 0;
+ PSI_SOCKET_CALL(end_socket_wait)(locker, bytes_written);
+ }
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= send(mysql_socket.fd, buf, IF_WIN((int),) n, flags);
+
+ return result;
+}
+
+/** mysql_socket_recv */
+
+static inline ssize_t
+inline_mysql_socket_recv
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, SOCKBUF_T *buf, size_t n, int flags)
+{
+ ssize_t result;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (mysql_socket.m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_RECV, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+ result= recv(mysql_socket.fd, buf, IF_WIN((int),) n, flags);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ {
+ size_t bytes_read;
+ bytes_read= (result > -1) ? result : 0;
+ PSI_SOCKET_CALL(end_socket_wait)(locker, bytes_read);
+ }
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= recv(mysql_socket.fd, buf, IF_WIN((int),) n, flags);
+
+ return result;
+}
+
+/** mysql_socket_sendto */
+
+static inline ssize_t
+inline_mysql_socket_sendto
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, const SOCKBUF_T *buf, size_t n, int flags, const struct sockaddr *addr, socklen_t addr_len)
+{
+ ssize_t result;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (mysql_socket.m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_SEND, n, src_file, src_line);
+
+ /* Instrumented code */
+ result= sendto(mysql_socket.fd, buf, IF_WIN((int),) n, flags, addr, addr_len);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ {
+ size_t bytes_written;
+ bytes_written = (result > -1) ? result : 0;
+ PSI_SOCKET_CALL(end_socket_wait)(locker, bytes_written);
+ }
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= sendto(mysql_socket.fd, buf, IF_WIN((int),) n, flags, addr, addr_len);
+
+ return result;
+}
+
+/** mysql_socket_recvfrom */
+
+static inline ssize_t
+inline_mysql_socket_recvfrom
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, SOCKBUF_T *buf, size_t n, int flags,
+ struct sockaddr *addr, socklen_t *addr_len)
+{
+ ssize_t result;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (mysql_socket.m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_RECV, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+ result= recvfrom(mysql_socket.fd, buf, IF_WIN((int),) n, flags, addr, addr_len);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ {
+ size_t bytes_read;
+ bytes_read = (result > -1) ? result : 0;
+ PSI_SOCKET_CALL(end_socket_wait)(locker, bytes_read);
+ }
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= recvfrom(mysql_socket.fd, buf, IF_WIN((int),) n, flags, addr, addr_len);
+
+ return result;
+}
+
+/** mysql_socket_getsockopt */
+
+static inline int
+inline_mysql_socket_getsockopt
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, int level, int optname, SOCKBUF_T *optval, socklen_t *optlen)
+{
+ int result;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (mysql_socket.m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_OPT, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+ result= getsockopt(mysql_socket.fd, level, optname, optval, optlen);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= getsockopt(mysql_socket.fd, level, optname, optval, optlen);
+
+ return result;
+}
+
+/** mysql_socket_setsockopt */
+
+static inline int
+inline_mysql_socket_setsockopt
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, int level, int optname, const SOCKBUF_T *optval,
+ socklen_t optlen)
+{
+ int result;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (mysql_socket.m_psi)
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_OPT, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+ result= setsockopt(mysql_socket.fd, level, optname, optval, optlen);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= setsockopt(mysql_socket.fd, level, optname, optval, optlen);
+
+ return result;
+}
+
+/** mysql_socket_listen */
+
+static inline int
+inline_mysql_socket_listen
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, int backlog)
+{
+ int result;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (mysql_socket.m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_CONNECT, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+ result= listen(mysql_socket.fd, backlog);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= listen(mysql_socket.fd, backlog);
+
+ return result;
+}
+
+/** mysql_socket_accept */
+
+static inline MYSQL_SOCKET
+inline_mysql_socket_accept
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line, PSI_socket_key key,
+#endif
+ MYSQL_SOCKET socket_listen, struct sockaddr *addr, socklen_t *addr_len)
+{
+ MYSQL_SOCKET socket_accept= MYSQL_INVALID_SOCKET;
+ socklen_t addr_length= (addr_len != NULL) ? *addr_len : 0;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (socket_listen.m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, socket_listen.m_psi, PSI_SOCKET_CONNECT, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+ socket_accept.fd= accept(socket_listen.fd, addr, &addr_length);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
+ }
+ else
+#endif
+ {
+ /* Non instrumented code */
+ socket_accept.fd= accept(socket_listen.fd, addr, &addr_length);
+ }
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (likely(socket_accept.fd != INVALID_SOCKET))
+ {
+ /* Initialize the instrument with the new socket descriptor and address */
+ socket_accept.m_psi= PSI_SOCKET_CALL(init_socket)
+ (key, (const my_socket*)&socket_accept.fd, addr, addr_length);
+ }
+#endif
+
+ return socket_accept;
+}
+
+/** mysql_socket_close */
+
+static inline int
+inline_mysql_socket_close
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket)
+{
+ int result;
+
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (mysql_socket.m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_CLOSE, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+ result= closesocket(mysql_socket.fd);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
+ /* Remove the instrumentation for this socket. */
+ if (mysql_socket.m_psi != NULL)
+ PSI_SOCKET_CALL(destroy_socket)(mysql_socket.m_psi);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= closesocket(mysql_socket.fd);
+
+ return result;
+}
+
+/** mysql_socket_shutdown */
+
+static inline int
+inline_mysql_socket_shutdown
+(
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ const char *src_file, uint src_line,
+#endif
+ MYSQL_SOCKET mysql_socket, int how)
+{
+ int result;
+
+#ifdef __WIN__
+ static LPFN_DISCONNECTEX DisconnectEx = NULL;
+ if (DisconnectEx == NULL)
+ {
+ DWORD dwBytesReturned;
+ GUID guidDisconnectEx = WSAID_DISCONNECTEX;
+ WSAIoctl(mysql_socket.fd, SIO_GET_EXTENSION_FUNCTION_POINTER,
+ &guidDisconnectEx, sizeof(GUID),
+ &DisconnectEx, sizeof(DisconnectEx),
+ &dwBytesReturned, NULL, NULL);
+ }
+#endif
+
+/* Instrumentation start */
+#ifdef HAVE_PSI_SOCKET_INTERFACE
+ if (mysql_socket.m_psi != NULL)
+ {
+ PSI_socket_locker *locker;
+ PSI_socket_locker_state state;
+ locker= PSI_SOCKET_CALL(start_socket_wait)
+ (&state, mysql_socket.m_psi, PSI_SOCKET_SHUTDOWN, (size_t)0, src_file, src_line);
+
+ /* Instrumented code */
+#ifdef __WIN__
+ if (DisconnectEx)
+ result= (DisconnectEx(mysql_socket.fd, (LPOVERLAPPED) NULL,
+ (DWORD) 0, (DWORD) 0) == TRUE) ? 0 : -1;
+ else
+#endif
+ result= shutdown(mysql_socket.fd, how);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_SOCKET_CALL(end_socket_wait)(locker, (size_t)0);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+#ifdef __WIN__
+ if (DisconnectEx)
+ result= (DisconnectEx(mysql_socket.fd, (LPOVERLAPPED) NULL,
+ (DWORD) 0, (DWORD) 0) == TRUE) ? 0 : -1;
+ else
+#endif
+ result= shutdown(mysql_socket.fd, how);
+
+ return result;
+}
+
+/** @} (end of group Socket_instrumentation) */
+
+#endif
+
diff --git a/include/mysql/psi/mysql_stage.h b/include/mysql/psi/mysql_stage.h
new file mode 100644
index 00000000000..61bfdbb7d59
--- /dev/null
+++ b/include/mysql/psi/mysql_stage.h
@@ -0,0 +1,72 @@
+/* Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#ifndef MYSQL_STAGE_H
+#define MYSQL_STAGE_H
+
+/**
+ @file mysql/psi/mysql_stage.h
+ Instrumentation helpers for stages.
+*/
+
+#include "mysql/psi/psi.h"
+
+/**
+ @defgroup Stage_instrumentation Stage Instrumentation
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ @def mysql_stage_register(P1, P2, P3)
+ Stage registration.
+*/
+#ifdef HAVE_PSI_STAGE_INTERFACE
+#define mysql_stage_register(P1, P2, P3) \
+ inline_mysql_stage_register(P1, P2, P3)
+#else
+#define mysql_stage_register(P1, P2, P3) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_STAGE_INTERFACE
+ #define MYSQL_SET_STAGE(K, F, L) \
+ inline_mysql_set_stage(K, F, L)
+#else
+ #define MYSQL_SET_STAGE(K, F, L) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_STAGE_INTERFACE
+static inline void inline_mysql_stage_register(
+ const char *category, PSI_stage_info **info, int count)
+{
+ PSI_STAGE_CALL(register_stage)(category, info, count);
+}
+#endif
+
+#ifdef HAVE_PSI_STAGE_INTERFACE
+static inline void
+inline_mysql_set_stage(PSI_stage_key key,
+ const char *src_file, int src_line)
+{
+ PSI_STAGE_CALL(start_stage)(key, src_file, src_line);
+}
+#endif
+
+/** @} (end of group Stage_instrumentation) */
+
+#endif
+
diff --git a/include/mysql/psi/mysql_statement.h b/include/mysql/psi/mysql_statement.h
new file mode 100644
index 00000000000..d7a76ee25e4
--- /dev/null
+++ b/include/mysql/psi/mysql_statement.h
@@ -0,0 +1,230 @@
+/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#ifndef MYSQL_STATEMENT_H
+#define MYSQL_STATEMENT_H
+
+/**
+ @file mysql/psi/mysql_statement.h
+ Instrumentation helpers for statements.
+*/
+
+#include "mysql/psi/psi.h"
+
+/**
+ @defgroup Statement_instrumentation Statement Instrumentation
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ @def mysql_statement_register(P1, P2, P3)
+ Statement registration.
+*/
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+#define mysql_statement_register(P1, P2, P3) \
+ inline_mysql_statement_register(P1, P2, P3)
+#else
+#define mysql_statement_register(P1, P2, P3) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+#ifdef HAVE_PSI_STATEMENT_DIGEST_INTERFACE
+ #define MYSQL_DIGEST_START(LOCKER) \
+ inline_mysql_digest_start(LOCKER)
+#else
+ #define MYSQL_DIGEST_START(LOCKER) \
+ NULL
+#endif
+#else
+ #define MYSQL_DIGEST_START(LOCKER) \
+ NULL
+#endif
+
+#ifdef HAVE_PSI_STATEMENT_DIGEST_INTERFACE
+ #define MYSQL_ADD_TOKEN(LOCKER, T, Y) \
+ inline_mysql_add_token(LOCKER, T, Y)
+#else
+ #define MYSQL_ADD_TOKEN(LOCKER, T, Y) \
+ NULL
+#endif
+
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+ #define MYSQL_START_STATEMENT(STATE, K, DB, DB_LEN, CS) \
+ inline_mysql_start_statement(STATE, K, DB, DB_LEN, CS, __FILE__, __LINE__)
+#else
+ #define MYSQL_START_STATEMENT(STATE, K, DB, DB_LEN, CS) \
+ NULL
+#endif
+
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+ #define MYSQL_REFINE_STATEMENT(LOCKER, K) \
+ inline_mysql_refine_statement(LOCKER, K)
+#else
+ #define MYSQL_REFINE_STATEMENT(LOCKER, K) \
+ NULL
+#endif
+
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+ #define MYSQL_SET_STATEMENT_TEXT(LOCKER, P1, P2) \
+ inline_mysql_set_statement_text(LOCKER, P1, P2)
+#else
+ #define MYSQL_SET_STATEMENT_TEXT(LOCKER, P1, P2) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+ #define MYSQL_SET_STATEMENT_LOCK_TIME(LOCKER, P1) \
+ inline_mysql_set_statement_lock_time(LOCKER, P1)
+#else
+ #define MYSQL_SET_STATEMENT_LOCK_TIME(LOCKER, P1) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+ #define MYSQL_SET_STATEMENT_ROWS_SENT(LOCKER, P1) \
+ inline_mysql_set_statement_rows_sent(LOCKER, P1)
+#else
+ #define MYSQL_SET_STATEMENT_ROWS_SENT(LOCKER, P1) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+ #define MYSQL_SET_STATEMENT_ROWS_EXAMINED(LOCKER, P1) \
+ inline_mysql_set_statement_rows_examined(LOCKER, P1)
+#else
+ #define MYSQL_SET_STATEMENT_ROWS_EXAMINED(LOCKER, P1) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+ #define MYSQL_END_STATEMENT(LOCKER, DA) \
+ inline_mysql_end_statement(LOCKER, DA)
+#else
+ #define MYSQL_END_STATEMENT(LOCKER, DA) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_STATEMENT_INTERFACE
+static inline void inline_mysql_statement_register(
+ const char *category, PSI_statement_info *info, int count)
+{
+ PSI_STATEMENT_CALL(register_statement)(category, info, count);
+}
+
+#ifdef HAVE_PSI_STATEMENT_DIGEST_INTERFACE
+static inline struct PSI_digest_locker *
+inline_mysql_digest_start(PSI_statement_locker *locker)
+{
+ PSI_digest_locker* digest_locker= NULL;
+
+ if (likely(locker != NULL))
+ digest_locker= PSI_STATEMENT_CALL(digest_start)(locker);
+ return digest_locker;
+}
+#endif
+
+#ifdef HAVE_PSI_STATEMENT_DIGEST_INTERFACE
+static inline struct PSI_digest_locker *
+inline_mysql_add_token(PSI_digest_locker *locker, uint token,
+ void *yylval)
+{
+ if (likely(locker != NULL))
+ locker= PSI_STATEMENT_CALL(digest_add_token)(locker, token,
+ (OPAQUE_LEX_YYSTYPE*)yylval);
+ return locker;
+}
+#endif
+
+static inline struct PSI_statement_locker *
+inline_mysql_start_statement(PSI_statement_locker_state *state,
+ PSI_statement_key key,
+ const char *db, uint db_len,
+ const CHARSET_INFO *charset,
+ const char *src_file, int src_line)
+{
+ PSI_statement_locker *locker;
+ locker= PSI_STATEMENT_CALL(get_thread_statement_locker)(state, key, charset);
+ if (likely(locker != NULL))
+ PSI_STATEMENT_CALL(start_statement)(locker, db, db_len, src_file, src_line);
+ return locker;
+}
+
+static inline struct PSI_statement_locker *
+inline_mysql_refine_statement(PSI_statement_locker *locker,
+ PSI_statement_key key)
+{
+ if (likely(locker != NULL))
+ {
+ locker= PSI_STATEMENT_CALL(refine_statement)(locker, key);
+ }
+ return locker;
+}
+
+static inline void
+inline_mysql_set_statement_text(PSI_statement_locker *locker,
+ const char *text, uint text_len)
+{
+ if (likely(locker != NULL))
+ {
+ PSI_STATEMENT_CALL(set_statement_text)(locker, text, text_len);
+ }
+}
+
+static inline void
+inline_mysql_set_statement_lock_time(PSI_statement_locker *locker,
+ ulonglong count)
+{
+ if (likely(locker != NULL))
+ {
+ PSI_STATEMENT_CALL(set_statement_lock_time)(locker, count);
+ }
+}
+
+static inline void
+inline_mysql_set_statement_rows_sent(PSI_statement_locker *locker,
+ ulonglong count)
+{
+ if (likely(locker != NULL))
+ {
+ PSI_STATEMENT_CALL(set_statement_rows_sent)(locker, count);
+ }
+}
+
+static inline void
+inline_mysql_set_statement_rows_examined(PSI_statement_locker *locker,
+ ulonglong count)
+{
+ if (likely(locker != NULL))
+ {
+ PSI_STATEMENT_CALL(set_statement_rows_examined)(locker, count);
+ }
+}
+
+static inline void
+inline_mysql_end_statement(struct PSI_statement_locker *locker,
+ Diagnostics_area *stmt_da)
+{
+ PSI_STAGE_CALL(end_stage)();
+ if (likely(locker != NULL))
+ PSI_STATEMENT_CALL(end_statement)(locker, stmt_da);
+}
+#endif
+
+/** @} (end of group Statement_instrumentation) */
+
+#endif
+
diff --git a/include/mysql/psi/mysql_table.h b/include/mysql/psi/mysql_table.h
new file mode 100644
index 00000000000..815313e654b
--- /dev/null
+++ b/include/mysql/psi/mysql_table.h
@@ -0,0 +1,189 @@
+/* Copyright (c) 2010, 2012, Oracle and/or its affiliates. All rights reserved.
+
+ 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,
+ 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
+
+#ifndef MYSQL_TABLE_H
+#define MYSQL_TABLE_H
+
+/**
+ @file mysql/psi/mysql_table.h
+ Instrumentation helpers for table io.
+*/
+
+#include "mysql/psi/psi.h"
+
+/**
+ @defgroup Table_instrumentation Table Instrumentation
+ @ingroup Instrumentation_interface
+ @{
+*/
+
+/**
+ @def MYSQL_TABLE_WAIT_VARIABLES
+ Instrumentation helper for table waits.
+ This instrumentation declares local variables.
+ Do not use a ';' after this macro
+ @param LOCKER the locker
+ @param STATE the locker state
+ @sa MYSQL_START_TABLE_IO_WAIT.
+ @sa MYSQL_END_TABLE_IO_WAIT.
+ @sa MYSQL_START_TABLE_LOCK_WAIT.
+ @sa MYSQL_END_TABLE_LOCK_WAIT.
+*/
+#ifdef HAVE_PSI_TABLE_INTERFACE
+ #define MYSQL_TABLE_WAIT_VARIABLES(LOCKER, STATE) \
+ struct PSI_table_locker* LOCKER; \
+ PSI_table_locker_state STATE;
+#else
+ #define MYSQL_TABLE_WAIT_VARIABLES(LOCKER, STATE)
+#endif
+
+/**
+ @def MYSQL_TABLE_IO_WAIT
+ Instrumentation helper for table io_waits.
+ This instrumentation marks the start of a wait event.
+ @param PSI the instrumented table
+ @param OP the table operation to be performed
+ @param INDEX the table index used if any, or MAY_KEY.
+ @param FLAGS per table operation flags.
+ @sa MYSQL_END_TABLE_WAIT.
+*/
+#ifdef HAVE_PSI_TABLE_INTERFACE
+ #define MYSQL_TABLE_IO_WAIT(PSI, OP, INDEX, FLAGS, PAYLOAD) \
+ { \
+ if (PSI != NULL) \
+ { \
+ PSI_table_locker *locker; \
+ PSI_table_locker_state state; \
+ locker= PSI_TABLE_CALL(start_table_io_wait) \
+ (& state, PSI, OP, INDEX, __FILE__, __LINE__); \
+ PAYLOAD \
+ if (locker != NULL) \
+ PSI_TABLE_CALL(end_table_io_wait)(locker); \
+ } \
+ else \
+ { \
+ PAYLOAD \
+ } \
+ }
+#else
+ #define MYSQL_TABLE_IO_WAIT(PSI, OP, INDEX, FLAGS, PAYLOAD) \
+ PAYLOAD
+#endif
+
+/**
+ @def MYSQL_TABLE_LOCK_WAIT
+ Instrumentation helper for table io_waits.
+ This instrumentation marks the start of a wait event.
+ @param PSI the instrumented table
+ @param OP the table operation to be performed
+ @param INDEX the table index used if any, or MAY_KEY.
+ @param FLAGS per table operation flags.
+ @sa MYSQL_END_TABLE_WAIT.
+*/
+#ifdef HAVE_PSI_TABLE_INTERFACE
+ #define MYSQL_TABLE_LOCK_WAIT(PSI, OP, FLAGS, PAYLOAD) \
+ { \
+ if (PSI != NULL) \
+ { \
+ PSI_table_locker *locker; \
+ PSI_table_locker_state state; \
+ locker= PSI_TABLE_CALL(start_table_lock_wait) \
+ (& state, PSI, OP, FLAGS, __FILE__, __LINE__); \
+ PAYLOAD \
+ if (locker != NULL) \
+ PSI_TABLE_CALL(end_table_lock_wait)(locker); \
+ } \
+ else \
+ { \
+ PAYLOAD \
+ } \
+ }
+#else
+ #define MYSQL_TABLE_LOCK_WAIT(PSI, OP, FLAGS, PAYLOAD) \
+ PAYLOAD
+#endif
+
+/**
+ @def MYSQL_START_TABLE_LOCK_WAIT
+ Instrumentation helper for table lock waits.
+ This instrumentation marks the start of a wait event.
+ @param LOCKER the locker
+ @param STATE the locker state
+ @param PSI the instrumented table
+ @param OP the table operation to be performed
+ @param FLAGS per table operation flags.
+ @sa MYSQL_END_TABLE_LOCK_WAIT.
+*/
+#ifdef HAVE_PSI_TABLE_INTERFACE
+ #define MYSQL_START_TABLE_LOCK_WAIT(LOCKER, STATE, PSI, OP, FLAGS) \
+ LOCKER= inline_mysql_start_table_lock_wait(STATE, PSI, \
+ OP, FLAGS, __FILE__, __LINE__)
+#else
+ #define MYSQL_START_TABLE_LOCK_WAIT(LOCKER, STATE, PSI, OP, FLAGS) \
+ do {} while (0)
+#endif
+
+/**
+ @def MYSQL_END_TABLE_LOCK_WAIT
+ Instrumentation helper for table lock waits.
+ This instrumentation marks the end of a wait event.
+ @param LOCKER the locker
+ @sa MYSQL_START_TABLE_LOCK_WAIT.
+*/
+#ifdef HAVE_PSI_TABLE_INTERFACE
+ #define MYSQL_END_TABLE_LOCK_WAIT(LOCKER) \
+ inline_mysql_end_table_lock_wait(LOCKER)
+#else
+ #define MYSQL_END_TABLE_LOCK_WAIT(LOCKER) \
+ do {} while (0)
+#endif
+
+#ifdef HAVE_PSI_TABLE_INTERFACE
+/**
+ Instrumentation calls for MYSQL_START_TABLE_LOCK_WAIT.
+ @sa MYSQL_END_TABLE_LOCK_WAIT.
+*/
+static inline struct PSI_table_locker *
+inline_mysql_start_table_lock_wait(PSI_table_locker_state *state,
+ struct PSI_table *psi,
+ enum PSI_table_lock_operation op,
+ ulong flags, const char *src_file, int src_line)
+{
+ if (psi != NULL)
+ {
+ struct PSI_table_locker *locker;
+ locker= PSI_TABLE_CALL(start_table_lock_wait)
+ (state, psi, op, flags, src_file, src_line);
+ return locker;
+ }
+ return NULL;
+}
+
+/**
+ Instrumentation calls for MYSQL_END_TABLE_LOCK_WAIT.
+ @sa MYSQL_START_TABLE_LOCK_WAIT.
+*/
+static inline void
+inline_mysql_end_table_lock_wait(struct PSI_table_locker *locker)
+{
+ if (locker != NULL)
+ PSI_TABLE_CALL(end_table_lock_wait)(locker);
+}
+#endif
+
+/** @} (end of group Table_instrumentation) */
+
+#endif
+
diff --git a/include/mysql/psi/mysql_thread.h b/include/mysql/psi/mysql_thread.h
new file mode 100644
index 00000000000..604b9c5af61
--- /dev/null
+++ b/include/mysql/psi/mysql_thread.h
@@ -0,0 +1,1268 @@
+/* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+
+ 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,
+ 51 Franklin Street, Suite 500, Boston, MA 02110-1335 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. */
+#ifdef SAFE_MUTEX
+ safe_mutex_t m_mutex;
+#elif defined(MY_PTHREAD_FASTMUTEX)
+ my_pthread_fastmutex_t m_mutex;
+#else
+ pthread_mutex_t m_mutex;
+#endif
+ /**
+ The instrumentation hook.
+ Note that this hook is not conditionally defined,
+ for binary compatibility of the @c mysql_mutex_t interface.
+ */
+ struct PSI_mutex *m_psi;
+};
+
+/**
+ Type of an instrumented mutex.
+ @c mysql_mutex_t is a drop-in replacement for @c pthread_mutex_t.
+ @sa mysql_mutex_assert_owner
+ @sa mysql_mutex_assert_not_owner
+ @sa mysql_mutex_init
+ @sa mysql_mutex_lock
+ @sa mysql_mutex_unlock
+ @sa mysql_mutex_destroy
+*/
+typedef struct st_mysql_mutex mysql_mutex_t;
+
+/**
+ An instrumented rwlock structure.
+ @sa mysql_rwlock_t
+*/
+struct st_mysql_rwlock
+{
+ /** The real rwlock */
+ rw_lock_t m_rwlock;
+ /**
+ The instrumentation hook.
+ Note that this hook is not conditionally defined,
+ for binary compatibility of the @c mysql_rwlock_t interface.
+ */
+ struct PSI_rwlock *m_psi;
+};
+
+/**
+ An instrumented prlock structure.
+ @sa mysql_prlock_t
+*/
+struct st_mysql_prlock
+{
+ /** The real prlock */
+ rw_pr_lock_t m_prlock;
+ /**
+ The instrumentation hook.
+ Note that this hook is not conditionally defined,
+ for binary compatibility of the @c mysql_rwlock_t interface.
+ */
+ struct PSI_rwlock *m_psi;
+};
+
+/**
+ Type of an instrumented rwlock.
+ @c mysql_rwlock_t is a drop-in replacement for @c pthread_rwlock_t.
+ @sa mysql_rwlock_init
+ @sa mysql_rwlock_rdlock
+ @sa mysql_rwlock_tryrdlock
+ @sa mysql_rwlock_wrlock
+ @sa mysql_rwlock_trywrlock
+ @sa mysql_rwlock_unlock
+ @sa mysql_rwlock_destroy
+*/
+typedef struct st_mysql_rwlock mysql_rwlock_t;
+
+/**
+ Type of an instrumented prlock.
+ A prlock is a read write lock that 'prefers readers' (pr).
+ @c mysql_prlock_t is a drop-in replacement for @c rw_pr_lock_t.
+ @sa mysql_prlock_init
+ @sa mysql_prlock_rdlock
+ @sa mysql_prlock_wrlock
+ @sa mysql_prlock_unlock
+ @sa mysql_prlock_destroy
+*/
+typedef struct st_mysql_prlock mysql_prlock_t;
+
+/**
+ An instrumented cond structure.
+ @sa mysql_cond_t
+*/
+struct st_mysql_cond
+{
+ /** The real condition */
+ pthread_cond_t m_cond;
+ /**
+ The instrumentation hook.
+ Note that this hook is not conditionally defined,
+ for binary compatibility of the @c mysql_cond_t interface.
+ */
+ struct PSI_cond *m_psi;
+};
+
+/**
+ Type of an instrumented condition.
+ @c mysql_cond_t is a drop-in replacement for @c pthread_cond_t.
+ @sa mysql_cond_init
+ @sa mysql_cond_wait
+ @sa mysql_cond_timedwait
+ @sa mysql_cond_signal
+ @sa mysql_cond_broadcast
+ @sa mysql_cond_destroy
+*/
+typedef struct st_mysql_cond mysql_cond_t;
+
+/*
+ Consider the following code:
+ static inline void foo() { bar(); }
+ when foo() is never called.
+
+ With gcc, foo() is a local static function, so the dependencies
+ are optimized away at compile time, and there is no dependency on bar().
+ With other compilers (HP, Sun Studio), the function foo() implementation
+ is compiled, and bar() needs to be present to link.
+
+ Due to the existing header dependencies in MySQL code, this header file
+ is sometime used when it is not needed, which in turn cause link failures
+ on some platforms.
+ The proper fix would be to cut these extra dependencies in the calling code.
+ DISABLE_MYSQL_THREAD_H is a work around to limit dependencies.
+ DISABLE_MYSQL_PRLOCK_H is similar, and is used to disable specifically
+ the prlock wrappers.
+*/
+#ifndef DISABLE_MYSQL_THREAD_H
+
+/**
+ @def mysql_mutex_assert_owner(M)
+ Wrapper, to use safe_mutex_assert_owner with instrumented mutexes.
+ @c mysql_mutex_assert_owner is a drop-in replacement
+ for @c safe_mutex_assert_owner.
+*/
+#define mysql_mutex_assert_owner(M) \
+ safe_mutex_assert_owner(&(M)->m_mutex)
+
+/**
+ @def mysql_mutex_assert_not_owner(M)
+ Wrapper, to use safe_mutex_assert_not_owner with instrumented mutexes.
+ @c mysql_mutex_assert_not_owner is a drop-in replacement
+ for @c safe_mutex_assert_not_owner.
+*/
+#define mysql_mutex_assert_not_owner(M) \
+ safe_mutex_assert_not_owner(&(M)->m_mutex)
+
+/** Wrappers for instrumented prlock objects. */
+
+#define mysql_prlock_assert_write_owner(M) \
+ rw_pr_lock_assert_write_owner(&(M)->m_prlock)
+
+#define mysql_prlock_assert_not_write_owner(M) \
+ rw_pr_lock_assert_not_write_owner(&(M)->m_prlock)
+
+/**
+ @def mysql_mutex_register(P1, P2, P3)
+ Mutex registration.
+*/
+#define mysql_mutex_register(P1, P2, P3) \
+ inline_mysql_mutex_register(P1, P2, P3)
+
+/**
+ @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_MUTEX_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_MUTEX_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_MUTEX_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_register(P1, P2, P3)
+ Rwlock registration.
+*/
+#define mysql_rwlock_register(P1, P2, P3) \
+ inline_mysql_rwlock_register(P1, P2, P3)
+
+/**
+ @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_RWLOCK_INTERFACE
+ #define mysql_rwlock_init(K, RW) inline_mysql_rwlock_init(K, RW)
+#else
+ #define mysql_rwlock_init(K, RW) inline_mysql_rwlock_init(RW)
+#endif
+
+/**
+ @def mysql_prlock_init(K, RW)
+ Instrumented rw_pr_init.
+ @c mysql_prlock_init is a replacement for @c rw_pr_init.
+ @param K The PSI_rwlock_key for this instrumented prlock
+ @param RW The prlock to initialize
+*/
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ #define mysql_prlock_init(K, RW) inline_mysql_prlock_init(K, RW)
+#else
+ #define mysql_prlock_init(K, RW) inline_mysql_prlock_init(RW)
+#endif
+
+/**
+ @def mysql_rwlock_destroy(RW)
+ Instrumented rwlock_destroy.
+ @c mysql_rwlock_destroy is a drop-in replacement
+ for @c pthread_rwlock_destroy.
+*/
+#define mysql_rwlock_destroy(RW) inline_mysql_rwlock_destroy(RW)
+
+/**
+ @def mysql_prlock_destroy(RW)
+ Instrumented rw_pr_destroy.
+ @c mysql_prlock_destroy is a drop-in replacement
+ for @c rw_pr_destroy.
+*/
+#define mysql_prlock_destroy(RW) inline_mysql_prlock_destroy(RW)
+
+/**
+ @def mysql_rwlock_rdlock(RW)
+ Instrumented rwlock_rdlock.
+ @c mysql_rwlock_rdlock is a drop-in replacement
+ for @c pthread_rwlock_rdlock.
+*/
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ #define mysql_rwlock_rdlock(RW) \
+ inline_mysql_rwlock_rdlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_rwlock_rdlock(RW) \
+ inline_mysql_rwlock_rdlock(RW)
+#endif
+
+/**
+ @def mysql_prlock_rdlock(RW)
+ Instrumented rw_pr_rdlock.
+ @c mysql_prlock_rdlock is a drop-in replacement
+ for @c rw_pr_rdlock.
+*/
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ #define mysql_prlock_rdlock(RW) \
+ inline_mysql_prlock_rdlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_prlock_rdlock(RW) \
+ inline_mysql_prlock_rdlock(RW)
+#endif
+
+/**
+ @def mysql_rwlock_wrlock(RW)
+ Instrumented rwlock_wrlock.
+ @c mysql_rwlock_wrlock is a drop-in replacement
+ for @c pthread_rwlock_wrlock.
+*/
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ #define mysql_rwlock_wrlock(RW) \
+ inline_mysql_rwlock_wrlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_rwlock_wrlock(RW) \
+ inline_mysql_rwlock_wrlock(RW)
+#endif
+
+/**
+ @def mysql_prlock_wrlock(RW)
+ Instrumented rw_pr_wrlock.
+ @c mysql_prlock_wrlock is a drop-in replacement
+ for @c rw_pr_wrlock.
+*/
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ #define mysql_prlock_wrlock(RW) \
+ inline_mysql_prlock_wrlock(RW, __FILE__, __LINE__)
+#else
+ #define mysql_prlock_wrlock(RW) \
+ inline_mysql_prlock_wrlock(RW)
+#endif
+
+/**
+ @def mysql_rwlock_tryrdlock(RW)
+ Instrumented rwlock_tryrdlock.
+ @c mysql_rwlock_tryrdlock is a drop-in replacement
+ for @c pthread_rwlock_tryrdlock.
+*/
+#ifdef HAVE_PSI_RWLOCK_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_RWLOCK_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_prlock_unlock(RW)
+ Instrumented rw_pr_unlock.
+ @c mysql_prlock_unlock is a drop-in replacement
+ for @c rw_pr_unlock.
+*/
+#define mysql_prlock_unlock(RW) inline_mysql_prlock_unlock(RW)
+
+/**
+ @def mysql_cond_register(P1, P2, P3)
+ Cond registration.
+*/
+#define mysql_cond_register(P1, P2, P3) \
+ inline_mysql_cond_register(P1, P2, P3)
+
+/**
+ @def mysql_cond_init(K, C, A)
+ Instrumented cond_init.
+ @c mysql_cond_init is a replacement for @c pthread_cond_init.
+ @param C The cond to initialize
+ @param K The PSI_cond_key for this instrumented cond
+ @param A Condition attributes
+*/
+#ifdef HAVE_PSI_COND_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_COND_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_COND_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_register(P1, P2, P3)
+ Thread registration.
+*/
+#define mysql_thread_register(P1, P2, P3) \
+ inline_mysql_thread_register(P1, P2, P3)
+
+/**
+ @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_THREAD_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_THREAD_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 void inline_mysql_mutex_register(
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ const char *category,
+ PSI_mutex_info *info,
+ int count
+#else
+ const char *category __attribute__ ((unused)),
+ void *info __attribute__ ((unused)),
+ int count __attribute__ ((unused))
+#endif
+)
+{
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ PSI_MUTEX_CALL(register_mutex)(category, info, count);
+#endif
+}
+
+static inline int inline_mysql_mutex_init(
+#ifdef HAVE_PSI_MUTEX_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_MUTEX_INTERFACE
+ that->m_psi= PSI_MUTEX_CALL(init_mutex)(key, &that->m_mutex);
+#else
+ that->m_psi= NULL;
+#endif
+#ifdef SAFE_MUTEX
+ return safe_mutex_init(&that->m_mutex, attr, src_file, src_line);
+#elif defined(MY_PTHREAD_FASTMUTEX)
+ return my_pthread_fastmutex_init(&that->m_mutex, attr);
+#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_MUTEX_INTERFACE
+ if (that->m_psi != NULL)
+ {
+ PSI_MUTEX_CALL(destroy_mutex)(that->m_psi);
+ that->m_psi= NULL;
+ }
+#endif
+#ifdef SAFE_MUTEX
+ return safe_mutex_destroy(&that->m_mutex, src_file, src_line);
+#elif defined(MY_PTHREAD_FASTMUTEX)
+ return pthread_mutex_destroy(&that->m_mutex.mutex);
+#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_MUTEX_INTERFACE)
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ if (that->m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_mutex_locker *locker;
+ PSI_mutex_locker_state state;
+ locker= PSI_MUTEX_CALL(start_mutex_wait)(&state, that->m_psi,
+ PSI_MUTEX_LOCK, src_file, src_line);
+
+ /* Instrumented code */
+#ifdef SAFE_MUTEX
+ result= safe_mutex_lock(&that->m_mutex, FALSE, src_file, src_line);
+#elif defined(MY_PTHREAD_FASTMUTEX)
+ result= my_pthread_fastmutex_lock(&that->m_mutex);
+#else
+ result= pthread_mutex_lock(&that->m_mutex);
+#endif
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_MUTEX_CALL(end_mutex_wait)(locker, result);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+#ifdef SAFE_MUTEX
+ result= safe_mutex_lock(&that->m_mutex, FALSE, src_file, src_line);
+#elif defined(MY_PTHREAD_FASTMUTEX)
+ result= my_pthread_fastmutex_lock(&that->m_mutex);
+#else
+ result= pthread_mutex_lock(&that->m_mutex);
+#endif
+
+ return result;
+}
+
+static inline int inline_mysql_mutex_trylock(
+ mysql_mutex_t *that
+#if defined(SAFE_MUTEX) || defined (HAVE_PSI_MUTEX_INTERFACE)
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+
+#ifdef HAVE_PSI_MUTEX_INTERFACE
+ if (that->m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_mutex_locker *locker;
+ PSI_mutex_locker_state state;
+ locker= PSI_MUTEX_CALL(start_mutex_wait)(&state, that->m_psi,
+ PSI_MUTEX_TRYLOCK, src_file, src_line);
+
+ /* Instrumented code */
+#ifdef SAFE_MUTEX
+ result= safe_mutex_lock(&that->m_mutex, TRUE, src_file, src_line);
+#elif defined(MY_PTHREAD_FASTMUTEX)
+ result= pthread_mutex_trylock(&that->m_mutex.mutex);
+#else
+ result= pthread_mutex_trylock(&that->m_mutex);
+#endif
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_MUTEX_CALL(end_mutex_wait)(locker, result);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+#ifdef SAFE_MUTEX
+ result= safe_mutex_lock(&that->m_mutex, TRUE, src_file, src_line);
+#elif defined(MY_PTHREAD_FASTMUTEX)
+ result= pthread_mutex_trylock(&that->m_mutex.mutex);
+#else
+ result= pthread_mutex_trylock(&that->m_mutex);
+#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_MUTEX_INTERFACE
+ if (that->m_psi != NULL)
+ PSI_MUTEX_CALL(unlock_mutex)(that->m_psi);
+#endif
+
+#ifdef SAFE_MUTEX
+ result= safe_mutex_unlock(&that->m_mutex, src_file, src_line);
+#elif defined(MY_PTHREAD_FASTMUTEX)
+ result= pthread_mutex_unlock(&that->m_mutex.mutex);
+#else
+ result= pthread_mutex_unlock(&that->m_mutex);
+#endif
+
+ return result;
+}
+
+static inline void inline_mysql_rwlock_register(
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ const char *category,
+ PSI_rwlock_info *info,
+ int count
+#else
+ const char *category __attribute__ ((unused)),
+ void *info __attribute__ ((unused)),
+ int count __attribute__ ((unused))
+#endif
+)
+{
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ PSI_RWLOCK_CALL(register_rwlock)(category, info, count);
+#endif
+}
+
+static inline int inline_mysql_rwlock_init(
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ PSI_rwlock_key key,
+#endif
+ mysql_rwlock_t *that)
+{
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ that->m_psi= PSI_RWLOCK_CALL(init_rwlock)(key, &that->m_rwlock);
+#else
+ that->m_psi= NULL;
+#endif
+ /*
+ pthread_rwlockattr_t is not used in MySQL.
+ */
+ return my_rwlock_init(&that->m_rwlock, NULL);
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_init(
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ PSI_rwlock_key key,
+#endif
+ mysql_prlock_t *that)
+{
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ that->m_psi= PSI_RWLOCK_CALL(init_rwlock)(key, &that->m_prlock);
+#else
+ that->m_psi= NULL;
+#endif
+ return rw_pr_init(&that->m_prlock);
+}
+#endif
+
+static inline int inline_mysql_rwlock_destroy(
+ mysql_rwlock_t *that)
+{
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ if (that->m_psi != NULL)
+ {
+ PSI_RWLOCK_CALL(destroy_rwlock)(that->m_psi);
+ that->m_psi= NULL;
+ }
+#endif
+ return rwlock_destroy(&that->m_rwlock);
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_destroy(
+ mysql_prlock_t *that)
+{
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ if (that->m_psi != NULL)
+ {
+ PSI_RWLOCK_CALL(destroy_rwlock)(that->m_psi);
+ that->m_psi= NULL;
+ }
+#endif
+ return rw_pr_destroy(&that->m_prlock);
+}
+#endif
+
+static inline int inline_mysql_rwlock_rdlock(
+ mysql_rwlock_t *that
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ if (that->m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_rwlock_locker *locker;
+ PSI_rwlock_locker_state state;
+ locker= PSI_RWLOCK_CALL(start_rwlock_rdwait)(&state, that->m_psi,
+ PSI_RWLOCK_READLOCK, src_file, src_line);
+
+ /* Instrumented code */
+ result= rw_rdlock(&that->m_rwlock);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, result);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= rw_rdlock(&that->m_rwlock);
+
+ return result;
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_rdlock(
+ mysql_prlock_t *that
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ if (that->m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_rwlock_locker *locker;
+ PSI_rwlock_locker_state state;
+ locker= PSI_RWLOCK_CALL(start_rwlock_rdwait)(&state, that->m_psi,
+ PSI_RWLOCK_READLOCK, src_file, src_line);
+
+ /* Instrumented code */
+ result= rw_pr_rdlock(&that->m_prlock);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, result);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= rw_pr_rdlock(&that->m_prlock);
+
+ return result;
+}
+#endif
+
+static inline int inline_mysql_rwlock_wrlock(
+ mysql_rwlock_t *that
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ if (that->m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_rwlock_locker *locker;
+ PSI_rwlock_locker_state state;
+ locker= PSI_RWLOCK_CALL(start_rwlock_wrwait)(&state, that->m_psi,
+ PSI_RWLOCK_WRITELOCK, src_file, src_line);
+
+ /* Instrumented code */
+ result= rw_wrlock(&that->m_rwlock);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_RWLOCK_CALL(end_rwlock_wrwait)(locker, result);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= rw_wrlock(&that->m_rwlock);
+
+ return result;
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_wrlock(
+ mysql_prlock_t *that
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ if (that->m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_rwlock_locker *locker;
+ PSI_rwlock_locker_state state;
+ locker= PSI_RWLOCK_CALL(start_rwlock_wrwait)(&state, that->m_psi,
+ PSI_RWLOCK_WRITELOCK, src_file, src_line);
+
+ /* Instrumented code */
+ result= rw_pr_wrlock(&that->m_prlock);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_RWLOCK_CALL(end_rwlock_wrwait)(locker, result);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= rw_pr_wrlock(&that->m_prlock);
+
+ return result;
+}
+#endif
+
+static inline int inline_mysql_rwlock_tryrdlock(
+ mysql_rwlock_t *that
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ if (that->m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_rwlock_locker *locker;
+ PSI_rwlock_locker_state state;
+ locker= PSI_RWLOCK_CALL(start_rwlock_rdwait)(&state, that->m_psi,
+ PSI_RWLOCK_TRYREADLOCK, src_file, src_line);
+
+ /* Instrumented code */
+ result= rw_tryrdlock(&that->m_rwlock);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, result);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= rw_tryrdlock(&that->m_rwlock);
+
+ return result;
+}
+
+static inline int inline_mysql_rwlock_trywrlock(
+ mysql_rwlock_t *that
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ if (that->m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_rwlock_locker *locker;
+ PSI_rwlock_locker_state state;
+ locker= PSI_RWLOCK_CALL(start_rwlock_wrwait)(&state, that->m_psi,
+ PSI_RWLOCK_TRYWRITELOCK, src_file, src_line);
+
+ /* Instrumented code */
+ result= rw_trywrlock(&that->m_rwlock);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_RWLOCK_CALL(end_rwlock_wrwait)(locker, result);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= rw_trywrlock(&that->m_rwlock);
+
+ return result;
+}
+
+static inline int inline_mysql_rwlock_unlock(
+ mysql_rwlock_t *that)
+{
+ int result;
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ if (that->m_psi != NULL)
+ PSI_RWLOCK_CALL(unlock_rwlock)(that->m_psi);
+#endif
+ result= rw_unlock(&that->m_rwlock);
+ return result;
+}
+
+#ifndef DISABLE_MYSQL_PRLOCK_H
+static inline int inline_mysql_prlock_unlock(
+ mysql_prlock_t *that)
+{
+ int result;
+#ifdef HAVE_PSI_RWLOCK_INTERFACE
+ if (that->m_psi != NULL)
+ PSI_RWLOCK_CALL(unlock_rwlock)(that->m_psi);
+#endif
+ result= rw_pr_unlock(&that->m_prlock);
+ return result;
+}
+#endif
+
+static inline void inline_mysql_cond_register(
+#ifdef HAVE_PSI_COND_INTERFACE
+ const char *category,
+ PSI_cond_info *info,
+ int count
+#else
+ const char *category __attribute__ ((unused)),
+ void *info __attribute__ ((unused)),
+ int count __attribute__ ((unused))
+#endif
+)
+{
+#ifdef HAVE_PSI_COND_INTERFACE
+ PSI_COND_CALL(register_cond)(category, info, count);
+#endif
+}
+
+static inline int inline_mysql_cond_init(
+#ifdef HAVE_PSI_COND_INTERFACE
+ PSI_cond_key key,
+#endif
+ mysql_cond_t *that,
+ const pthread_condattr_t *attr)
+{
+#ifdef HAVE_PSI_COND_INTERFACE
+ that->m_psi= PSI_COND_CALL(init_cond)(key, &that->m_cond);
+#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_COND_INTERFACE
+ if (that->m_psi != NULL)
+ {
+ PSI_COND_CALL(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_COND_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+
+#ifdef HAVE_PSI_COND_INTERFACE
+ if (that->m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_cond_locker *locker;
+ PSI_cond_locker_state state;
+ locker= PSI_COND_CALL(start_cond_wait)(&state, that->m_psi, mutex->m_psi,
+ PSI_COND_WAIT, src_file, src_line);
+
+ /* Instrumented code */
+ result= my_cond_wait(&that->m_cond, &mutex->m_mutex);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_COND_CALL(end_cond_wait)(locker, result);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= my_cond_wait(&that->m_cond, &mutex->m_mutex);
+
+ return result;
+}
+
+static inline int inline_mysql_cond_timedwait(
+ mysql_cond_t *that,
+ mysql_mutex_t *mutex,
+ struct timespec *abstime
+#ifdef HAVE_PSI_COND_INTERFACE
+ , const char *src_file, uint src_line
+#endif
+ )
+{
+ int result;
+
+#ifdef HAVE_PSI_COND_INTERFACE
+ if (that->m_psi != NULL)
+ {
+ /* Instrumentation start */
+ PSI_cond_locker *locker;
+ PSI_cond_locker_state state;
+ locker= PSI_COND_CALL(start_cond_wait)(&state, that->m_psi, mutex->m_psi,
+ PSI_COND_TIMEDWAIT, src_file, src_line);
+
+ /* Instrumented code */
+ result= my_cond_timedwait(&that->m_cond, &mutex->m_mutex, abstime);
+
+ /* Instrumentation end */
+ if (locker != NULL)
+ PSI_COND_CALL(end_cond_wait)(locker, result);
+
+ return result;
+ }
+#endif
+
+ /* Non instrumented code */
+ result= my_cond_timedwait(&that->m_cond, &mutex->m_mutex, abstime);
+
+ return result;
+}
+
+static inline int inline_mysql_cond_signal(
+ mysql_cond_t *that)
+{
+ int result;
+#ifdef HAVE_PSI_COND_INTERFACE
+ if (that->m_psi != NULL)
+ PSI_COND_CALL(signal_cond)(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_COND_INTERFACE
+ if (that->m_psi != NULL)
+ PSI_COND_CALL(broadcast_cond)(that->m_psi);
+#endif
+ result= pthread_cond_broadcast(&that->m_cond);
+ return result;
+}
+
+static inline void inline_mysql_thread_register(
+#ifdef HAVE_PSI_THREAD_INTERFACE
+ const char *category,
+ PSI_thread_info *info,
+ int count
+#else
+ const char *category __attribute__ ((unused)),
+ void *info __attribute__ ((unused)),
+ int count __attribute__ ((unused))
+#endif
+)
+{
+#ifdef HAVE_PSI_THREAD_INTERFACE
+ PSI_THREAD_CALL(register_thread)(category, info, count);
+#endif
+}
+
+#ifdef HAVE_PSI_THREAD_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;
+ result= PSI_THREAD_CALL(spawn_thread)(key, thread, attr, start_routine, arg);
+ return result;
+}
+
+static inline void inline_mysql_thread_set_psi_id(ulong id)
+{
+ struct PSI_thread *psi= PSI_THREAD_CALL(get_thread)();
+ PSI_THREAD_CALL(set_thread_id)(psi, id);
+}
+#endif
+
+#endif /* DISABLE_MYSQL_THREAD_H */
+
+/** @} (end of group Thread_instrumentation) */
+
+#endif
+
diff --git a/include/mysql/psi/psi.h b/include/mysql/psi/psi.h
new file mode 100644
index 00000000000..cc2057c630d
--- /dev/null
+++ b/include/mysql/psi/psi.h
@@ -0,0 +1,2431 @@
+/* Copyright (c) 2008, 2012, Oracle and/or its affiliates. All rights reserved.
+
+ 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,
+ 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
+
+#ifndef MYSQL_PERFORMANCE_SCHEMA_INTERFACE_H
+#define MYSQL_PERFORMANCE_SCHEMA_INTERFACE_H
+
+#ifdef EMBEDDED_LIBRARY
+#define DISABLE_PSI_MUTEX
+#define DISABLE_PSI_RWLOCK
+#define DISABLE_PSI_COND
+#define DISABLE_PSI_FILE
+#define DISABLE_PSI_TABLE
+#define DISABLE_PSI_SOCKET
+#define DISABLE_PSI_STAGE
+#define DISABLE_PSI_STATEMENT
+#define DISABLE_PSI_IDLE
+#define DISABLE_PSI_STATEMENT_DIGEST
+#endif /* EMBEDDED_LIBRARY */
+
+#ifndef MY_GLOBAL_INCLUDED
+/*
+ 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
+
+struct TABLE_SHARE;
+/*
+ There are 3 known bison parsers in the server:
+ - (1) the SQL parser itself, sql/sql_yacc.yy
+ - (2) storage/innobase/fts/fts0pars.y
+ - (3) storage/innobase/pars/pars0grm.y
+ What is instrumented here are the tokens from the SQL query text (1),
+ to make digests.
+ Now, to avoid name pollution and conflicts with different YYSTYPE definitions,
+ an opaque structure is used here.
+ The real type to use when invoking the digest api is LEX_YYSTYPE.
+*/
+struct OPAQUE_LEX_YYSTYPE;
+
+/**
+ @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;
+typedef struct PSI_mutex PSI_mutex;
+
+/**
+ Interface for an instrumented rwlock.
+ This is an opaque structure.
+*/
+struct PSI_rwlock;
+typedef struct PSI_rwlock PSI_rwlock;
+
+/**
+ Interface for an instrumented condition.
+ This is an opaque structure.
+*/
+struct PSI_cond;
+typedef struct PSI_cond PSI_cond;
+
+/**
+ Interface for an instrumented table share.
+ This is an opaque structure.
+*/
+struct PSI_table_share;
+typedef struct PSI_table_share PSI_table_share;
+
+/**
+ Interface for an instrumented table handle.
+ This is an opaque structure.
+*/
+struct PSI_table;
+typedef struct PSI_table PSI_table;
+
+/**
+ Interface for an instrumented thread.
+ This is an opaque structure.
+*/
+struct PSI_thread;
+typedef struct PSI_thread PSI_thread;
+
+/**
+ Interface for an instrumented file handle.
+ This is an opaque structure.
+*/
+struct PSI_file;
+typedef struct PSI_file PSI_file;
+
+/**
+ Interface for an instrumented socket descriptor.
+ This is an opaque structure.
+*/
+struct PSI_socket;
+typedef struct PSI_socket PSI_socket;
+
+/**
+ Interface for an instrumented table operation.
+ This is an opaque structure.
+*/
+struct PSI_table_locker;
+typedef struct PSI_table_locker PSI_table_locker;
+
+/**
+ Interface for an instrumented statement.
+ This is an opaque structure.
+*/
+struct PSI_statement_locker;
+typedef struct PSI_statement_locker PSI_statement_locker;
+
+/**
+ Interface for an instrumented idle operation.
+ This is an opaque structure.
+*/
+struct PSI_idle_locker;
+typedef struct PSI_idle_locker PSI_idle_locker;
+
+/**
+ Interface for an instrumented statement digest operation.
+ This is an opaque structure.
+*/
+struct PSI_digest_locker;
+typedef struct PSI_digest_locker PSI_digest_locker;
+
+/** 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);
+};
+typedef struct PSI_bootstrap PSI_bootstrap;
+
+#ifdef HAVE_PSI_INTERFACE
+
+/**
+ @def DISABLE_PSI_MUTEX
+ Compiling option to disable the mutex instrumentation.
+ This option is mostly intended to be used during development,
+ when doing special builds with only a subset of the performance schema instrumentation,
+ for code analysis / profiling / performance tuning of a specific instrumentation alone.
+ For this reason, DISABLE_PSI_MUTEX is not advertised in the cmake general options.
+ To disable mutexes, add -DDISABLE_PSI_MUTEX to CFLAGS.
+ @sa DISABLE_PSI_RWLOCK
+ @sa DISABLE_PSI_COND
+ @sa DISABLE_PSI_FILE
+ @sa DISABLE_PSI_THREAD
+ @sa DISABLE_PSI_TABLE
+ @sa DISABLE_PSI_STAGE
+ @sa DISABLE_PSI_STATEMENT
+ @sa DISABLE_PSI_SOCKET
+ @sa DISABLE_PSI_IDLE
+*/
+
+#ifndef DISABLE_PSI_MUTEX
+#define HAVE_PSI_MUTEX_INTERFACE
+#endif
+
+/**
+ @def DISABLE_PSI_RWLOCK
+ Compiling option to disable the rwlock instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+
+#ifndef DISABLE_PSI_RWLOCK
+#define HAVE_PSI_RWLOCK_INTERFACE
+#endif
+
+/**
+ @def DISABLE_PSI_COND
+ Compiling option to disable the cond instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+
+#ifndef DISABLE_PSI_COND
+#define HAVE_PSI_COND_INTERFACE
+#endif
+
+/**
+ @def DISABLE_PSI_FILE
+ Compiling option to disable the file instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+
+#ifndef DISABLE_PSI_FILE
+#define HAVE_PSI_FILE_INTERFACE
+#endif
+
+/**
+ @def DISABLE_PSI_THREAD
+ Compiling option to disable the thread instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+#ifndef DISABLE_PSI_THREAD
+#define HAVE_PSI_THREAD_INTERFACE
+#endif
+
+/**
+ @def DISABLE_PSI_TABLE
+ Compiling option to disable the table instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+
+#ifndef DISABLE_PSI_TABLE
+#define HAVE_PSI_TABLE_INTERFACE
+#endif
+
+/**
+ @def DISABLE_PSI_STAGE
+ Compiling option to disable the stage instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+
+#ifndef DISABLE_PSI_STAGE
+#define HAVE_PSI_STAGE_INTERFACE
+#endif
+
+/**
+ @def DISABLE_PSI_STATEMENT
+ Compiling option to disable the statement instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+
+#ifndef DISABLE_PSI_STATEMENT
+#define HAVE_PSI_STATEMENT_INTERFACE
+#endif
+
+/**
+ @def DISABLE_PSI_STATEMENT_DIGEST
+ Compiling option to disable the statement digest instrumentation.
+*/
+
+#ifndef DISABLE_PSI_STATEMENT
+#ifndef DISABLE_PSI_STATEMENT_DIGEST
+#define HAVE_PSI_STATEMENT_DIGEST_INTERFACE
+#endif
+#endif
+
+/**
+ @def DISABLE_PSI_SOCKET
+ Compiling option to disable the statement instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+
+#ifndef DISABLE_PSI_SOCKET
+#define HAVE_PSI_SOCKET_INTERFACE
+#endif
+
+/**
+ @def DISABLE_PSI_IDLE
+ Compiling option to disable the idle instrumentation.
+ @sa DISABLE_PSI_MUTEX
+*/
+
+#ifndef DISABLE_PSI_IDLE
+#define HAVE_PSI_IDLE_INTERFACE
+#endif
+
+/**
+ @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;
+typedef struct PSI_mutex_locker PSI_mutex_locker;
+
+/**
+ Interface for an instrumented rwlock operation.
+ This is an opaque structure.
+*/
+struct PSI_rwlock_locker;
+typedef struct PSI_rwlock_locker PSI_rwlock_locker;
+
+/**
+ Interface for an instrumented condition operation.
+ This is an opaque structure.
+*/
+struct PSI_cond_locker;
+typedef struct PSI_cond_locker PSI_cond_locker;
+
+/**
+ Interface for an instrumented file operation.
+ This is an opaque structure.
+*/
+struct PSI_file_locker;
+typedef struct PSI_file_locker PSI_file_locker;
+
+/**
+ Interface for an instrumented socket operation.
+ This is an opaque structure.
+*/
+struct PSI_socket_locker;
+typedef struct PSI_socket_locker PSI_socket_locker;
+
+/** Operation performed on an instrumented mutex. */
+enum PSI_mutex_operation
+{
+ /** Lock. */
+ PSI_MUTEX_LOCK= 0,
+ /** Lock attempt. */
+ PSI_MUTEX_TRYLOCK= 1
+};
+typedef enum PSI_mutex_operation PSI_mutex_operation;
+
+/** 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
+};
+typedef enum PSI_rwlock_operation PSI_rwlock_operation;
+
+/** Operation performed on an instrumented condition. */
+enum PSI_cond_operation
+{
+ /** Wait. */
+ PSI_COND_WAIT= 0,
+ /** Wait, with timeout. */
+ PSI_COND_TIMEDWAIT= 1
+};
+typedef enum PSI_cond_operation PSI_cond_operation;
+
+/** 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
+};
+typedef enum PSI_file_operation PSI_file_operation;
+
+/** IO operation performed on an instrumented table. */
+enum PSI_table_io_operation
+{
+ /** Row fetch. */
+ PSI_TABLE_FETCH_ROW= 0,
+ /** Row write. */
+ PSI_TABLE_WRITE_ROW= 1,
+ /** Row update. */
+ PSI_TABLE_UPDATE_ROW= 2,
+ /** Row delete. */
+ PSI_TABLE_DELETE_ROW= 3
+};
+typedef enum PSI_table_io_operation PSI_table_io_operation;
+
+/** Lock operation performed on an instrumented table. */
+enum PSI_table_lock_operation
+{
+ /** Table lock, in the server layer. */
+ PSI_TABLE_LOCK= 0,
+ /** Table lock, in the storage engine layer. */
+ PSI_TABLE_EXTERNAL_LOCK= 1
+};
+typedef enum PSI_table_lock_operation PSI_table_lock_operation;
+
+/** State of an instrumented socket. */
+enum PSI_socket_state
+{
+ /** Idle, waiting for the next command. */
+ PSI_SOCKET_STATE_IDLE= 1,
+ /** Active, executing a command. */
+ PSI_SOCKET_STATE_ACTIVE= 2
+};
+typedef enum PSI_socket_state PSI_socket_state;
+
+/** Operation performed on an instrumented socket. */
+enum PSI_socket_operation
+{
+ /** Socket creation, as in @c socket() or @c socketpair(). */
+ PSI_SOCKET_CREATE= 0,
+ /** Socket connection, as in @c connect(), @c listen() and @c accept(). */
+ PSI_SOCKET_CONNECT= 1,
+ /** Socket bind, as in @c bind(), @c getsockname() and @c getpeername(). */
+ PSI_SOCKET_BIND= 2,
+ /** Socket close, as in @c shutdown(). */
+ PSI_SOCKET_CLOSE= 3,
+ /** Socket send, @c send(). */
+ PSI_SOCKET_SEND= 4,
+ /** Socket receive, @c recv(). */
+ PSI_SOCKET_RECV= 5,
+ /** Socket send, @c sendto(). */
+ PSI_SOCKET_SENDTO= 6,
+ /** Socket receive, @c recvfrom). */
+ PSI_SOCKET_RECVFROM= 7,
+ /** Socket send, @c sendmsg(). */
+ PSI_SOCKET_SENDMSG= 8,
+ /** Socket receive, @c recvmsg(). */
+ PSI_SOCKET_RECVMSG= 9,
+ /** Socket seek, such as @c fseek() or @c seek(). */
+ PSI_SOCKET_SEEK= 10,
+ /** Socket options, as in @c getsockopt() and @c setsockopt(). */
+ PSI_SOCKET_OPT= 11,
+ /** Socket status, as in @c sockatmark() and @c isfdtype(). */
+ PSI_SOCKET_STAT= 12,
+ /** Socket shutdown, as in @c shutdown(). */
+ PSI_SOCKET_SHUTDOWN= 13,
+ /** Socket select, as in @c select() and @c poll(). */
+ PSI_SOCKET_SELECT= 14
+};
+typedef enum PSI_socket_operation PSI_socket_operation;
+
+/**
+ 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;
+
+/**
+ Instrumented stage key.
+ To instrument a stage, a stage key must be obtained using @c register_stage.
+ Using a zero key always disable the instrumentation.
+*/
+typedef unsigned int PSI_stage_key;
+
+/**
+ Instrumented statement key.
+ To instrument a statement, a statement key must be obtained using @c register_statement.
+ Using a zero key always disable the instrumentation.
+*/
+typedef unsigned int PSI_statement_key;
+
+/**
+ Instrumented socket key.
+ To instrument a socket, a socket key must be obtained using @c register_socket.
+ Using a zero key always disable the instrumentation.
+*/
+typedef unsigned int PSI_socket_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)
+
+/**
+ Global flag.
+ This flag indicate that an instrumentation point is a general placeholder,
+ that can mutate into a more specific instrumentation point.
+*/
+#define PSI_FLAG_MUTABLE (1 << 1)
+
+#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;
+};
+
+/**
+ Stage instrument information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented stage.
+*/
+struct PSI_stage_info_v1
+{
+ /** The registered stage key. */
+ PSI_stage_key m_key;
+ /** The name of the stage instrument to register. */
+ const char *m_name;
+ /** The flags of the stage instrument to register. */
+ int m_flags;
+};
+
+/**
+ Statement instrument information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented statement.
+*/
+struct PSI_statement_info_v1
+{
+ /** The registered statement key. */
+ PSI_statement_key m_key;
+ /** The name of the statement instrument to register. */
+ const char *m_name;
+ /** The flags of the statement instrument to register. */
+ int m_flags;
+};
+
+/**
+ Socket instrument information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented socket.
+*/
+struct PSI_socket_info_v1
+{
+ /**
+ Pointer to the key assigned to the registered socket.
+ */
+ PSI_socket_key *m_key;
+ /**
+ The name of the socket instrument to register.
+ */
+ const char *m_name;
+ /**
+ The flags of the socket instrument to register.
+ @sa PSI_FLAG_GLOBAL
+ */
+ int m_flags;
+};
+
+/**
+ State data storage for @c start_idle_wait_v1_t.
+ This structure provide temporary storage to an idle locker.
+ The content of this structure is considered opaque,
+ the fields are only hints of what an implementation
+ of the psi interface can use.
+ This memory is provided by the instrumented code for performance reasons.
+ @sa start_idle_wait_v1_t.
+*/
+struct PSI_idle_locker_state_v1
+{
+ /** Internal state. */
+ uint m_flags;
+ /** Current thread. */
+ struct PSI_thread *m_thread;
+ /** Timer start. */
+ ulonglong m_timer_start;
+ /** Timer function. */
+ ulonglong (*m_timer)(void);
+ /** Internal data. */
+ void *m_wait;
+};
+
+/**
+ State data storage for @c start_mutex_wait_v1_t.
+ This structure provide temporary storage to a mutex locker.
+ The content of this structure is considered opaque,
+ the fields are only hints of what an implementation
+ of the psi interface can use.
+ This memory is provided by the instrumented code for performance reasons.
+ @sa start_mutex_wait_v1_t
+*/
+struct PSI_mutex_locker_state_v1
+{
+ /** Internal state. */
+ uint m_flags;
+ /** Current operation. */
+ enum PSI_mutex_operation m_operation;
+ /** Current mutex. */
+ struct PSI_mutex *m_mutex;
+ /** Current thread. */
+ struct PSI_thread *m_thread;
+ /** Timer start. */
+ ulonglong m_timer_start;
+ /** Timer function. */
+ ulonglong (*m_timer)(void);
+ /** Internal data. */
+ void *m_wait;
+};
+
+/**
+ State data storage for @c start_rwlock_rdwait_v1_t, @c start_rwlock_wrwait_v1_t.
+ This structure provide temporary storage to a rwlock locker.
+ The content of this structure is considered opaque,
+ the fields are only hints of what an implementation
+ of the psi interface can use.
+ This memory is provided by the instrumented code for performance reasons.
+ @sa start_rwlock_rdwait_v1_t
+ @sa start_rwlock_wrwait_v1_t
+*/
+struct PSI_rwlock_locker_state_v1
+{
+ /** Internal state. */
+ uint m_flags;
+ /** Current operation. */
+ enum PSI_rwlock_operation m_operation;
+ /** Current rwlock. */
+ struct PSI_rwlock *m_rwlock;
+ /** Current thread. */
+ struct PSI_thread *m_thread;
+ /** Timer start. */
+ ulonglong m_timer_start;
+ /** Timer function. */
+ ulonglong (*m_timer)(void);
+ /** Internal data. */
+ void *m_wait;
+};
+
+/**
+ State data storage for @c start_cond_wait_v1_t.
+ This structure provide temporary storage to a condition locker.
+ The content of this structure is considered opaque,
+ the fields are only hints of what an implementation
+ of the psi interface can use.
+ This memory is provided by the instrumented code for performance reasons.
+ @sa start_cond_wait_v1_t
+*/
+struct PSI_cond_locker_state_v1
+{
+ /** Internal state. */
+ uint m_flags;
+ /** Current operation. */
+ enum PSI_cond_operation m_operation;
+ /** Current condition. */
+ struct PSI_cond *m_cond;
+ /** Current mutex. */
+ struct PSI_mutex *m_mutex;
+ /** Current thread. */
+ struct PSI_thread *m_thread;
+ /** Timer start. */
+ ulonglong m_timer_start;
+ /** Timer function. */
+ ulonglong (*m_timer)(void);
+ /** Internal data. */
+ void *m_wait;
+};
+
+/**
+ State data storage for @c get_thread_file_name_locker_v1_t.
+ This structure provide temporary storage to a file locker.
+ The content of this structure is considered opaque,
+ the fields are only hints of what an implementation
+ of the psi interface can use.
+ This memory is provided by the instrumented code for performance reasons.
+ @sa get_thread_file_name_locker_v1_t
+ @sa get_thread_file_stream_locker_v1_t
+ @sa get_thread_file_descriptor_locker_v1_t
+*/
+struct PSI_file_locker_state_v1
+{
+ /** Internal state. */
+ uint m_flags;
+ /** Current operation. */
+ enum PSI_file_operation m_operation;
+ /** Current file. */
+ struct PSI_file *m_file;
+ /** Current file name. */
+ const char *m_name;
+ /** Current file class. */
+ void *m_class;
+ /** Current thread. */
+ struct PSI_thread *m_thread;
+ /** Operation number of bytes. */
+ size_t m_number_of_bytes;
+ /** Timer start. */
+ ulonglong m_timer_start;
+ /** Timer function. */
+ ulonglong (*m_timer)(void);
+ /** Internal data. */
+ void *m_wait;
+};
+
+/**
+ State data storage for @c start_table_io_wait_v1_t,
+ @c start_table_lock_wait_v1_t.
+ This structure provide temporary storage to a table locker.
+ The content of this structure is considered opaque,
+ the fields are only hints of what an implementation
+ of the psi interface can use.
+ This memory is provided by the instrumented code for performance reasons.
+ @sa start_table_io_wait_v1_t
+ @sa start_table_lock_wait_v1_t
+*/
+struct PSI_table_locker_state_v1
+{
+ /** Internal state. */
+ uint m_flags;
+ /** Current io operation. */
+ enum PSI_table_io_operation m_io_operation;
+ /** Current table handle. */
+ struct PSI_table *m_table;
+ /** Current table share. */
+ struct PSI_table_share *m_table_share;
+ /** Current thread. */
+ struct PSI_thread *m_thread;
+ /** Timer start. */
+ ulonglong m_timer_start;
+ /** Timer function. */
+ ulonglong (*m_timer)(void);
+ /** Internal data. */
+ void *m_wait;
+ /**
+ Implementation specific.
+ For table io, the table io index.
+ For table lock, the lock type.
+ */
+ uint m_index;
+};
+
+#define PSI_MAX_DIGEST_STORAGE_SIZE 1024
+
+/**
+ Structure to store token count/array for a statement
+ on which digest is to be calculated.
+*/
+struct PSI_digest_storage
+{
+ my_bool m_full;
+ int m_byte_count;
+ /** Character set number. */
+ uint m_charset_number;
+ unsigned char m_token_array[PSI_MAX_DIGEST_STORAGE_SIZE];
+};
+typedef struct PSI_digest_storage PSI_digest_storage;
+
+struct PSI_digest_locker_state
+{
+ int m_last_id_index;
+ PSI_digest_storage m_digest_storage;
+};
+typedef struct PSI_digest_locker_state PSI_digest_locker_state;
+
+/* Duplicate of NAME_LEN, to avoid dependency on mysql_com.h */
+#define PSI_SCHEMA_NAME_LEN (64 * 3)
+
+/**
+ State data storage for @c get_thread_statement_locker_v1_t,
+ @c get_thread_statement_locker_v1_t.
+ This structure provide temporary storage to a statement locker.
+ The content of this structure is considered opaque,
+ the fields are only hints of what an implementation
+ of the psi interface can use.
+ This memory is provided by the instrumented code for performance reasons.
+ @sa get_thread_statement_locker_v1_t
+*/
+struct PSI_statement_locker_state_v1
+{
+ /** Discarded flag. */
+ my_bool m_discarded;
+ /** Metric, no index used flag. */
+ uchar m_no_index_used;
+ /** Metric, no good index used flag. */
+ uchar m_no_good_index_used;
+ /** Internal state. */
+ uint m_flags;
+ /** Instrumentation class. */
+ void *m_class;
+ /** Current thread. */
+ struct PSI_thread *m_thread;
+ /** Timer start. */
+ ulonglong m_timer_start;
+ /** Timer function. */
+ ulonglong (*m_timer)(void);
+ /** Internal data. */
+ void *m_statement;
+ /** Locked time. */
+ ulonglong m_lock_time;
+ /** Rows sent. */
+ ulonglong m_rows_sent;
+ /** Rows examined. */
+ ulonglong m_rows_examined;
+ /** Metric, temporary tables created on disk. */
+ ulong m_created_tmp_disk_tables;
+ /** Metric, temporary tables created. */
+ ulong m_created_tmp_tables;
+ /** Metric, number of select full join. */
+ ulong m_select_full_join;
+ /** Metric, number of select full range join. */
+ ulong m_select_full_range_join;
+ /** Metric, number of select range. */
+ ulong m_select_range;
+ /** Metric, number of select range check. */
+ ulong m_select_range_check;
+ /** Metric, number of select scan. */
+ ulong m_select_scan;
+ /** Metric, number of sort merge passes. */
+ ulong m_sort_merge_passes;
+ /** Metric, number of sort merge. */
+ ulong m_sort_range;
+ /** Metric, number of sort rows. */
+ ulong m_sort_rows;
+ /** Metric, number of sort scans. */
+ ulong m_sort_scan;
+ /** Statement digest. */
+ PSI_digest_locker_state m_digest_state;
+ /** Current schema name. */
+ char m_schema_name[PSI_SCHEMA_NAME_LEN];
+ /** Length in bytes of @c m_schema_name. */
+ uint m_schema_name_length;
+};
+
+/**
+ State data storage for @c start_socket_wait_v1_t.
+ This structure provide temporary storage to a socket locker.
+ The content of this structure is considered opaque,
+ the fields are only hints of what an implementation
+ of the psi interface can use.
+ This memory is provided by the instrumented code for performance reasons.
+ @sa start_socket_wait_v1_t
+*/
+struct PSI_socket_locker_state_v1
+{
+ /** Internal state. */
+ uint m_flags;
+ /** Current socket. */
+ struct PSI_socket *m_socket;
+ /** Current thread. */
+ struct PSI_thread *m_thread;
+ /** Operation number of bytes. */
+ size_t m_number_of_bytes;
+ /** Timer start. */
+ ulonglong m_timer_start;
+ /** Timer function. */
+ ulonglong (*m_timer)(void);
+ /** Current operation. */
+ enum PSI_socket_operation m_operation;
+ /** Source file. */
+ const char* m_src_file;
+ /** Source line number. */
+ int m_src_line;
+ /** Internal data. */
+ void *m_wait;
+};
+
+/* 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);
+
+/**
+ Stage registration API.
+ @param category a category name
+ @param info an array of stage info to register
+ @param count the size of the info array
+*/
+typedef void (*register_stage_v1_t)
+ (const char *category, struct PSI_stage_info_v1 **info, int count);
+
+/**
+ Statement registration API.
+ @param category a category name
+ @param info an array of stage info to register
+ @param count the size of the info array
+*/
+typedef void (*register_statement_v1_t)
+ (const char *category, struct PSI_statement_info_v1 *info, int count);
+
+/**
+ Socket registration API.
+ @param category a category name (typically a plugin name)
+ @param info an array of socket info to register
+ @param count the size of the info array
+*/
+typedef void (*register_socket_v1_t)
+ (const char *category, struct PSI_socket_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);
+
+/**
+ Socket instrumentation initialisation API.
+ @param key the registered mutex key
+ @param socket descriptor
+ @param addr the socket ip address
+ @param addr_len length of socket ip address
+ @return an instrumented socket
+*/
+typedef struct PSI_socket* (*init_socket_v1_t)
+ (PSI_socket_key key, const my_socket *fd,
+ const struct sockaddr *addr, socklen_t addr_len);
+
+/**
+ socket instrumentation destruction API.
+ @param socket the socket to destroy
+*/
+typedef void (*destroy_socket_v1_t)(struct PSI_socket *socket);
+
+/**
+ Acquire a table share instrumentation.
+ @param temporary True for temporary tables
+ @param share The SQL layer table share
+ @return a table share instrumentation, or NULL
+*/
+typedef struct PSI_table_share* (*get_table_share_v1_t)
+ (my_bool temporary, struct TABLE_SHARE *share);
+
+/**
+ Release a table share.
+ @param info the table share to release
+*/
+typedef void (*release_table_share_v1_t)(struct PSI_table_share *share);
+
+/**
+ Drop a table share.
+ @param temporary True for temporary tables
+ @param schema_name the table schema name
+ @param schema_name_length the table schema name length
+ @param table_name the table name
+ @param table_name_length the table name length
+*/
+typedef void (*drop_table_share_v1_t)
+ (my_bool temporary, const char *schema_name, int schema_name_length,
+ const char *table_name, int table_name_length);
+
+/**
+ 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);
+
+/**
+ Unbind a table handle from the current thread.
+ This operation happens when an opened table is added to the open table cache.
+ @param table the table to unbind
+*/
+typedef void (*unbind_table_v1_t)
+ (struct PSI_table *table);
+
+/**
+ Rebind a table handle to the current thread.
+ This operation happens when a table from the open table cache
+ is reused for a thread.
+ @param table the table to unbind
+*/
+typedef PSI_table* (*rebind_table_v1_t)
+ (PSI_table_share *share, const void *identity, PSI_table *table);
+
+/**
+ 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, ulonglong 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,
+ ulonglong 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);
+
+/**
+ Assign a user name to the instrumented thread.
+ @param user the user name
+ @param user_len the user name length
+*/
+typedef void (*set_thread_user_v1_t)(const char *user, int user_len);
+
+/**
+ Assign a user name and host name to the instrumented thread.
+ @param user the user name
+ @param user_len the user name length
+ @param host the host name
+ @param host_len the host name length
+*/
+typedef void (*set_thread_user_host_v1_t)(const char *user, int user_len,
+ const char *host, int host_len);
+
+/**
+ Assign a current database to the instrumented thread.
+ @param db the database name
+ @param db_len the database name length
+*/
+typedef void (*set_thread_db_v1_t)(const char* db, int db_len);
+
+/**
+ Assign a current command to the instrumented thread.
+ @param command the current command
+*/
+typedef void (*set_thread_command_v1_t)(int command);
+
+/**
+ Assign a start time to the instrumented thread.
+ @param start_time the thread start time
+*/
+typedef void (*set_thread_start_time_v1_t)(time_t start_time);
+
+/**
+ Assign a state to the instrumented thread.
+ @param state the thread state
+*/
+typedef void (*set_thread_state_v1_t)(const char* state);
+
+/**
+ Assign a process info to the instrumented thread.
+ @param info the process into string
+ @param info_len the process into string length
+*/
+typedef void (*set_thread_info_v1_t)(const char* info, int info_len);
+
+/**
+ Attach a thread instrumentation to the running thread.
+ In case of thread pools, this method should be called when
+ a worker thread picks a work item and runs it.
+ Also, this method should be called if the instrumented code does not
+ keep the pointer returned by @c new_thread() and relies on @c get_thread()
+ instead.
+ @param thread the thread instrumentation
+*/
+typedef void (*set_thread_v1_t)(struct PSI_thread *thread);
+
+/** Delete the current thread instrumentation. */
+typedef void (*delete_current_thread_v1_t)(void);
+
+/** Delete a thread instrumentation. */
+typedef void (*delete_thread_v1_t)(struct PSI_thread *thread);
+
+/**
+ Get a file instrumentation locker, for opening or creating a file.
+ @param state data storage for the locker
+ @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)
+ (struct PSI_file_locker_state_v1 *state,
+ PSI_file_key key, enum PSI_file_operation op, const char *name,
+ const void *identity);
+
+/**
+ Get a file stream instrumentation locker.
+ @param state data storage for the 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_locker_state_v1 *state,
+ struct PSI_file *file, enum PSI_file_operation op);
+
+/**
+ Get a file instrumentation locker.
+ @param state data storage for the 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)
+ (struct PSI_file_locker_state_v1 *state,
+ File file, enum PSI_file_operation op);
+
+/**
+ Record a mutex instrumentation unlock event.
+ @param mutex the mutex instrumentation
+*/
+typedef void (*unlock_mutex_v1_t)
+ (struct PSI_mutex *mutex);
+
+/**
+ Record a rwlock instrumentation unlock event.
+ @param rwlock the rwlock instrumentation
+*/
+typedef void (*unlock_rwlock_v1_t)
+ (struct PSI_rwlock *rwlock);
+
+/**
+ Record a condition instrumentation signal event.
+ @param cond the cond instrumentation
+*/
+typedef void (*signal_cond_v1_t)
+ (struct PSI_cond *cond);
+
+/**
+ Record a condition instrumentation broadcast event.
+ @param cond the cond instrumentation
+*/
+typedef void (*broadcast_cond_v1_t)
+ (struct PSI_cond *cond);
+
+typedef struct PSI_idle_locker* (*start_idle_wait_v1_t)
+ (struct PSI_idle_locker_state_v1 *state, const char *src_file, uint src_line);
+
+typedef void (*end_idle_wait_v1_t)
+ (struct PSI_idle_locker *locker);
+
+/**
+ Record a mutex instrumentation wait start event.
+ @param state data storage for the locker
+ @param mutex the instrumented mutex to lock
+ @param op the operation to perform
+ @param file the source file name
+ @param line the source line number
+ @return a mutex locker, or NULL
+*/
+typedef struct PSI_mutex_locker* (*start_mutex_wait_v1_t)
+ (struct PSI_mutex_locker_state_v1 *state,
+ struct PSI_mutex *mutex,
+ enum PSI_mutex_operation op,
+ 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 struct PSI_rwlock_locker* (*start_rwlock_rdwait_v1_t)
+ (struct PSI_rwlock_locker_state_v1 *state,
+ struct PSI_rwlock *rwlock,
+ enum PSI_rwlock_operation op,
+ 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 struct PSI_rwlock_locker* (*start_rwlock_wrwait_v1_t)
+ (struct PSI_rwlock_locker_state_v1 *state,
+ struct PSI_rwlock *rwlock,
+ enum PSI_rwlock_operation op,
+ 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 struct PSI_cond_locker* (*start_cond_wait_v1_t)
+ (struct PSI_cond_locker_state_v1 *state,
+ struct PSI_cond *cond,
+ struct PSI_mutex *mutex,
+ enum PSI_cond_operation op,
+ 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 io 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 struct PSI_table_locker* (*start_table_io_wait_v1_t)
+ (struct PSI_table_locker_state_v1 *state,
+ struct PSI_table *table,
+ enum PSI_table_io_operation op,
+ uint index,
+ const char *src_file, uint src_line);
+
+/**
+ Record a table instrumentation io wait end event.
+ @param locker a table locker for the running thread
+*/
+typedef void (*end_table_io_wait_v1_t)(struct PSI_table_locker *locker);
+
+/**
+ Record a table instrumentation lock 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 struct PSI_table_locker* (*start_table_lock_wait_v1_t)
+ (struct PSI_table_locker_state_v1 *state,
+ struct PSI_table *table,
+ enum PSI_table_lock_operation op,
+ ulong flags,
+ const char *src_file, uint src_line);
+
+/**
+ Record a table instrumentation lock wait end event.
+ @param locker a table locker for the running thread
+*/
+typedef void (*end_table_lock_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
+*/
+typedef void (*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.
+ @param result the opened file (NULL indicates failure, non NULL success).
+ @return an instrumented file handle
+*/
+typedef struct PSI_file* (*end_file_open_wait_v1_t)
+ (struct PSI_file_locker *locker, void *result);
+
+/**
+ 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);
+
+/**
+ Start a file instrumentation close 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
+*/
+typedef void (*start_file_close_wait_v1_t)
+ (struct PSI_file_locker *locker, const char *src_file, uint src_line);
+
+/**
+ End a file instrumentation close operation.
+ @param locker the file locker.
+ @param rc the close operation return code (0 for success).
+ @return an instrumented file handle
+*/
+typedef void (*end_file_close_wait_v1_t)
+ (struct PSI_file_locker *locker, int rc);
+
+/**
+ Start a new stage, and implicitly end the previous stage.
+ @param key the key of the new stage
+ @param src_file the source file name
+ @param src_line the source line number
+*/
+typedef void (*start_stage_v1_t)
+ (PSI_stage_key key, const char *src_file, int src_line);
+
+/** End the current stage. */
+typedef void (*end_stage_v1_t) (void);
+
+/**
+ Get a statement instrumentation locker.
+ @param state data storage for the locker
+ @param key the statement instrumentation key
+ @param charset client character set
+ @return a statement locker, or NULL
+*/
+typedef struct PSI_statement_locker* (*get_thread_statement_locker_v1_t)
+ (struct PSI_statement_locker_state_v1 *state,
+ PSI_statement_key key, const void *charset);
+
+/**
+ Refine a statement locker to a more specific key.
+ Note that only events declared mutable can be refined.
+ @param the statement locker for the current event
+ @param key the new key for the event
+ @sa PSI_FLAG_MUTABLE
+*/
+typedef struct PSI_statement_locker* (*refine_statement_v1_t)
+ (struct PSI_statement_locker *locker,
+ PSI_statement_key key);
+
+/**
+ Start a new statement event.
+ @param locker the statement locker for this event
+ @param db the active database name for this statement
+ @param db_length the active database name length for this statement
+ @param src_file source file name
+ @param src_line source line number
+*/
+typedef void (*start_statement_v1_t)
+ (struct PSI_statement_locker *locker,
+ const char *db, uint db_length,
+ const char *src_file, uint src_line);
+
+/**
+ Set the statement text for a statement event.
+ @param locker the current statement locker
+ @param text the statement text
+ @param text_len the statement text length
+*/
+typedef void (*set_statement_text_v1_t)
+ (struct PSI_statement_locker *locker,
+ const char *text, uint text_len);
+
+/**
+ Set a statement event lock time.
+ @param locker the statement locker
+ @param lock_time the locked time, in microseconds
+*/
+typedef void (*set_statement_lock_time_t)
+ (struct PSI_statement_locker *locker, ulonglong lock_time);
+
+/**
+ Set a statement event rows sent metric.
+ @param locker the statement locker
+ @param count the number of rows sent
+*/
+typedef void (*set_statement_rows_sent_t)
+ (struct PSI_statement_locker *locker, ulonglong count);
+
+/**
+ Set a statement event rows examined metric.
+ @param locker the statement locker
+ @param count the number of rows examined
+*/
+typedef void (*set_statement_rows_examined_t)
+ (struct PSI_statement_locker *locker, ulonglong count);
+
+/**
+ Increment a statement event "created tmp disk tables" metric.
+ @param locker the statement locker
+ @param count the metric increment value
+*/
+typedef void (*inc_statement_created_tmp_disk_tables_t)
+ (struct PSI_statement_locker *locker, ulong count);
+
+/**
+ Increment a statement event "created tmp tables" metric.
+ @param locker the statement locker
+ @param count the metric increment value
+*/
+typedef void (*inc_statement_created_tmp_tables_t)
+ (struct PSI_statement_locker *locker, ulong count);
+
+/**
+ Increment a statement event "select full join" metric.
+ @param locker the statement locker
+ @param count the metric increment value
+*/
+typedef void (*inc_statement_select_full_join_t)
+ (struct PSI_statement_locker *locker, ulong count);
+
+/**
+ Increment a statement event "select full range join" metric.
+ @param locker the statement locker
+ @param count the metric increment value
+*/
+typedef void (*inc_statement_select_full_range_join_t)
+ (struct PSI_statement_locker *locker, ulong count);
+
+/**
+ Increment a statement event "select range join" metric.
+ @param locker the statement locker
+ @param count the metric increment value
+*/
+typedef void (*inc_statement_select_range_t)
+ (struct PSI_statement_locker *locker, ulong count);
+
+/**
+ Increment a statement event "select range check" metric.
+ @param locker the statement locker
+ @param count the metric increment value
+*/
+typedef void (*inc_statement_select_range_check_t)
+ (struct PSI_statement_locker *locker, ulong count);
+
+/**
+ Increment a statement event "select scan" metric.
+ @param locker the statement locker
+ @param count the metric increment value
+*/
+typedef void (*inc_statement_select_scan_t)
+ (struct PSI_statement_locker *locker, ulong count);
+
+/**
+ Increment a statement event "sort merge passes" metric.
+ @param locker the statement locker
+ @param count the metric increment value
+*/
+typedef void (*inc_statement_sort_merge_passes_t)
+ (struct PSI_statement_locker *locker, ulong count);
+
+/**
+ Increment a statement event "sort range" metric.
+ @param locker the statement locker
+ @param count the metric increment value
+*/
+typedef void (*inc_statement_sort_range_t)
+ (struct PSI_statement_locker *locker, ulong count);
+
+/**
+ Increment a statement event "sort rows" metric.
+ @param locker the statement locker
+ @param count the metric increment value
+*/
+typedef void (*inc_statement_sort_rows_t)
+ (struct PSI_statement_locker *locker, ulong count);
+
+/**
+ Increment a statement event "sort scan" metric.
+ @param locker the statement locker
+ @param count the metric increment value
+*/
+typedef void (*inc_statement_sort_scan_t)
+ (struct PSI_statement_locker *locker, ulong count);
+
+/**
+ Set a statement event "no index used" metric.
+ @param locker the statement locker
+ @param count the metric value
+*/
+typedef void (*set_statement_no_index_used_t)
+ (struct PSI_statement_locker *locker);
+
+/**
+ Set a statement event "no good index used" metric.
+ @param locker the statement locker
+ @param count the metric value
+*/
+typedef void (*set_statement_no_good_index_used_t)
+ (struct PSI_statement_locker *locker);
+
+/**
+ End a statement event.
+ @param locker the statement locker
+ @param stmt_da the statement diagnostics area.
+ @sa Diagnostics_area
+*/
+typedef void (*end_statement_v1_t)
+ (struct PSI_statement_locker *locker, void *stmt_da);
+
+/**
+ Record a socket instrumentation start event.
+ @param locker a socket locker for the running thread
+ @param op socket 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 struct PSI_socket_locker* (*start_socket_wait_v1_t)
+ (struct PSI_socket_locker_state_v1 *state,
+ struct PSI_socket *socket,
+ enum PSI_socket_operation op,
+ size_t count,
+ const char *src_file, uint src_line);
+
+/**
+ Record a socket instrumentation end event.
+ Note that for socket close operations, the instrumented socket handle
+ associated with the socket (which was provided to obtain a locker)
+ is invalid after this call.
+ @param locker a socket 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_socket_locker
+*/
+typedef void (*end_socket_wait_v1_t)
+ (struct PSI_socket_locker *locker, size_t count);
+
+/**
+ Set the socket state for an instrumented socket.
+ @param socket the instrumented socket
+ @param state socket state
+ */
+typedef void (*set_socket_state_v1_t)(struct PSI_socket *socket,
+ enum PSI_socket_state state);
+
+/**
+ Set the socket info for an instrumented socket.
+ @param socket the instrumented socket
+ @param fd the socket descriptor
+ @param addr the socket ip address
+ @param addr_len length of socket ip address
+ @param thread_id associated thread id
+*/
+typedef void (*set_socket_info_v1_t)(struct PSI_socket *socket,
+ const my_socket *fd,
+ const struct sockaddr *addr,
+ socklen_t addr_len);
+
+/**
+ Bind a socket to the thread that owns it.
+ @param socket instrumented socket
+*/
+typedef void (*set_socket_thread_owner_v1_t)(struct PSI_socket *socket);
+
+typedef struct PSI_digest_locker * (*digest_start_v1_t)
+ (struct PSI_statement_locker *locker);
+
+typedef struct PSI_digest_locker* (*digest_add_token_v1_t)
+ (struct PSI_digest_locker *locker, uint token, struct OPAQUE_LEX_YYSTYPE *yylval);
+
+/**
+ Stores an array of connection attributes
+ @param buffer char array of length encoded connection attributes
+ in network format
+ @param length legnth of the data in buffer
+ @param from_cs charset in which @buffer is encodded
+ @return state
+ @retval non-0 attributes truncated
+ @retval 0 stored the attribute
+*/
+typedef int (*set_thread_connect_attrs_v1_t)(const char *buffer, uint length,
+ const void *from_cs);
+
+/**
+ 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 register_stage_v1_t. */
+ register_stage_v1_t register_stage;
+ /** @sa register_statement_v1_t. */
+ register_statement_v1_t register_statement;
+ /** @sa register_socket_v1_t. */
+ register_socket_v1_t register_socket;
+ /** @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 init_socket_v1_t. */
+ init_socket_v1_t init_socket;
+ /** @sa destroy_socket_v1_t. */
+ destroy_socket_v1_t destroy_socket;
+ /** @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 drop_table_share_v1_t. */
+ drop_table_share_v1_t drop_table_share;
+ /** @sa open_table_v1_t. */
+ open_table_v1_t open_table;
+ /** @sa unbind_table_v1_t. */
+ unbind_table_v1_t unbind_table;
+ /** @sa rebind_table_v1_t. */
+ rebind_table_v1_t rebind_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_user_v1_t. */
+ set_thread_user_v1_t set_thread_user;
+ /** @sa set_thread_user_host_v1_t. */
+ set_thread_user_host_v1_t set_thread_user_host;
+ /** @sa set_thread_db_v1_t. */
+ set_thread_db_v1_t set_thread_db;
+ /** @sa set_thread_command_v1_t. */
+ set_thread_command_v1_t set_thread_command;
+ /** @sa set_thread_start_time_v1_t. */
+ set_thread_start_time_v1_t set_thread_start_time;
+ /** @sa set_thread_state_v1_t. */
+ set_thread_state_v1_t set_thread_state;
+ /** @sa set_thread_info_v1_t. */
+ set_thread_info_v1_t set_thread_info;
+ /** @sa set_thread_v1_t. */
+ set_thread_v1_t set_thread;
+ /** @sa delete_current_thread_v1_t. */
+ delete_current_thread_v1_t delete_current_thread;
+ /** @sa delete_thread_v1_t. */
+ delete_thread_v1_t delete_thread;
+ /** @sa get_thread_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_idle_wait_v1_t. */
+ start_idle_wait_v1_t start_idle_wait;
+ /** @sa end_idle_wait_v1_t. */
+ end_idle_wait_v1_t end_idle_wait;
+ /** @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_io_wait_v1_t. */
+ start_table_io_wait_v1_t start_table_io_wait;
+ /** @sa end_table_io_wait_v1_t. */
+ end_table_io_wait_v1_t end_table_io_wait;
+ /** @sa start_table_lock_wait_v1_t. */
+ start_table_lock_wait_v1_t start_table_lock_wait;
+ /** @sa end_table_lock_wait_v1_t. */
+ end_table_lock_wait_v1_t end_table_lock_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;
+ /** @sa start_file_close_wait_v1_t. */
+ start_file_close_wait_v1_t start_file_close_wait;
+ /** @sa end_file_close_wait_v1_t. */
+ end_file_close_wait_v1_t end_file_close_wait;
+ /** @sa start_stage_v1_t. */
+ start_stage_v1_t start_stage;
+ /** @sa end_stage_v1_t. */
+ end_stage_v1_t end_stage;
+ /** @sa get_thread_statement_locker_v1_t. */
+ get_thread_statement_locker_v1_t get_thread_statement_locker;
+ /** @sa refine_statement_v1_t. */
+ refine_statement_v1_t refine_statement;
+ /** @sa start_statement_v1_t. */
+ start_statement_v1_t start_statement;
+ /** @sa set_statement_text_v1_t. */
+ set_statement_text_v1_t set_statement_text;
+ /** @sa set_statement_lock_time_t. */
+ set_statement_lock_time_t set_statement_lock_time;
+ /** @sa set_statement_rows_sent_t. */
+ set_statement_rows_sent_t set_statement_rows_sent;
+ /** @sa set_statement_rows_examined_t. */
+ set_statement_rows_examined_t set_statement_rows_examined;
+ /** @sa inc_statement_created_tmp_disk_tables. */
+ inc_statement_created_tmp_disk_tables_t inc_statement_created_tmp_disk_tables;
+ /** @sa inc_statement_created_tmp_tables. */
+ inc_statement_created_tmp_tables_t inc_statement_created_tmp_tables;
+ /** @sa inc_statement_select_full_join. */
+ inc_statement_select_full_join_t inc_statement_select_full_join;
+ /** @sa inc_statement_select_full_range_join. */
+ inc_statement_select_full_range_join_t inc_statement_select_full_range_join;
+ /** @sa inc_statement_select_range. */
+ inc_statement_select_range_t inc_statement_select_range;
+ /** @sa inc_statement_select_range_check. */
+ inc_statement_select_range_check_t inc_statement_select_range_check;
+ /** @sa inc_statement_select_scan. */
+ inc_statement_select_scan_t inc_statement_select_scan;
+ /** @sa inc_statement_sort_merge_passes. */
+ inc_statement_sort_merge_passes_t inc_statement_sort_merge_passes;
+ /** @sa inc_statement_sort_range. */
+ inc_statement_sort_range_t inc_statement_sort_range;
+ /** @sa inc_statement_sort_rows. */
+ inc_statement_sort_rows_t inc_statement_sort_rows;
+ /** @sa inc_statement_sort_scan. */
+ inc_statement_sort_scan_t inc_statement_sort_scan;
+ /** @sa set_statement_no_index_used. */
+ set_statement_no_index_used_t set_statement_no_index_used;
+ /** @sa set_statement_no_good_index_used. */
+ set_statement_no_good_index_used_t set_statement_no_good_index_used;
+ /** @sa end_statement_v1_t. */
+ end_statement_v1_t end_statement;
+ /** @sa start_socket_wait_v1_t. */
+ start_socket_wait_v1_t start_socket_wait;
+ /** @sa end_socket_wait_v1_t. */
+ end_socket_wait_v1_t end_socket_wait;
+ /** @sa set_socket_state_v1_t. */
+ set_socket_state_v1_t set_socket_state;
+ /** @sa set_socket_info_v1_t. */
+ set_socket_info_v1_t set_socket_info;
+ /** @sa set_socket_thread_owner_v1_t. */
+ set_socket_thread_owner_v1_t set_socket_thread_owner;
+ /** @sa digest_start_v1_t. */
+ digest_start_v1_t digest_start;
+ /** @sa digest_add_token_v1_t. */
+ digest_add_token_v1_t digest_add_token;
+ /** @sa set_thread_connect_attrs_v1_t. */
+ set_thread_connect_attrs_v1_t set_thread_connect_attrs;
+};
+
+/** @} (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;
+};
+
+/** Placeholder */
+struct PSI_stage_info_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_statement_info_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_idle_locker_state_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_mutex_locker_state_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_rwlock_locker_state_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_cond_locker_state_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_file_locker_state_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_table_locker_state_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_statement_locker_state_v2
+{
+ /** Placeholder */
+ int placeholder;
+};
+
+/** Placeholder */
+struct PSI_socket_locker_state_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;
+typedef struct PSI_stage_info_v1 PSI_stage_info;
+typedef struct PSI_statement_info_v1 PSI_statement_info;
+typedef struct PSI_socket_info_v1 PSI_socket_info;
+typedef struct PSI_idle_locker_state_v1 PSI_idle_locker_state;
+typedef struct PSI_mutex_locker_state_v1 PSI_mutex_locker_state;
+typedef struct PSI_rwlock_locker_state_v1 PSI_rwlock_locker_state;
+typedef struct PSI_cond_locker_state_v1 PSI_cond_locker_state;
+typedef struct PSI_file_locker_state_v1 PSI_file_locker_state;
+typedef struct PSI_table_locker_state_v1 PSI_table_locker_state;
+typedef struct PSI_statement_locker_state_v1 PSI_statement_locker_state;
+typedef struct PSI_socket_locker_state_v1 PSI_socket_locker_state;
+#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;
+typedef struct PSI_stage_info_v2 PSI_stage_info;
+typedef struct PSI_statement_info_v2 PSI_statement_info;
+typedef struct PSI_socket_info_v2 PSI_socket_info;
+typedef struct PSI_idle_locker_state_v2 PSI_idle_locker_state;
+typedef struct PSI_mutex_locker_state_v2 PSI_mutex_locker_state;
+typedef struct PSI_rwlock_locker_state_v2 PSI_rwlock_locker_state;
+typedef struct PSI_cond_locker_state_v2 PSI_cond_locker_state;
+typedef struct PSI_file_locker_state_v2 PSI_file_locker_state;
+typedef struct PSI_table_locker_state_v2 PSI_table_locker_state;
+typedef struct PSI_statement_locker_state_v2 PSI_statement_locker_state;
+typedef struct PSI_socket_locker_state_v2 PSI_socket_locker_state;
+#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;
+
+/**
+ Stage instrument information.
+ @since PSI_VERSION_1
+ This structure is used to register an instrumented stage.
+*/
+struct PSI_stage_info_none
+{
+ /** Unused stage key. */
+ unsigned int m_key;
+ /** The name of the stage instrument. */
+ const char *m_name;
+ /** Unused stage flags. */
+ int m_flags;
+};
+
+/**
+ The stage instrumentation has to co exist with the legacy
+ THD::set_proc_info instrumentation.
+ To avoid duplication of the instrumentation in the server,
+ the common PSI_stage_info structure is used,
+ so we export it here, even when not building
+ with HAVE_PSI_INTERFACE.
+*/
+typedef struct PSI_stage_info_none PSI_stage_info;
+
+#endif /* HAVE_PSI_INTERFACE */
+
+extern MYSQL_PLUGIN_IMPORT PSI *PSI_server;
+
+/*
+ Allow to override PSI_XXX_CALL at compile time
+ with more efficient implementations, if available.
+ If nothing better is available,
+ make a dynamic call using the PSI_server function pointer.
+*/
+
+#ifndef PSI_MUTEX_CALL
+#define PSI_MUTEX_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+#ifndef PSI_RWLOCK_CALL
+#define PSI_RWLOCK_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+#ifndef PSI_COND_CALL
+#define PSI_COND_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+#ifndef PSI_THREAD_CALL
+#define PSI_THREAD_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+#ifndef PSI_FILE_CALL
+#define PSI_FILE_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+#ifndef PSI_SOCKET_CALL
+#define PSI_SOCKET_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+#ifndef PSI_STAGE_CALL
+#define PSI_STAGE_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+#ifndef PSI_STATEMENT_CALL
+#define PSI_STATEMENT_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+#ifndef PSI_TABLE_CALL
+#define PSI_TABLE_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+#ifndef PSI_IDLE_CALL
+#define PSI_IDLE_CALL(M) PSI_DYNAMIC_CALL(M)
+#endif
+
+#define PSI_DYNAMIC_CALL(M) PSI_server->M
+
+/** @} */
+
+C_MODE_END
+#endif /* MYSQL_PERFORMANCE_SCHEMA_INTERFACE_H */
+
diff --git a/include/mysql/psi/psi_abi_v0.h b/include/mysql/psi/psi_abi_v0.h
new file mode 100644
index 00000000000..7444cb0b276
--- /dev/null
+++ b/include/mysql/psi/psi_abi_v0.h
@@ -0,0 +1,24 @@
+/* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+
+ 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,
+ 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
+
+/**
+ @file mysql/psi/psi_abi_v0.h
+ ABI check for mysql/psi/psi.h, when compiling without instrumentation.
+ This file is only used to automate detection of changes between versions.
+ Do not include this file, include mysql/psi/psi.h instead.
+*/
+#define _global_h
+#include "mysql/psi/psi.h"
+
diff --git a/include/mysql/psi/psi_abi_v0.h.pp b/include/mysql/psi/psi_abi_v0.h.pp
new file mode 100644
index 00000000000..b46b38ed144
--- /dev/null
+++ b/include/mysql/psi/psi_abi_v0.h.pp
@@ -0,0 +1,47 @@
+#include "mysql/psi/psi.h"
+C_MODE_START
+struct TABLE_SHARE;
+struct OPAQUE_LEX_YYSTYPE;
+struct PSI_mutex;
+typedef struct PSI_mutex PSI_mutex;
+struct PSI_rwlock;
+typedef struct PSI_rwlock PSI_rwlock;
+struct PSI_cond;
+typedef struct PSI_cond PSI_cond;
+struct PSI_table_share;
+typedef struct PSI_table_share PSI_table_share;
+struct PSI_table;
+typedef struct PSI_table PSI_table;
+struct PSI_thread;
+typedef struct PSI_thread PSI_thread;
+struct PSI_file;
+typedef struct PSI_file PSI_file;
+struct PSI_socket;
+typedef struct PSI_socket PSI_socket;
+struct PSI_table_locker;
+typedef struct PSI_table_locker PSI_table_locker;
+struct PSI_statement_locker;
+typedef struct PSI_statement_locker PSI_statement_locker;
+struct PSI_idle_locker;
+typedef struct PSI_idle_locker PSI_idle_locker;
+struct PSI_digest_locker;
+typedef struct PSI_digest_locker PSI_digest_locker;
+struct PSI_bootstrap
+{
+ void* (*get_interface)(int version);
+};
+typedef struct PSI_bootstrap PSI_bootstrap;
+struct PSI_none
+{
+ int opaque;
+};
+typedef struct PSI_none PSI;
+struct PSI_stage_info_none
+{
+ unsigned int m_key;
+ const char *m_name;
+ int m_flags;
+};
+typedef struct PSI_stage_info_none PSI_stage_info;
+extern MYSQL_PLUGIN_IMPORT PSI *PSI_server;
+C_MODE_END
diff --git a/include/mysql/psi/psi_abi_v1.h b/include/mysql/psi/psi_abi_v1.h
new file mode 100644
index 00000000000..54c49f0c518
--- /dev/null
+++ b/include/mysql/psi/psi_abi_v1.h
@@ -0,0 +1,26 @@
+/* Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
+
+ 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,
+ 51 Franklin Street, Suite 500, Boston, MA 02110-1335 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 MY_GLOBAL_INCLUDED
+#include "mysql/psi/psi.h"
+
diff --git a/include/mysql/psi/psi_abi_v1.h.pp b/include/mysql/psi/psi_abi_v1.h.pp
new file mode 100644
index 00000000000..f2037c5b724
--- /dev/null
+++ b/include/mysql/psi/psi_abi_v1.h.pp
@@ -0,0 +1,634 @@
+#include "mysql/psi/psi.h"
+C_MODE_START
+struct TABLE_SHARE;
+struct OPAQUE_LEX_YYSTYPE;
+struct PSI_mutex;
+typedef struct PSI_mutex PSI_mutex;
+struct PSI_rwlock;
+typedef struct PSI_rwlock PSI_rwlock;
+struct PSI_cond;
+typedef struct PSI_cond PSI_cond;
+struct PSI_table_share;
+typedef struct PSI_table_share PSI_table_share;
+struct PSI_table;
+typedef struct PSI_table PSI_table;
+struct PSI_thread;
+typedef struct PSI_thread PSI_thread;
+struct PSI_file;
+typedef struct PSI_file PSI_file;
+struct PSI_socket;
+typedef struct PSI_socket PSI_socket;
+struct PSI_table_locker;
+typedef struct PSI_table_locker PSI_table_locker;
+struct PSI_statement_locker;
+typedef struct PSI_statement_locker PSI_statement_locker;
+struct PSI_idle_locker;
+typedef struct PSI_idle_locker PSI_idle_locker;
+struct PSI_digest_locker;
+typedef struct PSI_digest_locker PSI_digest_locker;
+struct PSI_bootstrap
+{
+ void* (*get_interface)(int version);
+};
+typedef struct PSI_bootstrap PSI_bootstrap;
+struct PSI_mutex_locker;
+typedef struct PSI_mutex_locker PSI_mutex_locker;
+struct PSI_rwlock_locker;
+typedef struct PSI_rwlock_locker PSI_rwlock_locker;
+struct PSI_cond_locker;
+typedef struct PSI_cond_locker PSI_cond_locker;
+struct PSI_file_locker;
+typedef struct PSI_file_locker PSI_file_locker;
+struct PSI_socket_locker;
+typedef struct PSI_socket_locker PSI_socket_locker;
+enum PSI_mutex_operation
+{
+ PSI_MUTEX_LOCK= 0,
+ PSI_MUTEX_TRYLOCK= 1
+};
+typedef enum PSI_mutex_operation PSI_mutex_operation;
+enum PSI_rwlock_operation
+{
+ PSI_RWLOCK_READLOCK= 0,
+ PSI_RWLOCK_WRITELOCK= 1,
+ PSI_RWLOCK_TRYREADLOCK= 2,
+ PSI_RWLOCK_TRYWRITELOCK= 3
+};
+typedef enum PSI_rwlock_operation PSI_rwlock_operation;
+enum PSI_cond_operation
+{
+ PSI_COND_WAIT= 0,
+ PSI_COND_TIMEDWAIT= 1
+};
+typedef enum PSI_cond_operation PSI_cond_operation;
+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
+};
+typedef enum PSI_file_operation PSI_file_operation;
+enum PSI_table_io_operation
+{
+ PSI_TABLE_FETCH_ROW= 0,
+ PSI_TABLE_WRITE_ROW= 1,
+ PSI_TABLE_UPDATE_ROW= 2,
+ PSI_TABLE_DELETE_ROW= 3
+};
+typedef enum PSI_table_io_operation PSI_table_io_operation;
+enum PSI_table_lock_operation
+{
+ PSI_TABLE_LOCK= 0,
+ PSI_TABLE_EXTERNAL_LOCK= 1
+};
+typedef enum PSI_table_lock_operation PSI_table_lock_operation;
+enum PSI_socket_state
+{
+ PSI_SOCKET_STATE_IDLE= 1,
+ PSI_SOCKET_STATE_ACTIVE= 2
+};
+typedef enum PSI_socket_state PSI_socket_state;
+enum PSI_socket_operation
+{
+ PSI_SOCKET_CREATE= 0,
+ PSI_SOCKET_CONNECT= 1,
+ PSI_SOCKET_BIND= 2,
+ PSI_SOCKET_CLOSE= 3,
+ PSI_SOCKET_SEND= 4,
+ PSI_SOCKET_RECV= 5,
+ PSI_SOCKET_SENDTO= 6,
+ PSI_SOCKET_RECVFROM= 7,
+ PSI_SOCKET_SENDMSG= 8,
+ PSI_SOCKET_RECVMSG= 9,
+ PSI_SOCKET_SEEK= 10,
+ PSI_SOCKET_OPT= 11,
+ PSI_SOCKET_STAT= 12,
+ PSI_SOCKET_SHUTDOWN= 13,
+ PSI_SOCKET_SELECT= 14
+};
+typedef enum PSI_socket_operation PSI_socket_operation;
+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;
+typedef unsigned int PSI_stage_key;
+typedef unsigned int PSI_statement_key;
+typedef unsigned int PSI_socket_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;
+};
+struct PSI_stage_info_v1
+{
+ PSI_stage_key m_key;
+ const char *m_name;
+ int m_flags;
+};
+struct PSI_statement_info_v1
+{
+ PSI_statement_key m_key;
+ const char *m_name;
+ int m_flags;
+};
+struct PSI_socket_info_v1
+{
+ PSI_socket_key *m_key;
+ const char *m_name;
+ int m_flags;
+};
+struct PSI_idle_locker_state_v1
+{
+ uint m_flags;
+ struct PSI_thread *m_thread;
+ ulonglong m_timer_start;
+ ulonglong (*m_timer)(void);
+ void *m_wait;
+};
+struct PSI_mutex_locker_state_v1
+{
+ uint m_flags;
+ enum PSI_mutex_operation m_operation;
+ struct PSI_mutex *m_mutex;
+ struct PSI_thread *m_thread;
+ ulonglong m_timer_start;
+ ulonglong (*m_timer)(void);
+ void *m_wait;
+};
+struct PSI_rwlock_locker_state_v1
+{
+ uint m_flags;
+ enum PSI_rwlock_operation m_operation;
+ struct PSI_rwlock *m_rwlock;
+ struct PSI_thread *m_thread;
+ ulonglong m_timer_start;
+ ulonglong (*m_timer)(void);
+ void *m_wait;
+};
+struct PSI_cond_locker_state_v1
+{
+ uint m_flags;
+ enum PSI_cond_operation m_operation;
+ struct PSI_cond *m_cond;
+ struct PSI_mutex *m_mutex;
+ struct PSI_thread *m_thread;
+ ulonglong m_timer_start;
+ ulonglong (*m_timer)(void);
+ void *m_wait;
+};
+struct PSI_file_locker_state_v1
+{
+ uint m_flags;
+ enum PSI_file_operation m_operation;
+ struct PSI_file *m_file;
+ const char *m_name;
+ void *m_class;
+ struct PSI_thread *m_thread;
+ size_t m_number_of_bytes;
+ ulonglong m_timer_start;
+ ulonglong (*m_timer)(void);
+ void *m_wait;
+};
+struct PSI_table_locker_state_v1
+{
+ uint m_flags;
+ enum PSI_table_io_operation m_io_operation;
+ struct PSI_table *m_table;
+ struct PSI_table_share *m_table_share;
+ struct PSI_thread *m_thread;
+ ulonglong m_timer_start;
+ ulonglong (*m_timer)(void);
+ void *m_wait;
+ uint m_index;
+};
+struct PSI_digest_storage
+{
+ my_bool m_full;
+ int m_byte_count;
+ uint m_charset_number;
+ unsigned char m_token_array[1024];
+};
+typedef struct PSI_digest_storage PSI_digest_storage;
+struct PSI_digest_locker_state
+{
+ int m_last_id_index;
+ PSI_digest_storage m_digest_storage;
+};
+typedef struct PSI_digest_locker_state PSI_digest_locker_state;
+struct PSI_statement_locker_state_v1
+{
+ my_bool m_discarded;
+ uchar m_no_index_used;
+ uchar m_no_good_index_used;
+ uint m_flags;
+ void *m_class;
+ struct PSI_thread *m_thread;
+ ulonglong m_timer_start;
+ ulonglong (*m_timer)(void);
+ void *m_statement;
+ ulonglong m_lock_time;
+ ulonglong m_rows_sent;
+ ulonglong m_rows_examined;
+ ulong m_created_tmp_disk_tables;
+ ulong m_created_tmp_tables;
+ ulong m_select_full_join;
+ ulong m_select_full_range_join;
+ ulong m_select_range;
+ ulong m_select_range_check;
+ ulong m_select_scan;
+ ulong m_sort_merge_passes;
+ ulong m_sort_range;
+ ulong m_sort_rows;
+ ulong m_sort_scan;
+ PSI_digest_locker_state m_digest_state;
+ char m_schema_name[(64 * 3)];
+ uint m_schema_name_length;
+};
+struct PSI_socket_locker_state_v1
+{
+ uint m_flags;
+ struct PSI_socket *m_socket;
+ struct PSI_thread *m_thread;
+ size_t m_number_of_bytes;
+ ulonglong m_timer_start;
+ ulonglong (*m_timer)(void);
+ enum PSI_socket_operation m_operation;
+ const char* m_src_file;
+ int m_src_line;
+ void *m_wait;
+};
+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 void (*register_stage_v1_t)
+ (const char *category, struct PSI_stage_info_v1 **info, int count);
+typedef void (*register_statement_v1_t)
+ (const char *category, struct PSI_statement_info_v1 *info, int count);
+typedef void (*register_socket_v1_t)
+ (const char *category, struct PSI_socket_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_socket* (*init_socket_v1_t)
+ (PSI_socket_key key, const my_socket *fd,
+ const struct sockaddr *addr, socklen_t addr_len);
+typedef void (*destroy_socket_v1_t)(struct PSI_socket *socket);
+typedef struct PSI_table_share* (*get_table_share_v1_t)
+ (my_bool temporary, struct TABLE_SHARE *share);
+typedef void (*release_table_share_v1_t)(struct PSI_table_share *share);
+typedef void (*drop_table_share_v1_t)
+ (my_bool temporary, const char *schema_name, int schema_name_length,
+ const char *table_name, int table_name_length);
+typedef struct PSI_table* (*open_table_v1_t)
+ (struct PSI_table_share *share, const void *identity);
+typedef void (*unbind_table_v1_t)
+ (struct PSI_table *table);
+typedef PSI_table* (*rebind_table_v1_t)
+ (PSI_table_share *share, const void *identity, PSI_table *table);
+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, ulonglong thread_id);
+typedef void (*set_thread_id_v1_t)(struct PSI_thread *thread,
+ ulonglong id);
+typedef struct PSI_thread* (*get_thread_v1_t)(void);
+typedef void (*set_thread_user_v1_t)(const char *user, int user_len);
+typedef void (*set_thread_user_host_v1_t)(const char *user, int user_len,
+ const char *host, int host_len);
+typedef void (*set_thread_db_v1_t)(const char* db, int db_len);
+typedef void (*set_thread_command_v1_t)(int command);
+typedef void (*set_thread_start_time_v1_t)(time_t start_time);
+typedef void (*set_thread_state_v1_t)(const char* state);
+typedef void (*set_thread_info_v1_t)(const char* info, int info_len);
+typedef void (*set_thread_v1_t)(struct PSI_thread *thread);
+typedef void (*delete_current_thread_v1_t)(void);
+typedef void (*delete_thread_v1_t)(struct PSI_thread *thread);
+typedef struct PSI_file_locker* (*get_thread_file_name_locker_v1_t)
+ (struct PSI_file_locker_state_v1 *state,
+ 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_locker_state_v1 *state,
+ struct PSI_file *file, enum PSI_file_operation op);
+typedef struct PSI_file_locker* (*get_thread_file_descriptor_locker_v1_t)
+ (struct PSI_file_locker_state_v1 *state,
+ File file, enum PSI_file_operation op);
+typedef void (*unlock_mutex_v1_t)
+ (struct PSI_mutex *mutex);
+typedef void (*unlock_rwlock_v1_t)
+ (struct PSI_rwlock *rwlock);
+typedef void (*signal_cond_v1_t)
+ (struct PSI_cond *cond);
+typedef void (*broadcast_cond_v1_t)
+ (struct PSI_cond *cond);
+typedef struct PSI_idle_locker* (*start_idle_wait_v1_t)
+ (struct PSI_idle_locker_state_v1 *state, const char *src_file, uint src_line);
+typedef void (*end_idle_wait_v1_t)
+ (struct PSI_idle_locker *locker);
+typedef struct PSI_mutex_locker* (*start_mutex_wait_v1_t)
+ (struct PSI_mutex_locker_state_v1 *state,
+ struct PSI_mutex *mutex,
+ enum PSI_mutex_operation op,
+ const char *src_file, uint src_line);
+typedef void (*end_mutex_wait_v1_t)
+ (struct PSI_mutex_locker *locker, int rc);
+typedef struct PSI_rwlock_locker* (*start_rwlock_rdwait_v1_t)
+ (struct PSI_rwlock_locker_state_v1 *state,
+ struct PSI_rwlock *rwlock,
+ enum PSI_rwlock_operation op,
+ const char *src_file, uint src_line);
+typedef void (*end_rwlock_rdwait_v1_t)
+ (struct PSI_rwlock_locker *locker, int rc);
+typedef struct PSI_rwlock_locker* (*start_rwlock_wrwait_v1_t)
+ (struct PSI_rwlock_locker_state_v1 *state,
+ struct PSI_rwlock *rwlock,
+ enum PSI_rwlock_operation op,
+ const char *src_file, uint src_line);
+typedef void (*end_rwlock_wrwait_v1_t)
+ (struct PSI_rwlock_locker *locker, int rc);
+typedef struct PSI_cond_locker* (*start_cond_wait_v1_t)
+ (struct PSI_cond_locker_state_v1 *state,
+ struct PSI_cond *cond,
+ struct PSI_mutex *mutex,
+ enum PSI_cond_operation op,
+ const char *src_file, uint src_line);
+typedef void (*end_cond_wait_v1_t)
+ (struct PSI_cond_locker *locker, int rc);
+typedef struct PSI_table_locker* (*start_table_io_wait_v1_t)
+ (struct PSI_table_locker_state_v1 *state,
+ struct PSI_table *table,
+ enum PSI_table_io_operation op,
+ uint index,
+ const char *src_file, uint src_line);
+typedef void (*end_table_io_wait_v1_t)(struct PSI_table_locker *locker);
+typedef struct PSI_table_locker* (*start_table_lock_wait_v1_t)
+ (struct PSI_table_locker_state_v1 *state,
+ struct PSI_table *table,
+ enum PSI_table_lock_operation op,
+ ulong flags,
+ const char *src_file, uint src_line);
+typedef void (*end_table_lock_wait_v1_t)(struct PSI_table_locker *locker);
+typedef void (*start_file_open_wait_v1_t)
+ (struct PSI_file_locker *locker, const char *src_file, uint src_line);
+typedef struct PSI_file* (*end_file_open_wait_v1_t)
+ (struct PSI_file_locker *locker, void *result);
+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);
+typedef void (*start_file_close_wait_v1_t)
+ (struct PSI_file_locker *locker, const char *src_file, uint src_line);
+typedef void (*end_file_close_wait_v1_t)
+ (struct PSI_file_locker *locker, int rc);
+typedef void (*start_stage_v1_t)
+ (PSI_stage_key key, const char *src_file, int src_line);
+typedef void (*end_stage_v1_t) (void);
+typedef struct PSI_statement_locker* (*get_thread_statement_locker_v1_t)
+ (struct PSI_statement_locker_state_v1 *state,
+ PSI_statement_key key, const void *charset);
+typedef struct PSI_statement_locker* (*refine_statement_v1_t)
+ (struct PSI_statement_locker *locker,
+ PSI_statement_key key);
+typedef void (*start_statement_v1_t)
+ (struct PSI_statement_locker *locker,
+ const char *db, uint db_length,
+ const char *src_file, uint src_line);
+typedef void (*set_statement_text_v1_t)
+ (struct PSI_statement_locker *locker,
+ const char *text, uint text_len);
+typedef void (*set_statement_lock_time_t)
+ (struct PSI_statement_locker *locker, ulonglong lock_time);
+typedef void (*set_statement_rows_sent_t)
+ (struct PSI_statement_locker *locker, ulonglong count);
+typedef void (*set_statement_rows_examined_t)
+ (struct PSI_statement_locker *locker, ulonglong count);
+typedef void (*inc_statement_created_tmp_disk_tables_t)
+ (struct PSI_statement_locker *locker, ulong count);
+typedef void (*inc_statement_created_tmp_tables_t)
+ (struct PSI_statement_locker *locker, ulong count);
+typedef void (*inc_statement_select_full_join_t)
+ (struct PSI_statement_locker *locker, ulong count);
+typedef void (*inc_statement_select_full_range_join_t)
+ (struct PSI_statement_locker *locker, ulong count);
+typedef void (*inc_statement_select_range_t)
+ (struct PSI_statement_locker *locker, ulong count);
+typedef void (*inc_statement_select_range_check_t)
+ (struct PSI_statement_locker *locker, ulong count);
+typedef void (*inc_statement_select_scan_t)
+ (struct PSI_statement_locker *locker, ulong count);
+typedef void (*inc_statement_sort_merge_passes_t)
+ (struct PSI_statement_locker *locker, ulong count);
+typedef void (*inc_statement_sort_range_t)
+ (struct PSI_statement_locker *locker, ulong count);
+typedef void (*inc_statement_sort_rows_t)
+ (struct PSI_statement_locker *locker, ulong count);
+typedef void (*inc_statement_sort_scan_t)
+ (struct PSI_statement_locker *locker, ulong count);
+typedef void (*set_statement_no_index_used_t)
+ (struct PSI_statement_locker *locker);
+typedef void (*set_statement_no_good_index_used_t)
+ (struct PSI_statement_locker *locker);
+typedef void (*end_statement_v1_t)
+ (struct PSI_statement_locker *locker, void *stmt_da);
+typedef struct PSI_socket_locker* (*start_socket_wait_v1_t)
+ (struct PSI_socket_locker_state_v1 *state,
+ struct PSI_socket *socket,
+ enum PSI_socket_operation op,
+ size_t count,
+ const char *src_file, uint src_line);
+typedef void (*end_socket_wait_v1_t)
+ (struct PSI_socket_locker *locker, size_t count);
+typedef void (*set_socket_state_v1_t)(struct PSI_socket *socket,
+ enum PSI_socket_state state);
+typedef void (*set_socket_info_v1_t)(struct PSI_socket *socket,
+ const my_socket *fd,
+ const struct sockaddr *addr,
+ socklen_t addr_len);
+typedef void (*set_socket_thread_owner_v1_t)(struct PSI_socket *socket);
+typedef struct PSI_digest_locker * (*digest_start_v1_t)
+ (struct PSI_statement_locker *locker);
+typedef struct PSI_digest_locker* (*digest_add_token_v1_t)
+ (struct PSI_digest_locker *locker, uint token, struct OPAQUE_LEX_YYSTYPE *yylval);
+typedef int (*set_thread_connect_attrs_v1_t)(const char *buffer, uint length,
+ const void *from_cs);
+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;
+ register_stage_v1_t register_stage;
+ register_statement_v1_t register_statement;
+ register_socket_v1_t register_socket;
+ 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;
+ init_socket_v1_t init_socket;
+ destroy_socket_v1_t destroy_socket;
+ get_table_share_v1_t get_table_share;
+ release_table_share_v1_t release_table_share;
+ drop_table_share_v1_t drop_table_share;
+ open_table_v1_t open_table;
+ unbind_table_v1_t unbind_table;
+ rebind_table_v1_t rebind_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_user_v1_t set_thread_user;
+ set_thread_user_host_v1_t set_thread_user_host;
+ set_thread_db_v1_t set_thread_db;
+ set_thread_command_v1_t set_thread_command;
+ set_thread_start_time_v1_t set_thread_start_time;
+ set_thread_state_v1_t set_thread_state;
+ set_thread_info_v1_t set_thread_info;
+ set_thread_v1_t set_thread;
+ delete_current_thread_v1_t delete_current_thread;
+ delete_thread_v1_t delete_thread;
+ 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_idle_wait_v1_t start_idle_wait;
+ end_idle_wait_v1_t end_idle_wait;
+ 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_io_wait_v1_t start_table_io_wait;
+ end_table_io_wait_v1_t end_table_io_wait;
+ start_table_lock_wait_v1_t start_table_lock_wait;
+ end_table_lock_wait_v1_t end_table_lock_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;
+ start_file_close_wait_v1_t start_file_close_wait;
+ end_file_close_wait_v1_t end_file_close_wait;
+ start_stage_v1_t start_stage;
+ end_stage_v1_t end_stage;
+ get_thread_statement_locker_v1_t get_thread_statement_locker;
+ refine_statement_v1_t refine_statement;
+ start_statement_v1_t start_statement;
+ set_statement_text_v1_t set_statement_text;
+ set_statement_lock_time_t set_statement_lock_time;
+ set_statement_rows_sent_t set_statement_rows_sent;
+ set_statement_rows_examined_t set_statement_rows_examined;
+ inc_statement_created_tmp_disk_tables_t inc_statement_created_tmp_disk_tables;
+ inc_statement_created_tmp_tables_t inc_statement_created_tmp_tables;
+ inc_statement_select_full_join_t inc_statement_select_full_join;
+ inc_statement_select_full_range_join_t inc_statement_select_full_range_join;
+ inc_statement_select_range_t inc_statement_select_range;
+ inc_statement_select_range_check_t inc_statement_select_range_check;
+ inc_statement_select_scan_t inc_statement_select_scan;
+ inc_statement_sort_merge_passes_t inc_statement_sort_merge_passes;
+ inc_statement_sort_range_t inc_statement_sort_range;
+ inc_statement_sort_rows_t inc_statement_sort_rows;
+ inc_statement_sort_scan_t inc_statement_sort_scan;
+ set_statement_no_index_used_t set_statement_no_index_used;
+ set_statement_no_good_index_used_t set_statement_no_good_index_used;
+ end_statement_v1_t end_statement;
+ start_socket_wait_v1_t start_socket_wait;
+ end_socket_wait_v1_t end_socket_wait;
+ set_socket_state_v1_t set_socket_state;
+ set_socket_info_v1_t set_socket_info;
+ set_socket_thread_owner_v1_t set_socket_thread_owner;
+ digest_start_v1_t digest_start;
+ digest_add_token_v1_t digest_add_token;
+ set_thread_connect_attrs_v1_t set_thread_connect_attrs;
+};
+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;
+typedef struct PSI_stage_info_v1 PSI_stage_info;
+typedef struct PSI_statement_info_v1 PSI_statement_info;
+typedef struct PSI_socket_info_v1 PSI_socket_info;
+typedef struct PSI_idle_locker_state_v1 PSI_idle_locker_state;
+typedef struct PSI_mutex_locker_state_v1 PSI_mutex_locker_state;
+typedef struct PSI_rwlock_locker_state_v1 PSI_rwlock_locker_state;
+typedef struct PSI_cond_locker_state_v1 PSI_cond_locker_state;
+typedef struct PSI_file_locker_state_v1 PSI_file_locker_state;
+typedef struct PSI_table_locker_state_v1 PSI_table_locker_state;
+typedef struct PSI_statement_locker_state_v1 PSI_statement_locker_state;
+typedef struct PSI_socket_locker_state_v1 PSI_socket_locker_state;
+extern MYSQL_PLUGIN_IMPORT PSI *PSI_server;
+C_MODE_END
diff --git a/include/mysql/psi/psi_abi_v2.h b/include/mysql/psi/psi_abi_v2.h
new file mode 100644
index 00000000000..08bca609b41
--- /dev/null
+++ b/include/mysql/psi/psi_abi_v2.h
@@ -0,0 +1,26 @@
+/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
+
+ 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,
+ 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
+
+/**
+ @file mysql/psi/psi_abi_v1.h
+ ABI check for mysql/psi/psi.h, when using PSI_VERSION_2.
+ This file is only used to automate detection of changes between versions.
+ Do not include this file, include mysql/psi/psi.h instead.
+*/
+#define USE_PSI_2
+#define HAVE_PSI_INTERFACE
+#define _global_h
+#include "mysql/psi/psi.h"
+
diff --git a/include/mysql/psi/psi_abi_v2.h.pp b/include/mysql/psi/psi_abi_v2.h.pp
new file mode 100644
index 00000000000..458013b43e4
--- /dev/null
+++ b/include/mysql/psi/psi_abi_v2.h.pp
@@ -0,0 +1,214 @@
+#include "mysql/psi/psi.h"
+C_MODE_START
+struct TABLE_SHARE;
+struct OPAQUE_LEX_YYSTYPE;
+struct PSI_mutex;
+typedef struct PSI_mutex PSI_mutex;
+struct PSI_rwlock;
+typedef struct PSI_rwlock PSI_rwlock;
+struct PSI_cond;
+typedef struct PSI_cond PSI_cond;
+struct PSI_table_share;
+typedef struct PSI_table_share PSI_table_share;
+struct PSI_table;
+typedef struct PSI_table PSI_table;
+struct PSI_thread;
+typedef struct PSI_thread PSI_thread;
+struct PSI_file;
+typedef struct PSI_file PSI_file;
+struct PSI_socket;
+typedef struct PSI_socket PSI_socket;
+struct PSI_table_locker;
+typedef struct PSI_table_locker PSI_table_locker;
+struct PSI_statement_locker;
+typedef struct PSI_statement_locker PSI_statement_locker;
+struct PSI_idle_locker;
+typedef struct PSI_idle_locker PSI_idle_locker;
+struct PSI_digest_locker;
+typedef struct PSI_digest_locker PSI_digest_locker;
+struct PSI_bootstrap
+{
+ void* (*get_interface)(int version);
+};
+typedef struct PSI_bootstrap PSI_bootstrap;
+struct PSI_mutex_locker;
+typedef struct PSI_mutex_locker PSI_mutex_locker;
+struct PSI_rwlock_locker;
+typedef struct PSI_rwlock_locker PSI_rwlock_locker;
+struct PSI_cond_locker;
+typedef struct PSI_cond_locker PSI_cond_locker;
+struct PSI_file_locker;
+typedef struct PSI_file_locker PSI_file_locker;
+struct PSI_socket_locker;
+typedef struct PSI_socket_locker PSI_socket_locker;
+enum PSI_mutex_operation
+{
+ PSI_MUTEX_LOCK= 0,
+ PSI_MUTEX_TRYLOCK= 1
+};
+typedef enum PSI_mutex_operation PSI_mutex_operation;
+enum PSI_rwlock_operation
+{
+ PSI_RWLOCK_READLOCK= 0,
+ PSI_RWLOCK_WRITELOCK= 1,
+ PSI_RWLOCK_TRYREADLOCK= 2,
+ PSI_RWLOCK_TRYWRITELOCK= 3
+};
+typedef enum PSI_rwlock_operation PSI_rwlock_operation;
+enum PSI_cond_operation
+{
+ PSI_COND_WAIT= 0,
+ PSI_COND_TIMEDWAIT= 1
+};
+typedef enum PSI_cond_operation PSI_cond_operation;
+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
+};
+typedef enum PSI_file_operation PSI_file_operation;
+enum PSI_table_io_operation
+{
+ PSI_TABLE_FETCH_ROW= 0,
+ PSI_TABLE_WRITE_ROW= 1,
+ PSI_TABLE_UPDATE_ROW= 2,
+ PSI_TABLE_DELETE_ROW= 3
+};
+typedef enum PSI_table_io_operation PSI_table_io_operation;
+enum PSI_table_lock_operation
+{
+ PSI_TABLE_LOCK= 0,
+ PSI_TABLE_EXTERNAL_LOCK= 1
+};
+typedef enum PSI_table_lock_operation PSI_table_lock_operation;
+enum PSI_socket_state
+{
+ PSI_SOCKET_STATE_IDLE= 1,
+ PSI_SOCKET_STATE_ACTIVE= 2
+};
+typedef enum PSI_socket_state PSI_socket_state;
+enum PSI_socket_operation
+{
+ PSI_SOCKET_CREATE= 0,
+ PSI_SOCKET_CONNECT= 1,
+ PSI_SOCKET_BIND= 2,
+ PSI_SOCKET_CLOSE= 3,
+ PSI_SOCKET_SEND= 4,
+ PSI_SOCKET_RECV= 5,
+ PSI_SOCKET_SENDTO= 6,
+ PSI_SOCKET_RECVFROM= 7,
+ PSI_SOCKET_SENDMSG= 8,
+ PSI_SOCKET_RECVMSG= 9,
+ PSI_SOCKET_SEEK= 10,
+ PSI_SOCKET_OPT= 11,
+ PSI_SOCKET_STAT= 12,
+ PSI_SOCKET_SHUTDOWN= 13,
+ PSI_SOCKET_SELECT= 14
+};
+typedef enum PSI_socket_operation PSI_socket_operation;
+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;
+typedef unsigned int PSI_stage_key;
+typedef unsigned int PSI_statement_key;
+typedef unsigned int PSI_socket_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;
+};
+struct PSI_stage_info_v2
+{
+ int placeholder;
+};
+struct PSI_statement_info_v2
+{
+ int placeholder;
+};
+struct PSI_idle_locker_state_v2
+{
+ int placeholder;
+};
+struct PSI_mutex_locker_state_v2
+{
+ int placeholder;
+};
+struct PSI_rwlock_locker_state_v2
+{
+ int placeholder;
+};
+struct PSI_cond_locker_state_v2
+{
+ int placeholder;
+};
+struct PSI_file_locker_state_v2
+{
+ int placeholder;
+};
+struct PSI_table_locker_state_v2
+{
+ int placeholder;
+};
+struct PSI_statement_locker_state_v2
+{
+ int placeholder;
+};
+struct PSI_socket_locker_state_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;
+typedef struct PSI_stage_info_v2 PSI_stage_info;
+typedef struct PSI_statement_info_v2 PSI_statement_info;
+typedef struct PSI_socket_info_v2 PSI_socket_info;
+typedef struct PSI_idle_locker_state_v2 PSI_idle_locker_state;
+typedef struct PSI_mutex_locker_state_v2 PSI_mutex_locker_state;
+typedef struct PSI_rwlock_locker_state_v2 PSI_rwlock_locker_state;
+typedef struct PSI_cond_locker_state_v2 PSI_cond_locker_state;
+typedef struct PSI_file_locker_state_v2 PSI_file_locker_state;
+typedef struct PSI_table_locker_state_v2 PSI_table_locker_state;
+typedef struct PSI_statement_locker_state_v2 PSI_statement_locker_state;
+typedef struct PSI_socket_locker_state_v2 PSI_socket_locker_state;
+extern MYSQL_PLUGIN_IMPORT PSI *PSI_server;
+C_MODE_END