List:Commits« Previous MessageNext Message »
From:Marc Alff Date:October 22 2008 10:22pm
Subject:bzr commit into mysql-6.0-perf branch (marc.alff:2715)
View as plain text  
#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 Alff23 Oct