#At file:///home/malff/BZR-TREE/mysql-6.0-perf/
2715 Marc Alff 2008-10-22
Implemented mutex/rwlock/cond registration
Drafted configure options
Drafted command line options
added:
storage/perfschema/psm_global.cc
storage/perfschema/psm_global.h
storage/perfschema/psm_sync.cc
storage/perfschema/psm_sync.h
storage/perfschema/psm_sync_info.cc
storage/perfschema/psm_sync_info.h
modified:
include/mysql/mysql_mutex.h
include/mysql/psi.h
include/mysql/psi_abi_v1.h.pp
sql/mysqld.cc
storage/perfschema/Makefile.am
storage/perfschema/plug.in
storage/perfschema/psm.cc
storage/perfschema/psm.h
storage/perfschema/psm_server.cc
storage/perfschema/psm_server.h
=== modified file 'include/mysql/mysql_mutex.h'
--- a/include/mysql/mysql_mutex.h 2008-10-17 17:51:19 +0000
+++ b/include/mysql/mysql_mutex.h 2008-10-22 22:21:54 +0000
@@ -109,7 +109,7 @@ static inline int mysql_mutex_destroy(
{
#ifdef HAVE_PSI_INTERFACE
if (PSI_server && that->m_psi)
- PSI_server->destroy_mutex(that->m_psi, & that->m_mutex);
+ PSI_server->destroy_mutex(that->m_psi);
#endif
#ifdef SAFE_MUTEX
return safe_mutex_destroy(& that->m_mutex, file, line);
@@ -195,8 +195,8 @@ static inline int mysql_rwlock_destroy(
mysql_rwlock_t *that)
{
#ifdef HAVE_PSI_INTERFACE
- if (PSI_server)
- PSI_server->destroy_rwlock(that->m_psi, & that->m_rwlock);
+ if (PSI_server && that->m_psi)
+ PSI_server->destroy_rwlock(that->m_psi);
#endif
return rwlock_destroy(& that->m_rwlock);
}
@@ -314,8 +314,8 @@ static inline int mysql_cond_destroy(
mysql_cond_t *that)
{
#ifdef HAVE_PSI_INTERFACE
- if (PSI_server)
- PSI_server->destroy_cond(that->m_psi, & that->m_cond);
+ if (PSI_server && that->m_psi)
+ PSI_server->destroy_cond(that->m_psi);
#endif
return pthread_cond_destroy(& that->m_cond);
}
=== modified file 'include/mysql/psi.h'
--- a/include/mysql/psi.h 2008-10-16 00:25:49 +0000
+++ b/include/mysql/psi.h 2008-10-22 22:21:54 +0000
@@ -75,16 +75,13 @@ struct PSI_v1
struct PSI_mutex* (*init_mutex)(PSI_mutex_key key,
void *identity);
- void (*destroy_mutex)(struct PSI_mutex *mutex,
- void *identity);
+ void (*destroy_mutex)(struct PSI_mutex *mutex);
struct PSI_rwlock* (*init_rwlock)(PSI_rwlock_key key,
void *identity);
- void (*destroy_rwlock)(struct PSI_rwlock *rwlock,
- void *identity);
+ void (*destroy_rwlock)(struct PSI_rwlock *rwlock);
struct PSI_cond* (*init_cond)(PSI_cond_key key,
void *identity);
- void (*destroy_cond)(struct PSI_cond *cond,
- void *identity);
+ void (*destroy_cond)(struct PSI_cond *cond);
struct PSI_thread* (*new_thread)();
struct PSI_thread* (*get_thread)();
=== modified file 'include/mysql/psi_abi_v1.h.pp'
--- a/include/mysql/psi_abi_v1.h.pp 2008-10-16 00:25:49 +0000
+++ b/include/mysql/psi_abi_v1.h.pp 2008-10-22 22:21:54 +0000
@@ -42,16 +42,13 @@ struct PSI_v1
int count);
struct PSI_mutex* (*init_mutex)(PSI_mutex_key key,
void *identity);
- void (*destroy_mutex)(struct PSI_mutex *mutex,
- void *identity);
+ void (*destroy_mutex)(struct PSI_mutex *mutex);
struct PSI_rwlock* (*init_rwlock)(PSI_rwlock_key key,
void *identity);
- void (*destroy_rwlock)(struct PSI_rwlock *rwlock,
- void *identity);
+ void (*destroy_rwlock)(struct PSI_rwlock *rwlock);
struct PSI_cond* (*init_cond)(PSI_cond_key key,
void *identity);
- void (*destroy_cond)(struct PSI_cond *cond,
- void *identity);
+ void (*destroy_cond)(struct PSI_cond *cond);
struct PSI_thread* (*new_thread)();
struct PSI_thread* (*get_thread)();
void (*set_thread)(struct PSI_thread *thread);
=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc 2008-10-20 20:01:39 +0000
+++ b/sql/mysqld.cc 2008-10-22 22:21:54 +0000
@@ -389,6 +389,9 @@ bool opt_large_files= sizeof(my_off_t) >
Used with --help for detailed option
*/
static my_bool opt_help= 0, opt_verbose= 0;
+#ifdef HAVE_PERFORMANCE_SCHEMA
+static my_bool opt_psm_help= 0;
+#endif
arg_cmp_func Arg_comparator::comparator_matrix[5][2] =
{{&Arg_comparator::compare_string, &Arg_comparator::compare_e_string},
@@ -4448,12 +4451,19 @@ int main(int argc, char **argv)
#endif
{
#ifdef HAVE_PERFORMANCE_SCHEMA
- /*
- In order to instrument the entire code, including mysys,
- the instrumentation hooks must be installed before executing
- the mysys initialization code (my_init())
- */
- PSI_hook= initialize_performance_schema(argc, argv);
+ {
+ int argc_input;
+ char **argv_input;
+ /*
+ In order to instrument the entire code, including mysys,
+ the instrumentation hooks must be installed before executing
+ the mysys initialization code (my_init())
+ */
+ argc_input= argc;
+ argv_input= argv;
+ PSI_hook= initialize_performance_schema(argc_input, argv_input,
+ & argc, & argv);
+ }
#endif
#ifdef HAVE_PSI_INTERFACE
@@ -5884,6 +5894,11 @@ enum options_mysqld
struct my_option my_long_options[] =
{
+#ifdef HAVE_PERFORMANCE_SCHEMA
+ {"psm-help", 0, "Display the performance schema help and exit.",
+ (uchar**) &opt_psm_help, (uchar**) &opt_psm_help, 0, GET_BOOL, NO_ARG,
+ 0, 0, 0, 0, 0, 0},
+#endif
{"help", '?', "Display this help and exit.",
(uchar**) &opt_help, (uchar**) &opt_help, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0,
0, 0},
@@ -7776,6 +7791,12 @@ Starts the MySQL database server\n");
/* Print out all the options including plugin supplied options */
my_print_help_inc_plugins(my_long_options, sizeof(my_long_options)/sizeof(my_option));
+#ifdef HAVE_PERFORMANCE_SCHEMA
+ puts("\n\
+To see the help for the performance schema instrumentation, type\n\
+'mysqld --psm-help'.");
+#endif
+
puts("\n\
To see what values a running MySQL server is using, type\n\
'mysqladmin variables' instead of 'mysqld --verbose --help'.");
=== modified file 'storage/perfschema/Makefile.am'
--- a/storage/perfschema/Makefile.am 2008-10-10 20:34:55 +0000
+++ b/storage/perfschema/Makefile.am 2008-10-22 22:21:54 +0000
@@ -32,9 +32,11 @@ DEFS = -DMYSQL_SERVER @
SUBDIRS = . unittest
-noinst_HEADERS = ha_perfschema.h pse_metadata.h psm.h psm_server.h
+noinst_HEADERS = ha_perfschema.h pse_metadata.h psm.h psm_server.h \
+ psm_global.h psm_sync_info.h psm_sync.h
-PSE_SOURCES = ha_perfschema.cc pse_metadata.cc psm.cc psm_server.cc
+PSE_SOURCES = ha_perfschema.cc pse_metadata.cc psm.cc psm_server.cc \
+ psm_global.cc psm_sync_info.cc psm_sync.cc
EXTRA_LIBRARIES = libperfschema.a
noinst_LIBRARIES = @plugin_perfschema_static_target@
=== modified file 'storage/perfschema/plug.in'
--- a/storage/perfschema/plug.in 2008-10-10 20:34:55 +0000
+++ b/storage/perfschema/plug.in 2008-10-22 22:21:54 +0000
@@ -1,11 +1,154 @@
-MYSQL_STORAGE_ENGINE(perfschema, perfschema, [Performance Schema],
- [Performance Schema], [max,max-no-ndb])
+dnl -*- ksh -*-
+dnl This file is part of the configure scripts used by autoconf.
+
+MYSQL_STORAGE_ENGINE(perfschema,
+ perfschema,
+ [Performance Schema],
+ [Performance Schema],
+ [max,max-no-ndb])
MYSQL_PLUGIN_DIRECTORY(perfschema, [storage/perfschema])
-MYSQL_PLUGIN_STATIC(perfschema, [libperfschema.a])
+MYSQL_PLUGIN_STATIC(perfschema, [libperfschema.a])
+
+MYSQL_PLUGIN_ACTIONS(perfschema, [
+
+dnl -------------------------------------------------------------------------
+dnl HAVE_PERFORMANCE_SCHEMA
+dnl -------------------------------------------------------------------------
-MYSQL_PLUGIN_ACTIONS(perfschema, [
-AC_CONFIG_FILES(storage/perfschema/unittest/Makefile)
AC_DEFINE([HAVE_PERFORMANCE_SCHEMA], [1],
[Performance schema implementation])
+
+dnl -------------------------------------------------------------------------
+dnl PSM_MAX_SYNC_INFO
+dnl -------------------------------------------------------------------------
+
+AC_ARG_WITH(
+ [psm-max-sync-info],
+ AS_HELP_STRING(
+ [--with-psm-max-sync-info=N],
+ [Performance Schema: maximum number of sync info objects.]),
+ [psm_max_sync_info="$withval"],
+ [psm_max_sync_info="0"]
+)
+
+AC_MSG_CHECKING([psm max sync info])
+
+if test "$psm_max_sync_info" != "0"
+then
+ AC_DEFINE_UNQUOTED(
+ [PSM_MAX_SYNC_INFO],
+ [$psm_max_sync_info],
+ [Performance Schema: Maximum number of sync info objects.])
+fi
+
+AC_MSG_RESULT([$psm_max_sync_info])
+
+dnl -------------------------------------------------------------------------
+dnl PSM_MAX_MUTEX
+dnl -------------------------------------------------------------------------
+
+AC_ARG_WITH(
+ [psm-max-mutex],
+ AS_HELP_STRING(
+ [--with-psm-max-mutex=N],
+ [Performance Schema: maximum number of instrumented MUTEX.]),
+ [psm_max_mutex="$withval"],
+ [psm_max_mutex="0"]
+)
+
+AC_MSG_CHECKING([psm max mutex])
+
+if test "$psm_max_mutex" != "0"
+then
+ AC_DEFINE_UNQUOTED(
+ [PSM_MAX_MUTEX],
+ [$psm_max_mutex],
+ [Performance Schema: Maximum number of instrumented MUTEX.])
+fi
+
+AC_MSG_RESULT([$psm_max_mutex])
+
+dnl -------------------------------------------------------------------------
+dnl PSM_MAX_RWLOCK
+dnl -------------------------------------------------------------------------
+
+AC_ARG_WITH(
+ [psm-max-rwlock],
+ AS_HELP_STRING(
+ [--with-psm-max-rwlock=N],
+ [Performance Schema: maximum number of instrumented RWLOCK.]),
+ [psm_max_rwlock="$withval"],
+ [psm_max_rwlock="0"]
+)
+
+AC_MSG_CHECKING([psm max rwlock])
+
+if test "$psm_max_rwlock" != "0"
+then
+ AC_DEFINE_UNQUOTED(
+ [PSM_MAX_RWLOCK],
+ [$psm_max_rwlock],
+ [Performance Schema: Maximum number of instrumented RWLOCK.])
+fi
+
+AC_MSG_RESULT([$psm_max_rwlock])
+
+dnl -------------------------------------------------------------------------
+dnl PSM_MAX_COND
+dnl -------------------------------------------------------------------------
+
+AC_ARG_WITH(
+ [psm-max-cond],
+ AS_HELP_STRING(
+ [--with-psm-max-cond=N],
+ [Performance Schema: maximum number of instrumented COND.]),
+ [psm_max_cond="$withval"],
+ [psm_max_cond="0"]
+)
+
+AC_MSG_CHECKING([psm max cond])
+
+if test "$psm_max_cond" != "0"
+then
+ AC_DEFINE_UNQUOTED(
+ [PSM_MAX_COND],
+ [$psm_max_cond],
+ [Performance Schema: Maximum number of instrumented COND.])
+fi
+
+AC_MSG_RESULT([$psm_max_cond])
+
+dnl -------------------------------------------------------------------------
+dnl PSM_MAX_THREAD
+dnl -------------------------------------------------------------------------
+
+AC_ARG_WITH(
+ [psm-max-thread],
+ AS_HELP_STRING(
+ [--with-psm-max-thread=N],
+ [Performance Schema: maximum number of instrumented threads.]),
+ [psm_max_thread="$withval"],
+ [psm_max_thread="0"]
+)
+
+AC_MSG_CHECKING([psm max thread])
+
+if test "$psm_max_thread" != "0"
+then
+ AC_DEFINE_UNQUOTED(
+ [PSM_MAX_THREAD],
+ [$psm_max_thread],
+ [Performance Schema: Maximum number of instrumented threads.])
+fi
+
+AC_MSG_RESULT([$psm_max_thread])
+
+dnl -------------------------------------------------------------------------
+dnl Configuration files
+dnl -------------------------------------------------------------------------
+
+AC_CONFIG_FILES(storage/perfschema/unittest/Makefile)
+
])
+
=== modified file 'storage/perfschema/psm.cc'
--- a/storage/perfschema/psm.cc 2008-10-16 00:25:49 +0000
+++ b/storage/perfschema/psm.cc 2008-10-22 22:21:54 +0000
@@ -1,5 +1,7 @@
#include "psm.h"
+#include "psm_sync_info.h"
+#include "psm_sync.h"
pthread_key(PSM_thread*, THR_PSM);
@@ -7,6 +9,16 @@ static void register_mutex_v1(const char
struct PSI_mutex_info_v1 *info,
int count)
{
+ DBUG_ASSERT(category != NULL);
+ PSM_sync_key key;
+
+ for (; count>0; count--, info++)
+ {
+ DBUG_ASSERT(info->m_key != NULL);
+ DBUG_ASSERT(info->m_name != NULL);
+ key= register_sync_info(SYNC_MUTEX, category, info->m_name, info->m_flags);
+ *(info->m_key)= (PSI_mutex_key) key;
+ }
return;
}
@@ -14,6 +26,15 @@ static void register_rwlock_v1(const cha
struct PSI_rwlock_info_v1 *info,
int count)
{
+ DBUG_ASSERT(category != NULL);
+ PSM_sync_key key;
+
+ for (; count>0; count--, info++)
+ {
+ DBUG_ASSERT(info->m_key != NULL);
+ key= register_sync_info(SYNC_RWLOCK, category, info->m_name, info->m_flags);
+ *(info->m_key)= (PSI_rwlock_key) key;
+ }
return;
}
@@ -21,40 +42,76 @@ static void register_cond_v1(const char*
struct PSI_cond_info_v1 *info,
int count)
{
+ DBUG_ASSERT(category != NULL);
+ PSM_sync_key key;
+
+ for (; count>0; count--, info++)
+ {
+ DBUG_ASSERT(info->m_key != NULL);
+ key= register_sync_info(SYNC_COND, category, info->m_name, info->m_flags);
+ *(info->m_key)= (PSI_cond_key) key;
+ }
return;
}
static PSI_mutex* init_mutex_v1(PSI_mutex_key key, void *identity)
{
- static PSM_mutex dummy;
- PSM_mutex *psm= & dummy;
+ PSM_sync_info *info;
+ PSM_mutex *psm;
+
+ info= find_sync_info(key);
+ if (info)
+ psm= create_mutex(info, identity);
+ else
+ psm = NULL;
+
return (PSI_mutex*) psm;
}
-static void destroy_mutex_v1(PSI_mutex* mutex, void *identity)
+static void destroy_mutex_v1(PSI_mutex* mutex)
{
+ PSM_mutex *psm= (PSM_mutex*) mutex;
+ destroy_mutex(psm);
}
static PSI_rwlock* init_rwlock_v1(PSI_rwlock_key key, void *identity)
{
- static PSM_rwlock dummy;
- PSM_rwlock *psm= & dummy;
+ PSM_sync_info *info;
+ PSM_rwlock *psm;
+
+ info= find_sync_info(key);
+ if (info)
+ psm= create_rwlock(info, identity);
+ else
+ psm = NULL;
+
return (PSI_rwlock*) psm;
}
-static void destroy_rwlock_v1(PSI_rwlock* rwlock, void *identity)
+static void destroy_rwlock_v1(PSI_rwlock* rwlock)
{
+ PSM_rwlock *psm= (PSM_rwlock*) rwlock;
+ destroy_rwlock(psm);
}
static PSI_cond* init_cond_v1(PSI_cond_key key, void *identity)
{
- static PSM_cond dummy;
- PSM_cond *psm= & dummy;
+ PSM_sync_info *info;
+ PSM_cond *psm;
+
+ info= find_sync_info(key);
+ if (info)
+ psm= create_cond(info, identity);
+ else
+ psm = NULL;
+
return (PSI_cond*) psm;
}
-static void destroy_cond_v1(PSI_cond* cond, void *identity)
+static void destroy_cond_v1(PSI_cond* cond)
{
+ PSM_cond *psm= (PSM_cond*) cond;
+ destroy_cond(psm);
}
static PSI_thread* new_thread_v1()
=== modified file 'storage/perfschema/psm.h'
--- a/storage/perfschema/psm.h 2008-10-13 20:42:40 +0000
+++ b/storage/perfschema/psm.h 2008-10-22 22:21:54 +0000
@@ -10,21 +10,6 @@
extern struct PSI_v1 PSM_v1;
extern struct PSI_v2 PSM_v2;
-struct PSM_mutex
-{
- int todo;
-};
-
-struct PSM_rwlock
-{
- int todo;
-};
-
-struct PSM_cond
-{
- int todo;
-};
-
struct PSM_thread
{
int todo;
=== added file 'storage/perfschema/psm_global.cc'
--- a/storage/perfschema/psm_global.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/psm_global.cc 2008-10-22 22:21:54 +0000
@@ -0,0 +1,31 @@
+
+#include "my_global.h"
+#include "my_sys.h"
+#include "psm_global.h"
+
+#include <malloc.h>
+#include <string.h>
+
+int psm_initialized= 0;
+
+/**
+ Memory allocation for the performance schema.
+ The memory used internally in the performance schema implementation
+ is allocated once during startup, and considered static therafter.
+*/
+void *psm_malloc(size_t size, myf flags)
+{
+ DBUG_ASSERT(! psm_initialized);
+
+ void *ptr= malloc(size);
+ if (ptr && (flags & MY_ZEROFILL))
+ memset(ptr, 0, size);
+ return ptr;
+}
+
+void psm_free(void *ptr)
+{
+ if (ptr)
+ free(ptr);
+}
+
=== added file 'storage/perfschema/psm_global.h'
--- a/storage/perfschema/psm_global.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/psm_global.h 2008-10-22 22:21:54 +0000
@@ -0,0 +1,12 @@
+
+#ifndef PSM_GLOBAL_H
+#define PSM_GLOBAL_H
+
+extern int psm_initialized;
+
+void *psm_malloc(size_t size, myf flags);
+#define PSM_MALLOC_ARRAY(n,T,f) (T*) psm_malloc((n) * sizeof(T), (f))
+void psm_free(void *ptr);
+
+#endif
+
=== modified file 'storage/perfschema/psm_server.cc'
--- a/storage/perfschema/psm_server.cc 2008-10-14 01:55:03 +0000
+++ b/storage/perfschema/psm_server.cc 2008-10-22 22:21:54 +0000
@@ -1,13 +1,312 @@
+#include "my_global.h"
+#include "my_sys.h"
+#include "mysys_err.h"
#include "psm_server.h"
#include "psm.h"
+#include "psm_global.h"
+#include "psm_sync_info.h"
+#include "psm_sync.h"
+
+enum psm_option_type
+{
+ OPTION_FUNC,
+ OPTION_BOOL,
+ OPTION_UINT
+};
+
+struct psm_option
+{
+ const char* m_name;
+ const char* m_help;
+ psm_option_type m_type;
+ uint *m_value;
+ void (*m_fct)();
+};
+
+static void psm_help();
+
+#ifdef PSM_MAX_SYNC_INFO
+static uint sync_info_sizing= PSM_MAX_SYNC_INFO;
+#else
+static uint sync_info_sizing= 1000;
+#endif
+
+#ifdef PSM_MAX_MUTEX
+static uint mutex_sizing= PSM_MAX_MUTEX;
+#else
+static uint mutex_sizing= 1000;
+#endif
+
+#ifdef PSM_MAX_RWLOCK
+static uint rwlock_sizing= PSM_MAX_RWLOCK;
+#else
+static uint rwlock_sizing= 1000;
+#endif
+
+#ifdef PSM_MAX_COND
+static uint cond_sizing= PSM_MAX_COND;
+#else
+static uint cond_sizing= 1000;
+#endif
+
+#ifdef PSM_MAX_THREAD
+static uint thread_sizing= PSM_MAX_THREAD;
+#else
+static uint thread_sizing= 1000;
+#endif
+
+int argc_filtered= 0;
+char ** argv_filtered= NULL;
+
+struct psm_option all_psm_options[] =
+{
+ {
+ "--psm-help",
+ "Displays the performance schema command line options help.",
+ OPTION_FUNC,
+ NULL,
+ psm_help
+ },
+ {
+ "--psm-max-sync-info",
+ "Maximum number of sync info objects.",
+ OPTION_UINT,
+ & sync_info_sizing,
+ NULL
+ },
+ {
+ "--psm-max-mutex",
+ "Maximum number of instrumented MUTEX.",
+ OPTION_UINT,
+ & mutex_sizing,
+ NULL
+ },
+ {
+ "--psm-max-rwlock",
+ "Maximum number of instrumented RWLOCK.",
+ OPTION_UINT,
+ & rwlock_sizing,
+ NULL
+ },
+ {
+ "--psm-max-cond",
+ "Maximum number of instrumented COND.",
+ OPTION_UINT,
+ & cond_sizing,
+ NULL
+ },
+ {
+ "--psm-max-thread",
+ "Maximum number of instrumented threads.",
+ OPTION_UINT,
+ & thread_sizing,
+ NULL
+ },
+ { NULL, NULL, OPTION_FUNC, NULL, NULL}
+};
+
+void print_help(FILE *where)
+{
+ psm_option *option;
+
+ fprintf(where, "\n"
+"Performance schema specific options.\n"
+"====================================\n");
+
+ for (option= &all_psm_options[0]; option->m_name != NULL; option++)
+ {
+ fprintf(where, "\n%s", option->m_name);
+ switch (option->m_type) {
+ case OPTION_FUNC: fprintf(where, "\n"); break;
+ case OPTION_BOOL: fprintf(where, "={true|false}\n"); break;
+ case OPTION_UINT: fprintf(where, "=<number>\n"); break;
+ default: DBUG_ASSERT(FALSE);
+ }
+ fprintf(where, " %s\n", option->m_help);
+ }
+}
+
+void psm_help()
+{
+ print_help(stdout);
+ exit(0);
+}
+
+void psm_usage()
+{
+ fprintf(stderr, "Usage: %s [OPTIONS] [PERFORMANCE SCHEMA OPTIONS]\n",
+ argv_filtered[0]);
+
+ print_help(stderr);
+}
+
+psm_option *find_option(const char* name, const char ** param_position)
+{
+ int name_len;
+ int option_len;
+ psm_option *option;
+
+ name_len=strlen(name);
+ for (option= &all_psm_options[0]; option->m_name != NULL; option++)
+ {
+ option_len= strlen(option->m_name);
+
+ if (name_len == option_len)
+ {
+ if (strcasecmp(name, option->m_name) == 0)
+ {
+ *param_position= NULL;
+ return option;
+ }
+ }
+
+ if (name_len > option_len+1)
+ {
+ if ((strncasecmp(name, option->m_name, option_len) == 0) &&
+ (name[option_len] == '='))
+ {
+ *param_position= & name[option_len+1];
+ return option;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+int process_option(psm_option *option, const char *param_position)
+{
+ DBUG_ASSERT(option);
+ DBUG_ASSERT(option->m_type);
+ DBUG_ASSERT(option->m_value);
+ DBUG_ASSERT(param_position);
+
+ switch (option->m_type) {
+ case OPTION_BOOL:
+ {
+ if (strcasecmp(param_position, "true") == 0)
+ *(option->m_value)= 1;
+ else
+ *(option->m_value)= 0;
+ break;
+ }
+ case OPTION_UINT:
+ {
+ *(option->m_value)= atoi(param_position);
+ break;
+ }
+ case OPTION_FUNC:
+ default:
+ DBUG_ASSERT(FALSE);
+ }
+ return 0;
+}
+
+void parse_args(int argc_input, char ** argv_input,
+ int *argc_output, char *** argv_output)
+{
+ DBUG_ASSERT(argc_input >= 1);
+ DBUG_ASSERT(argv_input[0] != NULL);
+
+ argc_filtered= 0;
+ argv_filtered= PSM_MALLOC_ARRAY(argc_input, char*, 0);
+ if (argv_filtered == NULL)
+ exit(EXIT_OUT_OF_MEMORY);
+
+ /* Passing the program name to the next layer. */
+ argv_filtered[argc_filtered]= argv_input[0];
+ argc_filtered++;
+ argc_input--;
+ argv_input++;
+
+ while (argc_input>0)
+ {
+ if (strncasecmp(argv_input[0], "--psm-", 6) == 0)
+ {
+ /* Performance schema option. */
+ psm_option *option;
+ const char *param_position;
+
+ option= find_option(argv_input[0], & param_position);
+ if (option == NULL)
+ {
+ fprintf(stderr,
+ "Unknown performance schema option <%s>\n",
+ argv_input[0]);
+ psm_usage();
+ exit(EXIT_UNKNOWN_OPTION);
+ }
+
+ if (option->m_type == OPTION_FUNC)
+ {
+ /* Accept this '--psm-xxx' option and filter it. */
+ argc_input--;
+ argv_input++;
+ option->m_fct();
+ continue;
+ }
+
+ if (param_position == NULL)
+ {
+ /* Expecting '--psm-xxx' 'value'. */
+ /* Accept and filter '--psm-xxx'. */
+ argc_input--;
+ argv_input++;
+
+ if (argc_input>0)
+ {
+ /* Accept and filter <value>. */
+ param_position= argv_input[0];
+ argc_input--;
+ argv_input++;
+ }
+ else
+ {
+ fprintf(stderr,
+ "Missing argument for performance schema option <%s>\n",
+ option->m_name);
+ psm_usage();
+ exit(EXIT_ARGUMENT_REQUIRED);
+ }
+ }
+ else
+ {
+ /* Accept and filter '--psm-xxx=<value>'. */
+ argc_input--;
+ argv_input++;
+ }
+
+ if (process_option(option, param_position))
+ {
+ fprintf(stderr,
+ "Invalid argument <%s> for performance schema option <%s>\n",
+ param_position,
+ option->m_name);
+ psm_usage();
+ exit(EXIT_ARGUMENT_INVALID);
+ }
+ }
+ else
+ {
+ /* Not a --psm option, passing it to the next layer. */
+ argv_filtered[argc_filtered]= argv_input[0];
+ argc_filtered++;
+ argc_input--;
+ argv_input++;
+ }
+ }
+
+ *argc_output= argc_filtered;
+ *argv_output= argv_filtered;
+}
void* get_PSM(int version)
{
- switch(version) {
+ switch (version) {
case PSI_VERSION_1: return & PSM_v1;
case PSI_VERSION_2: return & PSM_v2;
- default: return 0;
+ default: return NULL;
}
}
@@ -16,8 +315,19 @@ struct PSI_bootstrap PSM_boostrap=
get_PSM
};
-struct PSI_bootstrap* initialize_performance_schema(int argc, char ** argv)
+struct PSI_bootstrap*
+initialize_performance_schema(int argc_input, char ** argv_input,
+ int *argc_output, char *** argv_output)
{
+ psm_initialized= 0;
+
+ parse_args(argc_input, argv_input, argc_output, argv_output);
+
+ if (init_sync_info(sync_info_sizing) ||
+ init_sync(mutex_sizing, rwlock_sizing, cond_sizing))
+ return NULL;
+
+ psm_initialized= 1;
return & PSM_boostrap;
}
@@ -31,5 +341,6 @@ int initialize_performance_schema_pthrea
void shutdown_performance_schema()
{
+ cleanup_sync_info();
}
=== modified file 'storage/perfschema/psm_server.h'
--- a/storage/perfschema/psm_server.h 2008-10-14 01:55:03 +0000
+++ b/storage/perfschema/psm_server.h 2008-10-22 22:21:54 +0000
@@ -3,9 +3,11 @@
#define PSM_SERVER_H
struct PSI_bootstrap*
-initialize_performance_schema(int argc, char ** argv);
+initialize_performance_schema(int argc_input, char ** argv_input,
+ int * argc_output, char *** argv_output);
int initialize_performance_schema_pthread();
+
void shutdown_performance_schema();
#endif
=== added file 'storage/perfschema/psm_sync.cc'
--- a/storage/perfschema/psm_sync.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/psm_sync.cc 2008-10-22 22:21:54 +0000
@@ -0,0 +1,76 @@
+
+#include "my_global.h"
+#include "my_sys.h"
+#include "psm_sync.h"
+#include "psm_global.h"
+
+static uint mutex_max;
+static uint mutex_lost;
+static uint rwlock_max;
+static uint rwlock_lost;
+static uint cond_max;
+static uint cond_lost;
+
+static PSM_mutex *mutex_array= NULL;
+static PSM_rwlock *rwlock_array= NULL;
+static PSM_cond *cond_array= NULL;
+
+int init_sync(uint mutex_sizing, uint rwlock_sizing, uint cond_sizing)
+{
+ mutex_max= mutex_sizing;
+ mutex_lost= 0;
+ rwlock_max= rwlock_sizing;
+ rwlock_lost= 0;
+ cond_max= cond_sizing;
+ cond_lost= 0;
+
+ mutex_array= PSM_MALLOC_ARRAY(mutex_max, PSM_mutex, MYF(MY_ZEROFILL));
+ rwlock_array= PSM_MALLOC_ARRAY(rwlock_max, PSM_rwlock, MYF(MY_ZEROFILL));
+ cond_array= PSM_MALLOC_ARRAY(cond_max, PSM_cond, MYF(MY_ZEROFILL));
+
+ return ((mutex_array && rwlock_array && cond_array) ? 0 : 1);
+}
+
+void cleanup_sync()
+{
+ psm_free(mutex_array);
+ mutex_array= NULL;
+ psm_free(rwlock_array);
+ rwlock_array= NULL;
+ psm_free(cond_array);
+ cond_array= NULL;
+}
+
+PSM_mutex* create_mutex(PSM_sync_info *info, void *identity)
+{
+ mutex_lost++;
+ return NULL;
+}
+
+void destroy_mutex(PSM_mutex *psm)
+{
+ DBUG_ASSERT(psm != NULL);
+}
+
+PSM_rwlock* create_rwlock(PSM_sync_info *info, void *identity)
+{
+ rwlock_lost++;
+ return NULL;
+}
+
+void destroy_rwlock(PSM_rwlock *psm)
+{
+ DBUG_ASSERT(psm != NULL);
+}
+
+PSM_cond* create_cond(PSM_sync_info *info, void *identity)
+{
+ cond_lost++;
+ return NULL;
+}
+
+void destroy_cond(PSM_cond *psm)
+{
+ DBUG_ASSERT(psm != NULL);
+}
+
=== added file 'storage/perfschema/psm_sync.h'
--- a/storage/perfschema/psm_sync.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/psm_sync.h 2008-10-22 22:21:54 +0000
@@ -0,0 +1,68 @@
+
+#ifndef PSM_SYNC_H
+#define PSM_SYNC_H
+
+#include "psm_sync_info.h"
+
+struct PSM_thread;
+
+struct PSM_mutex_stat
+{
+ int m_lock_count;
+ int m_unlock_count;
+};
+
+struct PSM_mutex
+{
+ bool m_allocated;
+ void *m_identity;
+ PSM_sync_info *m_info;
+ PSM_mutex_stat m_stat;
+ PSM_thread *m_owner;
+};
+
+struct PSM_rwlock_stat
+{
+ int m_read_count;
+ int m_write_count;
+ int m_unlock_count;
+};
+
+struct PSM_rwlock
+{
+ bool m_allocated;
+ void *m_identity;
+ PSM_sync_info *m_info;
+ PSM_rwlock_stat m_stat;
+ PSM_thread *m_writer;
+};
+
+struct PSM_cond_stat
+{
+ int m_wait_count;
+ int m_signal_count;
+ int m_broadcast_count;
+};
+
+struct PSM_cond
+{
+ bool m_allocated;
+ void *m_identity;
+ PSM_sync_info *m_info;
+ PSM_cond_stat m_stat;
+};
+
+int init_sync(uint mutex_sizing, uint rwlock_sizing, uint cond_sizing);
+void cleanup_sync();
+
+PSM_mutex* create_mutex(PSM_sync_info *info, void *identity);
+void destroy_mutex(PSM_mutex *psm);
+
+PSM_rwlock* create_rwlock(PSM_sync_info *info, void *identity);
+void destroy_rwlock(PSM_rwlock *psm);
+
+PSM_cond* create_cond(PSM_sync_info *info, void *identity);
+void destroy_cond(PSM_cond *psm);
+
+#endif
+
=== added file 'storage/perfschema/psm_sync_info.cc'
--- a/storage/perfschema/psm_sync_info.cc 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/psm_sync_info.cc 2008-10-22 22:21:54 +0000
@@ -0,0 +1,113 @@
+
+#include "my_global.h"
+#include "my_sys.h"
+#include "psm_sync_info.h"
+#include "psm_global.h"
+#include "mysql/mysql_mutex.h"
+
+#include <string.h>
+
+/**
+ Current number or elements in sync_info_array.
+ This global variable is written to during:
+ - the performance schema initialization
+ - a plugin initialization
+*/
+static uint sync_info_count;
+
+/**
+ Maximum nember of elements in sync_info_array.
+ This global variable is written to during:
+ - the performance schema initialization,
+ and is constant afterwards.
+*/
+static uint sync_info_max;
+
+/**
+ Number of elements the code failed to record in sync_info_array.
+ Normally, this variable should be 0.
+*/
+static uint sync_info_lost;
+
+static PSM_sync_info *sync_info_array= NULL;
+
+int init_sync_info(uint sync_info_sizing)
+{
+ sync_info_count= 0;
+ sync_info_max= sync_info_sizing;
+ sync_info_lost= 0;
+
+ sync_info_array= PSM_MALLOC_ARRAY(sync_info_max, PSM_sync_info, 0);
+
+ return (sync_info_array ? 0 : 1);
+}
+
+void cleanup_sync_info()
+{
+ psm_free(sync_info_array);
+ sync_info_array= NULL;
+}
+
+PSM_sync_key register_sync_info(PSM_sync_type sync_type,
+ const char* category,
+ const char* name,
+ int flags)
+{
+ int index;
+ PSM_sync_info *entry;
+
+#ifndef DBUG_OFF
+ {
+ extern int mysqld_server_started;
+ extern mysql_mutex_t LOCK_plugin;
+
+ /*
+ Make sure register_sync_info() is safe to execute:
+ - either the server is not started yet, the thread running main() is
+ performing registration for the server,
+ - or the server is started, and a plug-in is performing it's own
+ registration. In this case, we are protected by the LOCK_plugin mutex.
+ */
+ if (mysqld_server_started)
+ {
+ MYSQL_MUTEX_ASSERT_OWNER(& LOCK_plugin);
+ }
+ }
+#endif
+
+ for (index= 0; index < sync_info_count; index++)
+ {
+ entry= & sync_info_array[index];
+
+ if ((entry->m_type == sync_type) &&
+ (strncmp(entry->m_category, category, CATEGORY_LENGTH) == 0) &&
+ (strncmp(entry->m_name, name, SYNC_NAME_LENGTH) == 0))
+ {
+ DBUG_ASSERT(entry->m_flags == flags);
+ return (index+1);
+ }
+ }
+
+ if (sync_info_count < sync_info_max)
+ {
+ entry= & sync_info_array[sync_info_count];
+ entry->m_type= sync_type;
+ strncpy(entry->m_category, category, CATEGORY_LENGTH);
+ strncpy(entry->m_name, name, SYNC_NAME_LENGTH);
+ entry->m_flags= flags;
+ sync_info_count++;
+ return sync_info_count;
+ }
+
+ sync_info_lost++;
+ return 0;
+}
+
+PSM_sync_info *find_sync_info(PSM_sync_key key)
+{
+ if ((key <= 0) || (key > sync_info_count))
+ return 0;
+
+ return & sync_info_array[key-1];
+}
+
=== added file 'storage/perfschema/psm_sync_info.h'
--- a/storage/perfschema/psm_sync_info.h 1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/psm_sync_info.h 2008-10-22 22:21:54 +0000
@@ -0,0 +1,39 @@
+
+#ifndef PSM_SYNC_INFO_H
+#define PSM_SYNC_INFO_H
+
+#define CATEGORY_LENGTH 12
+#define SYNC_NAME_LENGTH 64
+
+#include "mysql/psi.h"
+
+typedef int PSM_sync_key;
+
+enum PSM_sync_type
+{
+ NO_SYNC = 0,
+ SYNC_MUTEX,
+ SYNC_RWLOCK,
+ SYNC_COND
+};
+
+struct PSM_sync_info
+{
+ PSM_sync_type m_type;
+ char m_category[CATEGORY_LENGTH];
+ char m_name[SYNC_NAME_LENGTH];
+ int m_flags;
+};
+
+int init_sync_info(uint sync_info_sizing);
+void cleanup_sync_info();
+
+PSM_sync_key register_sync_info(PSM_sync_type sync_type,
+ const char* category,
+ const char* name,
+ int flags);
+
+PSM_sync_info *find_sync_info(PSM_sync_key key);
+
+#endif
+
| Thread |
|---|
| • bzr commit into mysql-6.0-perf branch (marc.alff:2715) | Marc Alff | 23 Oct |