List:Commits« Previous MessageNext Message »
From:Marc Alff Date:December 18 2008 9:50am
Subject:bzr commit into mysql-6.0-perf branch (marc.alff:2754)
View as plain text  
#At file:///home/malff/BZR-TREE/mysql-6.0-perf/

 2754 Marc Alff	2008-12-18
      File IO instrumentation, in progress
added:
  include/mysql/mysql_file.h
  storage/perfschema/pse_events_file.h
  storage/perfschema/table_events_file.cc
  storage/perfschema/table_events_file.h
  storage/perfschema/table_file_instances.cc
  storage/perfschema/table_file_instances.h
  storage/perfschema/table_file_usage_summary.cc
  storage/perfschema/table_file_usage_summary.h
modified:
  include/my_sys.h
  include/mysql/psi.h
  include/mysql/psi_abi_v1.h.pp
  include/mysql/psi_abi_v2.h.pp
  mysql-test/suite/perfschema/r/dml_setup_instruments.result
  mysql-test/suite/perfschema/r/information_schema.result
  mysql-test/suite/perfschema/r/schema.result
  mysql-test/suite/perfschema/r/start_server_off.result
  mysql-test/suite/perfschema/r/start_server_on.result
  mysql-test/suite/perfschema/t/schema.test
  sql/derror.cc
  sql/mysql_priv.h
  sql/mysqld.cc
  sql/table.cc
  storage/perfschema/Makefile.am
  storage/perfschema/plug.in
  storage/perfschema/pse.cc
  storage/perfschema/pse_bootstrap.cc
  storage/perfschema/pse_column_values.cc
  storage/perfschema/pse_column_values.h
  storage/perfschema/pse_events_waits.cc
  storage/perfschema/pse_events_waits.h
  storage/perfschema/pse_global.cc
  storage/perfschema/pse_global.h
  storage/perfschema/pse_server.cc
  storage/perfschema/pse_server.h
  storage/perfschema/pse_stat.h
  storage/perfschema/pse_sync.cc
  storage/perfschema/pse_sync.h
  storage/perfschema/pse_sync_info.cc
  storage/perfschema/pse_sync_info.h
  storage/perfschema/pse_table.cc
  storage/perfschema/table_events_waits.cc
  storage/perfschema/table_setup_instruments.cc
  storage/perfschema/table_setup_instruments.h

=== modified file 'include/my_sys.h'
--- a/include/my_sys.h	2008-12-09 01:31:06 +0000
+++ b/include/my_sys.h	2008-12-18 08:49:47 +0000
@@ -1052,5 +1052,7 @@ extern struct PSI_bootstrap *PSI_hook;
 extern PSI *PSI_server;
 #endif
 
+#include "mysql/mysql_file.h"
+
 C_MODE_END
 #endif /* _my_sys_h */

=== added file 'include/mysql/mysql_file.h'
--- a/include/mysql/mysql_file.h	1970-01-01 00:00:00 +0000
+++ b/include/mysql/mysql_file.h	2008-12-18 08:49:47 +0000
@@ -0,0 +1,319 @@
+/* Copyright (C) 2008 Sun Microsystems, Inc
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; version 2 of the License.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#ifndef MYSQL_FILE_H
+#define MYSQL_FILE_H
+
+/**
+  @file mysql/mysql_file.h
+ */
+
+#ifdef HAVE_PSI_INTERFACE
+#include "mysql/psi.h"
+extern PSI *PSI_server;
+#else
+struct PSI_file;
+#endif
+
+/**
+  @defgroup File_instrumentation File Instrumentation
+  @ingroup Performance_schema_interface
+  @{
+*/
+
+/**
+  \def MYSQL_FILE_OPEN(K,N,F1,F2)
+  Instrumented fopen.
+  @c MYSQL_FILE_OPEN is a replacement
+  for @c my_fopen.
+*/
+#ifdef HAVE_PSI_INTERFACE
+  #define MYSQL_FOPEN(K,N,F1,F2) mysql_fopen(K,N,F1,F2)
+#else
+  #define MYSQL_FOPEN(K,N,F1,F2) my_fopen(N,F1,F2)
+#endif
+
+#ifdef HAVE_PSI_INTERFACE
+  #define MYSQL_FCLOSE(FD,FL) mysql_fclose(FD,FL)
+#else
+  #define MYSQL_FCLOSE(FD,FL) my_fclose(FD,FL)
+#endif
+
+#ifdef HAVE_PSI_INTERFACE
+  #define MYSQL_FREAD(FD,B,S,F) mysql_fread(FD,B,S,F)
+#else
+  #define MYSQL_FREAD(FD,B,S,F) my_fread(FD,B,S,F)
+#endif
+
+#ifdef HAVE_PSI_INTERFACE
+  #define MYSQL_FWRITE(FD,B,S) mysql_fwrite(FD,B,S)
+#else
+  #define MYSQL_FWRITE(FD,B,S) my_fwrite(FD,B,S)
+#endif
+
+#ifdef HAVE_PSI_INTERFACE
+  #define MYSQL_FSEEK(FD,P,W,F) mysql_fseek(FD,P,W,F)
+#else
+  #define MYSQL_FSEEK(FD,P,W,F) my_fseek(FD,P,W,F)
+#endif
+
+#ifdef HAVE_PSI_INTERFACE
+  #define MYSQL_FTELL(FD,F) mysql_ftell(FD,F)
+#else
+  #define MYSQL_FTELL(FD,F) my_ftell(FD,F)
+#endif
+
+#ifdef HAVE_PSI_INTERFACE
+  #define MYSQL_CREATE(K,N,F1,F2,F3) mysql_create(K,N,F1,F2,F3)
+#else
+  #define MYSQL_CREATE(K,N,F1,F2,F3) my_create(N,F1,F2,F3)
+#endif
+
+#ifdef HAVE_PSI_INTERFACE
+  #define MYSQL_OPEN(K,N,F1,F2) mysql_open(K,N,F1,F2)
+#else
+  #define MYSQL_OPEN(K,N,F1,F2) my_open(N,F1,F2)
+#endif
+
+#ifdef HAVE_PSI_INTERFACE
+  #define MYSQL_CLOSE(FD,F) mysql_close_descr(FD,F)
+#else
+  #define MYSQL_CLOSE(FD,F) my_close(FD,F)
+#endif
+
+#ifdef HAVE_PSI_INTERFACE
+  #define MYSQL_READ(FD,B,S,F) mysql_read(FD,B,S,F)
+#else
+  #define MYSQL_READ(FD,B,S,F) my_read(FD,B,S,F)
+#endif
+
+#ifdef HAVE_PSI_INTERFACE
+  #define MYSQL_WRITE(FD,B,S,F) mysql_write(FD,B,S,F)
+#else
+  #define MYSQL_WRITE(FD,B,S,F) my_write(FD,B,S,F)
+#endif
+
+#ifdef HAVE_PSI_INTERFACE
+  #define MYSQL_PREAD(FD,B,S,O,F) mysql_pread(FD,B,S,O,F)
+#else
+  #define MYSQL_PREAD(FD,B,S,O,F) my_pread(FD,B,S,O,F)
+#endif
+
+#ifdef HAVE_PSI_INTERFACE
+  #define MYSQL_PWRITE(FD,B,S,O,F) mysql_pwrite(FD,B,S,O,F)
+#else
+  #define MYSQL_PWRITE(FD,B,S,O,F) my_pwrite(FD,B,S,O,F)
+#endif
+
+#ifdef HAVE_PSI_INTERFACE
+  #define MYSQL_SEEK(FD,P,W,F) mysql_seek(FD,P,W,F)
+#else
+  #define MYSQL_SEEK(FD,P,W,F) my_seek(FD,P,W,F)
+#endif
+
+#ifdef HAVE_PSI_INTERFACE
+  #define MYSQL_TELL(FD,F) mysql_tell(FD,F)
+#else
+  #define MYSQL_TELL(FD,F) my_tell(FD,F)
+#endif
+
+/**
+  An instrumented FILE structure.
+  @sa MYSQL_FILE
+*/
+struct s_mysql_file
+{
+  /** The real file. */
+  FILE *m_file;
+  /** The instrumentation hook. */
+  struct PSI_file *m_psi;
+};
+
+
+struct s_mysql_file_descr
+{
+  File m_file;
+  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
+*/
+#ifdef HAVE_PSI_INTERFACE
+typedef struct s_mysql_file MYSQL_FILE;
+#else
+typedef FILE MYSQL_FILE;
+#endif
+
+static inline MYSQL_FILE*
+mysql_fopen(PSI_file_key key, const char *filename, int flags, myf myFlags)
+{
+  MYSQL_FILE *that;
+  that= (MYSQL_FILE*) my_malloc(sizeof(MYSQL_FILE), MYF(MY_WME));
+  if (that)
+  {
+    that->m_file= my_fopen(filename, flags, myFlags);
+    if (PSI_server)
+      that->m_psi= PSI_server->open_file_stream(key, filename, that->m_file);
+    else
+      that->m_psi= NULL;
+  }
+  return that;
+}
+
+static inline int
+mysql_fclose(MYSQL_FILE *file, myf flags)
+{
+  int result= 0;
+  if (file)
+  {
+    if (PSI_server && file->m_psi)
+      PSI_server->close_file_stream(file->m_psi);
+    result= my_fclose(file->m_file, flags);
+    my_free(file, MYF(0));
+  }
+  return result;
+}
+
+static inline int
+mysql_fread(MYSQL_FILE *file, uchar *buffer, size_t count, myf flags)
+{
+  int result= 0;
+  if (PSI_server && file->m_psi)
+  {
+    PSI_server->read_file_stream(file->m_psi, count);
+  }
+  result= my_fread(file->m_file, buffer, count, flags);
+  return result;
+}
+
+static inline int
+mysql_fwrite(MYSQL_FILE *file, uchar *buffer, size_t count, myf flags)
+{
+  int result= 0;
+  if (PSI_server && file->m_psi)
+  {
+    PSI_server->write_file_stream(file->m_psi, count);
+  }
+  result= my_fwrite(file->m_file, buffer, count, flags);
+  return result;
+}
+
+static inline int
+mysql_fseek(MYSQL_FILE *file, my_off_t pos, int whence, myf flags)
+{
+  return my_fseek(file->m_file, pos, whence, flags);
+}
+
+static inline int
+mysql_ftell(MYSQL_FILE *file, myf flags)
+{
+  return my_ftell(file->m_file, flags);
+}
+
+static inline File
+mysql_create(PSI_file_key key, const char *filename, int create_flags,
+             int access_flags, myf myFlags)
+{
+  File file;
+  file= my_create(filename, create_flags, access_flags, myFlags);
+  if (PSI_server)
+    PSI_server->create_file(key, filename, file);
+  return file;
+}
+
+static inline File
+mysql_open(PSI_file_key key, const char *filename, int flags, myf myFlags)
+{
+  File file;
+  file= my_open(filename, flags, myFlags);
+  if (PSI_server)
+    PSI_server->open_file(key, filename, file);
+  return file;
+}
+
+// mysql_close is used in the client API
+static inline int
+mysql_close_descr(File file, myf flags)
+{
+  int result;
+  if (PSI_server)
+    PSI_server->close_file(file);
+  result= my_close(file, flags);
+  return result;
+}
+
+static inline int
+mysql_read(File file, uchar *buffer, size_t count, myf flags)
+{
+  int result;
+  if (PSI_server)
+    PSI_server->read_file(file, count);
+  result= my_read(file, buffer, count, flags);
+  return result;
+}
+
+static inline int
+mysql_write(File file, uchar *buffer, size_t count, myf flags)
+{
+  int result;
+  if (PSI_server)
+    PSI_server->write_file(file, count);
+  result= my_write(file, buffer, count, flags);
+  return result;
+}
+
+static inline int
+mysql_pread(File file, uchar *buffer, size_t count, my_off_t offset,
+            myf flags)
+{
+  int result;
+  if (PSI_server)
+    PSI_server->read_file(file, count);
+  result= my_pread(file, buffer, count, offset, flags);
+  return result;
+}
+
+static inline int
+mysql_pwrite(File file, uchar *buffer, size_t count, my_off_t offset,
+             myf flags)
+{
+  int result;
+  if (PSI_server)
+    PSI_server->write_file(file, count);
+  result= my_pwrite(file, buffer, count, offset, flags);
+  return result;
+}
+
+static inline int
+mysql_seek(File file, my_off_t pos, int whence, myf flags)
+{
+  return my_seek(file, pos, whence, flags);
+}
+
+static inline int
+mysql_tell(File file, myf flags)
+{
+  return my_tell(file, flags);
+}
+
+/**
+  @} (end of group File_instrumentation)
+*/
+
+#endif
+

=== modified file 'include/mysql/psi.h'
--- a/include/mysql/psi.h	2008-12-08 23:59:01 +0000
+++ b/include/mysql/psi.h	2008-12-18 08:49:47 +0000
@@ -98,6 +98,8 @@ struct PSI_table;
 */
 struct PSI_thread;
 
+struct PSI_file;
+
 /**
   Interface for an instrumented lock operation.
   This is an opaque structure.
@@ -128,6 +130,8 @@ typedef unsigned int PSI_cond_key;
 */
 typedef unsigned int PSI_thread_key;
 
+typedef unsigned int PSI_file_key;
+
 /**
   \def USE_PSI_1
   Define USE_PSI_1 to use the interface version 1.
@@ -255,6 +259,13 @@ struct PSI_thread_info_v1
   int m_flags;
 };
 
+struct PSI_file_info_v1
+{
+  PSI_file_key *m_key;
+  const char* m_name;
+  int m_flags;
+};
+
 /**
   Performance Schema Interface, version 1.
   @since PSI_VERSION_1
@@ -301,6 +312,10 @@ struct PSI_v1
                           struct PSI_thread_info_v1 *info,
                           int count);
 
+  void (*register_file)(const char* category,
+                        struct PSI_file_info_v1 *info,
+                        int count);
+
   /**
     Mutex initialisation API.
     @param key the registered mutex key
@@ -357,7 +372,21 @@ struct PSI_v1
   struct PSI_table* (*open_table)(struct PSI_table_info *info);
   void (*close_table)(struct PSI_table *table);
 
-
+  struct PSI_file* (*create_file_stream)(PSI_file_key key,
+                                  const char* name,
+                                  void *identity);
+  struct PSI_file* (*open_file_stream)(PSI_file_key key,
+                                const char* name,
+                                void *identity);
+  void (*close_file_stream)(struct PSI_file* file);
+  void (*read_file_stream)(struct PSI_file* file, int count);
+  void (*write_file_stream)(struct PSI_file* file, int count);
+
+  void (*create_file)(PSI_file_key key, const char* name, File file);
+  void (*open_file)(PSI_file_key key, const char* name, File file);
+  void (*close_file)(File file);
+  void (*read_file)(File file, int count);
+  void (*write_file)(File file, int count);
 
   /**
     Create an instrumented thread.
@@ -619,6 +648,11 @@ struct PSI_thread_info_v2
   int placeholder;
 };
 
+struct PSI_file_info_v2
+{
+  int placeholder;
+};
+
 /**
   @} (end of group Group_PSI_v2)
 */
@@ -653,6 +687,7 @@ typedef struct PSI_mutex_info_v1 PSI_mut
 typedef struct PSI_rwlock_info_v1 PSI_rwlock_info;
 typedef struct PSI_cond_info_v1 PSI_cond_info;
 typedef struct PSI_thread_info_v1 PSI_thread_info;
+typedef struct PSI_file_info_v1 PSI_file_info;
 #endif
 
 #ifdef USE_PSI_2
@@ -661,6 +696,7 @@ typedef struct PSI_mutex_info_v2 PSI_mut
 typedef struct PSI_rwlock_info_v2 PSI_rwlock_info;
 typedef struct PSI_cond_info_v2 PSI_cond_info;
 typedef struct PSI_thread_info_v2 PSI_thread_info;
+typedef struct PSI_file_info_v2 PSI_file_info;
 #endif
 
 /**

=== modified file 'include/mysql/psi_abi_v1.h.pp'
--- a/include/mysql/psi_abi_v1.h.pp	2008-12-08 23:59:01 +0000
+++ b/include/mysql/psi_abi_v1.h.pp	2008-12-18 08:49:47 +0000
@@ -9,11 +9,13 @@ struct PSI_cond;
 struct PSI_table_info;
 struct PSI_table;
 struct PSI_thread;
+struct PSI_file;
 struct PSI_locker;
 typedef unsigned int PSI_mutex_key;
 typedef unsigned int PSI_rwlock_key;
 typedef unsigned int PSI_cond_key;
 typedef unsigned int PSI_thread_key;
+typedef unsigned int PSI_file_key;
 struct PSI_mutex_info_v1
 {
   PSI_mutex_key *m_key;
@@ -38,6 +40,12 @@ struct PSI_thread_info_v1
   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_v1
 {
   void (*register_mutex)(const char* category,
@@ -52,6 +60,9 @@ struct PSI_v1
   void (*register_thread)(const char* category,
                           struct PSI_thread_info_v1 *info,
                           int count);
+  void (*register_file)(const char* category,
+                        struct PSI_file_info_v1 *info,
+                        int count);
   struct PSI_mutex* (*init_mutex)(PSI_mutex_key key,
                                   void *identity);
   void (*destroy_mutex)(struct PSI_mutex *mutex);
@@ -69,6 +80,20 @@ struct PSI_v1
   void (*release_table_info)(struct PSI_table_info *info);
   struct PSI_table* (*open_table)(struct PSI_table_info *info);
   void (*close_table)(struct PSI_table *table);
+  struct PSI_file* (*create_file_stream)(PSI_file_key key,
+                                  const char* name,
+                                  void *identity);
+  struct PSI_file* (*open_file_stream)(PSI_file_key key,
+                                const char* name,
+                                void *identity);
+  void (*close_file_stream)(struct PSI_file* file);
+  void (*read_file_stream)(struct PSI_file* file, int count);
+  void (*write_file_stream)(struct PSI_file* file, int count);
+  void (*create_file)(PSI_file_key key, const char* name, File file);
+  void (*open_file)(PSI_file_key key, const char* name, File file);
+  void (*close_file)(File file);
+  void (*read_file)(File file, int count);
+  void (*write_file)(File file, int count);
   struct PSI_thread* (*new_thread)(PSI_thread_key key,
                                    void *identity);
   void (*set_thread_id)(struct PSI_thread *thread, unsigned long id);
@@ -129,3 +154,4 @@ typedef struct PSI_mutex_info_v1 PSI_mut
 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;

=== modified file 'include/mysql/psi_abi_v2.h.pp'
--- a/include/mysql/psi_abi_v2.h.pp	2008-12-08 23:59:01 +0000
+++ b/include/mysql/psi_abi_v2.h.pp	2008-12-18 08:49:47 +0000
@@ -9,11 +9,13 @@ struct PSI_cond;
 struct PSI_table_info;
 struct PSI_table;
 struct PSI_thread;
+struct PSI_file;
 struct PSI_locker;
 typedef unsigned int PSI_mutex_key;
 typedef unsigned int PSI_rwlock_key;
 typedef unsigned int PSI_cond_key;
 typedef unsigned int PSI_thread_key;
+typedef unsigned int PSI_file_key;
 struct PSI_v2
 {
   int placeholder;
@@ -34,8 +36,13 @@ struct PSI_thread_info_v2
 {
   int placeholder;
 };
+struct PSI_file_info_v2
+{
+  int placeholder;
+};
 typedef struct PSI_v2 PSI;
 typedef struct PSI_mutex_info_v2 PSI_mutex_info;
 typedef struct PSI_rwlock_info_v2 PSI_rwlock_info;
 typedef struct PSI_cond_info_v2 PSI_cond_info;
 typedef struct PSI_thread_info_v2 PSI_thread_info;
+typedef struct PSI_file_info_v2 PSI_file_info;

=== modified file 'mysql-test/suite/perfschema/r/dml_setup_instruments.result'
--- a/mysql-test/suite/perfschema/r/dml_setup_instruments.result	2008-12-04 16:56:02 +0000
+++ b/mysql-test/suite/perfschema/r/dml_setup_instruments.result	2008-12-18 08:49:47 +0000
@@ -175,6 +175,27 @@ Wait/Synch/Cond/Maria/MARIA_SORT_INFO::c
 Wait/Synch/Cond/Maria/COND_checkpoint	YES	YES
 Wait/Synch/Cond/Maria/translog_b::waiting_filling_buffer	YES	YES
 Wait/Synch/Cond/Maria/translog_d::log_flush	YES	YES
+Thread/Sql/Main	YES	YES
+Thread/Sql/Bootstrap	YES	YES
+Thread/Sql/Listen/Socket	YES	YES
+Thread/Sql/Listen/NamedPipes	YES	YES
+Thread/Sql/Listen/SharedMemory	YES	YES
+Thread/Sql/Connection	YES	YES
+Thread/Sql/EventScheduler	YES	YES
+Thread/Sql/EventWorker	YES	YES
+Thread/Sql/NdbBinlog	YES	YES
+Thread/Sql/NdbUtil	YES	YES
+Thread/Sql/Manager	YES	YES
+Thread/Sql/Signal	YES	YES
+Thread/Sql/OneConnection	YES	YES
+Thread/Sql/KillServer	YES	YES
+Thread/Sql/LibEvent	YES	YES
+Thread/Sql/Slave_IO	YES	YES
+Thread/Sql/slave_SQL	YES	YES
+Thread/Maria/find_all_keys	YES	YES
+Thread/Maria/checkpoint_background	YES	YES
+IO/File/Sql/ERRMSG	YES	YES
+IO/File/Sql/FRM	YES	YES
 select * from performance_schema.setup_instruments
 where name like 'Wait/Synch/Mutex/%';
 NAME	ENABLED	TIMED
@@ -540,6 +561,27 @@ Wait/Synch/Cond/Maria/MARIA_SORT_INFO::c
 Wait/Synch/Cond/Maria/COND_checkpoint	YES	YES
 Wait/Synch/Cond/Maria/translog_b::waiting_filling_buffer	YES	YES
 Wait/Synch/Cond/Maria/translog_d::log_flush	YES	YES
+Thread/Sql/Main	YES	YES
+Thread/Sql/Bootstrap	YES	YES
+Thread/Sql/Listen/Socket	YES	YES
+Thread/Sql/Listen/NamedPipes	YES	YES
+Thread/Sql/Listen/SharedMemory	YES	YES
+Thread/Sql/Connection	YES	YES
+Thread/Sql/EventScheduler	YES	YES
+Thread/Sql/EventWorker	YES	YES
+Thread/Sql/NdbBinlog	YES	YES
+Thread/Sql/NdbUtil	YES	YES
+Thread/Sql/Manager	YES	YES
+Thread/Sql/Signal	YES	YES
+Thread/Sql/OneConnection	YES	YES
+Thread/Sql/KillServer	YES	YES
+Thread/Sql/LibEvent	YES	YES
+Thread/Sql/Slave_IO	YES	YES
+Thread/Sql/slave_SQL	YES	YES
+Thread/Maria/find_all_keys	YES	YES
+Thread/Maria/checkpoint_background	YES	YES
+IO/File/Sql/ERRMSG	YES	YES
+IO/File/Sql/FRM	YES	YES
 insert into performance_schema.setup_instruments
 set name='FOO', enabled='YES', timed='YES';
 ERROR HY000: Table storage engine for 'setup_instruments' doesn't have this option
@@ -727,6 +769,27 @@ Wait/Synch/Cond/Maria/MARIA_SORT_INFO::c
 Wait/Synch/Cond/Maria/COND_checkpoint	NO	NO
 Wait/Synch/Cond/Maria/translog_b::waiting_filling_buffer	NO	NO
 Wait/Synch/Cond/Maria/translog_d::log_flush	NO	NO
+Thread/Sql/Main	NO	NO
+Thread/Sql/Bootstrap	NO	NO
+Thread/Sql/Listen/Socket	NO	NO
+Thread/Sql/Listen/NamedPipes	NO	NO
+Thread/Sql/Listen/SharedMemory	NO	NO
+Thread/Sql/Connection	NO	NO
+Thread/Sql/EventScheduler	NO	NO
+Thread/Sql/EventWorker	NO	NO
+Thread/Sql/NdbBinlog	NO	NO
+Thread/Sql/NdbUtil	NO	NO
+Thread/Sql/Manager	NO	NO
+Thread/Sql/Signal	NO	NO
+Thread/Sql/OneConnection	NO	NO
+Thread/Sql/KillServer	NO	NO
+Thread/Sql/LibEvent	NO	NO
+Thread/Sql/Slave_IO	NO	NO
+Thread/Sql/slave_SQL	NO	NO
+Thread/Maria/find_all_keys	NO	NO
+Thread/Maria/checkpoint_background	NO	NO
+IO/File/Sql/ERRMSG	NO	NO
+IO/File/Sql/FRM	NO	NO
 update performance_schema.setup_instruments
 set enabled='YES', timed='YES';
 delete from performance_schema.setup_instruments;

=== modified file 'mysql-test/suite/perfschema/r/information_schema.result'
--- a/mysql-test/suite/perfschema/r/information_schema.result	2008-12-04 16:56:02 +0000
+++ b/mysql-test/suite/perfschema/r/information_schema.result	2008-12-18 08:49:47 +0000
@@ -3,12 +3,16 @@ from information_schema.tables
 where TABLE_SCHEMA='performance_schema';
 TABLE_SCHEMA	TABLE_NAME	TABLE_CATALOG
 performance_schema	cond_instances	NULL
+performance_schema	events_file_current	NULL
 performance_schema	events_waits_current	NULL
 performance_schema	events_waits_history	NULL
 performance_schema	events_waits_history_long	NULL
 performance_schema	events_waits_summary_by_instance	NULL
 performance_schema	events_waits_summary_by_name	NULL
 performance_schema	events_waits_summary_by_thread_by_name	NULL
+performance_schema	file_instances	NULL
+performance_schema	file_usage_summary_by_instance	NULL
+performance_schema	file_usage_summary_by_name	NULL
 performance_schema	mutex_instances	NULL
 performance_schema	performance_timers	NULL
 performance_schema	processlist	NULL
@@ -22,12 +26,16 @@ from information_schema.tables
 where TABLE_SCHEMA='performance_schema';
 TABLE_NAME	TABLE_TYPE	ENGINE
 cond_instances	BASE TABLE	PERFORMANCE_SCHEMA
+events_file_current	BASE TABLE	PERFORMANCE_SCHEMA
 events_waits_current	BASE TABLE	PERFORMANCE_SCHEMA
 events_waits_history	BASE TABLE	PERFORMANCE_SCHEMA
 events_waits_history_long	BASE TABLE	PERFORMANCE_SCHEMA
 events_waits_summary_by_instance	BASE TABLE	PERFORMANCE_SCHEMA
 events_waits_summary_by_name	BASE TABLE	PERFORMANCE_SCHEMA
 events_waits_summary_by_thread_by_name	BASE TABLE	PERFORMANCE_SCHEMA
+file_instances	BASE TABLE	PERFORMANCE_SCHEMA
+file_usage_summary_by_instance	BASE TABLE	PERFORMANCE_SCHEMA
+file_usage_summary_by_name	BASE TABLE	PERFORMANCE_SCHEMA
 mutex_instances	BASE TABLE	PERFORMANCE_SCHEMA
 performance_timers	BASE TABLE	PERFORMANCE_SCHEMA
 processlist	BASE TABLE	PERFORMANCE_SCHEMA
@@ -41,12 +49,16 @@ from information_schema.tables
 where TABLE_SCHEMA='performance_schema';
 TABLE_NAME	VERSION	ROW_FORMAT
 cond_instances	10	Dynamic
+events_file_current	10	Dynamic
 events_waits_current	10	Dynamic
 events_waits_history	10	Dynamic
 events_waits_history_long	10	Dynamic
 events_waits_summary_by_instance	10	Dynamic
 events_waits_summary_by_name	10	Dynamic
 events_waits_summary_by_thread_by_name	10	Dynamic
+file_instances	10	Dynamic
+file_usage_summary_by_instance	10	Dynamic
+file_usage_summary_by_name	10	Dynamic
 mutex_instances	10	Dynamic
 performance_timers	10	Fixed
 processlist	10	Dynamic
@@ -60,12 +72,16 @@ from information_schema.tables
 where TABLE_SCHEMA='performance_schema';
 TABLE_NAME	TABLE_ROWS	AVG_ROW_LENGTH
 cond_instances	1000	0
+events_file_current	1000	0
 events_waits_current	1000	0
 events_waits_history	1000	0
 events_waits_history_long	10000	0
 events_waits_summary_by_instance	1000	0
 events_waits_summary_by_name	1000	0
 events_waits_summary_by_thread_by_name	1000	0
+file_instances	1000	0
+file_usage_summary_by_instance	1000	0
+file_usage_summary_by_name	1000	0
 mutex_instances	1000	0
 performance_timers	5	0
 processlist	1000	0
@@ -79,12 +95,16 @@ from information_schema.tables
 where TABLE_SCHEMA='performance_schema';
 TABLE_NAME	DATA_LENGTH	MAX_DATA_LENGTH
 cond_instances	0	0
+events_file_current	0	0
 events_waits_current	0	0
 events_waits_history	0	0
 events_waits_history_long	0	0
 events_waits_summary_by_instance	0	0
 events_waits_summary_by_name	0	0
 events_waits_summary_by_thread_by_name	0	0
+file_instances	0	0
+file_usage_summary_by_instance	0	0
+file_usage_summary_by_name	0	0
 mutex_instances	0	0
 performance_timers	0	0
 processlist	0	0
@@ -98,12 +118,16 @@ from information_schema.tables
 where TABLE_SCHEMA='performance_schema';
 TABLE_NAME	INDEX_LENGTH	DATA_FREE	AUTO_INCREMENT
 cond_instances	0	0	NULL
+events_file_current	0	0	NULL
 events_waits_current	0	0	NULL
 events_waits_history	0	0	NULL
 events_waits_history_long	0	0	NULL
 events_waits_summary_by_instance	0	0	NULL
 events_waits_summary_by_name	0	0	NULL
 events_waits_summary_by_thread_by_name	0	0	NULL
+file_instances	0	0	NULL
+file_usage_summary_by_instance	0	0	NULL
+file_usage_summary_by_name	0	0	NULL
 mutex_instances	0	0	NULL
 performance_timers	0	0	NULL
 processlist	0	0	NULL
@@ -117,12 +141,16 @@ from information_schema.tables
 where TABLE_SCHEMA='performance_schema';
 TABLE_NAME	CREATE_TIME	UPDATE_TIME	CHECK_TIME
 cond_instances	NULL	NULL	NULL
+events_file_current	NULL	NULL	NULL
 events_waits_current	NULL	NULL	NULL
 events_waits_history	NULL	NULL	NULL
 events_waits_history_long	NULL	NULL	NULL
 events_waits_summary_by_instance	NULL	NULL	NULL
 events_waits_summary_by_name	NULL	NULL	NULL
 events_waits_summary_by_thread_by_name	NULL	NULL	NULL
+file_instances	NULL	NULL	NULL
+file_usage_summary_by_instance	NULL	NULL	NULL
+file_usage_summary_by_name	NULL	NULL	NULL
 mutex_instances	NULL	NULL	NULL
 performance_timers	NULL	NULL	NULL
 processlist	NULL	NULL	NULL
@@ -136,12 +164,16 @@ from information_schema.tables
 where TABLE_SCHEMA='performance_schema';
 TABLE_NAME	TABLE_COLLATION	CHECKSUM
 cond_instances	utf8_general_ci	NULL
+events_file_current	utf8_general_ci	NULL
 events_waits_current	utf8_general_ci	NULL
 events_waits_history	utf8_general_ci	NULL
 events_waits_history_long	utf8_general_ci	NULL
 events_waits_summary_by_instance	utf8_general_ci	NULL
 events_waits_summary_by_name	utf8_general_ci	NULL
 events_waits_summary_by_thread_by_name	utf8_general_ci	NULL
+file_instances	utf8_general_ci	NULL
+file_usage_summary_by_instance	utf8_general_ci	NULL
+file_usage_summary_by_name	utf8_general_ci	NULL
 mutex_instances	utf8_general_ci	NULL
 performance_timers	utf8_general_ci	NULL
 processlist	utf8_general_ci	NULL
@@ -155,12 +187,16 @@ from information_schema.tables
 where TABLE_SCHEMA='performance_schema';
 TABLE_NAME	CREATE_OPTIONS	TABLESPACE_NAME
 cond_instances		NULL
+events_file_current		NULL
 events_waits_current		NULL
 events_waits_history		NULL
 events_waits_history_long		NULL
 events_waits_summary_by_instance		NULL
 events_waits_summary_by_name		NULL
 events_waits_summary_by_thread_by_name		NULL
+file_instances		NULL
+file_usage_summary_by_instance		NULL
+file_usage_summary_by_name		NULL
 mutex_instances		NULL
 performance_timers		NULL
 processlist		NULL
@@ -174,12 +210,16 @@ from information_schema.tables
 where TABLE_SCHEMA='performance_schema';
 TABLE_NAME	TABLE_COMMENT
 cond_instances	
+events_file_current	
 events_waits_current	
 events_waits_history	
 events_waits_history_long	
 events_waits_summary_by_instance	
 events_waits_summary_by_name	
 events_waits_summary_by_thread_by_name	
+file_instances	
+file_usage_summary_by_instance	
+file_usage_summary_by_name	
 mutex_instances	
 performance_timers	
 processlist	

=== modified file 'mysql-test/suite/perfschema/r/schema.result'
--- a/mysql-test/suite/perfschema/r/schema.result	2008-12-05 20:19:48 +0000
+++ b/mysql-test/suite/perfschema/r/schema.result	2008-12-18 08:49:47 +0000
@@ -8,12 +8,16 @@ use performance_schema;
 show tables;
 Tables_in_performance_schema
 cond_instances
+events_file_current
 events_waits_current
 events_waits_history
 events_waits_history_long
 events_waits_summary_by_instance
 events_waits_summary_by_name
 events_waits_summary_by_thread_by_name
+file_instances
+file_usage_summary_by_instance
+file_usage_summary_by_name
 mutex_instances
 performance_timers
 processlist
@@ -22,7 +26,25 @@ setup_actors
 setup_consumers
 setup_instruments
 setup_timers
-show create table performance_schema.events_waits_current;
+show create table cond_instances;
+Table	Create Table
+cond_instances	CREATE TABLE `cond_instances` (
+  `NAME` varchar(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
+  `OBJECT_INSTANCE_BEGIN` bigint(20) NOT NULL
+) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
+show create table events_file_current;
+Table	Create Table
+events_file_current	CREATE TABLE `events_file_current` (
+  `THREAD_ID` int(11) NOT NULL,
+  `EVENT_ID` bigint(20) NOT NULL,
+  `NESTING_EVENT_ID` bigint(20) DEFAULT NULL,
+  `EVENT_NAME` varchar(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
+  `TIMER_START` bigint(20) DEFAULT NULL,
+  `TIMER_END` bigint(20) DEFAULT NULL,
+  `TIMER_WAIT` bigint(20) DEFAULT NULL,
+  `FILE_NAME` varchar(1024) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL
+) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
+show create table events_waits_current;
 Table	Create Table
 events_waits_current	CREATE TABLE `events_waits_current` (
   `THREAD_ID` int(11) NOT NULL,
@@ -38,7 +60,7 @@ events_waits_current	CREATE TABLE `event
   `OBJECT_NAME` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
   `OBJECT_INSTANCE_BEGIN` bigint(20) NOT NULL
 ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
-show create table performance_schema.events_waits_history;
+show create table events_waits_history;
 Table	Create Table
 events_waits_history	CREATE TABLE `events_waits_history` (
   `THREAD_ID` int(11) NOT NULL,
@@ -54,7 +76,7 @@ events_waits_history	CREATE TABLE `event
   `OBJECT_NAME` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
   `OBJECT_INSTANCE_BEGIN` bigint(20) NOT NULL
 ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
-show create table performance_schema.events_waits_history_long;
+show create table events_waits_history_long;
 Table	Create Table
 events_waits_history_long	CREATE TABLE `events_waits_history_long` (
   `THREAD_ID` int(11) NOT NULL,
@@ -70,28 +92,7 @@ events_waits_history_long	CREATE TABLE `
   `OBJECT_NAME` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
   `OBJECT_INSTANCE_BEGIN` bigint(20) NOT NULL
 ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
-show create table performance_schema.cond_instances;
-Table	Create Table
-cond_instances	CREATE TABLE `cond_instances` (
-  `NAME` varchar(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
-  `OBJECT_INSTANCE_BEGIN` bigint(20) NOT NULL
-) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
-show create table performance_schema.mutex_instances;
-Table	Create Table
-mutex_instances	CREATE TABLE `mutex_instances` (
-  `NAME` varchar(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
-  `OBJECT_INSTANCE_BEGIN` bigint(20) NOT NULL,
-  `LOCKED_BY_THREAD_ID` int(11) DEFAULT NULL
-) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
-show create table performance_schema.rwlock_instances;
-Table	Create Table
-rwlock_instances	CREATE TABLE `rwlock_instances` (
-  `NAME` varchar(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
-  `OBJECT_INSTANCE_BEGIN` bigint(20) NOT NULL,
-  `WRITE_LOCKED_BY_THREAD_ID` int(11) DEFAULT NULL,
-  `READ_LOCKED_BY_COUNT` int(11) NOT NULL
-) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
-show create table performance_schema.events_waits_summary_by_instance;
+show create table events_waits_summary_by_instance;
 Table	Create Table
 events_waits_summary_by_instance	CREATE TABLE `events_waits_summary_by_instance` (
   `NAME` varchar(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
@@ -102,7 +103,7 @@ events_waits_summary_by_instance	CREATE 
   `AVG_WAIT` bigint(20) NOT NULL,
   `MAX_WAIT` bigint(20) NOT NULL
 ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
-show create table performance_schema.events_waits_summary_by_name;
+show create table events_waits_summary_by_name;
 Table	Create Table
 events_waits_summary_by_name	CREATE TABLE `events_waits_summary_by_name` (
   `NAME` varchar(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
@@ -112,7 +113,7 @@ events_waits_summary_by_name	CREATE TABL
   `AVG_WAIT` bigint(20) NOT NULL,
   `MAX_WAIT` bigint(20) NOT NULL
 ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
-show create table performance_schema.events_waits_summary_by_thread_by_name;
+show create table events_waits_summary_by_thread_by_name;
 Table	Create Table
 events_waits_summary_by_thread_by_name	CREATE TABLE
`events_waits_summary_by_thread_by_name` (
   `THREAD_ID` int(11) NOT NULL,
@@ -123,7 +124,40 @@ events_waits_summary_by_thread_by_name	C
   `AVG_WAIT` bigint(20) NOT NULL,
   `MAX_WAIT` bigint(20) NOT NULL
 ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
-show create table performance_schema.performance_timers;
+show create table file_instances;
+Table	Create Table
+file_instances	CREATE TABLE `file_instances` (
+  `FILE_NAME` varchar(1024) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
+  `EVENT_NAME` varchar(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
+  `OPEN_COUNT` int(11) NOT NULL
+) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
+show create table file_usage_summary_by_instance;
+Table	Create Table
+file_usage_summary_by_instance	CREATE TABLE `file_usage_summary_by_instance` (
+  `FILE_NAME` varchar(1024) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
+  `EVENT_NAME` varchar(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
+  `READ_COUNT` int(11) NOT NULL,
+  `WRITE_COUNT` int(11) NOT NULL,
+  `READ_BYTES` bigint(20) NOT NULL,
+  `WRITE_BYTES` bigint(20) NOT NULL
+) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
+show create table file_usage_summary_by_name;
+Table	Create Table
+file_usage_summary_by_name	CREATE TABLE `file_usage_summary_by_name` (
+  `EVENT_NAME` varchar(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
+  `READ_COUNT` int(11) NOT NULL,
+  `WRITE_COUNT` int(11) NOT NULL,
+  `READ_BYTES` bigint(20) NOT NULL,
+  `WRITE_BYTES` bigint(20) NOT NULL
+) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
+show create table mutex_instances;
+Table	Create Table
+mutex_instances	CREATE TABLE `mutex_instances` (
+  `NAME` varchar(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
+  `OBJECT_INSTANCE_BEGIN` bigint(20) NOT NULL,
+  `LOCKED_BY_THREAD_ID` int(11) DEFAULT NULL
+) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
+show create table performance_timers;
 Table	Create Table
 performance_timers	CREATE TABLE `performance_timers` (
   `TIMER_NAME` enum('CYCLE','NANOSECOND','MICROSECOND','MILLISECOND','TICK') NOT NULL,
@@ -131,34 +165,42 @@ performance_timers	CREATE TABLE `perform
   `TIMER_RESOLUTION` bigint(20) NOT NULL,
   `TIMER_OVERHEAD` bigint(20) NOT NULL
 ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
-show create table performance_schema.processlist;
+show create table processlist;
 Table	Create Table
 processlist	CREATE TABLE `processlist` (
   `THREAD_ID` int(11) NOT NULL,
   `ID` int(11) NOT NULL,
   `NAME` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL
 ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
-show create table performance_schema.setup_actors;
+show create table rwlock_instances;
+Table	Create Table
+rwlock_instances	CREATE TABLE `rwlock_instances` (
+  `NAME` varchar(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
+  `OBJECT_INSTANCE_BEGIN` bigint(20) NOT NULL,
+  `WRITE_LOCKED_BY_THREAD_ID` int(11) DEFAULT NULL,
+  `READ_LOCKED_BY_COUNT` int(11) NOT NULL
+) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
+show create table setup_actors;
 Table	Create Table
 setup_actors	CREATE TABLE `setup_actors` (
   `TYPE` enum('ALL','BACKGROUND','CONNECTION','EVENT','USER') NOT NULL,
   `ACTOR_SCHEMA` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL,
   `NAME` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci DEFAULT NULL
 ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
-show create table performance_schema.setup_consumers;
+show create table setup_consumers;
 Table	Create Table
 setup_consumers	CREATE TABLE `setup_consumers` (
   `NAME` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
   `ENABLED` enum('YES','NO') NOT NULL
 ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
-show create table performance_schema.setup_instruments;
+show create table setup_instruments;
 Table	Create Table
 setup_instruments	CREATE TABLE `setup_instruments` (
   `NAME` varchar(128) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,
   `ENABLED` enum('YES','NO') NOT NULL,
   `TIMED` enum('YES','NO') NOT NULL
 ) ENGINE=PERFORMANCE_SCHEMA DEFAULT CHARSET=utf8
-show create table performance_schema.setup_timers;
+show create table setup_timers;
 Table	Create Table
 setup_timers	CREATE TABLE `setup_timers` (
   `NAME` varchar(64) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL,

=== modified file 'mysql-test/suite/perfschema/r/start_server_off.result'
--- a/mysql-test/suite/perfschema/r/start_server_off.result	2008-12-08 23:59:01 +0000
+++ b/mysql-test/suite/perfschema/r/start_server_off.result	2008-12-18 08:49:47 +0000
@@ -41,7 +41,7 @@ performance_schema	(PSE_COND).ROW_SIZE	8
 performance_schema	(PSE_COND).ROW_COUNT	0
 performance_schema	(PSE_COND).ROW_LOST	0
 performance_schema	(PSE_COND).MEMORY	0
-performance_schema	(PSE_THREAD).ROW_SIZE	360
+performance_schema	(PSE_THREAD).ROW_SIZE	432
 performance_schema	(PSE_THREAD).ROW_COUNT	0
 performance_schema	(PSE_THREAD).ROW_LOST	0
 performance_schema	(PSE_THREAD).MEMORY	0

=== modified file 'mysql-test/suite/perfschema/r/start_server_on.result'
--- a/mysql-test/suite/perfschema/r/start_server_on.result	2008-12-05 20:19:48 +0000
+++ b/mysql-test/suite/perfschema/r/start_server_on.result	2008-12-18 08:49:47 +0000
@@ -41,14 +41,14 @@ performance_schema	(PSE_COND).ROW_SIZE	8
 performance_schema	(PSE_COND).ROW_COUNT	1000
 performance_schema	(PSE_COND).ROW_LOST	0
 performance_schema	(PSE_COND).MEMORY	88000
-performance_schema	(PSE_THREAD).ROW_SIZE	360
+performance_schema	(PSE_THREAD).ROW_SIZE	432
 performance_schema	(PSE_THREAD).ROW_COUNT	1000
 performance_schema	(PSE_THREAD).ROW_LOST	0
-performance_schema	(PSE_THREAD).MEMORY	360000
+performance_schema	(PSE_THREAD).MEMORY	432000
 performance_schema	EVENTS_WAITS_SUMMARY_BY_THREAD_BY_NAME.ROW_SIZE	32
 performance_schema	EVENTS_WAITS_SUMMARY_BY_THREAD_BY_NAME.ROW_COUNT	3000000
 performance_schema	EVENTS_WAITS_SUMMARY_BY_THREAD_BY_NAME.MEMORY	96000000
-performance_schema	PERFORMANCE_SCHEMA.MEMORY	98464800
+performance_schema	PERFORMANCE_SCHEMA.MEMORY	98536800
 select count(*) from performance_schema.performance_timers;
 count(*)
 5
@@ -57,7 +57,7 @@ count(*)
 9
 select count(*) from performance_schema.setup_instruments;
 count(*)
-175
+196
 select count(*) from performance_schema.setup_timers;
 count(*)
 1

=== modified file 'mysql-test/suite/perfschema/t/schema.test'
--- a/mysql-test/suite/perfschema/t/schema.test	2008-12-04 16:56:02 +0000
+++ b/mysql-test/suite/perfschema/t/schema.test	2008-12-18 08:49:47 +0000
@@ -5,19 +5,23 @@ use performance_schema;
 
 show tables;
 
-show create table performance_schema.events_waits_current;
-show create table performance_schema.events_waits_history;
-show create table performance_schema.events_waits_history_long;
-show create table performance_schema.cond_instances;
-show create table performance_schema.mutex_instances;
-show create table performance_schema.rwlock_instances;
-show create table performance_schema.events_waits_summary_by_instance;
-show create table performance_schema.events_waits_summary_by_name;
-show create table performance_schema.events_waits_summary_by_thread_by_name;
-show create table performance_schema.performance_timers;
-show create table performance_schema.processlist;
-show create table performance_schema.setup_actors;
-show create table performance_schema.setup_consumers;
-show create table performance_schema.setup_instruments;
-show create table performance_schema.setup_timers;
+show create table cond_instances;
+show create table events_file_current;
+show create table events_waits_current;
+show create table events_waits_history;
+show create table events_waits_history_long;
+show create table events_waits_summary_by_instance;
+show create table events_waits_summary_by_name;
+show create table events_waits_summary_by_thread_by_name;
+show create table file_instances;
+show create table file_usage_summary_by_instance;
+show create table file_usage_summary_by_name;
+show create table mutex_instances;
+show create table performance_timers;
+show create table processlist;
+show create table rwlock_instances;
+show create table setup_actors;
+show create table setup_consumers;
+show create table setup_instruments;
+show create table setup_timers;
 

=== modified file 'sql/derror.cc'
--- a/sql/derror.cc	2008-04-09 00:56:49 +0000
+++ b/sql/derror.cc	2008-12-18 08:49:47 +0000
@@ -101,13 +101,14 @@ static bool read_texts(const char *file_
 
   LINT_INIT(buff);
   funktpos=0;
-  if ((file=my_open(fn_format(name,file_name,language,"",4),
+  if ((file=MYSQL_OPEN(key_file_ERRMSG,
+                       fn_format(name,file_name,language,"",4),
 		    O_RDONLY | O_SHARE | O_BINARY,
 		    MYF(0))) < 0)
     goto err; /* purecov: inspected */
 
   funktpos=1;
-  if (my_read(file,(uchar*) head,32,MYF(MY_NABP))) goto err;
+  if (MYSQL_READ(file,(uchar*) head,32,MYF(MY_NABP))) goto err;
   if (head[0] != (uchar) 254 || head[1] != (uchar) 254 ||
       head[2] != 2 || head[3] != 1)
     goto err; /* purecov: inspected */
@@ -137,7 +138,7 @@ Error message file '%s' had only %d erro
 but it should contain at least %d error messages.\n\
 Check that the above file is the right version for this program!",
 		    name,count,error_messages);
-    (void) my_close(file,MYF(MY_WME));
+    (void) MYSQL_CLOSE(file,MYF(MY_WME));
     DBUG_RETURN(1);
   }
 
@@ -150,21 +151,21 @@ Check that the above file is the right v
   }
   buff= (uchar*) (*point + count);
 
-  if (my_read(file, buff, (size_t) count*2,MYF(MY_NABP)))
+  if (MYSQL_READ(file, buff, (size_t) count*2,MYF(MY_NABP)))
     goto err;
   for (i=0, pos= buff ; i< count ; i++)
   {
     (*point)[i]= (char*) buff+uint2korr(pos);
     pos+=2;
   }
-  if (my_read(file, buff, length, MYF(MY_NABP)))
+  if (MYSQL_READ(file, buff, length, MYF(MY_NABP)))
     goto err;
 
   for (i=1 ; i < textcount ; i++)
   {
     point[i]= *point +uint2korr(head+10+i+i);
   }
-  (void) my_close(file,MYF(0));
+  (void) MYSQL_CLOSE(file,MYF(0));
   DBUG_RETURN(0);
 
 err:
@@ -182,7 +183,7 @@ err:
   sql_print_error(errmsg, name);
 err1:
   if (file != FERR)
-    (void) my_close(file,MYF(MY_WME));
+    (void) MYSQL_CLOSE(file,MYF(MY_WME));
   DBUG_RETURN(1);
 } /* read_texts */
 

=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h	2008-12-09 01:31:06 +0000
+++ b/sql/mysql_priv.h	2008-12-18 08:49:47 +0000
@@ -2189,6 +2189,9 @@ extern PSI_thread_key key_thread_libeven
 extern PSI_thread_key key_thread_slave_io;
 extern PSI_thread_key key_thread_slave_sql;
 
+extern PSI_file_key key_file_ERRMSG;
+extern PSI_file_key key_file_frm;
+
 void init_server_psi_keys();
 PSI_thread* init_psi_thread_with_id(PSI_thread_key key,
                                     void* identity,
@@ -2439,7 +2442,7 @@ ulong make_new_entry(File file,uchar *fi
 		     const char *newname);
 ulong next_io_size(ulong pos);
 void append_unescaped(String *res, const char *pos, uint length);
-int create_frm(THD *thd, const char *name, const char *db, const char *table,
+File create_frm(THD *thd, const char *name, const char *db, const char *table,
                uint reclength, uchar *fileinfo,
 	       HA_CREATE_INFO *create_info, uint keys, KEY *key_info);
 void update_create_info_from_table(HA_CREATE_INFO *info, TABLE *form);

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2008-12-09 01:31:06 +0000
+++ b/sql/mysqld.cc	2008-12-18 08:49:47 +0000
@@ -4463,15 +4463,15 @@ int main(int argc, char **argv)
     */
     argc_input= argc;
     argv_input= argv;
-    PSI_hook= initialize_performance_schema(argc_input, argv_input,
-                                            & argc, & argv);
+    PSI_hook= initialize_performance_schema_1(argc_input, argv_input,
+                                              & argc, & argv);
   }
 #endif
 
   my_init_thread();
 
 #ifdef HAVE_PERFORMANCE_SCHEMA
-  if (initialize_performance_schema_pthread())
+  if (initialize_performance_schema_2())
     PSI_hook= NULL;
 #endif
 
@@ -4492,6 +4492,11 @@ int main(int argc, char **argv)
   MY_INIT(argv[0]);		// init my_sys library
   /* nothing should come before this line ^^^ */
 
+#ifdef HAVE_PERFORMANCE_SCHEMA
+  if (initialize_performance_schema_3())
+    PSI_hook= NULL;
+#endif
+
   /* Set signal used to kill MySQL */
 #if defined(SIGUSR2)
   thr_kill_signal= thd_lib_detected == THD_LIB_LT ? SIGINT : SIGUSR2;
@@ -9573,6 +9578,17 @@ static PSI_thread_info all_server_thread
    "slave_SQL", PSI_FLAG_GLOBAL}
 };
 
+PSI_file_key key_file_ERRMSG;
+PSI_file_key key_file_frm;
+
+static PSI_file_info all_server_files[]=
+{
+  { & key_file_ERRMSG,
+   "ERRMSG", PSI_FLAG_GLOBAL},
+  { & key_file_frm,
+   "FRM", 0}
+};
+
 void init_server_psi_keys()
 {
   const char* category= "Sql";
@@ -9592,6 +9608,9 @@ void init_server_psi_keys()
 
   count= sizeof(all_server_threads)/sizeof(all_server_threads[0]);
   PSI_server->register_thread(category, all_server_threads, count);
+
+  count= sizeof(all_server_files)/sizeof(all_server_files[0]);
+  PSI_server->register_file(category, all_server_files, count);
 }
 
 PSI_thread *init_psi_thread_with_id(PSI_thread_key key, void* identity,

=== modified file 'sql/table.cc'
--- a/sql/table.cc	2008-12-09 03:33:41 +0000
+++ b/sql/table.cc	2008-12-18 08:49:47 +0000
@@ -615,7 +615,7 @@ int open_table_def(THD *thd, TABLE_SHARE
   error_given= 0;
 
   strxmov(path, share->normalized_path.str, reg_ext, NullS);
-  if ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0)
+  if ((file= MYSQL_OPEN(key_file_frm, path, O_RDONLY | O_SHARE, MYF(0))) < 0)
   {
     /*
       We don't try to open 5.0 unencoded name, if
@@ -652,7 +652,7 @@ int open_table_def(THD *thd, TABLE_SHARE
       so no need to check the old file name.
     */
     if (length == share->normalized_path.length ||
-        ((file= my_open(path, O_RDONLY | O_SHARE, MYF(0))) < 0))
+        ((file= MYSQL_OPEN(key_file_frm, path, O_RDONLY | O_SHARE, MYF(0))) < 0))
       goto err_not_open;
 
     /* Unencoded 5.0 table name found */
@@ -662,7 +662,7 @@ int open_table_def(THD *thd, TABLE_SHARE
   }
 
   error= 4;
-  if (my_read(file, head, 64, MYF(MY_NABP)))
+  if (MYSQL_READ(file, head, 64, MYF(MY_NABP)))
     goto err;
 
   if (head[0] == (uchar) 254 && head[1] == 1)
@@ -715,7 +715,7 @@ int open_table_def(THD *thd, TABLE_SHARE
     thd->status_var.opened_shares++;
 
 err:
-  my_close(file, MYF(MY_WME));
+  MYSQL_CLOSE(file, MYF(MY_WME));
 
 err_not_open:
   if (error && !error_given)
@@ -768,8 +768,8 @@ static int open_binary_frm(THD *thd, TAB
   error= 3;
   if (!(pos=get_form_pos(file,head,(TYPELIB*) 0)))
     goto err;                                   /* purecov: inspected */
-  my_seek(file,pos,MY_SEEK_SET,MYF(0));
-  if (my_read(file,forminfo,288,MYF(MY_NABP)))
+  MYSQL_SEEK(file,pos,MY_SEEK_SET,MYF(0));
+  if (MYSQL_READ(file,forminfo,288,MYF(MY_NABP)))
     goto err;
 
   share->frm_version= head[2];
@@ -837,7 +837,7 @@ static int open_binary_frm(THD *thd, TAB
 
   /* Read keyinformation */
   key_info_length= (uint) uint2korr(head+28);
-  my_seek(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0));
+  MYSQL_SEEK(file,(ulong) uint2korr(head+6),MY_SEEK_SET,MYF(0));
   if (read_string(file,(uchar**) &disk_buff,key_info_length))
     goto err;                                   /* purecov: inspected */
   if (disk_buff[0] & 0x80)
@@ -955,7 +955,7 @@ static int open_binary_frm(THD *thd, TAB
     DBUG_PRINT("info", ("extra segment size is %u bytes", n_length));
     if (!(next_chunk= buff= (uchar*) my_malloc(n_length, MYF(MY_WME))))
       goto err;
-    if (my_pread(file, buff, n_length, record_offset + share->reclength,
+    if (MYSQL_PREAD(file, buff, n_length, record_offset + share->reclength,
                  MYF(MY_NABP)))
     {
       goto err;
@@ -1176,11 +1176,11 @@ static int open_binary_frm(THD *thd, TAB
                                      rec_buff_length)))
     goto err;                                   /* purecov: inspected */
   share->default_values= record;
-  if (my_pread(file, record, (size_t) share->reclength,
+  if (MYSQL_PREAD(file, record, (size_t) share->reclength,
                record_offset, MYF(MY_NABP)))
     goto err;                                   /* purecov: inspected */
 
-  my_seek(file,pos+288,MY_SEEK_SET,MYF(0));
+  MYSQL_SEEK(file,pos+288,MY_SEEK_SET,MYF(0));
 #ifdef HAVE_CRYPTED_FRM
   if (crypted)
   {
@@ -2240,10 +2240,10 @@ ulong get_form_pos(File file, uchar *hea
   if (names)
   {
     length=uint2korr(head+4);
-    my_seek(file,64L,MY_SEEK_SET,MYF(0));
+    MYSQL_SEEK(file,64L,MY_SEEK_SET,MYF(0));
     if (!(buf= (uchar*) my_malloc((size_t) length+a_length+names*4,
 				  MYF(MY_WME))) ||
-	my_read(file, buf+a_length, (size_t) (length+names*4),
+	MYSQL_READ(file, buf+a_length, (size_t) (length+names*4),
 		MYF(MY_NABP)))
     {						/* purecov: inspected */
       x_free((uchar*) buf);			/* purecov: inspected */
@@ -2282,7 +2282,7 @@ int read_string(File file, uchar**to, si
 
   x_free(*to);
   if (!(*to= (uchar*) my_malloc(length+1,MYF(MY_WME))) ||
-      my_read(file, *to, length,MYF(MY_NABP)))
+      MYSQL_READ(file, *to, length,MYF(MY_NABP)))
   {
     x_free(*to);                              /* purecov: inspected */
     *to= 0;                                   /* purecov: inspected */
@@ -2626,7 +2626,7 @@ File create_frm(THD *thd, const char *na
                 const char *table, uint reclength, uchar *fileinfo,
   		HA_CREATE_INFO *create_info, uint keys, KEY *key_info)
 {
-  register File file;
+  File file;
   ulong length;
   uchar fill[IO_SIZE];
   int create_flags= O_RDWR | O_TRUNC;
@@ -2642,7 +2642,7 @@ File create_frm(THD *thd, const char *na
   if (create_info->min_rows > UINT_MAX32)
     create_info->min_rows= UINT_MAX32;
 
-  if ((file= my_create(name, CREATE_MODE, create_flags, MYF(0))) >= 0)
+  if ((file= MYSQL_CREATE(key_file_frm, name, CREATE_MODE, create_flags, MYF(0))) >=
0)
   {
     uint key_length, tmp_key_length, tmp, csid;
     bzero((char*) fileinfo,64);
@@ -2718,9 +2718,9 @@ File create_frm(THD *thd, const char *na
     bzero(fill,IO_SIZE);
     for (; length > IO_SIZE ; length-= IO_SIZE)
     {
-      if (my_write(file,fill, IO_SIZE, MYF(MY_WME | MY_NABP)))
+      if (MYSQL_WRITE(file,fill, IO_SIZE, MYF(MY_WME | MY_NABP)))
       {
-	(void) my_close(file,MYF(0));
+	(void) MYSQL_CLOSE(file,MYF(0));
 	(void) my_delete(name,MYF(0));
 	return(-1);
       }

=== modified file 'storage/perfschema/Makefile.am'
--- a/storage/perfschema/Makefile.am	2008-12-04 16:56:02 +0000
+++ b/storage/perfschema/Makefile.am	2008-12-18 08:49:47 +0000
@@ -41,7 +41,8 @@ noinst_HEADERS = ha_perfschema.h pse_tab
 		pse_events_waits.h pse_timer.h table_processlist.h \
 		table_sync_instances.h \
 		table_events_waits_summary.h pse_stat.h \
-		table_all_sync.h
+		table_all_sync.h table_events_file.h \
+		table_file_instances.h table_file_usage_summary.h
 
 PSE_SOURCES = ha_perfschema.cc pse_table.cc pse.cc pse_server.cc \
 		pse_global.cc pse_sync_info.cc pse_sync.cc \
@@ -52,7 +53,8 @@ PSE_SOURCES = ha_perfschema.cc pse_table
 		pse_events_waits.cc pse_timer.cc table_processlist.cc \
 		table_sync_instances.cc \
 		table_events_waits_summary.cc \
-		table_all_sync.cc
+		table_all_sync.cc table_events_file.cc \
+		table_file_instances.cc table_file_usage_summary.cc
 
 EXTRA_LIBRARIES = libperfschema.a
 noinst_LIBRARIES = @plugin_perfschema_static_target@

=== modified file 'storage/perfschema/plug.in'
--- a/storage/perfschema/plug.in	2008-12-08 23:59:01 +0000
+++ b/storage/perfschema/plug.in	2008-12-18 08:49:47 +0000
@@ -167,6 +167,31 @@ fi
 AC_MSG_RESULT([$pse_max_thread_info])
 
 dnl -------------------------------------------------------------------------
+dnl PSE_MAX_FILE_INFO
+dnl -------------------------------------------------------------------------
+
+AC_ARG_WITH(
+  [pse-max-file-info],
+  AS_HELP_STRING(
+    [--with-pse-max-file-info=N],
+    [Performance Schema: maximum number of file info objects.]),
+    [pse_max_file_info="$withval"],
+    [pse_max_file_info="0"]
+)
+
+AC_MSG_CHECKING([pse max file info])
+
+if test "$pse_max_file_info" != "0"
+then
+  AC_DEFINE_UNQUOTED(
+    [PSE_MAX_FILE_INFO],
+    [$pse_max_file_info],
+    [Performance Schema: Maximum number of file info objects.])
+fi
+
+AC_MSG_RESULT([$pse_max_file_info])
+
+dnl -------------------------------------------------------------------------
 dnl PSE_MAX_MUTEX
 dnl -------------------------------------------------------------------------
 
@@ -292,6 +317,31 @@ fi
 AC_MSG_RESULT([$pse_max_table])
 
 dnl -------------------------------------------------------------------------
+dnl PSE_MAX_FILE
+dnl -------------------------------------------------------------------------
+
+AC_ARG_WITH(
+  [pse-max-file],
+  AS_HELP_STRING(
+    [--with-pse-max-file=N],
+    [Performance Schema: maximum number of instrumented file.]),
+    [pse_max_file="$withval"],
+    [pse_max_file="0"]
+)
+
+AC_MSG_CHECKING([pse max file])
+
+if test "$pse_max_file" != "0"
+then
+  AC_DEFINE_UNQUOTED(
+    [PSE_MAX_FILE],
+    [$pse_max_file],
+    [Performance Schema: Maximum number of instrumented files.])
+fi
+
+AC_MSG_RESULT([$pse_max_file])
+
+dnl -------------------------------------------------------------------------
 dnl PSE_WAITS_HISTORY_SIZE
 dnl -------------------------------------------------------------------------
 

=== modified file 'storage/perfschema/pse.cc'
--- a/storage/perfschema/pse.cc	2008-12-09 03:33:41 +0000
+++ b/storage/perfschema/pse.cc	2008-12-18 08:49:47 +0000
@@ -13,6 +13,7 @@
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
+#include "my_global.h"
 #include "pse.h"
 #include "pse_sync_info.h"
 #include "pse_sync.h"
@@ -213,6 +214,45 @@ static void register_thread_v1(const cha
   return;
 }
 
+static void register_file_v1(const char* category,
+                             struct PSI_file_info_v1 *info,
+                             int count)
+{
+  PSI_file_key key;
+  char formatted_name[MAX_INFO_NAME_LENGTH];
+  int prefix_length;
+  int len;
+
+  DBUG_ASSERT(category != NULL);
+  DBUG_ASSERT(info != NULL);
+  if (build_prefix(& file_instrument_prefix, category,
+                   formatted_name, & prefix_length))
+    return ;
+
+  for (; count>0; count--, info++)
+  {
+    DBUG_ASSERT(info->m_key != NULL);
+    DBUG_ASSERT(info->m_name != NULL);
+    len= strlen(info->m_name);
+    if (prefix_length + len <= MAX_INFO_NAME_LENGTH)
+    {
+      memcpy(formatted_name + prefix_length, info->m_name, len);
+      key= register_file_info(formatted_name,
+                              prefix_length + len,
+                              info->m_flags);
+    }
+    else
+    {
+      pse_print_error("register_file_v1: name too long <%s> <%s>\n",
+                      category, info->m_name);
+      key= 0;
+    }
+
+    *(info->m_key)= key;
+  }
+  return;
+}
+
 static PSI_mutex* init_mutex_v1(PSI_mutex_key key, void *identity)
 {
   PSE_mutex_info *info;
@@ -305,6 +345,146 @@ static void close_table_v1(PSI_table *ta
   PSE_table_dummy++;
 }
 
+PSI_file* create_file_stream_v1(PSI_file_key key,
+                         const char* name,
+                         void *identity)
+{
+  return NULL;
+}
+
+PSI_file* open_file_stream_v1(PSI_file_key key,
+                       const char* name,
+                       void *identity)
+{
+  PSE_file_info *info;
+  PSE_file *pse;
+
+  info= find_file_info(key);
+  if (info)
+  {
+    uint len= strlen(name);
+    pse= find_or_create_file(info, name, len);
+  }
+  else
+    pse = NULL;
+
+  return (PSI_file*) pse;
+}
+
+void close_file_stream_v1(PSI_file* file)
+{
+  PSE_file *pse= (PSE_file*) file;
+  release_file(pse);
+}
+
+void read_file_stream_v1(PSI_file* file, int count)
+{
+  PSE_file *pse= (PSE_file*) file;
+  pse->m_file_stat.m_read_count++;
+  pse->m_file_stat.m_read_bytes+= count;
+}
+
+void write_file_stream_v1(PSI_file* file, int count)
+{
+  PSE_file *pse= (PSE_file*) file;
+  pse->m_file_stat.m_write_count++;
+  pse->m_file_stat.m_write_bytes+= count;
+}
+
+#define MAX_FILE 16
+static PSE_file *file_instrumentation[MAX_FILE];
+
+void create_file_v1(PSI_file_key key, const char* name, File file)
+{
+  PSE_file_info *info;
+  PSE_file *pse= NULL;
+  int index= (int) file;
+
+  if (index >= 0)
+  {
+    if (index < MAX_FILE)
+    {
+      info= find_file_info(key);
+      if (info)
+      {
+        uint len= strlen(name);
+        pse= find_or_create_file(info, name, len);
+      }
+      file_instrumentation[index]= pse;
+    }
+    else
+      file_lost++;
+  }
+}
+
+void open_file_v1(PSI_file_key key, const char* name, File file)
+{
+  PSE_file_info *info;
+  PSE_file *pse= NULL;
+  int index= (int) file;
+
+  if (index >= 0)
+  {
+    if (index < MAX_FILE)
+    {
+      info= find_file_info(key);
+      if (info)
+      {
+        uint len= strlen(name);
+        pse= find_or_create_file(info, name, len);
+      }
+      file_instrumentation[index]= pse;
+    }
+    else
+      file_lost++;
+  }
+}
+
+void close_file_v1(File file)
+{
+  int index= (int) file;
+
+  if ((index >= 0) && (index < MAX_FILE))
+  {
+    PSE_file *pse= file_instrumentation[index];
+    if (pse)
+    {
+      file_instrumentation[index]= NULL;
+      release_file(pse);
+    }
+  }
+}
+
+void read_file_v1(File file, int count)
+{
+  int index= (int) file;
+
+  if ((index >= 0) && (index < MAX_FILE))
+  {
+    PSE_file *pse= file_instrumentation[index];
+    if (pse)
+    {
+      pse->m_file_stat.m_read_count++;
+      pse->m_file_stat.m_read_bytes+= count;
+    }
+  }
+}
+
+void write_file_v1(File file, int count)
+{
+  int index= (int) file;
+
+  if ((index >= 0) && (index < MAX_FILE))
+  {
+    PSE_file *pse= file_instrumentation[index];
+    if (pse)
+    {
+      pse->m_file_stat.m_write_count++;
+      pse->m_file_stat.m_write_bytes+= count;
+    }
+  }
+}
+
 static PSI_thread* new_thread_v1(PSI_thread_key key, void *identity)
 {
   PSE_thread_info *info;
@@ -357,13 +537,13 @@ static PSI_locker* get_thread_mutex_lock
     return NULL;
   if (! pse_thread->m_enabled)
     return NULL;
-  if (pse_thread->m_locker_count >= LOCKER_STACK_SIZE)
+  if (pse_thread->m_wait_locker_count >= LOCKER_STACK_SIZE)
   {
     locker_lost++;
     return NULL;
   }
-  PSE_locker *pse_locker;
-  pse_locker= & pse_thread->m_locker_stack[pse_thread->m_locker_count];
+  PSE_wait_locker *pse_locker;
+  pse_locker= &
pse_thread->m_wait_locker_stack[pse_thread->m_wait_locker_count];
 
   pse_locker->m_timer_name= wait_timer;
   pse_locker->m_target.m_mutex= pse_mutex;
@@ -373,7 +553,7 @@ static PSI_locker* get_thread_mutex_lock
   pse_locker->m_waits_current.m_identity= pse_mutex->m_identity;
   pse_locker->m_waits_current.m_wait_class= WAIT_CLASS_MUTEX;
 
-  pse_thread->m_locker_count++;
+  pse_thread->m_wait_locker_count++;
   return (PSI_locker*) pse_locker;
 }
 
@@ -390,13 +570,13 @@ static PSI_locker* get_thread_rwlock_loc
     return NULL;
   if (! pse_thread->m_enabled)
     return NULL;
-  if (pse_thread->m_locker_count >= LOCKER_STACK_SIZE)
+  if (pse_thread->m_wait_locker_count >= LOCKER_STACK_SIZE)
   {
     locker_lost++;
     return NULL;
   }
-  PSE_locker *pse_locker;
-  pse_locker= & pse_thread->m_locker_stack[pse_thread->m_locker_count];
+  PSE_wait_locker *pse_locker;
+  pse_locker= &
pse_thread->m_wait_locker_stack[pse_thread->m_wait_locker_count];
 
   pse_locker->m_timer_name= wait_timer;
   pse_locker->m_target.m_rwlock= pse_rwlock;
@@ -406,7 +586,7 @@ static PSI_locker* get_thread_rwlock_loc
   pse_locker->m_waits_current.m_identity= pse_rwlock->m_identity;
   pse_locker->m_waits_current.m_wait_class= WAIT_CLASS_RWLOCK;
 
-  pse_thread->m_locker_count++;
+  pse_thread->m_wait_locker_count++;
   return (PSI_locker*) pse_locker;
 }
 
@@ -423,13 +603,13 @@ static PSI_locker* get_thread_cond_locke
     return NULL;
   if (! pse_thread->m_enabled)
     return NULL;
-  if (pse_thread->m_locker_count >= LOCKER_STACK_SIZE)
+  if (pse_thread->m_wait_locker_count >= LOCKER_STACK_SIZE)
   {
     locker_lost++;
     return NULL;
   }
-  PSE_locker *pse_locker;
-  pse_locker= & pse_thread->m_locker_stack[pse_thread->m_locker_count];
+  PSE_wait_locker *pse_locker;
+  pse_locker= &
pse_thread->m_wait_locker_stack[pse_thread->m_wait_locker_count];
 
   pse_locker->m_timer_name= wait_timer;
   pse_locker->m_target.m_cond= pse_cond;
@@ -439,7 +619,7 @@ static PSI_locker* get_thread_cond_locke
   pse_locker->m_waits_current.m_identity= pse_cond->m_identity;
   pse_locker->m_waits_current.m_wait_class= WAIT_CLASS_COND;
 
-  pse_thread->m_locker_count++;
+  pse_thread->m_wait_locker_count++;
   return (PSI_locker*) pse_locker;
 }
 
@@ -571,7 +751,7 @@ static void broadcast_cond_v1(PSI_thread
 static void start_wait_v1(PSI_locker* locker, int must,
                           const char* file, int line)
 {
-  PSE_locker *pse_locker= (PSE_locker*) locker;
+  PSE_wait_locker *pse_locker= (PSE_wait_locker*) locker;
   DBUG_ASSERT(pse_locker != NULL);
 
   if (! flag_events_waits_current)
@@ -592,7 +772,7 @@ static void start_wait_v1(PSI_locker* lo
 
 static void end_wait_v1(PSI_locker* locker, int rc)
 {
-  PSE_locker *pse_locker= (PSE_locker*) locker;
+  PSE_wait_locker *pse_locker= (PSE_wait_locker*) locker;
   DBUG_ASSERT(pse_locker != NULL);
   PSE_events_waits *wait= & pse_locker->m_waits_current;
 
@@ -624,13 +804,13 @@ static void end_wait_v1(PSI_locker* lock
       }
     }
   }
-  wait->m_thread->m_locker_count--;
+  wait->m_thread->m_wait_locker_count--;
 }
 
 static void start_rdwait_v1(PSI_locker* locker, int must,
                             const char* file, int line)
 {
-  PSE_locker *pse_locker= (PSE_locker*) locker;
+  PSE_wait_locker *pse_locker= (PSE_wait_locker*) locker;
   DBUG_ASSERT(pse_locker != NULL);
 
   if (! flag_events_waits_current)
@@ -651,7 +831,7 @@ static void start_rdwait_v1(PSI_locker* 
 
 static void end_rdwait_v1(PSI_locker* locker, int rc)
 {
-  PSE_locker *pse_locker= (PSE_locker*) locker;
+  PSE_wait_locker *pse_locker= (PSE_wait_locker*) locker;
   DBUG_ASSERT(pse_locker != NULL);
   PSE_events_waits *wait= & pse_locker->m_waits_current;
 
@@ -694,13 +874,13 @@ static void end_rdwait_v1(PSI_locker* lo
       }
     }
   }
-  wait->m_thread->m_locker_count--;
+  wait->m_thread->m_wait_locker_count--;
 }
 
 static void start_wrwait_v1(PSI_locker* locker, int must,
                             const char* file, int line)
 {
-  PSE_locker *pse_locker= (PSE_locker*) locker;
+  PSE_wait_locker *pse_locker= (PSE_wait_locker*) locker;
   DBUG_ASSERT(pse_locker != NULL);
 
   if (! flag_events_waits_current)
@@ -721,7 +901,7 @@ static void start_wrwait_v1(PSI_locker* 
 
 static void end_wrwait_v1(PSI_locker* locker, int rc)
 {
-  PSE_locker *pse_locker= (PSE_locker*) locker;
+  PSE_wait_locker *pse_locker= (PSE_wait_locker*) locker;
   DBUG_ASSERT(pse_locker != NULL);
   PSE_events_waits *wait= & pse_locker->m_waits_current;
 
@@ -756,13 +936,13 @@ static void end_wrwait_v1(PSI_locker* lo
     }
   }
 
-  wait->m_thread->m_locker_count--;
+  wait->m_thread->m_wait_locker_count--;
 }
 
 static void start_condwait_v1(PSI_locker* locker, int must,
                               const char* file, int line)
 {
-  PSE_locker *pse_locker= (PSE_locker*) locker;
+  PSE_wait_locker *pse_locker= (PSE_wait_locker*) locker;
   DBUG_ASSERT(pse_locker != NULL);
 
   if (! flag_events_waits_current)
@@ -783,7 +963,7 @@ static void start_condwait_v1(PSI_locker
 
 static void end_condwait_v1(PSI_locker* locker, int rc)
 {
-  PSE_locker *pse_locker= (PSE_locker*) locker;
+  PSE_wait_locker *pse_locker= (PSE_wait_locker*) locker;
   DBUG_ASSERT(pse_locker != NULL);
   PSE_events_waits *wait= & pse_locker->m_waits_current;
 
@@ -814,7 +994,7 @@ static void end_condwait_v1(PSI_locker* 
     }
   }
 
-  wait->m_thread->m_locker_count--;
+  wait->m_thread->m_wait_locker_count--;
 }
 
 static void start_table_wait_v1(PSI_locker* locker)
@@ -831,6 +1011,7 @@ struct PSI_v1 PSE_v1=
   register_rwlock_v1,
   register_cond_v1,
   register_thread_v1,
+  register_file_v1,
   init_mutex_v1,
   destroy_mutex_v1,
   init_rwlock_v1,
@@ -841,6 +1022,16 @@ struct PSI_v1 PSE_v1=
   release_table_info_v1,
   open_table_v1,
   close_table_v1,
+  create_file_stream_v1,
+  open_file_stream_v1,
+  close_file_stream_v1,
+  read_file_stream_v1,
+  write_file_stream_v1,
+  create_file_v1,
+  open_file_v1,
+  close_file_v1,
+  read_file_v1,
+  write_file_v1,
   new_thread_v1,
   set_thread_id_v1,
   get_thread_v1,

=== modified file 'storage/perfschema/pse_bootstrap.cc'
--- a/storage/perfschema/pse_bootstrap.cc	2008-12-04 16:56:02 +0000
+++ b/storage/perfschema/pse_bootstrap.cc	2008-12-18 08:49:47 +0000
@@ -181,6 +181,48 @@ const char* pse_bootstrap_queries[]=
     "OBJECT_INSTANCE_BEGIN BIGINT not null"
   ") ENGINE=PERFORMANCE_SCHEMA;"
   ,
+  "DROP TABLE IF EXISTS performance_schema.events_file_current;"
+  ,
+  "CREATE TABLE performance_schema.events_file_current("
+    "THREAD_ID INTEGER not null, "
+    "EVENT_ID BIGINT not null, "
+    "NESTING_EVENT_ID BIGINT, "
+    "EVENT_NAME VARCHAR(128) character set utf8 collate utf8_unicode_ci not null, "
+    "TIMER_START BIGINT,"
+    "TIMER_END BIGINT,"
+    "TIMER_WAIT BIGINT,"
+    "FILE_NAME VARCHAR(1024) character set utf8 collate utf8_unicode_ci not null"
+  ") ENGINE=PERFORMANCE_SCHEMA;"
+  ,
+  "DROP TABLE IF EXISTS performance_schema.file_instances;"
+  ,
+  "CREATE TABLE performance_schema.file_instances("
+    "FILE_NAME VARCHAR(1024) character set utf8 collate utf8_unicode_ci not null, "
+    "EVENT_NAME VARCHAR(128) character set utf8 collate utf8_unicode_ci not null, "
+    "OPEN_COUNT INTEGER not null"
+  ") ENGINE=PERFORMANCE_SCHEMA;"
+  ,
+  "DROP TABLE IF EXISTS performance_schema.file_usage_summary_by_instance;"
+  ,
+  "CREATE TABLE performance_schema.file_usage_summary_by_instance("
+    "FILE_NAME VARCHAR(1024) character set utf8 collate utf8_unicode_ci not null, "
+    "EVENT_NAME VARCHAR(128) character set utf8 collate utf8_unicode_ci not null, "
+    "READ_COUNT INTEGER not null, "
+    "WRITE_COUNT INTEGER not null, "
+    "READ_BYTES BIGINT not null, "
+    "WRITE_BYTES BIGINT not null"
+  ") ENGINE=PERFORMANCE_SCHEMA;"
+  ,
+  "DROP TABLE IF EXISTS performance_schema.file_usage_summary_by_name;"
+  ,
+  "CREATE TABLE performance_schema.file_usage_summary_by_name("
+    "EVENT_NAME VARCHAR(128) character set utf8 collate utf8_unicode_ci not null, "
+    "READ_COUNT INTEGER not null, "
+    "WRITE_COUNT INTEGER not null, "
+    "READ_BYTES BIGINT not null, "
+    "WRITE_BYTES BIGINT not null"
+  ") ENGINE=PERFORMANCE_SCHEMA;"
+  ,
   0
 };
 

=== modified file 'storage/perfschema/pse_column_values.cc'
--- a/storage/perfschema/pse_column_values.cc	2008-11-22 00:28:06 +0000
+++ b/storage/perfschema/pse_column_values.cc	2008-12-18 08:49:47 +0000
@@ -31,3 +31,6 @@ LEX_STRING cond_instrument_prefix=
 LEX_STRING thread_instrument_prefix=
 { C_STRING_WITH_LEN("Thread/") };
 
+LEX_STRING file_instrument_prefix=
+{ C_STRING_WITH_LEN("IO/File/") };
+

=== modified file 'storage/perfschema/pse_column_values.h'
--- a/storage/perfschema/pse_column_values.h	2008-11-22 00:28:06 +0000
+++ b/storage/perfschema/pse_column_values.h	2008-12-18 08:49:47 +0000
@@ -22,6 +22,7 @@ extern LEX_STRING mutex_instrument_prefi
 extern LEX_STRING rwlock_instrument_prefix;
 extern LEX_STRING cond_instrument_prefix;
 extern LEX_STRING thread_instrument_prefix;
+extern LEX_STRING file_instrument_prefix;
 
 #endif
 

=== added file 'storage/perfschema/pse_events_file.h'
--- a/storage/perfschema/pse_events_file.h	1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/pse_events_file.h	2008-12-18 08:49:47 +0000
@@ -0,0 +1,78 @@
+/* Copyright (C) 2008 Sun Microsystems, Inc
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; version 2 of the License.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#ifndef PSE_EVENTS_FILE_H
+#define PSE_EVENTS_FILE_H
+
+#include "pse_column_types.h"
+
+struct PSE_thread;
+struct PSE_file_info;
+struct PSE_file;
+
+enum events_file_class
+{
+  NO_FILE_CLASS= 0,
+  FILE_CLASS_DISK
+};
+
+struct PSE_events_file
+{
+  volatile events_file_class m_file_class;
+  PSE_thread *m_thread;
+  PSE_file_info *m_info;
+  bool m_timed;
+  ulonglong m_event_id;
+  ulonglong m_timer_start;
+  ulonglong m_timer_end;
+  PSE_file *m_file;
+};
+
+struct PSE_file_locker
+{
+  enum_timer_name m_timer_name;
+  PSE_events_file m_file_current;
+};
+
+void insert_events_waits_history(PSE_thread *thread, PSE_events_waits *wait);
+void insert_events_waits_history_long(PSE_events_waits *wait);
+
+extern bool flag_events_waits_current;
+extern bool flag_events_waits_history;
+extern bool flag_events_waits_history_long;
+extern bool flag_events_waits_summary_by_thread_by_name;
+extern bool flag_events_waits_summary_by_name;
+extern bool flag_events_waits_summary_by_instance;
+extern bool flag_events_locks_summary_by_thread_by_name;
+extern bool flag_events_locks_summary_by_name;
+extern bool flag_events_locks_summary_by_instance;
+
+extern bool events_waits_history_long_full;
+extern uint events_waits_history_long_index;
+extern PSE_events_waits *events_waits_history_long_array;
+extern uint events_waits_history_long_size;
+
+int init_events_waits_history_long(uint events_waits_history_long_sizing);
+void cleanup_events_waits_history_long();
+
+void reset_events_waits_current();
+void reset_events_waits_history();
+void reset_events_waits_history_long();
+void reset_events_waits_summary_by_thread_by_name();
+void reset_events_waits_summary_by_name();
+void reset_events_waits_summary_by_instance();
+
+#endif
+

=== modified file 'storage/perfschema/pse_events_waits.cc'
--- a/storage/perfschema/pse_events_waits.cc	2008-12-08 23:59:01 +0000
+++ b/storage/perfschema/pse_events_waits.cc	2008-12-18 08:49:47 +0000
@@ -116,7 +116,7 @@ void reset_events_waits_current()
 
     for (local_index=0 ; local_index < LOCKER_STACK_SIZE; local_index++)
     {
-      pse_thread->m_locker_stack[local_index].m_waits_current.m_wait_class
+      pse_thread->m_wait_locker_stack[local_index].m_waits_current.m_wait_class
         = NO_WAIT_CLASS;
     }
   }

=== modified file 'storage/perfschema/pse_events_waits.h'
--- a/storage/perfschema/pse_events_waits.h	2008-12-08 23:59:01 +0000
+++ b/storage/perfschema/pse_events_waits.h	2008-12-18 08:49:47 +0000
@@ -64,7 +64,7 @@ struct PSE_events_waits
   int m_line;
 };
 
-struct PSE_locker
+struct PSE_wait_locker
 {
   enum_timer_name m_timer_name;
   events_waits_target m_target;

=== modified file 'storage/perfschema/pse_global.cc'
--- a/storage/perfschema/pse_global.cc	2008-11-13 03:12:30 +0000
+++ b/storage/perfschema/pse_global.cc	2008-12-18 08:49:47 +0000
@@ -43,7 +43,7 @@ void pse_free(void *ptr)
     free(ptr);
 }
 
-uint randomized_index(void *ptr, uint max_size)
+uint randomized_index(const void *ptr, uint max_size)
 {
   ulonglong index;
 

=== modified file 'storage/perfschema/pse_global.h'
--- a/storage/perfschema/pse_global.h	2008-11-13 03:12:30 +0000
+++ b/storage/perfschema/pse_global.h	2008-12-18 08:49:47 +0000
@@ -22,7 +22,7 @@ void *pse_malloc(size_t size, myf flags)
 #define PSE_MALLOC_ARRAY(n,T,f) (T*) pse_malloc((n) * sizeof(T), (f))
 void pse_free(void *ptr);
 
-uint randomized_index(void *ptr, uint max_size);
+uint randomized_index(const void *ptr, uint max_size);
 
 void pse_print_error(const char* format, ...);
 

=== modified file 'storage/perfschema/pse_server.cc'
--- a/storage/perfschema/pse_server.cc	2008-12-09 01:31:06 +0000
+++ b/storage/perfschema/pse_server.cc	2008-12-18 08:49:47 +0000
@@ -75,6 +75,11 @@ static uint thread_info_sizing= PSE_MAX_
 #endif
 static uint table_info_sizing= PSE_MAX_TABLE_INFO;
 
+#ifndef PSE_MAX_FILE_INFO
+  #define PSE_MAX_FILE_INFO 10
+#endif
+static uint file_info_sizing= PSE_MAX_FILE_INFO;
+
 #ifndef PSE_MAX_MUTEX
   #define PSE_MAX_MUTEX 1000
 #endif
@@ -100,6 +105,11 @@ static uint thread_sizing= PSE_MAX_THREA
 #endif
 static uint table_sizing= PSE_MAX_TABLE;
 
+#ifndef PSE_MAX_FILE
+  #define PSE_MAX_FILE 1000
+#endif
+static uint file_sizing= PSE_MAX_FILE;
+
 #ifndef PSE_WAITS_HISTORY_SIZE
   #define PSE_WAITS_HISTORY_SIZE 10
 #endif
@@ -165,6 +175,13 @@ struct pse_option all_pse_options[] =
     NULL
   },
   {
+    "--pse-max-file-info",
+    "Maximum number of file info objects.",
+    OPTION_UINT,
+    & file_info_sizing,
+    NULL
+  },
+  {
     "--pse-max-mutex",
     "Maximum number of instrumented MUTEX.",
     OPTION_UINT,
@@ -200,6 +217,13 @@ struct pse_option all_pse_options[] =
     NULL
   },
   {
+    "--pse-max-file",
+    "Maximum number of instrumented files.",
+    OPTION_UINT,
+    & file_sizing,
+    NULL
+  },
+  {
     "--pse-waits-history-size",
     "Number of rows per thread in EVENTS_WAITS_HISTORY.",
     OPTION_UINT,
@@ -445,8 +469,8 @@ struct PSI_bootstrap PSE_boostrap=
 };
 
 struct PSI_bootstrap*
-initialize_performance_schema(int argc_input, char ** argv_input,
-                              int *argc_output, char *** argv_output)
+initialize_performance_schema_1(int argc_input, char ** argv_input,
+                                int *argc_output, char *** argv_output)
 {
   pse_initialized= 0;
 
@@ -463,8 +487,11 @@ initialize_performance_schema(int argc_i
 
   if (init_sync_info(mutex_info_sizing, rwlock_info_sizing, cond_info_sizing) ||
       init_thread_info(thread_info_sizing) ||
+      init_table_info(table_info_sizing) ||
+      init_file_info(file_info_sizing) ||
       init_sync(mutex_sizing, rwlock_sizing, cond_sizing, thread_sizing,
waits_history_sizing) ||
-      init_events_waits_history_long(waits_history_long_sizing))
+      init_events_waits_history_long(waits_history_long_sizing) ||
+      init_file(file_sizing))
   {
     /*
       The performance schema initialization failed.
@@ -485,14 +512,28 @@ static void destroy_pse_thread(void *key
   destroy_thread(pse);
 }
 
-int initialize_performance_schema_pthread()
+int initialize_performance_schema_2()
 {
+  /*
+    Must be called after my_init_thread()
+  */
   if (pthread_key_create(&THR_PSE, destroy_pse_thread))
     return 1;
 
   return 0;
 }
 
+int initialize_performance_schema_3()
+{
+  /*
+    Must be called after MY_INIT()
+  */
+  if (init_file_hash())
+    return 1;
+
+  return 0;
+}
+
 int bootstrap_one_query(THD *thd, const char* query)
 {
   int length= strlen(query);
@@ -549,7 +590,11 @@ void shutdown_performance_schema()
 {
   cleanup_sync_info();
   cleanup_thread_info();
+  cleanup_table_info();
+  cleanup_file_info();
   cleanup_sync();
   cleanup_events_waits_history_long();
+  cleanup_file();
+  cleanup_file_hash();
 }
 

=== modified file 'storage/perfschema/pse_server.h'
--- a/storage/perfschema/pse_server.h	2008-11-13 03:12:30 +0000
+++ b/storage/perfschema/pse_server.h	2008-12-18 08:49:47 +0000
@@ -19,10 +19,11 @@
 class THD;
 
 struct PSI_bootstrap*
-initialize_performance_schema(int argc_input, char ** argv_input,
-                              int * argc_output, char *** argv_output);
+initialize_performance_schema_1(int argc_input, char ** argv_input,
+                                int * argc_output, char *** argv_output);
 
-int initialize_performance_schema_pthread();
+int initialize_performance_schema_2();
+int initialize_performance_schema_3();
 
 int bootstrap_performance_schema(THD *thd);
 

=== modified file 'storage/perfschema/pse_stat.h'
--- a/storage/perfschema/pse_stat.h	2008-12-05 20:19:48 +0000
+++ b/storage/perfschema/pse_stat.h	2008-12-18 08:49:47 +0000
@@ -83,5 +83,14 @@ struct PSE_cond_stat
   ulong m_broadcast_count;
 };
 
+struct PSE_file_stat
+{
+  ulong m_open_count;
+  ulong m_read_count;
+  ulong m_write_count;
+  ulonglong m_read_bytes;
+  ulonglong m_write_bytes;
+};
+
 #endif
 

=== modified file 'storage/perfschema/pse_sync.cc'
--- a/storage/perfschema/pse_sync.cc	2008-12-08 23:59:01 +0000
+++ b/storage/perfschema/pse_sync.cc	2008-12-18 08:49:47 +0000
@@ -14,6 +14,8 @@
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
 #include "my_global.h"
+#include "mysql_priv.h"
+#include "hash_filo.h"
 #include "my_sys.h"
 #include "pse_stat.h"
 #include "pse_sync.h"
@@ -27,6 +29,8 @@ uint cond_max;
 uint cond_lost;
 uint thread_max;
 uint thread_lost;
+uint file_max;
+uint file_lost;
 uint events_waits_history_per_thread;
 uint sync_info_per_thread;
 
@@ -34,11 +38,15 @@ PSE_mutex *mutex_array= NULL;
 PSE_rwlock *rwlock_array= NULL;
 PSE_cond *cond_array= NULL;
 PSE_thread *thread_array= NULL;
+PSE_file *file_array= NULL;
 static PSE_events_waits *thread_history_array= NULL;
 static PSE_single_stat *thread_sync_info_waits_array= NULL;
 
 static ulong thread_internal_id_counter= 0;
 
+// TODO: find out how the lock free hash (lf.h) works, and use it instead
+static hash_filo *filename_hash= NULL;
+
 int init_sync(uint mutex_sizing,
               uint rwlock_sizing,
               uint cond_sizing,
@@ -156,6 +164,58 @@ void cleanup_sync()
   thread_sync_info_waits_array= NULL;
 }
 
+int init_file(uint file_sizing)
+{
+  file_max= file_sizing;
+  file_lost= 0;
+
+  file_array= PSE_MALLOC_ARRAY(file_max, PSE_file, MYF(MY_ZEROFILL));
+  if (file_array == NULL)
+    return 1;
+
+  return 0;
+}
+
+int init_file_hash()
+{
+  PSE_file dummy;
+  uint offset= (uint) ((char*) (& dummy.m_filename) - (char*) & dummy);
+
+  filename_hash= new hash_filo(file_max,
+                               offset,
+                               sizeof(dummy.m_filename),
+                               NULL,
+                               NULL,
+                               &my_charset_bin);
+  if (filename_hash == NULL)
+    return 1;
+
+  filename_hash->clear();
+  return 0;
+}
+
+void cleanup_file()
+{
+  pse_free(file_array);
+  file_array= NULL;
+  file_max= 0;
+
+  if (filename_hash)
+  {
+    delete filename_hash;
+    filename_hash= NULL;
+  }
+}
+
+void cleanup_file_hash()
+{
+  if (filename_hash)
+  {
+    delete filename_hash;
+    filename_hash= NULL;
+  }
+}
+
 PSE_mutex* create_mutex(PSE_mutex_info *info, void *identity)
 {
   int pass;
@@ -319,7 +379,7 @@ PSE_thread* create_thread(PSE_thread_inf
         pse->m_enabled= true;
         pse->m_identity= identity;
         pse->m_info= info;
-        pse->m_locker_count= 0;
+        pse->m_wait_locker_count= 0;
         pse->m_waits_history_full= false;
         pse->m_waits_history_index= 0;
 
@@ -342,6 +402,80 @@ void destroy_thread(PSE_thread *pse)
   pse->m_allocated= false;
 }
 
+PSE_file*
+find_or_create_file(PSE_file_info *info, const char* filename, uint len)
+{
+  int pass;
+  PSE_file *pse;
+
+  if (filename_hash == NULL)
+  {
+    /*
+      The server initialization sequence in mysys is a tangled mess:
+      - you need an initialized THD_LOCK_MALLOC mutex to get memory with new,
+      - you need memory to get a hash_filo::lock mutex
+      The filename hash is initialized late, giving up on file io
+      instrumentation that may happen during the mysys initialization.
+    */
+    file_lost++;
+    return NULL;
+  }
+
+  if (len >= sizeof(pse->m_filename))
+    len= sizeof(pse->m_filename)-1;
+
+  MYSQL_MUTEX_LOCK(&filename_hash->lock);
+  pse= (PSE_file*) filename_hash->search((uchar*) filename, len);
+  if (pse)
+  {
+    pse->m_file_stat.m_open_count++;
+    MYSQL_MUTEX_UNLOCK(&filename_hash->lock);
+    return pse;
+  }
+
+  /* filename is not constant, just using it for noise on the first open */
+  uint i= randomized_index(filename, file_max);
+
+  /*
+    Pass 1: [random, file_max-1]
+    Pass 2: [0, file_max-1]
+  */
+  for (pass= 1; pass <= 2; i=0, pass++)
+  {
+    for ( ; i < file_max; i++)
+    {
+      pse= & file_array[i];
+      if (! pse->m_allocated)
+      {
+        // Safe, protected by the hash lock
+        pse->m_allocated= true;
+        pse->m_info= info;
+        strncpy(pse->m_filename, filename, len);
+        pse->m_filename[len]= '\0';
+        pse->m_filename_length= len;
+        pse->m_file_stat.m_open_count= 1;
+
+        /* FIXME: use a struct friendly, intrusive, lock free, hash table */
+        /* pse->m_hash_filo_element was initialized with memset */
+        filename_hash->add(& pse->m_hash_filo_element);
+        MYSQL_MUTEX_UNLOCK(&filename_hash->lock);
+        return pse;
+      }
+    }
+  }
+
+  MYSQL_MUTEX_UNLOCK(&filename_hash->lock);
+
+  file_lost++;
+  return NULL;
+}
+
+void release_file(PSE_file *pse)
+{
+  DBUG_ASSERT(pse != NULL);
+  pse->m_file_stat.m_open_count--;
+}
+
 bool flag_mutex_instances= true;
 bool flag_rwlock_instances= true;
 bool flag_cond_instances= true;

=== modified file 'storage/perfschema/pse_sync.h'
--- a/storage/perfschema/pse_sync.h	2008-12-08 23:59:01 +0000
+++ b/storage/perfschema/pse_sync.h	2008-12-18 08:49:47 +0000
@@ -16,8 +16,11 @@
 #ifndef PSE_SYNC_H
 #define PSE_SYNC_H
 
+#include "mysql_priv.h"
+#include "hash_filo.h"
 #include "pse_sync_info.h"
 #include "pse_events_waits.h"
+#include "pse_events_file.h"
 
 struct PSE_thread;
 
@@ -56,6 +59,18 @@ struct PSE_cond
   PSE_cond_stat m_cond_stat;
 };
 
+struct PSE_file
+{
+  hash_filo_element m_hash_filo_element;
+  char m_filename[1024];
+  uint m_filename_length;
+  bool m_allocated;
+  void *m_identity;
+  PSE_file_info *m_info;
+  PSE_single_stat_chain m_wait_stat;
+  PSE_file_stat m_file_stat;
+};
+
 #define LOCKER_STACK_SIZE 3
 
 struct PSE_thread
@@ -66,8 +81,9 @@ struct PSE_thread
   unsigned long m_thread_internal_id;
   unsigned long m_thread_id;
   PSE_thread_info *m_info;
-  uint m_locker_count;
-  PSE_locker m_locker_stack[LOCKER_STACK_SIZE];
+  uint m_wait_locker_count;
+  PSE_wait_locker m_wait_locker_stack[LOCKER_STACK_SIZE];
+  PSE_file_locker m_file_locker;
   bool m_waits_history_full;
   uint m_waits_history_index;
   PSE_events_waits *m_waits_history;
@@ -85,6 +101,11 @@ int init_sync(uint mutex_sizing,
               uint events_history_sizing);
 void cleanup_sync();
 
+int init_file(uint file_sizing);
+int init_file_hash();
+void cleanup_file();
+void cleanup_file_hash();
+
 PSE_mutex* create_mutex(PSE_mutex_info *info, void *identity);
 void destroy_mutex(PSE_mutex *pse);
 
@@ -97,6 +118,11 @@ void destroy_cond(PSE_cond *pse);
 PSE_thread* create_thread(PSE_thread_info *info, void *identity);
 void destroy_thread(PSE_thread *pse);
 
+PSE_file* find_or_create_file(PSE_file_info *info,
+                              const char* filename,
+                              uint len);
+void release_file(PSE_file *pse);
+
 /* For iterators and show status. */
 extern uint mutex_max;
 extern uint mutex_lost;
@@ -106,6 +132,8 @@ extern uint cond_max;
 extern uint cond_lost;
 extern uint thread_max;
 extern uint thread_lost;
+extern uint file_max;
+extern uint file_lost;
 extern uint events_waits_history_per_thread;
 extern uint sync_info_per_thread;
 
@@ -114,6 +142,7 @@ extern PSE_mutex *mutex_array;
 extern PSE_rwlock *rwlock_array;
 extern PSE_cond *cond_array;
 extern PSE_thread *thread_array;
+extern PSE_file *file_array;
 
 extern bool flag_mutex_instances;
 extern bool flag_rwlock_instances;

=== modified file 'storage/perfschema/pse_sync_info.cc'
--- a/storage/perfschema/pse_sync_info.cc	2008-12-05 20:19:48 +0000
+++ b/storage/perfschema/pse_sync_info.cc	2008-12-18 08:49:47 +0000
@@ -28,9 +28,9 @@
   - the performance schema initialization
   - a plugin initialization
 */
-static uint mutex_info_count;
-static uint rwlock_info_count;
-static uint cond_info_count;
+static uint mutex_info_count= 0;
+static uint rwlock_info_count= 0;
+static uint cond_info_count= 0;
 
 /**
   Maximum number of elements in sync_info_array.
@@ -38,17 +38,17 @@ static uint cond_info_count;
   - the performance schema initialization,
   and is constant afterwards.
 */
-uint mutex_info_max;
-uint rwlock_info_max;
-uint cond_info_max;
+uint mutex_info_max= 0;
+uint rwlock_info_max= 0;
+uint cond_info_max= 0;
 
 /**
   Number of elements the code failed to record in sync_info_array.
   Normally, this variable should be 0.
 */
-uint mutex_info_lost;
-uint rwlock_info_lost;
-uint cond_info_lost;
+uint mutex_info_lost= 0;
+uint rwlock_info_lost= 0;
+uint cond_info_lost= 0;
 
 static PSE_mutex_info *mutex_info_array= NULL;
 static PSE_rwlock_info *rwlock_info_array= NULL;
@@ -60,7 +60,7 @@ static PSE_cond_info *cond_info_array= N
   - the performance schema initialization
   - a plugin initialization
 */
-static uint thread_info_count;
+static uint thread_info_count= 0;
 
 /**
   Maximum number of elements in thread_info_array.
@@ -68,16 +68,28 @@ static uint thread_info_count;
   - the performance schema initialization,
   and is constant afterwards.
 */
-static uint thread_info_max;
+static uint thread_info_max= 0;
 
 /**
   Number of elements the code failed to record in thread_info_array.
   Normally, this variable should be 0.
 */
-static uint thread_info_lost;
+static uint thread_info_lost= 0;
 
 static PSE_thread_info *thread_info_array= NULL;
 
+static uint table_info_count= 0;
+static uint table_info_max= 0;
+static uint table_info_lost= 0;
+
+static PSE_table_info *table_info_array= NULL;
+
+static uint file_info_count= 0;
+static uint file_info_max= 0;
+static uint file_info_lost= 0;
+
+static PSE_file_info *file_info_array= NULL;
+
 #ifndef DBUG_OFF
 static void DEBUG_assert_main_or_plugin()
 {
@@ -123,10 +135,16 @@ void cleanup_sync_info()
 {
   pse_free(mutex_info_array);
   mutex_info_array= NULL;
+  mutex_info_count= 0;
+  mutex_info_max= 0;
   pse_free(rwlock_info_array);
   rwlock_info_array= NULL;
+  rwlock_info_count= 0;
+  rwlock_info_max= 0;
   pse_free(cond_info_array);
   cond_info_array= NULL;
+  cond_info_count= 0;
+  cond_info_max= 0;
 }
 
 int init_thread_info(uint thread_info_sizing)
@@ -144,6 +162,46 @@ void cleanup_thread_info()
 {
   pse_free(thread_info_array);
   thread_info_array= NULL;
+  thread_info_count= 0;
+  thread_info_max= 0;
+}
+
+int init_table_info(uint table_info_sizing)
+{
+  table_info_count= 0;
+  table_info_max= table_info_sizing;
+  table_info_lost= 0;
+
+  table_info_array= PSE_MALLOC_ARRAY(table_info_max, PSE_table_info, 0);
+
+  return (table_info_array ? 0 : 1);
+}
+
+void cleanup_table_info()
+{
+  pse_free(table_info_array);
+  table_info_array= NULL;
+  table_info_count= 0;
+  table_info_max= 0;
+}
+
+int init_file_info(uint file_info_sizing)
+{
+  file_info_count= 0;
+  file_info_max= file_info_sizing;
+  file_info_lost= 0;
+
+  file_info_array= PSE_MALLOC_ARRAY(file_info_max, PSE_file_info, 0);
+
+  return (file_info_array ? 0 : 1);
+}
+
+void cleanup_file_info()
+{
+  pse_free(file_info_array);
+  file_info_array= NULL;
+  file_info_count= 0;
+  file_info_max= 0;
 }
 
 void init_sync_info(PSE_sync_info *info,
@@ -152,6 +210,7 @@ void init_sync_info(PSE_sync_info *info,
                     int flags)
 {
   DBUG_ASSERT(name_length <= MAX_INFO_NAME_LENGTH);
+  memset(info, 0, sizeof(PSE_sync_info));
   strncpy(info->m_name, name, name_length);
   info->m_name_length= name_length;
   info->m_flags= flags;
@@ -339,6 +398,7 @@ PSE_thread_key register_thread_info(cons
     entry->m_name_length= name_length;
     entry->m_flags= flags;
     entry->m_enabled= true;
+    entry->m_timed= true;
     thread_info_count++;
     return thread_info_count;
   }
@@ -356,4 +416,53 @@ PSE_thread_info *find_thread_info(PSE_sy
   return & thread_info_array[key-1];
 }
 
+PSI_file_key register_file_info(const char* name,
+                                int name_length,
+                                int flags)
+{
+  uint index;
+  PSE_file_info *entry;
+
+#ifndef DBUG_OFF
+  DEBUG_assert_main_or_plugin();
+#endif
+
+  for (index= 0; index < file_info_count; index++)
+  {
+    entry= & file_info_array[index];
+
+    if (strncmp(entry->m_name, name, MAX_INFO_NAME_LENGTH) == 0)
+    {
+      DBUG_ASSERT(entry->m_flags == flags);
+      return (index+1);
+    }
+  }
+
+  if (file_info_count < file_info_max)
+  {
+    entry= & file_info_array[file_info_count];
+    DBUG_ASSERT(name_length <= MAX_INFO_NAME_LENGTH);
+    memset(entry, 0, sizeof(PSE_file_info));
+    strncpy(entry->m_name, name, name_length);
+    entry->m_name_length= name_length;
+    entry->m_flags= flags;
+    entry->m_enabled= true;
+    entry->m_timed= true;
+    file_info_count++;
+    return file_info_count;
+  }
+
+  file_info_lost++;
+  return 0;
+}
+
+
+PSE_file_info *find_file_info(PSI_file_key key)
+{
+  if ((key == 0) || (key > file_info_count))
+    return 0;
+
+  return & file_info_array[key-1];
+}
+
 

=== modified file 'storage/perfschema/pse_sync_info.h'
--- a/storage/perfschema/pse_sync_info.h	2008-12-09 01:31:06 +0000
+++ b/storage/perfschema/pse_sync_info.h	2008-12-18 08:49:47 +0000
@@ -68,6 +68,26 @@ struct PSE_thread_info
   uint m_name_length;
   int m_flags;
   bool m_enabled;
+  bool m_timed;
+};
+
+struct PSE_table_info
+{
+  char m_schema_name[64];
+  uint m_schema_name_length;
+  char m_table_name[64];
+  uint m_table_name_length;
+  bool m_enabled;
+  bool m_timed;
+};
+
+struct PSE_file_info
+{
+  char m_name[MAX_INFO_NAME_LENGTH];
+  uint m_name_length;
+  int m_flags;
+  bool m_enabled;
+  bool m_timed;
 };
 
 int init_sync_info(uint mutex_info_sizing,
@@ -78,6 +98,12 @@ void cleanup_sync_info();
 int init_thread_info(uint thread_info_sizing);
 void cleanup_thread_info();
 
+int init_table_info(uint table_info_sizing);
+void cleanup_table_info();
+
+int init_file_info(uint file_info_sizing);
+void cleanup_file_info();
+
 PSE_sync_key register_mutex_info(const char* name,
                                  int name_length,
                                  int flags);
@@ -100,6 +126,12 @@ PSE_thread_key register_thread_info(cons
 
 PSE_thread_info *find_thread_info(PSE_sync_key key);
 
+PSI_file_key register_file_info(const char* name,
+                                int name_length,
+                                int flags);
+
+PSE_file_info *find_file_info(PSI_file_key key);
+
 extern uint mutex_info_max;
 extern uint mutex_info_lost;
 extern uint rwlock_info_max;

=== modified file 'storage/perfschema/pse_table.cc'
--- a/storage/perfschema/pse_table.cc	2008-12-08 23:59:01 +0000
+++ b/storage/perfschema/pse_table.cc	2008-12-18 08:49:47 +0000
@@ -17,6 +17,7 @@
 #include "pse_table.h"
 
 #include "table_events_waits.h"
+#include "table_events_file.h"
 #include "table_setup_actors.h"
 #include "table_setup_consumers.h"
 #include "table_setup_instruments.h"
@@ -25,6 +26,8 @@
 #include "table_processlist.h"
 #include "table_events_waits_summary.h"
 #include "table_sync_instances.h"
+#include "table_file_instances.h"
+#include "table_file_usage_summary.h"
 
 /* For show status */
 #include "pse_column_values.h"
@@ -32,6 +35,7 @@
 
 static pse_table_info *pse_all_tables[]=
 {
+  & table_events_file_current::m_info,
   & table_events_waits_current::m_info,
   & table_events_waits_history::m_info,
   & table_events_waits_history_long::m_info,
@@ -45,9 +49,12 @@ static pse_table_info *pse_all_tables[]=
   & table_events_waits_summary_by_thread_by_name::m_info,
   & table_events_waits_summary_by_name::m_info,
   & table_events_waits_summary_by_instance::m_info,
+  & table_file_usage_summary_by_name::m_info,
+  & table_file_usage_summary_by_instance::m_info,
   & table_mutex_instances::m_info,
   & table_rwlock_instances::m_info,
   & table_cond_instances::m_info,
+  & table_file_instances::m_info,
   NULL
 };
 
@@ -135,7 +142,7 @@ bool pse_show_status(handlerton *hton, T
     switch (i){
     case 0:
       name= "EVENTS_WAITS_CURRENT.ROW_SIZE";
-      size= sizeof(PSE_locker);
+      size= sizeof(PSE_wait_locker);
       break;
     case 1:
       name= "EVENTS_WAITS_CURRENT.ROW_COUNT";

=== added file 'storage/perfschema/table_events_file.cc'
--- a/storage/perfschema/table_events_file.cc	1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_events_file.cc	2008-12-18 08:49:47 +0000
@@ -0,0 +1,125 @@
+/* Copyright (C) 2008 Sun Microsystems, Inc
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; version 2 of the License.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#include "mysql_priv.h"
+#include "table_events_file.h"
+#include "pse_sync_info.h"
+#include "pse_sync.h"
+
+pse_table_info
+table_events_file_current::m_info=
+{
+  { C_STRING_WITH_LEN("events_file_current") },
+  & table_events_file_current::create,
+  NULL, /* write_row */
+  & table_events_file_current::delete_all_rows,
+  1000, // TODO: records
+  sizeof(pos_events_file_current), // ref length
+  1000 // TODO: estimate rows upper bound
+};
+
+table_events_file_common::table_events_file_common()
+{
+  memset(& m_row, 0, sizeof(m_row));
+  m_row_exists= false;
+}
+
+void table_events_file_common::make_row(PSE_thread *pse_thread,
+                                       PSE_events_file *file)
+{
+  // TODO
+}
+
+int table_events_file_common::read_row_values(TABLE *table,
+                                             unsigned char *buf,
+                                             Field **fields,
+                                             bool read_all)
+{
+  // TODO
+  return 0;
+}
+
+pse_table* table_events_file_current::create()
+{
+  return new table_events_file_current();
+}
+
+table_events_file_current::table_events_file_current()
+{
+  m_pos.m_thread_index= 0;
+  m_next_thread_index= 0;
+}
+
+int table_events_file_current::rnd_next(void *ref)
+{
+  PSE_thread *pse_thread;
+  PSE_events_file *file;
+
+  m_pos.m_thread_index= m_next_thread_index;
+
+  for ( ; m_pos.m_thread_index < thread_max; )
+  {
+    pse_thread= & thread_array[m_pos.m_thread_index];
+
+    if (! pse_thread->m_allocated)
+    {
+      /* This thread does not exist */
+      goto next_thread;
+    }
+
+    file= & pse_thread->m_file_locker.m_file_current;
+    if (file->m_file_class == NO_FILE_CLASS)
+      goto next_thread;
+
+    record_position(ref);
+    make_row(pse_thread, file);
+    /* Next iteration, look for the next thread */
+    m_next_thread_index= m_pos.m_thread_index + 1;
+    return 0;
+
+next_thread:
+    m_pos.m_thread_index++;
+  }
+
+  return HA_ERR_END_OF_FILE;
+}
+
+int table_events_file_current::rnd_pos(void *ref, const void *pos)
+{
+  set_position(pos);
+  if (ref != pos)
+    record_position(ref);
+
+  return HA_ERR_WRONG_COMMAND;
+}
+
+void table_events_file_current::record_position(void *ref)
+{
+  memcpy(ref, & m_pos, sizeof(pos_events_file_current));
+}
+
+void table_events_file_current::set_position(const void *ref)
+{
+  memcpy(& m_pos, ref, sizeof(pos_events_file_current));
+}
+
+int table_events_file_current::delete_all_rows()
+{
+#ifdef LATER
+  reset_events_file_current();
+#endif
+  return 0;
+}
+

=== added file 'storage/perfschema/table_events_file.h'
--- a/storage/perfschema/table_events_file.h	1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_events_file.h	2008-12-18 08:49:47 +0000
@@ -0,0 +1,89 @@
+/* Copyright (C) 2008 Sun Microsystems, Inc
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; version 2 of the License.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#ifndef TABLE_EVENTS_FILE_H
+#define TABLE_EVENTS_FILE_H
+
+#include "pse_column_types.h"
+#include "pse_table.h"
+
+struct PSE_thread;
+struct PSE_events_file;
+
+struct row_events_file
+{
+  ulong m_thread_internal_id;
+  longlong m_event_id;
+  const char* m_name;
+  uint m_name_length;
+  bool m_timed;
+  longlong m_timer_start;
+  longlong m_timer_end;
+  longlong m_timer_wait;
+  const char* m_filename;
+  uint m_filename_length;
+};
+
+struct pos_events_file_current
+{
+  uint m_thread_index;
+};
+
+class table_events_file_common : public pse_readonly_table
+{
+protected:
+  virtual int read_row_values(TABLE *table,
+                              unsigned char *buf,
+                              Field **fields,
+                              bool read_all);
+
+  table_events_file_common();
+
+public:
+  ~table_events_file_common()
+  {}
+
+protected:
+  void make_row(PSE_thread *pse_thread, PSE_events_file *file);
+
+  row_events_file m_row;
+  bool m_row_exists;
+};
+
+class table_events_file_current : public table_events_file_common
+{
+public:
+  static pse_table_info m_info;
+  static pse_table* create();
+  static int delete_all_rows();
+
+  virtual int rnd_next(void *ref);
+  virtual int rnd_pos(void *ref, const void *pos);
+  virtual void record_position(void *ref);
+  virtual void set_position(const void *ref);
+
+protected:
+  table_events_file_current();
+
+public:
+  ~table_events_file_current()
+  {}
+
+private:
+  pos_events_file_current m_pos;
+  uint m_next_thread_index;
+};
+
+#endif

=== modified file 'storage/perfschema/table_events_waits.cc'
--- a/storage/perfschema/table_events_waits.cc	2008-12-08 23:59:01 +0000
+++ b/storage/perfschema/table_events_waits.cc	2008-12-18 08:49:47 +0000
@@ -238,7 +238,7 @@ int table_events_waits_current::rnd_next
 // #define ONLY_SHOW_CURRENT_WAITS
 
 #ifdef ONLY_SHOW_CURRENT_WAITS
-    if (m_pos.m_local_index >= pse_thread->m_locker_count)
+    if (m_pos.m_local_index >= pse_thread->m_wait_locker_count)
 #else
     if (m_pos.m_local_index >= LOCKER_STACK_SIZE)
 #endif
@@ -247,7 +247,7 @@ int table_events_waits_current::rnd_next
       goto next_thread;
     }
 
-    if (pse_thread->m_locker_stack[m_pos.m_local_index]
+    if (pse_thread->m_wait_locker_stack[m_pos.m_local_index]
         .m_waits_current.m_wait_class == NO_WAIT_CLASS)
     {
       /*
@@ -257,7 +257,7 @@ int table_events_waits_current::rnd_next
       goto next_thread;
     }
 
-    wait= & pse_thread->m_locker_stack[m_pos.m_local_index].m_waits_current;
+    wait= & pse_thread->m_wait_locker_stack[m_pos.m_local_index].m_waits_current;
 
     record_position(ref);
     make_row(pse_thread, wait);

=== added file 'storage/perfschema/table_file_instances.cc'
--- a/storage/perfschema/table_file_instances.cc	1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_file_instances.cc	2008-12-18 08:49:47 +0000
@@ -0,0 +1,153 @@
+/* Copyright (C) 2008 Sun Microsystems, Inc
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; version 2 of the License.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#include "mysql_priv.h"
+#include "pse_sync.h"
+#include "pse_column_types.h"
+#include "pse_column_values.h"
+#include "table_file_instances.h"
+#include "pse_global.h"
+
+pse_table_info
+table_file_instances::m_info=
+{
+  { C_STRING_WITH_LEN("file_instances") },
+  & table_file_instances::create,
+  NULL, /* write_row */
+  & table_file_instances::delete_all_rows,
+  1000,
+  sizeof(pos_file_instances),
+  1000
+};
+
+pse_table* table_file_instances::create()
+{
+  return new table_file_instances();
+}
+
+int table_file_instances::delete_all_rows()
+{
+  // reset_file_instances();
+  return 0;
+}
+
+table_file_instances::table_file_instances()
+{
+  m_pos.m_index= 0;
+  memset(& m_row, 0, sizeof(m_row));
+  m_row_exists= false;
+}
+
+int table_file_instances::rnd_next(void *ref)
+{
+  PSE_file *pse;
+
+  for ( ; m_pos.m_index < file_max; )
+  {
+    pse= & file_array[m_pos.m_index];
+
+    if (! pse->m_allocated)
+    {
+      /* This file does not exist, skip to the next one */
+      m_pos.m_index++;
+      continue;
+    }
+
+    record_position(ref);
+    make_row(pse);
+    m_pos.m_index++;
+    return 0;
+  }
+
+  return HA_ERR_END_OF_FILE;
+}
+
+int table_file_instances::rnd_pos(void *ref, const void *pos)
+{
+  return 0;
+}
+
+void table_file_instances::record_position(void *ref)
+{
+  memcpy(ref, & m_pos, sizeof(pos_file_instances));
+}
+
+void table_file_instances::set_position(const void *ref)
+{
+  memcpy(& m_pos, ref, sizeof(pos_file_instances));
+}
+
+void table_file_instances::make_row(PSE_file *pse)
+{
+  m_row.m_filename= pse->m_filename;
+  m_row.m_filename_length= pse->m_filename_length;
+  m_row.m_name= pse->m_info->m_name;
+  m_row.m_name_length= pse->m_info->m_name_length;
+  m_row.m_open_count= pse->m_file_stat.m_open_count;
+
+  m_row_exists= true;
+}
+
+int table_file_instances::read_row_values(TABLE *table,
+                                          unsigned char *buf,
+                                          Field **fields,
+                                          bool read_all)
+{
+  Field *f;
+  Field_varstring *col_filename;
+  Field_varstring *col_name;
+  Field_long *col_open_count;
+  CHARSET_INFO *cs;
+
+  cs= & my_charset_utf8_bin;
+
+  /* Set the null bits */
+  DBUG_ASSERT(table->s->null_bytes == 0);
+
+  if (! m_row_exists)
+    return HA_ERR_RECORD_DELETED;
+
+  for (; *fields ; fields++)
+  {
+    f= *fields;
+
+    if (read_all || bitmap_is_set(table->read_set, f->field_index))
+    {
+      switch(f->field_index)
+      {
+      case 0:
+        DBUG_ASSERT(f->real_type() == MYSQL_TYPE_VARCHAR);
+        col_filename= (Field_varstring*) f;
+        col_filename->store(m_row.m_filename, m_row.m_filename_length, cs);
+        break;
+      case 1:
+        DBUG_ASSERT(f->real_type() == MYSQL_TYPE_VARCHAR);
+        col_name= (Field_varstring*) f;
+        col_name->store(m_row.m_name, m_row.m_name_length, cs);
+        break;
+      case 2:
+        DBUG_ASSERT(f->real_type() == MYSQL_TYPE_LONG);
+        col_open_count= (Field_long*) f;
+        col_open_count->store(m_row.m_open_count);
+        break;
+      default:
+        DBUG_ASSERT(false);
+      }
+    }
+  }
+
+  return 0;
+}
+

=== added file 'storage/perfschema/table_file_instances.h'
--- a/storage/perfschema/table_file_instances.h	1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_file_instances.h	2008-12-18 08:49:47 +0000
@@ -0,0 +1,68 @@
+/* Copyright (C) 2008 Sun Microsystems, Inc
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; version 2 of the License.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#ifndef TABLE_FILE_INSTANCE_H
+#define TABLE_FILE_INSTANCE_H
+
+#include "pse_column_types.h"
+#include "pse_table.h"
+
+struct row_file_instances
+{
+  const char* m_filename;
+  uint m_filename_length;
+  const char* m_name;
+  uint m_name_length;
+  uint m_open_count;
+};
+
+struct pos_file_instances
+{
+  uint m_index;
+};
+
+class table_file_instances : public pse_readonly_table
+{
+public:
+  static pse_table_info m_info;
+  static pse_table* create();
+  static int delete_all_rows();
+
+  virtual int rnd_next(void *ref);
+  virtual int rnd_pos(void *ref, const void *pos);
+  virtual void record_position(void *ref);
+  virtual void set_position(const void *ref);
+
+private:
+  virtual int read_row_values(TABLE *table,
+                              unsigned char *buf,
+                              Field **fields,
+                              bool read_all);
+
+  table_file_instances();
+
+public:
+  ~table_file_instances()
+  {}
+
+private:
+  void make_row(PSE_file *pse);
+
+  row_file_instances m_row;
+  pos_file_instances m_pos;
+  bool m_row_exists;
+};
+
+#endif

=== added file 'storage/perfschema/table_file_usage_summary.cc'
--- a/storage/perfschema/table_file_usage_summary.cc	1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_file_usage_summary.cc	2008-12-18 08:49:47 +0000
@@ -0,0 +1,235 @@
+/* Copyright (C) 2008 Sun Microsystems, Inc
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; version 2 of the License.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#include "mysql_priv.h"
+#include "pse_sync_info.h"
+#include "pse_column_types.h"
+#include "pse_column_values.h"
+#include "table_file_usage_summary.h"
+#include "pse_global.h"
+
+pse_table_info
+table_file_usage_summary_by_name::m_info=
+{
+  { C_STRING_WITH_LEN("file_usage_summary_by_name") },
+  & table_file_usage_summary_by_name::create,
+  NULL, /* write_row */
+  NULL, /* delete_all_rows */
+  1000,
+  sizeof(pos_file_usage_summary_by_name),
+  1000
+};
+
+pse_table* table_file_usage_summary_by_name::create()
+{
+  return new table_file_usage_summary_by_name();
+}
+
+table_file_usage_summary_by_name::table_file_usage_summary_by_name()
+{
+  m_pos.m_index= 0;
+  m_next_index= 0;
+  m_row_exists= false;
+}
+
+int table_file_usage_summary_by_name::rnd_next(void *ref)
+{
+// TODO
+  return HA_ERR_END_OF_FILE;
+}
+
+int table_file_usage_summary_by_name::rnd_pos(void *ref, const void *pos)
+{
+  set_position(pos);
+  if (ref != pos)
+    record_position(ref);
+
+  return HA_ERR_WRONG_COMMAND;
+}
+
+void table_file_usage_summary_by_name::record_position(void *ref)
+{
+  memcpy(ref, & m_pos, sizeof(pos_file_usage_summary_by_name));
+}
+
+void table_file_usage_summary_by_name::set_position(const void *ref)
+{
+  memcpy(& m_pos, ref, sizeof(pos_file_usage_summary_by_name));
+}
+
+void table_file_usage_summary_by_name::make_row(PSE_file_info *info)
+{
+  // TODO
+}
+
+int table_file_usage_summary_by_name::read_row_values(TABLE *table,
+                                             unsigned char *buf,
+                                             Field **fields,
+                                             bool read_all)
+{
+  // TODO
+  return 0;
+}
+
+pse_table_info
+table_file_usage_summary_by_instance::m_info=
+{
+  { C_STRING_WITH_LEN("file_usage_summary_by_instance") },
+  & table_file_usage_summary_by_instance::create,
+  NULL, /* write_row */
+  NULL, /* delete_all_rows */
+  1000,
+  sizeof(pos_file_usage_summary_by_instance),
+  1000
+};
+
+pse_table* table_file_usage_summary_by_instance::create()
+{
+  return new table_file_usage_summary_by_instance();
+}
+
+table_file_usage_summary_by_instance::table_file_usage_summary_by_instance()
+{
+  m_pos.m_index= 0;
+  m_next_index= 0;
+  m_row_exists= false;
+}
+
+int table_file_usage_summary_by_instance::rnd_next(void *ref)
+{
+  PSE_file *pse;
+
+  for ( ; m_pos.m_index < file_max; )
+  {
+    pse= & file_array[m_pos.m_index];
+
+    if (! pse->m_allocated)
+    {
+      /* This file does not exist, skip to the next one */
+      m_pos.m_index++;
+      continue;
+    }
+
+    record_position(ref);
+    make_row(pse);
+    m_pos.m_index++;
+    return 0;
+  }
+
+  return HA_ERR_END_OF_FILE;
+}
+
+int table_file_usage_summary_by_instance::rnd_pos(void *ref, const void *pos)
+{
+  set_position(pos);
+  if (ref != pos)
+    record_position(ref);
+
+  return HA_ERR_WRONG_COMMAND;
+}
+
+void table_file_usage_summary_by_instance::record_position(void *ref)
+{
+  memcpy(ref, & m_pos, sizeof(pos_file_usage_summary_by_instance));
+}
+
+void table_file_usage_summary_by_instance::set_position(const void *ref)
+{
+  memcpy(& m_pos, ref, sizeof(pos_file_usage_summary_by_instance));
+}
+
+void table_file_usage_summary_by_instance::make_row(PSE_file *pse)
+{
+  m_row.m_filename= pse->m_filename;
+  m_row.m_filename_length= pse->m_filename_length;
+  m_row.m_name= pse->m_info->m_name;
+  m_row.m_name_length= pse->m_info->m_name_length;
+  m_row.m_read_count= pse->m_file_stat.m_read_count;
+  m_row.m_write_count= pse->m_file_stat.m_write_count;
+  m_row.m_read_bytes= pse->m_file_stat.m_read_bytes;
+  m_row.m_write_bytes= pse->m_file_stat.m_write_bytes;
+
+  m_row_exists= true;
+}
+
+int table_file_usage_summary_by_instance::read_row_values(TABLE *table,
+                                             unsigned char *buf,
+                                             Field **fields,
+                                             bool read_all)
+{
+  Field *f;
+  Field_varstring *col_filename;
+  Field_varstring *col_name;
+  Field_long *col_read_count;
+  Field_long *col_write_count;
+  Field_longlong *col_read_bytes;
+  Field_longlong *col_write_bytes;
+  CHARSET_INFO *cs;
+
+  cs= & my_charset_utf8_bin;
+
+  /* Set the null bits */
+  DBUG_ASSERT(table->s->null_bytes == 0);
+
+  if (! m_row_exists)
+    return HA_ERR_RECORD_DELETED;
+
+  for (; *fields ; fields++)
+  {
+    f= *fields;
+
+    if (read_all || bitmap_is_set(table->read_set, f->field_index))
+    {
+      switch(f->field_index)
+      {
+      case 0:
+        DBUG_ASSERT(f->real_type() == MYSQL_TYPE_VARCHAR);
+        col_filename= (Field_varstring*) f;
+        col_filename->store(m_row.m_filename, m_row.m_filename_length, cs);
+        break;
+      case 1:
+        DBUG_ASSERT(f->real_type() == MYSQL_TYPE_VARCHAR);
+        col_name= (Field_varstring*) f;
+        col_name->store(m_row.m_name, m_row.m_name_length, cs);
+        break;
+      case 2:
+        DBUG_ASSERT(f->real_type() == MYSQL_TYPE_LONG);
+        col_read_count= (Field_long*) f;
+        col_read_count->store(m_row.m_read_count);
+        break;
+      case 3:
+        DBUG_ASSERT(f->real_type() == MYSQL_TYPE_LONG);
+        col_write_count= (Field_long*) f;
+        col_write_count->store(m_row.m_write_count);
+        break;
+      case 4:
+        DBUG_ASSERT(f->real_type() == MYSQL_TYPE_LONGLONG);
+        col_read_bytes= (Field_longlong*) f;
+        col_read_bytes->store(m_row.m_read_bytes);
+        break;
+      case 5:
+        DBUG_ASSERT(f->real_type() == MYSQL_TYPE_LONGLONG);
+        col_write_bytes= (Field_longlong*) f;
+        col_write_bytes->store(m_row.m_write_bytes);
+        break;
+      default:
+        DBUG_ASSERT(false);
+      }
+    }
+  }
+
+  return 0;
+}
+

=== added file 'storage/perfschema/table_file_usage_summary.h'
--- a/storage/perfschema/table_file_usage_summary.h	1970-01-01 00:00:00 +0000
+++ b/storage/perfschema/table_file_usage_summary.h	2008-12-18 08:49:47 +0000
@@ -0,0 +1,120 @@
+/* Copyright (C) 2008 Sun Microsystems, Inc
+
+  This program is free software; you can redistribute it and/or modify
+  it under the terms of the GNU General Public License as published by
+  the Free Software Foundation; version 2 of the License.
+
+  This program is distributed in the hope that it will be useful,
+  but WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+  GNU General Public License for more details.
+
+  You should have received a copy of the GNU General Public License
+  along with this program; if not, write to the Free Software
+  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
+
+#ifndef TABLE_FILE_USAGE_SUMMARY_H
+#define TABLE_FILE_USAGE_SUMMARY_H
+
+#include "pse_column_types.h"
+#include "pse_table.h"
+#include "pse_sync_info.h"
+#include "pse_sync.h"
+
+struct row_file_usage_summary_by_name
+{
+  const char* m_name;
+  uint m_name_length;
+  ulong m_read_count;
+  ulong m_write_count;
+  ulonglong m_read_bytes;
+  ulonglong m_write_bytes;
+};
+
+struct pos_file_usage_summary_by_name
+{
+  uint m_index;
+};
+
+class table_file_usage_summary_by_name : public pse_readonly_table
+{
+public:
+  static pse_table_info m_info;
+  static pse_table* create();
+
+  virtual int rnd_next(void *ref);
+  virtual int rnd_pos(void *ref, const void *pos);
+  virtual void record_position(void *ref);
+  virtual void set_position(const void *ref);
+
+protected:
+  virtual void make_row(PSE_file_info *info);
+
+  virtual int read_row_values(TABLE *table,
+                              unsigned char *buf,
+                              Field **fields,
+                              bool read_all);
+
+  table_file_usage_summary_by_name();
+
+public:
+  ~table_file_usage_summary_by_name()
+  {}
+
+protected:
+  row_file_usage_summary_by_name m_row;
+  pos_file_usage_summary_by_name m_pos;
+  uint m_next_index;
+  bool m_row_exists;
+};
+
+struct row_file_usage_summary_by_instance
+{
+  const char* m_filename;
+  uint m_filename_length;
+  const char* m_name;
+  uint m_name_length;
+  ulong m_read_count;
+  ulong m_write_count;
+  ulonglong m_read_bytes;
+  ulonglong m_write_bytes;
+};
+
+struct pos_file_usage_summary_by_instance
+{
+  uint m_index;
+};
+
+class table_file_usage_summary_by_instance : public pse_readonly_table
+{
+public:
+  static pse_table_info m_info;
+  static pse_table* create();
+
+  virtual int rnd_next(void *ref);
+  virtual int rnd_pos(void *ref, const void *pos);
+  virtual void record_position(void *ref);
+  virtual void set_position(const void *ref);
+
+protected:
+  virtual void make_row(PSE_file *pse);
+
+  virtual int read_row_values(TABLE *table,
+                              unsigned char *buf,
+                              Field **fields,
+                              bool read_all);
+
+  table_file_usage_summary_by_instance();
+
+public:
+  ~table_file_usage_summary_by_instance()
+  {}
+
+protected:
+  row_file_usage_summary_by_instance m_row;
+  pos_file_usage_summary_by_instance m_pos;
+  uint m_next_index;
+  bool m_row_exists;
+};
+
+#endif

=== modified file 'storage/perfschema/table_setup_instruments.cc'
--- a/storage/perfschema/table_setup_instruments.cc	2008-12-04 16:56:02 +0000
+++ b/storage/perfschema/table_setup_instruments.cc	2008-12-18 08:49:47 +0000
@@ -23,6 +23,8 @@
 const uint VIEW_MUTEX= 1;
 const uint VIEW_RWLOCK= 2;
 const uint VIEW_COND= 3;
+const uint VIEW_THREAD= 4;
+const uint VIEW_FILE= 5;
 
 pse_table_info
 table_setup_instruments::m_info=
@@ -56,11 +58,13 @@ int table_setup_instruments::rnd_next(vo
   PSE_mutex_info *mutex_info;
   PSE_rwlock_info *rwlock_info;
   PSE_cond_info *cond_info;
+  PSE_thread_info *thread_info;
+  PSE_file_info *file_info;
 
   m_pos.m_view_index= m_next_view_index;
   m_pos.m_local_index= m_next_local_index;
 
-  for ( ; m_pos.m_view_index <= VIEW_COND; )
+  for ( ; m_pos.m_view_index <= VIEW_FILE; )
   {
     switch (m_pos.m_view_index) {
     case VIEW_MUTEX:
@@ -102,6 +106,32 @@ int table_setup_instruments::rnd_next(vo
       m_pos.m_view_index++;
       m_pos.m_local_index= 1;
       break;
+    case VIEW_THREAD:
+      thread_info= find_thread_info(m_pos.m_local_index);
+      if (thread_info)
+      {
+        record_position(ref);
+        make_row(thread_info);
+        m_next_view_index= m_pos.m_view_index;
+        m_next_local_index= m_pos.m_local_index + 1;
+        return 0;
+      }
+      m_pos.m_view_index++;
+      m_pos.m_local_index= 1;
+      break;
+    case VIEW_FILE:
+      file_info= find_file_info(m_pos.m_local_index);
+      if (file_info)
+      {
+        record_position(ref);
+        make_row(file_info);
+        m_next_view_index= m_pos.m_view_index;
+        m_next_local_index= m_pos.m_local_index + 1;
+        return 0;
+      }
+      m_pos.m_view_index++;
+      m_pos.m_local_index= 1;
+      break;
     }
   }
 
@@ -155,6 +185,36 @@ void table_setup_instruments::make_row(P
   m_row_exists= true;
 }
 
+void table_setup_instruments::make_row(PSE_thread_info *info)
+{
+  if (info == NULL)
+  {
+    m_row_exists= false;
+    return;
+  }
+
+  m_row.m_name= & info->m_name[0];
+  m_row.m_name_length= info->m_name_length;
+  m_row.m_enabled_ptr= & info->m_enabled;
+  m_row.m_timed_ptr= & info->m_timed;
+  m_row_exists= true;
+}
+
+void table_setup_instruments::make_row(PSE_file_info *info)
+{
+  if (info == NULL)
+  {
+    m_row_exists= false;
+    return;
+  }
+
+  m_row.m_name= & info->m_name[0];
+  m_row.m_name_length= info->m_name_length;
+  m_row.m_enabled_ptr= & info->m_enabled;
+  m_row.m_timed_ptr= & info->m_timed;
+  m_row_exists= true;
+}
+
 int table_setup_instruments::read_row_values(TABLE *table,
                                              unsigned char *buf,
                                              Field **fields,

=== modified file 'storage/perfschema/table_setup_instruments.h'
--- a/storage/perfschema/table_setup_instruments.h	2008-12-09 01:31:06 +0000
+++ b/storage/perfschema/table_setup_instruments.h	2008-12-18 08:49:47 +0000
@@ -30,7 +30,7 @@ struct row_setup_instruments
 struct pos_setup_instruments
 {
   uint m_view_index;
-  PSE_sync_key m_local_index;
+  uint m_local_index;
 };
 
 class table_setup_instruments : public pse_updatable_table
@@ -63,6 +63,8 @@ public:
 
 private:
   void make_row(PSE_sync_info *info);
+  void make_row(PSE_thread_info *info);
+  void make_row(PSE_file_info *info);
 
   pos_setup_instruments m_pos;
   row_setup_instruments m_row;

Thread
bzr commit into mysql-6.0-perf branch (marc.alff:2754) Marc Alff18 Dec