List:Commits« Previous MessageNext Message »
From:Christopher Powers Date:August 3 2010 9:14pm
Subject:bzr commit into mysql-next-mr-wl4896 branch (chris.powers:3156)
View as plain text  
#At file:///home/cpowers/work/dev/base-wl4896/mysql/ based on revid:chris.powers@stripped

 3156 Christopher Powers	2010-08-03
      merge

    modified:
      include/mysql/psi/mysql_file.h
      include/mysql/psi/mysql_thread.h
      include/mysql/psi/psi.h
      include/mysql/psi/psi_abi_v1.h
      include/mysql/psi/psi_abi_v2.h
      storage/perfschema/CMakeLists.txt
      storage/perfschema/Makefile.am
      storage/perfschema/ha_perfschema.cc
      storage/perfschema/pfs.cc
      storage/perfschema/pfs_column_types.h
      storage/perfschema/pfs_events_waits.h
      storage/perfschema/pfs_instr.cc
      storage/perfschema/pfs_instr.h
      storage/perfschema/pfs_instr_class.cc
      storage/perfschema/pfs_instr_class.h
      storage/perfschema/pfs_server.h
      storage/perfschema/table_all_instr.h
      storage/perfschema/table_events_waits.cc
      storage/perfschema/table_events_waits.h
      storage/perfschema/table_events_waits_summary.h
      storage/perfschema/table_setup_instruments.cc
      storage/perfschema/table_setup_instruments.h
      storage/perfschema/table_setup_objects.cc
      storage/perfschema/table_setup_objects.h
=== modified file 'include/mysql/psi/mysql_file.h'
--- a/include/mysql/psi/mysql_file.h	2010-03-31 14:05:33 +0000
+++ b/include/mysql/psi/mysql_file.h	2010-08-03 21:14:19 +0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -10,8 +10,8 @@
   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 */
+  along with this program; if not, write to the Free Software Foundation,
+  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
 
 #ifndef MYSQL_FILE_H
 #define MYSQL_FILE_H
@@ -506,9 +506,10 @@ inline_mysql_file_fgets(
   char *result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server && file->m_psi))
   {
-    locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+    locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi,
                                                       PSI_FILE_READ);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, (size_t) size, src_file, src_line);
@@ -532,9 +533,10 @@ inline_mysql_file_fgetc(
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server && file->m_psi))
   {
-    locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+    locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi,
                                                       PSI_FILE_READ);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, (size_t) 1, src_file, src_line);
@@ -558,10 +560,11 @@ inline_mysql_file_fputs(
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   size_t bytes= 0;
   if (likely(PSI_server && file->m_psi))
   {
-    locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+    locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi,
                                                       PSI_FILE_WRITE);
     if (likely(locker != NULL))
     {
@@ -588,9 +591,10 @@ inline_mysql_file_fputc(
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server && file->m_psi))
   {
-    locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+    locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi,
                                                       PSI_FILE_WRITE);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, (size_t) 1, src_file, src_line);
@@ -614,9 +618,10 @@ inline_mysql_file_fprintf(MYSQL_FILE *fi
   va_list args;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server && file->m_psi))
   {
-    locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+    locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi,
                                                       PSI_FILE_WRITE);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, (size_t) 0, __FILE__, __LINE__);
@@ -642,9 +647,10 @@ inline_mysql_file_vfprintf(
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server && file->m_psi))
   {
-    locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+    locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi,
                                                       PSI_FILE_WRITE);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
@@ -668,9 +674,10 @@ inline_mysql_file_fflush(
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server && file->m_psi))
   {
-    locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+    locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi,
                                                       PSI_FILE_FLUSH);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
@@ -700,9 +707,10 @@ inline_mysql_file_fstat(
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server != NULL))
   {
-    locker= PSI_server->get_thread_file_descriptor_locker(filenr,
+    locker= PSI_server->get_thread_file_descriptor_locker(&state, filenr,
                                                           PSI_FILE_FSTAT);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
@@ -726,9 +734,11 @@ inline_mysql_file_stat(
   MY_STAT *result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server != NULL))
   {
-    locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_STAT,
+    locker= PSI_server->get_thread_file_name_locker(&state,
+                                                    key, PSI_FILE_STAT,
                                                     path, &locker);
     if (likely(locker != NULL))
       PSI_server->start_file_open_wait(locker, src_file, src_line);
@@ -752,9 +762,10 @@ inline_mysql_file_chsize(
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server != NULL))
   {
-    locker= PSI_server->get_thread_file_descriptor_locker(file,
+    locker= PSI_server->get_thread_file_descriptor_locker(&state, file,
                                                           PSI_FILE_CHSIZE);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, (size_t) newlength, src_file,
@@ -784,10 +795,11 @@ inline_mysql_file_fopen(
     {
 #ifdef HAVE_PSI_INTERFACE
       struct PSI_file_locker *locker= NULL;
+      PSI_file_locker_state state;
       if (likely(PSI_server != NULL))
       {
         locker= PSI_server->get_thread_file_name_locker
-          (key, PSI_FILE_STREAM_OPEN, filename, that);
+          (&state, key, PSI_FILE_STREAM_OPEN, filename, that);
         if (likely(locker != NULL))
           that->m_psi= PSI_server->start_file_open_wait(locker, src_file,
                                                         src_line);
@@ -800,7 +812,7 @@ inline_mysql_file_fopen(
 #endif
       if (unlikely(that->m_file == NULL))
       {
-        my_free(that, MYF(0));
+        my_free(that);
         return NULL;
       }
     }
@@ -820,10 +832,11 @@ inline_mysql_file_fclose(
   {
 #ifdef HAVE_PSI_INTERFACE
     struct PSI_file_locker *locker= NULL;
+    PSI_file_locker_state state;
     DBUG_ASSERT(file != NULL);
     if (likely(PSI_server && file->m_psi))
     {
-      locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+      locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi,
                                                         PSI_FILE_STREAM_CLOSE);
       if (likely(locker != NULL))
         PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
@@ -834,7 +847,7 @@ inline_mysql_file_fclose(
     if (likely(locker != NULL))
       PSI_server->end_file_wait(locker, (size_t) 0);
 #endif
-    my_free(file, MYF(0));
+    my_free(file);
   }
   return result;
 }
@@ -849,9 +862,10 @@ inline_mysql_file_fread(
   size_t result= 0;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server && file->m_psi))
   {
-    locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+    locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi,
                                                       PSI_FILE_READ);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, count, src_file, src_line);
@@ -882,9 +896,10 @@ inline_mysql_file_fwrite(
   size_t result= 0;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server && file->m_psi))
   {
-    locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+    locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi,
                                                       PSI_FILE_WRITE);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, count, src_file, src_line);
@@ -915,9 +930,10 @@ inline_mysql_file_fseek(
   my_off_t result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server && file->m_psi))
   {
-    locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+    locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi,
                                                       PSI_FILE_SEEK);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
@@ -941,9 +957,10 @@ inline_mysql_file_ftell(
   my_off_t result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server && file->m_psi))
   {
-    locker= PSI_server->get_thread_file_stream_locker(file->m_psi,
+    locker= PSI_server->get_thread_file_stream_locker(&state, file->m_psi,
                                                       PSI_FILE_TELL);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
@@ -967,9 +984,10 @@ inline_mysql_file_create(
   File file;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server != NULL))
   {
-    locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_CREATE,
+    locker= PSI_server->get_thread_file_name_locker(&state, key, PSI_FILE_CREATE,
                                                     filename, &locker);
     if (likely(locker != NULL))
       PSI_server->start_file_open_wait(locker, src_file, src_line);
@@ -1014,9 +1032,10 @@ inline_mysql_file_open(
   File file;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server != NULL))
   {
-    locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_OPEN,
+    locker= PSI_server->get_thread_file_name_locker(&state, key, PSI_FILE_OPEN,
                                                     filename, &locker);
     if (likely(locker != NULL))
       PSI_server->start_file_open_wait(locker, src_file, src_line);
@@ -1040,9 +1059,10 @@ inline_mysql_file_close(
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server != NULL))
   {
-    locker= PSI_server->get_thread_file_descriptor_locker(file,
+    locker= PSI_server->get_thread_file_descriptor_locker(&state, file,
                                                           PSI_FILE_CLOSE);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
@@ -1066,9 +1086,10 @@ inline_mysql_file_read(
   size_t result= 0;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server != NULL))
   {
-    locker= PSI_server->get_thread_file_descriptor_locker(file,
+    locker= PSI_server->get_thread_file_descriptor_locker(&state, file,
                                                           PSI_FILE_READ);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, count, src_file, src_line);
@@ -1099,9 +1120,10 @@ inline_mysql_file_write(
   size_t result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server != NULL))
   {
-    locker= PSI_server->get_thread_file_descriptor_locker(file,
+    locker= PSI_server->get_thread_file_descriptor_locker(&state, file,
                                                           PSI_FILE_WRITE);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, count, src_file, src_line);
@@ -1132,9 +1154,10 @@ inline_mysql_file_pread(
   size_t result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server != NULL))
   {
-    locker= PSI_server->get_thread_file_descriptor_locker(file, PSI_FILE_READ);
+    locker= PSI_server->get_thread_file_descriptor_locker(&state, file, PSI_FILE_READ);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, count, src_file, src_line);
   }
@@ -1164,9 +1187,10 @@ inline_mysql_file_pwrite(
   size_t result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server != NULL))
   {
-    locker= PSI_server->get_thread_file_descriptor_locker(file,
+    locker= PSI_server->get_thread_file_descriptor_locker(&state, file,
                                                           PSI_FILE_WRITE);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, count, src_file, src_line);
@@ -1197,9 +1221,10 @@ inline_mysql_file_seek(
   my_off_t result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server != NULL))
   {
-    locker= PSI_server->get_thread_file_descriptor_locker(file, PSI_FILE_SEEK);
+    locker= PSI_server->get_thread_file_descriptor_locker(&state, file, PSI_FILE_SEEK);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
   }
@@ -1222,9 +1247,10 @@ inline_mysql_file_tell(
   my_off_t result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server != NULL))
   {
-    locker= PSI_server->get_thread_file_descriptor_locker(file, PSI_FILE_TELL);
+    locker= PSI_server->get_thread_file_descriptor_locker(&state, file, PSI_FILE_TELL);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
   }
@@ -1247,9 +1273,10 @@ inline_mysql_file_delete(
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server != NULL))
   {
-    locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_DELETE,
+    locker= PSI_server->get_thread_file_name_locker(&state, key, PSI_FILE_DELETE,
                                                     name, &locker);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
@@ -1273,9 +1300,10 @@ inline_mysql_file_rename(
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server != NULL))
   {
-    locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_RENAME,
+    locker= PSI_server->get_thread_file_name_locker(&state, key, PSI_FILE_RENAME,
                                                     to, &locker);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
@@ -1300,9 +1328,10 @@ inline_mysql_file_create_with_symlink(
   File file;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server != NULL))
   {
-    locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_CREATE,
+    locker= PSI_server->get_thread_file_name_locker(&state, key, PSI_FILE_CREATE,
                                                     filename, &locker);
     if (likely(locker != NULL))
       PSI_server->start_file_open_wait(locker, src_file, src_line);
@@ -1327,9 +1356,10 @@ inline_mysql_file_delete_with_symlink(
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server != NULL))
   {
-    locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_DELETE,
+    locker= PSI_server->get_thread_file_name_locker(&state, key, PSI_FILE_DELETE,
                                                     name, &locker);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
@@ -1353,9 +1383,10 @@ inline_mysql_file_rename_with_symlink(
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server != NULL))
   {
-    locker= PSI_server->get_thread_file_name_locker(key, PSI_FILE_RENAME,
+    locker= PSI_server->get_thread_file_name_locker(&state, key, PSI_FILE_RENAME,
                                                     to, &locker);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
@@ -1379,9 +1410,10 @@ inline_mysql_file_sync(
   int result= 0;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_file_locker *locker= NULL;
+  PSI_file_locker_state state;
   if (likely(PSI_server != NULL))
   {
-    locker= PSI_server->get_thread_file_descriptor_locker(fd, PSI_FILE_SYNC);
+    locker= PSI_server->get_thread_file_descriptor_locker(&state, fd, PSI_FILE_SYNC);
     if (likely(locker != NULL))
       PSI_server->start_file_wait(locker, (size_t) 0, src_file, src_line);
   }

=== modified file 'include/mysql/psi/mysql_thread.h'
--- a/include/mysql/psi/mysql_thread.h	2010-03-09 18:03:02 +0000
+++ b/include/mysql/psi/mysql_thread.h	2010-08-03 21:14:19 +0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -10,8 +10,8 @@
   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 */
+  along with this program; if not, write to the Free Software Foundation,
+  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
 
 #ifndef MYSQL_THREAD_H
 #define MYSQL_THREAD_H
@@ -625,9 +625,10 @@ static inline int inline_mysql_mutex_loc
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_mutex_locker *locker= NULL;
+  PSI_mutex_locker_state state;
   if (likely(PSI_server && that->m_psi))
   {
-    locker= PSI_server->get_thread_mutex_locker(that->m_psi, PSI_MUTEX_LOCK);
+    locker= PSI_server->get_thread_mutex_locker(&state, that->m_psi, PSI_MUTEX_LOCK);
     if (likely(locker != NULL))
       PSI_server->start_mutex_wait(locker, src_file, src_line);
   }
@@ -654,9 +655,10 @@ static inline int inline_mysql_mutex_try
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_mutex_locker *locker= NULL;
+  PSI_mutex_locker_state state;
   if (likely(PSI_server && that->m_psi))
   {
-    locker= PSI_server->get_thread_mutex_locker(that->m_psi, PSI_MUTEX_TRYLOCK);
+    locker= PSI_server->get_thread_mutex_locker(&state, that->m_psi, PSI_MUTEX_TRYLOCK);
     if (likely(locker != NULL))
       PSI_server->start_mutex_wait(locker, src_file, src_line);
   }
@@ -682,13 +684,8 @@ static inline int inline_mysql_mutex_unl
 {
   int result;
 #ifdef HAVE_PSI_INTERFACE
-  struct PSI_thread *thread;
   if (likely(PSI_server && that->m_psi))
-  {
-    thread= PSI_server->get_thread();
-    if (likely(thread != NULL))
-      PSI_server->unlock_mutex(thread, that->m_psi);
-  }
+    PSI_server->unlock_mutex(that->m_psi);
 #endif
 #ifdef SAFE_MUTEX
   result= safe_mutex_unlock(&that->m_mutex, src_file, src_line);
@@ -771,9 +768,10 @@ static inline int inline_mysql_rwlock_rd
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_rwlock_locker *locker= NULL;
+  PSI_rwlock_locker_state state;
   if (likely(PSI_server && that->m_psi))
   {
-    locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+    locker= PSI_server->get_thread_rwlock_locker(&state, that->m_psi,
                                                  PSI_RWLOCK_READLOCK);
     if (likely(locker != NULL))
       PSI_server->start_rwlock_rdwait(locker, src_file, src_line);
@@ -798,9 +796,10 @@ static inline int inline_mysql_prlock_rd
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_rwlock_locker *locker= NULL;
+  PSI_rwlock_locker_state state;
   if (likely(PSI_server && that->m_psi))
   {
-    locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+    locker= PSI_server->get_thread_rwlock_locker(&state, that->m_psi,
                                                  PSI_RWLOCK_READLOCK);
     if (likely(locker != NULL))
       PSI_server->start_rwlock_rdwait(locker, src_file, src_line);
@@ -825,9 +824,10 @@ static inline int inline_mysql_rwlock_wr
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_rwlock_locker *locker= NULL;
+  PSI_rwlock_locker_state state;
   if (likely(PSI_server && that->m_psi))
   {
-    locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+    locker= PSI_server->get_thread_rwlock_locker(&state, that->m_psi,
                                                  PSI_RWLOCK_WRITELOCK);
     if (likely(locker != NULL))
       PSI_server->start_rwlock_wrwait(locker, src_file, src_line);
@@ -852,9 +852,10 @@ static inline int inline_mysql_prlock_wr
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_rwlock_locker *locker= NULL;
+  PSI_rwlock_locker_state state;
   if (likely(PSI_server && that->m_psi))
   {
-    locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+    locker= PSI_server->get_thread_rwlock_locker(&state, that->m_psi,
                                                  PSI_RWLOCK_WRITELOCK);
     if (likely(locker != NULL))
       PSI_server->start_rwlock_wrwait(locker, src_file, src_line);
@@ -879,9 +880,10 @@ static inline int inline_mysql_rwlock_tr
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_rwlock_locker *locker= NULL;
+  PSI_rwlock_locker_state state;
   if (likely(PSI_server && that->m_psi))
   {
-    locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+    locker= PSI_server->get_thread_rwlock_locker(&state, that->m_psi,
                                                  PSI_RWLOCK_TRYREADLOCK);
     if (likely(locker != NULL))
       PSI_server->start_rwlock_rdwait(locker, src_file, src_line);
@@ -906,9 +908,10 @@ static inline int inline_mysql_prlock_tr
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_rwlock_locker *locker= NULL;
+  PSI_rwlock_locker_state state;
   if (likely(PSI_server && that->m_psi))
   {
-    locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+    locker= PSI_server->get_thread_rwlock_locker(&state, that->m_psi,
                                                  PSI_RWLOCK_TRYREADLOCK);
     if (likely(locker != NULL))
       PSI_server->start_rwlock_rdwait(locker, src_file, src_line);
@@ -933,9 +936,10 @@ static inline int inline_mysql_rwlock_tr
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_rwlock_locker *locker= NULL;
+  PSI_rwlock_locker_state state;
   if (likely(PSI_server && that->m_psi))
   {
-    locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+    locker= PSI_server->get_thread_rwlock_locker(&state, that->m_psi,
                                                  PSI_RWLOCK_TRYWRITELOCK);
     if (likely(locker != NULL))
       PSI_server->start_rwlock_wrwait(locker, src_file, src_line);
@@ -960,9 +964,10 @@ static inline int inline_mysql_prlock_tr
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_rwlock_locker *locker= NULL;
+  PSI_rwlock_locker_state state;
   if (likely(PSI_server && that->m_psi))
   {
-    locker= PSI_server->get_thread_rwlock_locker(that->m_psi,
+    locker= PSI_server->get_thread_rwlock_locker(&state, that->m_psi,
                                                  PSI_RWLOCK_TRYWRITELOCK);
     if (likely(locker != NULL))
       PSI_server->start_rwlock_wrwait(locker, src_file, src_line);
@@ -982,13 +987,8 @@ static inline int inline_mysql_rwlock_un
 {
   int result;
 #ifdef HAVE_PSI_INTERFACE
-  struct PSI_thread *thread;
   if (likely(PSI_server && that->m_psi))
-  {
-    thread= PSI_server->get_thread();
-    if (likely(thread != NULL))
-      PSI_server->unlock_rwlock(thread, that->m_psi);
-  }
+    PSI_server->unlock_rwlock(that->m_psi);
 #endif
   result= rw_unlock(&that->m_rwlock);
   return result;
@@ -1000,13 +1000,8 @@ static inline int inline_mysql_prlock_un
 {
   int result;
 #ifdef HAVE_PSI_INTERFACE
-  struct PSI_thread *thread;
   if (likely(PSI_server && that->m_psi))
-  {
-    thread= PSI_server->get_thread();
-    if (likely(thread != NULL))
-      PSI_server->unlock_rwlock(thread, that->m_psi);
-  }
+    PSI_server->unlock_rwlock(that->m_psi);
 #endif
   result= rw_pr_unlock(&that->m_prlock);
   return result;
@@ -1053,9 +1048,10 @@ static inline int inline_mysql_cond_wait
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_cond_locker *locker= NULL;
+  PSI_cond_locker_state state;
   if (likely(PSI_server && that->m_psi))
   {
-    locker= PSI_server->get_thread_cond_locker(that->m_psi, mutex->m_psi,
+    locker= PSI_server->get_thread_cond_locker(&state, that->m_psi, mutex->m_psi,
                                                PSI_COND_WAIT);
     if (likely(locker != NULL))
       PSI_server->start_cond_wait(locker, src_file, src_line);
@@ -1081,9 +1077,10 @@ static inline int inline_mysql_cond_time
   int result;
 #ifdef HAVE_PSI_INTERFACE
   struct PSI_cond_locker *locker= NULL;
+  PSI_cond_locker_state state;
   if (likely(PSI_server && that->m_psi))
   {
-    locker= PSI_server->get_thread_cond_locker(that->m_psi, mutex->m_psi,
+    locker= PSI_server->get_thread_cond_locker(&state, that->m_psi, mutex->m_psi,
                                                PSI_COND_TIMEDWAIT);
     if (likely(locker != NULL))
       PSI_server->start_cond_wait(locker, src_file, src_line);
@@ -1102,13 +1099,8 @@ static inline int inline_mysql_cond_sign
 {
   int result;
 #ifdef HAVE_PSI_INTERFACE
-  struct PSI_thread *thread;
   if (likely(PSI_server && that->m_psi))
-  {
-    thread= PSI_server->get_thread();
-    if (likely(thread != NULL))
-      PSI_server->signal_cond(thread, that->m_psi);
-  }
+    PSI_server->signal_cond(that->m_psi);
 #endif
   result= pthread_cond_signal(&that->m_cond);
   return result;
@@ -1119,13 +1111,8 @@ static inline int inline_mysql_cond_broa
 {
   int result;
 #ifdef HAVE_PSI_INTERFACE
-  struct PSI_thread *thread;
   if (likely(PSI_server && that->m_psi))
-  {
-    thread= PSI_server->get_thread();
-    if (likely(thread != NULL))
-      PSI_server->broadcast_cond(thread, that->m_psi);
-  }
+    PSI_server->broadcast_cond(that->m_psi);
 #endif
   result= pthread_cond_broadcast(&that->m_cond);
   return result;

=== modified file 'include/mysql/psi/psi.h'
--- a/include/mysql/psi/psi.h	2010-07-29 19:56:17 +0000
+++ b/include/mysql/psi/psi.h	2010-08-03 21:14:19 +0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2010 Sun Microsystems, Inc
+/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -10,8 +10,8 @@
   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 */
+  along with this program; if not, write to the Free Software Foundation,
+  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
 
 #ifndef MYSQL_PERFORMANCE_SCHEMA_INTERFACE_H
 #define MYSQL_PERFORMANCE_SCHEMA_INTERFACE_H
@@ -29,6 +29,8 @@
 
 C_MODE_START
 
+struct TABLE_SHARE;
+
 /**
   @file mysql/psi/psi.h
   Performance schema instrumentation interface.
@@ -86,6 +88,12 @@ struct PSI_file;
 */
 struct PSI_socket;
 
+/**
+  Interface for an instrumented table operation.
+  This is an opaque structure.
+*/
+struct PSI_table_locker;
+
 /** Entry point for the performance schema interface. */
 struct PSI_bootstrap
 {
@@ -235,6 +243,23 @@ enum PSI_file_operation
   PSI_FILE_SYNC= 16
 };
 
+/** Operation performed on an instrumented table. */
+enum PSI_table_operation
+{
+  /** Table lock, in the server layer. */
+  PSI_TABLE_LOCK= 0,
+  /** Table lock, in the storage engine layer. */
+  PSI_TABLE_EXTERNAL_LOCK= 1,
+  /** Row fetch. */
+  PSI_TABLE_FETCH_ROW= 2,
+  /** Row write. */
+  PSI_TABLE_WRITE_ROW= 3,
+  /** Row update. */
+  PSI_TABLE_UPDATE_ROW= 4,
+  /** Row delete. */
+  PSI_TABLE_DELETE_ROW= 5
+};
+
 /** Operation performed on an instrumented socket. */
 enum PSI_socket_operation
 {
@@ -269,13 +294,6 @@ enum PSI_socket_operation
   PSI_SOCKET_SHUTDOWN= 9
 };
 
-
-/**
-  Interface for an instrumented table operation.
-  This is an opaque structure.
-*/
-struct PSI_table_locker;
-
 /**
   Instrumented mutex key.
   To instrument a mutex, a mutex key must be obtained using @c register_mutex.
@@ -492,6 +510,175 @@ struct PSI_socket_info_v1
   int m_flags;
 };
 
+/**
+  State data storage for @c get_thread_mutex_locker_v1_t.
+  This structure provide temporary storage to a mutex locker.
+  The content of this structure is considered opaque,
+  the fields are only hints of what an implementation
+  of the psi interface can use.
+  This memory is provided by the instrumented code for performance reasons.
+  @sa get_thread_mutex_locker_v1_t
+*/
+struct PSI_mutex_locker_state_v1
+{
+  /** Internal state. */
+  uint m_flags;
+  /** Current mutex. */
+  struct PSI_mutex *m_mutex;
+  /** Current thread. */
+  struct PSI_thread *m_thread;
+  /** Timer start. */
+  ulonglong m_timer_start;
+  /** Timer function. */
+  ulonglong (*m_timer)(void);
+  /** Current operation. */
+  enum PSI_mutex_operation m_operation;
+  /** Source file. */
+  const char* m_src_file;
+  /** Source line number. */
+  int m_src_line;
+  /** Internal data. */
+  void *m_wait;
+};
+
+/**
+  State data storage for @c get_thread_rwlock_locker_v1_t.
+  This structure provide temporary storage to a rwlock locker.
+  The content of this structure is considered opaque,
+  the fields are only hints of what an implementation
+  of the psi interface can use.
+  This memory is provided by the instrumented code for performance reasons.
+  @sa get_thread_rwlock_locker_v1_t
+*/
+struct PSI_rwlock_locker_state_v1
+{
+  /** Internal state. */
+  uint m_flags;
+  /** Current rwlock. */
+  struct PSI_rwlock *m_rwlock;
+  /** Current thread. */
+  struct PSI_thread *m_thread;
+  /** Timer start. */
+  ulonglong m_timer_start;
+  /** Timer function. */
+  ulonglong (*m_timer)(void);
+  /** Current operation. */
+  enum PSI_rwlock_operation m_operation;
+  /** Source file. */
+  const char* m_src_file;
+  /** Source line number. */
+  int m_src_line;
+  /** Internal data. */
+  void *m_wait;
+};
+
+/**
+  State data storage for @c get_thread_cond_locker_v1_t.
+  This structure provide temporary storage to a condition locker.
+  The content of this structure is considered opaque,
+  the fields are only hints of what an implementation
+  of the psi interface can use.
+  This memory is provided by the instrumented code for performance reasons.
+  @sa get_thread_cond_locker_v1_t
+*/
+struct PSI_cond_locker_state_v1
+{
+  /** Internal state. */
+  uint m_flags;
+  /** Current condition. */
+  struct PSI_cond *m_cond;
+  /** Current mutex. */
+  struct PSI_mutex *m_mutex;
+  /** Current thread. */
+  struct PSI_thread *m_thread;
+  /** Timer start. */
+  ulonglong m_timer_start;
+  /** Timer function. */
+  ulonglong (*m_timer)(void);
+  /** Current operation. */
+  enum PSI_cond_operation m_operation;
+  /** Source file. */
+  const char* m_src_file;
+  /** Source line number. */
+  int m_src_line;
+  /** Internal data. */
+  void *m_wait;
+};
+
+/**
+  State data storage for @c get_thread_file_name_locker_v1_t.
+  This structure provide temporary storage to a file locker.
+  The content of this structure is considered opaque,
+  the fields are only hints of what an implementation
+  of the psi interface can use.
+  This memory is provided by the instrumented code for performance reasons.
+  @sa get_thread_file_name_locker_v1_t
+  @sa get_thread_file_stream_locker_v1_t
+  @sa get_thread_file_descriptor_locker_v1_t
+*/
+struct PSI_file_locker_state_v1
+{
+  /** Internal state. */
+  uint m_flags;
+  /** Current file. */
+  struct PSI_file *m_file;
+  /** Current thread. */
+  struct PSI_thread *m_thread;
+  /** Operation number of bytes. */
+  size_t m_number_of_bytes;
+  /** Timer start. */
+  ulonglong m_timer_start;
+  /** Timer function. */
+  ulonglong (*m_timer)(void);
+  /** Current operation. */
+  enum PSI_file_operation m_operation;
+  /** Source file. */
+  const char* m_src_file;
+  /** Source line number. */
+  int m_src_line;
+  /** Internal data. */
+  void *m_wait;
+};
+
+/**
+  State data storage for @c get_thread_table_locker_v1_t.
+  This structure provide temporary storage to a table locker.
+  The content of this structure is considered opaque,
+  the fields are only hints of what an implementation
+  of the psi interface can use.
+  This memory is provided by the instrumented code for performance reasons.
+  @sa get_thread_table_locker_v1_t
+*/
+struct PSI_table_locker_state_v1
+{
+  /** Internal state. */
+  uint m_flags;
+  /** Current table handle. */
+  struct PSI_table *m_table;
+  /** Current table share. */
+  struct PSI_table_share *m_table_share;
+  /** Instrumentation class. */
+  void *m_class;
+  /** Current thread. */
+  struct PSI_thread *m_thread;
+  /** Timer start. */
+  ulonglong m_timer_start;
+  /** Timer function. */
+  ulonglong (*m_timer)(void);
+  /** Current operation. */
+  enum PSI_table_operation m_operation;
+  /** Current table io index. */
+  uint m_index;
+  /** Current table lock index. */
+  uint m_lock_index;
+  /** Source file. */
+  const char* m_src_file;
+  /** Source line number. */
+  int m_src_line;
+  /** Internal data. */
+  void *m_wait;
+};
+
 /* Using typedef to make reuse between PSI_v1 and PSI_v2 easier later. */
 
 /**
@@ -594,6 +781,15 @@ typedef struct PSI_cond* (*init_cond_v1_
 typedef void (*destroy_cond_v1_t)(struct PSI_cond *cond);
 
 /**
+  Acquire a table share instrumentation.
+  @param temporary True for temporary tables
+  @param share The SQL layer table share
+  @return a table share instrumentation, or NULL
+*/
+typedef struct PSI_table_share* (*get_table_share_v1_t)
+  (my_bool temporary, struct TABLE_SHARE *share);
+
+/**
   Socket instrumentation initialisation API.
   @param key the registered mutex key
   @param identity the address of the socket itself
@@ -608,26 +804,23 @@ typedef struct PSI_socket* (*init_socket
 */
 typedef void (*destroy_socket_v1_t)(struct PSI_socket *socket);
 
-/**
-  Acquire a table info by name.
-  @param schema_name name of the table schema
-  @param schema_name_length length of schema_name
-  @param table_name name of the table
-  @param table_name_length length of table_name
-  @param identity table identity pointer, typically the table share
-  @return a table info, or NULL if the table is not instrumented
-*/
-typedef struct PSI_table_share* (*get_table_share_v1_t)
-  (const char *schema_name, int schema_name_length, const char *table_name,
-   int table_name_length, const void *identity);
-
-/**
   Release a table share.
   @param info the table share to release
 */
 typedef void (*release_table_share_v1_t)(struct PSI_table_share *share);
 
 /**
+  Drop a table share.
+  @param schema_name the table schema name
+  @param schema_name_length the table schema name length
+  @param table_name the table name
+  @param table_name_length the table name length
+*/
+typedef void (*drop_table_share_v1_t)
+  (const char *schema_name, int schema_name_length,
+   const char *table_name, int table_name_length);
+
+/**
   Open an instrumentation table handle.
   @param share the table to open
   @param identity table handle identity
@@ -713,40 +906,53 @@ typedef void (*delete_thread_v1_t)(struc
 
 /**
   Get a mutex instrumentation locker.
+  @param state data storage for the locker
   @param mutex the instrumented mutex to lock
   @return a mutex locker, or NULL
 */
 typedef struct PSI_mutex_locker* (*get_thread_mutex_locker_v1_t)
-  (struct PSI_mutex *mutex, enum PSI_mutex_operation op);
+  (struct PSI_mutex_locker_state_v1 *state,
+   struct PSI_mutex *mutex,
+   enum PSI_mutex_operation op);
 
 /**
   Get a rwlock instrumentation locker.
+  @param state data storage for the locker
   @param rwlock the instrumented rwlock to lock
   @return a rwlock locker, or NULL
 */
 typedef struct PSI_rwlock_locker* (*get_thread_rwlock_locker_v1_t)
-  (struct PSI_rwlock *rwlock, enum PSI_rwlock_operation op);
+  (struct PSI_rwlock_locker_state_v1 *state,
+   struct PSI_rwlock *rwlock,
+   enum PSI_rwlock_operation op);
 
 /**
   Get a cond instrumentation locker.
+  @param state data storage for the locker
   @param cond the instrumented condition to wait on
   @param mutex the instrumented mutex associated with the condition
   @return a condition locker, or NULL
 */
 typedef struct PSI_cond_locker* (*get_thread_cond_locker_v1_t)
-  (struct PSI_cond *cond, struct PSI_mutex *mutex,
+  (struct PSI_cond_locker_state_v1 *state,
+   struct PSI_cond *cond, struct PSI_mutex *mutex,
    enum PSI_cond_operation op);
 
 /**
   Get a table instrumentation locker.
+  @param state data storage for the locker
   @param table the instrumented table to lock
+  @param op the operation to be performed
+  @param flags Per operation flags
   @return a table locker, or NULL
 */
 typedef struct PSI_table_locker* (*get_thread_table_locker_v1_t)
-  (struct PSI_table *table);
+  (struct PSI_table_locker_state_v1 *state,
+   struct PSI_table *table, enum PSI_table_operation op, ulong flags);
 
 /**
   Get a file instrumentation locker, for opening or creating a file.
+  @param state data storage for the locker
   @param key the file instrumentation key
   @param op the operation to perform
   @param name the file name
@@ -754,27 +960,31 @@ typedef struct PSI_table_locker* (*get_t
   @return a file locker, or NULL
 */
 typedef struct PSI_file_locker* (*get_thread_file_name_locker_v1_t)
-  (PSI_file_key key, enum PSI_file_operation op, const char *name,
+  (struct PSI_file_locker_state_v1 *state,
+   PSI_file_key key, enum PSI_file_operation op, const char *name,
    const void *identity);
 
 /**
   Get a file stream instrumentation locker.
+  @param state data storage for the locker
   @param file the file stream to access
   @param op the operation to perform
   @return a file locker, or NULL
 */
 typedef struct PSI_file_locker* (*get_thread_file_stream_locker_v1_t)
-  (struct PSI_file *file, enum PSI_file_operation op);
+  (struct PSI_file_locker_state_v1 *state,
+   struct PSI_file *file, enum PSI_file_operation op);
 
 /**
   Get a file instrumentation locker.
+  @param state data storage for the locker
   @param file the file descriptor to access
   @param op the operation to perform
   @return a file locker, or NULL
 */
 typedef struct PSI_file_locker* (*get_thread_file_descriptor_locker_v1_t)
-  (File file, enum PSI_file_operation op);
-
+  (struct PSI_file_locker_state_v1 *state,
+   File file, enum PSI_file_operation op);
 /**
   Get a socket instrumentation locker.
   @param socket the socket to access
@@ -786,35 +996,31 @@ typedef struct PSI_socket_locker* (*get_
 
 /**
   Record a mutex instrumentation unlock event.
-  @param thread the running thread instrumentation
   @param mutex the mutex instrumentation
 */
 typedef void (*unlock_mutex_v1_t)
-  (struct PSI_thread *thread, struct PSI_mutex *mutex);
+  (struct PSI_mutex *mutex);
 
 /**
   Record a rwlock instrumentation unlock event.
-  @param thread the running thread instrumentation
   @param rwlock the rwlock instrumentation
 */
 typedef void (*unlock_rwlock_v1_t)
-  (struct PSI_thread *thread, struct PSI_rwlock *rwlock);
+  (struct PSI_rwlock *rwlock);
 
 /**
   Record a condition instrumentation signal event.
-  @param thread the running thread instrumentation
   @param cond the cond instrumentation
 */
 typedef void (*signal_cond_v1_t)
-  (struct PSI_thread *thread, struct PSI_cond *cond);
+  (struct PSI_cond *cond);
 
 /**
   Record a condition instrumentation broadcast event.
-  @param thread the running thread instrumentation
   @param cond the cond instrumentation
 */
 typedef void (*broadcast_cond_v1_t)
-  (struct PSI_thread *thread, struct PSI_cond *cond);
+  (struct PSI_cond *cond);
 
 /**
   Record a mutex instrumentation wait start event.
@@ -882,11 +1088,12 @@ typedef void (*end_cond_wait_v1_t)
 /**
   Record a table instrumentation wait start event.
   @param locker a table locker for the running thread
+  @param index the index used if any, or MAX_KEY
   @param file the source file name
   @param line the source line number
 */
 typedef void (*start_table_wait_v1_t)
-  (struct PSI_table_locker *locker, const char *src_file, uint src_line);
+  (struct PSI_table_locker *locker, uint index, const char *src_file, uint src_line);
 
 /**
   Record a table instrumentation wait end event.
@@ -1032,6 +1239,8 @@ struct PSI_v1
   get_table_share_v1_t get_table_share;
   /** @sa release_table_share_v1_t. */
   release_table_share_v1_t release_table_share;
+  /** @sa drop_table_share_v1_t. */
+  drop_table_share_v1_t drop_table_share;
   /** @sa open_table_v1_t. */
   open_table_v1_t open_table;
   /** @sa close_table_v1_t. */
@@ -1182,6 +1391,36 @@ struct PSI_file_info_v2
   int placeholder;
 };
 
+struct PSI_mutex_locker_state_v2
+{
+  /** Placeholder */
+  int placeholder;
+};
+
+struct PSI_rwlock_locker_state_v2
+{
+  /** Placeholder */
+  int placeholder;
+};
+
+struct PSI_cond_locker_state_v2
+{
+  /** Placeholder */
+  int placeholder;
+};
+
+struct PSI_file_locker_state_v2
+{
+  /** Placeholder */
+  int placeholder;
+};
+
+struct PSI_table_locker_state_v2
+{
+  /** Placeholder */
+  int placeholder;
+};
+
 /** @} (end of group Group_PSI_v2) */
 
 #endif /* HAVE_PSI_2 */
@@ -1226,6 +1465,11 @@ typedef struct PSI_cond_info_v1 PSI_cond
 typedef struct PSI_thread_info_v1 PSI_thread_info;
 typedef struct PSI_file_info_v1 PSI_file_info;
 typedef struct PSI_socket_info_v1 PSI_socket_info;
+typedef struct PSI_mutex_locker_state_v1 PSI_mutex_locker_state;
+typedef struct PSI_rwlock_locker_state_v1 PSI_rwlock_locker_state;
+typedef struct PSI_cond_locker_state_v1 PSI_cond_locker_state;
+typedef struct PSI_file_locker_state_v1 PSI_file_locker_state;
+typedef struct PSI_table_locker_state_v1 PSI_table_locker_state;
 #endif
 
 #ifdef USE_PSI_2
@@ -1236,6 +1480,11 @@ typedef struct PSI_cond_info_v2 PSI_cond
 typedef struct PSI_thread_info_v2 PSI_thread_info;
 typedef struct PSI_file_info_v2 PSI_file_info;
 typedef struct PSI_socket_info_v2 PSI_socket_info;
+typedef struct PSI_mutex_locker_state_v2 PSI_mutex_locker_state;
+typedef struct PSI_rwlock_locker_state_v2 PSI_rwlock_locker_state;
+typedef struct PSI_cond_locker_state_v2 PSI_cond_locker_state;
+typedef struct PSI_file_locker_state_v2 PSI_file_locker_state;
+typedef struct PSI_table_locker_state_v2 PSI_table_locker_state;
 #endif
 
 #else /* HAVE_PSI_INTERFACE */

=== modified file 'include/mysql/psi/psi_abi_v1.h'
--- a/include/mysql/psi/psi_abi_v1.h	2009-12-01 00:49:15 +0000
+++ b/include/mysql/psi/psi_abi_v1.h	2010-08-03 21:14:19 +0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -10,8 +10,8 @@
   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 */
+  along with this program; if not, write to the Free Software Foundation,
+  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
 
 /**
   @file mysql/psi/psi_abi_v1.h

=== modified file 'include/mysql/psi/psi_abi_v2.h'
--- a/include/mysql/psi/psi_abi_v2.h	2009-12-01 00:49:15 +0000
+++ b/include/mysql/psi/psi_abi_v2.h	2010-08-03 21:14:19 +0000
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008-2009 Sun Microsystems, Inc
+/* Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
 
   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
@@ -10,8 +10,8 @@
   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 */
+  along with this program; if not, write to the Free Software Foundation,
+  51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
 
 /**
   @file mysql/psi/psi_abi_v1.h

=== modified file 'storage/perfschema/CMakeLists.txt'
--- a/storage/perfschema/CMakeLists.txt	2010-07-07 19:49:15 +0000
+++ b/storage/perfschema/CMakeLists.txt	2010-08-03 21:14:19 +0000
@@ -10,9 +10,8 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
-
+# along with this program; if not, write to the Free Software Foundation,
+# 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}
                     ${CMAKE_SOURCE_DIR}/include
@@ -41,6 +40,7 @@ SET(PERFSCHEMA_SOURCES ha_perfschema.h
   table_events_waits_summary.h
   table_file_instances.h
   table_file_summary.h
+  table_helper.h
   table_socket_instances.h
   table_performance_timers.h
   table_processlist.h

=== modified file 'storage/perfschema/Makefile.am'
--- a/storage/perfschema/Makefile.am	2010-04-19 12:26:29 +0000
+++ b/storage/perfschema/Makefile.am	2010-08-03 21:14:19 +0000
@@ -10,8 +10,8 @@
 # GNU General Public License for more details.
 #
 # You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+# along with this program; if not, write to the Free Software Foundation,
+# 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
 
 #called from the top level Makefile
 
@@ -37,7 +37,7 @@ noinst_HEADERS = ha_perfschema.h pfs_eng
 		pfs_global.h pfs_instr_class.h pfs_instr.h \
                 pfs_column_types.h pfs_column_values.h \
                 table_setup_instruments.h table_performance_timers.h \
-                table_setup_timers.h \
+                table_setup_timers.h table_helper.h \
                 table_setup_consumers.h table_events_waits.h \
 		pfs_events_waits.h pfs_timer.h table_processlist.h \
 		table_sync_instances.h \

=== modified file 'storage/perfschema/ha_perfschema.cc'
--- a/storage/perfschema/ha_perfschema.cc	2010-07-09 02:23:31 +0000
+++ b/storage/perfschema/ha_perfschema.cc	2010-08-03 21:14:19 +0000
@@ -148,7 +148,7 @@ mysql_declare_plugin(perfschema)
   MYSQL_STORAGE_ENGINE_PLUGIN,
   &pfs_storage_engine,
   pfs_engine_name,
-  "Marc Alff, Sun Microsystems",
+  "Marc Alff, Oracle", /* Formerly Sun Microsystems, formerly MySQL */
   "Performance Schema",
   PLUGIN_LICENSE_GPL,
   pfs_init_func,                                /* Plugin Init */
@@ -188,8 +188,6 @@ int ha_perfschema::open(const char *name
   thr_lock_data_init(m_table_share->m_thr_lock_ptr, &m_thr_lock, NULL);
   ref_length= m_table_share->m_ref_length;
 
-  psi_open();
-
   DBUG_RETURN(0);
 }
 
@@ -200,8 +198,6 @@ int ha_perfschema::close(void)
   delete m_table;
   m_table= NULL;
 
-  psi_close();
-
   DBUG_RETURN(0);
 }
 

=== modified file 'storage/perfschema/pfs.cc'
--- a/storage/perfschema/pfs.cc	2010-07-29 19:56:17 +0000
+++ b/storage/perfschema/pfs.cc	2010-08-03 21:14:19 +0000
@@ -20,6 +20,8 @@
 
 #include <arpa/inet.h>
 #include "my_global.h"
+#include "my_pthread.h"
+#include "sql_const.h"
 #include "pfs.h"
 #include "pfs_instr_class.h"
 #include "pfs_instr.h"
@@ -28,9 +30,6 @@
 #include "pfs_timer.h"
 #include "pfs_events_waits.h"
 
-/* Pending WL#4895 PERFORMANCE_SCHEMA Instrumenting Table IO */
-#undef HAVE_TABLE_WAIT
-
 /**
   @page PAGE_PERFORMANCE_SCHEMA The Performance Schema main page
   MySQL PERFORMANCE_SCHEMA implementation.
@@ -671,7 +670,7 @@ static inline int mysql_mutex_lock(...)
   @ingroup Performance_schema
 
   @defgroup Performance_schema_tables Performance Schema Tables
-  @ingroup Performance_schema_implementationf
+  @ingroup Performance_schema_implementation
 */
 
 pthread_key(PFS_thread*, THR_PFS);
@@ -723,6 +722,20 @@ static enum_operation_type file_operatio
 };
 
 /**
+  Conversion map from PSI_table_operation to enum_operation_type.
+  Indexed by enum PSI_table_operation.
+*/
+static enum_operation_type table_operation_map[]=
+{
+  OPERATION_TYPE_TABLE_LOCK,
+  OPERATION_TYPE_TABLE_EXTERNAL_LOCK,
+  OPERATION_TYPE_TABLE_FETCH,
+  OPERATION_TYPE_TABLE_WRITE_ROW,
+  OPERATION_TYPE_TABLE_UPDATE_ROW,
+  OPERATION_TYPE_TABLE_DELETE_ROW
+};
+
+/**
   Conversion map from PSI_socket_operation to enum_operation_type.
   Indexed by enum PSI_socket_operation.
 */
@@ -936,69 +949,76 @@ static void destroy_cond_v1(PSI_cond* co
   destroy_cond(pfs);
 }
 
-static PSI_socket*
-init_socket_v1(PSI_socket_key key, const void *identity)
+/**
+  Implementation of the table instrumentation interface.
+  @sa PSI_v1::get_table_share.
+*/
+static PSI_table_share*
+get_table_share_v1(my_bool temporary, TABLE_SHARE *share)
 {
-//  INIT_BODY_V1(socket, key, identity);
-  PFS_socket_class *klass;
-  PFS_socket *pfs;
   PFS_thread *pfs_thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
   if (unlikely(pfs_thread == NULL))
     return NULL;
-  if (! pfs_thread->m_enabled)
+  if (! global_table_class.m_enabled)
     return NULL;
-  klass= find_socket_class(key);
-  if (unlikely(klass == NULL))
-    return NULL;
-  if (! klass->m_enabled)
-    return NULL;
-  pfs= create_socket(klass, identity);
-  return reinterpret_cast<PSI_socket *> (pfs);
+  PFS_table_share* pfs_share;
+  pfs_share= find_or_create_table_share(pfs_thread, temporary, share);
+  return reinterpret_cast<PSI_table_share*> (pfs_share);
 }
 
-static void destroy_socket_v1(PSI_socket* socket)
-{
-  PFS_socket *pfs= reinterpret_cast<PFS_socket*> (socket);
-  destroy_socket(pfs);
-}
-
-static PSI_table_share*
-get_table_share_v1(const char *schema_name, int schema_name_length,
-                   const char *table_name, int table_name_length,
-                   const void *identity)
+/**
+  Implementation of the table instrumentation interface.
+  @sa PSI_v1::release_table_share.
+*/
+static void release_table_share_v1(PSI_table_share* share)
 {
-#ifdef HAVE_TABLE_WAIT
+  DBUG_ASSERT(share != NULL);
   PFS_thread *pfs_thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
   if (unlikely(pfs_thread == NULL))
-    return NULL;
-  PFS_table_share* share;
-  share= find_or_create_table_share(pfs_thread,
-                                    schema_name, schema_name_length,
-                                    table_name, table_name_length);
-  return reinterpret_cast<PSI_table_share*> (share);
-#else
-  return NULL;
-#endif
+    return;
+  PFS_table_share* pfs;
+  pfs= reinterpret_cast<PFS_table_share*> (share);
+  purge_table_share(pfs_thread, pfs);
 }
 
-static void release_table_share_v1(PSI_table_share* share)
+/**
+  Implementation of the table instrumentation interface.
+  @sa PSI_v1::drop_table_share.
+*/
+static void
+drop_table_share_v1(const char *schema_name, int schema_name_length,
+                    const char *table_name, int table_name_length)
 {
-  /*
-    To be implemented by WL#4895 PERFORMANCE_SCHEMA Instrumenting Table IO.
-  */
+  PFS_thread *pfs_thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
+  if (unlikely(pfs_thread == NULL))
+    return;
+  /* TODO: temporary tables */
+  drop_table_share(pfs_thread, false, schema_name, schema_name_length,
+                   table_name, table_name_length);
 }
 
+/**
+  Implementation of the table instrumentation interface.
+  @sa PSI_v1::open_table.
+*/
 static PSI_table*
 open_table_v1(PSI_table_share *share, const void *identity)
 {
+  PFS_thread *thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
+  if (unlikely(thread == NULL))
+    return NULL;
   PFS_table_share *pfs_table_share=
     reinterpret_cast<PFS_table_share*> (share);
   PFS_table *pfs_table;
   DBUG_ASSERT(pfs_table_share);
-  pfs_table= create_table(pfs_table_share, identity);
+  pfs_table= create_table(pfs_table_share, thread, identity);
   return reinterpret_cast<PSI_table *> (pfs_table);
 }
 
+/**
+  Implementation of the table instrumentation interface.
+  @sa PSI_v1::close_table.
+*/
 static void close_table_v1(PSI_table *table)
 {
   PFS_table *pfs= reinterpret_cast<PFS_table*> (table);
@@ -1006,6 +1026,32 @@ static void close_table_v1(PSI_table *ta
   destroy_table(pfs);
 }
 
+static PSI_socket*
+init_socket_v1(PSI_socket_key key, const void *identity)
+{
+//  INIT_BODY_V1(socket, key, identity);
+  PFS_socket_class *klass;
+  PFS_socket *pfs;
+  PFS_thread *pfs_thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
+  if (unlikely(pfs_thread == NULL))
+    return NULL;
+  if (! pfs_thread->m_enabled)
+    return NULL;
+  klass= find_socket_class(key);
+  if (unlikely(klass == NULL))
+    return NULL;
+  if (! klass->m_enabled)
+    return NULL;
+  pfs= create_socket(klass, identity);
+  return reinterpret_cast<PSI_socket *> (pfs);
+}
+
+static void destroy_socket_v1(PSI_socket* socket)
+{
+  PFS_socket *pfs= reinterpret_cast<PFS_socket*> (socket);
+  destroy_socket(pfs);
+}
+
 static void create_file_v1(PSI_file_key key, const char *name, File file)
 {
   int index= (int) file;
@@ -1064,7 +1110,7 @@ void* pfs_spawn_thread(void *arg)
   */
   user_start_routine= typed_arg->m_user_start_routine;
   user_arg= typed_arg->m_user_arg;
-  my_free(typed_arg, MYF(0));
+  my_free(typed_arg);
 
   /* Then, execute the user code for this thread. */
   (*user_start_routine)(user_arg);
@@ -1092,7 +1138,7 @@ static int spawn_thread_v1(PSI_thread_ke
 
   int result= pthread_create(thread, attr, pfs_spawn_thread, psi_arg);
   if (unlikely(result != 0))
-    my_free(psi_arg, MYF(0));
+    my_free(psi_arg);
   return result;
 }
 
@@ -1148,7 +1194,8 @@ static void delete_thread_v1(PSI_thread
 }
 
 static PSI_mutex_locker*
-get_thread_mutex_locker_v1(PSI_mutex *mutex, PSI_mutex_operation op)
+get_thread_mutex_locker_v1(PSI_mutex_locker_state *state,
+                           PSI_mutex *mutex, PSI_mutex_operation op)
 {
   PFS_mutex *pfs_mutex= reinterpret_cast<PFS_mutex*> (mutex);
   DBUG_ASSERT((int) op >= 0);
@@ -1171,6 +1218,14 @@ get_thread_mutex_locker_v1(PSI_mutex *mu
   }
   PFS_wait_locker *pfs_locker= &pfs_thread->m_wait_locker_stack
     [pfs_thread->m_wait_locker_count];
+  if (likely(pfs_thread->m_wait_locker_count == 0))
+    pfs_locker->m_waits_current.m_nesting_event_id= 0;
+  else
+  {
+    PFS_wait_locker *parent_locker= pfs_locker-1;
+    pfs_locker->m_waits_current.m_nesting_event_id=
+      parent_locker->m_waits_current.m_event_id;
+  }
   pfs_locker->m_waits_current.m_wait_class= NO_WAIT_CLASS;
 
   pfs_locker->m_target.m_mutex= pfs_mutex;
@@ -1193,15 +1248,14 @@ get_thread_mutex_locker_v1(PSI_mutex *mu
 }
 
 static PSI_rwlock_locker*
-get_thread_rwlock_locker_v1(PSI_rwlock *rwlock, PSI_rwlock_operation op)
+get_thread_rwlock_locker_v1(PSI_rwlock_locker_state *state,
+                            PSI_rwlock *rwlock, PSI_rwlock_operation op)
 {
   PFS_rwlock *pfs_rwlock= reinterpret_cast<PFS_rwlock*> (rwlock);
-
   DBUG_ASSERT(static_cast<int> (op) >= 0);
   DBUG_ASSERT(static_cast<uint> (op) < array_elements(rwlock_operation_map));
   DBUG_ASSERT(pfs_rwlock != NULL);
   DBUG_ASSERT(pfs_rwlock->m_class != NULL);
-
   if (! flag_events_waits_current)
     return NULL;
   if (! pfs_rwlock->m_class->m_enabled)
@@ -1218,6 +1272,14 @@ get_thread_rwlock_locker_v1(PSI_rwlock *
   }
   PFS_wait_locker *pfs_locker= &pfs_thread->m_wait_locker_stack
     [pfs_thread->m_wait_locker_count];
+  if (likely(pfs_thread->m_wait_locker_count == 0))
+    pfs_locker->m_waits_current.m_nesting_event_id= 0;
+  else
+  {
+    PFS_wait_locker *parent_locker= pfs_locker-1;
+    pfs_locker->m_waits_current.m_nesting_event_id=
+      parent_locker->m_waits_current.m_event_id;
+  }
   pfs_locker->m_waits_current.m_wait_class= NO_WAIT_CLASS;
 
   pfs_locker->m_target.m_rwlock= pfs_rwlock;
@@ -1241,7 +1303,8 @@ get_thread_rwlock_locker_v1(PSI_rwlock *
 }
 
 static PSI_cond_locker*
-get_thread_cond_locker_v1(PSI_cond *cond, PSI_mutex * /* unused: mutex */,
+get_thread_cond_locker_v1(PSI_cond_locker_state *state,
+                          PSI_cond *cond, PSI_mutex * /* unused: mutex */,
                           PSI_cond_operation op)
 {
   /*
@@ -1276,6 +1339,14 @@ get_thread_cond_locker_v1(PSI_cond *cond
   }
   PFS_wait_locker *pfs_locker= &pfs_thread->m_wait_locker_stack
     [pfs_thread->m_wait_locker_count];
+  if (likely(pfs_thread->m_wait_locker_count == 0))
+    pfs_locker->m_waits_current.m_nesting_event_id= 0;
+  else
+  {
+    PFS_wait_locker *parent_locker= pfs_locker-1;
+    pfs_locker->m_waits_current.m_nesting_event_id=
+      parent_locker->m_waits_current.m_event_id;
+  }
   pfs_locker->m_waits_current.m_wait_class= NO_WAIT_CLASS;
 
   pfs_locker->m_target.m_cond= pfs_cond;
@@ -1298,14 +1369,29 @@ get_thread_cond_locker_v1(PSI_cond *cond
   return reinterpret_cast<PSI_cond_locker*> (pfs_locker);
 }
 
+/**
+  Implementation of the table instrumentation interface.
+  @sa PSI_v1::get_thread_table_locker.
+*/
 static PSI_table_locker*
-get_thread_table_locker_v1(PSI_table *table)
+get_thread_table_locker_v1(PSI_table_locker_state *state,
+                           PSI_table *table, PSI_table_operation op, ulong flags)
 {
+  DBUG_ASSERT(static_cast<int> (op) >= 0);
+  DBUG_ASSERT(static_cast<uint> (op) < array_elements(table_operation_map));
   PFS_table *pfs_table= reinterpret_cast<PFS_table*> (table);
   DBUG_ASSERT(pfs_table != NULL);
   DBUG_ASSERT(pfs_table->m_share != NULL);
+
   if (! flag_events_waits_current)
     return NULL;
+  if (! global_table_class.m_enabled)
+    return NULL;
+  /*
+    Table locks will be recorded with WL#5371.
+  */
+  if ((op == PSI_TABLE_EXTERNAL_LOCK) || (op == PSI_TABLE_LOCK))
+    return NULL;
   if (! pfs_table->m_share->m_enabled)
     return NULL;
   PFS_thread *pfs_thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
@@ -1320,6 +1406,14 @@ get_thread_table_locker_v1(PSI_table *ta
   }
   PFS_wait_locker *pfs_locker= &pfs_thread->m_wait_locker_stack
     [pfs_thread->m_wait_locker_count];
+  if (likely(pfs_thread->m_wait_locker_count == 0))
+    pfs_locker->m_waits_current.m_nesting_event_id= 0;
+  else
+  {
+    PFS_wait_locker *parent_locker= pfs_locker-1;
+    pfs_locker->m_waits_current.m_nesting_event_id=
+      parent_locker->m_waits_current.m_event_id;
+  }
   pfs_locker->m_waits_current.m_wait_class= NO_WAIT_CLASS;
 
   pfs_locker->m_target.m_table= pfs_table;
@@ -1334,6 +1428,9 @@ get_thread_table_locker_v1(PSI_table *ta
     pfs_locker->m_waits_current.m_timer_state= TIMER_STATE_UNTIMED;
   pfs_locker->m_waits_current.m_object_instance_addr= pfs_table->m_identity;
   pfs_locker->m_waits_current.m_event_id= pfs_thread->m_event_id++;
+  pfs_locker->m_waits_current.m_operation=
+    table_operation_map[static_cast<int> (op)];
+  pfs_locker->m_waits_current.m_flags= flags;
   pfs_locker->m_waits_current.m_wait_class= WAIT_CLASS_TABLE;
 
   pfs_thread->m_wait_locker_count++;
@@ -1341,7 +1438,8 @@ get_thread_table_locker_v1(PSI_table *ta
 }
 
 static PSI_file_locker*
-get_thread_file_name_locker_v1(PSI_file_key key,
+get_thread_file_name_locker_v1(PSI_file_locker_state *state,
+                               PSI_file_key key,
                                PSI_file_operation op,
                                const char *name, const void *identity)
 {
@@ -1372,6 +1470,14 @@ get_thread_file_name_locker_v1(PSI_file_
 
   PFS_wait_locker *pfs_locker= &pfs_thread->m_wait_locker_stack
     [pfs_thread->m_wait_locker_count];
+  if (likely(pfs_thread->m_wait_locker_count == 0))
+    pfs_locker->m_waits_current.m_nesting_event_id= 0;
+  else
+  {
+    PFS_wait_locker *parent_locker= pfs_locker-1;
+    pfs_locker->m_waits_current.m_nesting_event_id=
+      parent_locker->m_waits_current.m_event_id;
+  }
   pfs_locker->m_waits_current.m_wait_class= NO_WAIT_CLASS;
 
   pfs_locker->m_target.m_file= pfs_file;
@@ -1398,7 +1504,8 @@ get_thread_file_name_locker_v1(PSI_file_
 }
 
 static PSI_file_locker*
-get_thread_file_stream_locker_v1(PSI_file *file, PSI_file_operation op)
+get_thread_file_stream_locker_v1(PSI_file_locker_state *state,
+                                 PSI_file *file, PSI_file_operation op)
 {
   PFS_file *pfs_file= reinterpret_cast<PFS_file*> (file);
 
@@ -1423,6 +1530,14 @@ get_thread_file_stream_locker_v1(PSI_fil
   }
   PFS_wait_locker *pfs_locker= &pfs_thread->m_wait_locker_stack
     [pfs_thread->m_wait_locker_count];
+  if (likely(pfs_thread->m_wait_locker_count == 0))
+    pfs_locker->m_waits_current.m_nesting_event_id= 0;
+  else
+  {
+    PFS_wait_locker *parent_locker= pfs_locker-1;
+    pfs_locker->m_waits_current.m_nesting_event_id=
+      parent_locker->m_waits_current.m_event_id;
+  }
   pfs_locker->m_waits_current.m_wait_class= NO_WAIT_CLASS;
 
   pfs_locker->m_target.m_file= pfs_file;
@@ -1449,7 +1564,8 @@ get_thread_file_stream_locker_v1(PSI_fil
 }
 
 static PSI_file_locker*
-get_thread_file_descriptor_locker_v1(File file, PSI_file_operation op)
+get_thread_file_descriptor_locker_v1(PSI_file_locker_state *state,
+                                     File file, PSI_file_operation op)
 {
   int index= static_cast<int> (file);
 
@@ -1491,6 +1607,14 @@ get_thread_file_descriptor_locker_v1(Fil
       }
       PFS_wait_locker *pfs_locker= &pfs_thread->m_wait_locker_stack
         [pfs_thread->m_wait_locker_count];
+      if (likely(pfs_thread->m_wait_locker_count == 0))
+        pfs_locker->m_waits_current.m_nesting_event_id= 0;
+      else
+      {
+        PFS_wait_locker *parent_locker= pfs_locker-1;
+        pfs_locker->m_waits_current.m_nesting_event_id=
+          parent_locker->m_waits_current.m_event_id;
+      }
       pfs_locker->m_waits_current.m_wait_class= NO_WAIT_CLASS;
 
       pfs_locker->m_target.m_file= pfs_file;
@@ -1577,7 +1701,6 @@ get_thread_socket_locker_v1(PSI_socket *
   return reinterpret_cast<PSI_socket_locker*> (pfs_locker);
 }
 
-static void unlock_mutex_v1(PSI_thread * thread, PSI_mutex *mutex)
 {
   PFS_mutex *pfs_mutex= reinterpret_cast<PFS_mutex*> (mutex);
   DBUG_ASSERT(pfs_mutex != NULL);
@@ -1616,7 +1739,7 @@ static void unlock_mutex_v1(PSI_thread *
 #endif
 }
 
-static void unlock_rwlock_v1(PSI_thread *thread, PSI_rwlock *rwlock)
+static void unlock_rwlock_v1(PSI_rwlock *rwlock)
 {
   PFS_rwlock *pfs_rwlock= reinterpret_cast<PFS_rwlock*> (rwlock);
   DBUG_ASSERT(pfs_rwlock != NULL);
@@ -1692,7 +1815,7 @@ static void unlock_rwlock_v1(PSI_thread
 #endif
 }
 
-static void signal_cond_v1(PSI_thread *thread, PSI_cond* cond)
+static void signal_cond_v1(PSI_cond* cond)
 {
   PFS_cond *pfs_cond= reinterpret_cast<PFS_cond*> (cond);
   DBUG_ASSERT(pfs_cond != NULL);
@@ -1700,7 +1823,7 @@ static void signal_cond_v1(PSI_thread *t
   pfs_cond->m_cond_stat.m_signal_count++;
 }
 
-static void broadcast_cond_v1(PSI_thread *thread, PSI_cond* cond)
+static void broadcast_cond_v1(PSI_cond* cond)
 {
   PFS_cond *pfs_cond= reinterpret_cast<PFS_cond*> (cond);
   DBUG_ASSERT(pfs_cond != NULL);
@@ -1752,7 +1875,7 @@ static void end_mutex_wait_v1(PSI_mutex_
     aggregate_single_stat_chain(&mutex->m_wait_stat, wait_time);
     stat= find_per_thread_mutex_class_wait_stat(wait->m_thread,
                                                 mutex->m_class);
-   aggregate_single_stat_chain(stat, wait_time);
+    aggregate_single_stat_chain(stat, wait_time);
   }
   wait->m_thread->m_wait_locker_count--;
 }
@@ -1904,7 +2027,7 @@ static void end_cond_wait_v1(PSI_cond_lo
       Not thread safe, race conditions will occur.
       A first race condition is:
       - thread 1 waits on cond A
-      - thread 2 waits on cond B
+      - thread 2 waits on cond A
       threads 1 and 2 compete when updating the same cond A
       statistics, possibly missing a min / max / sum / count.
       A second race condition is:
@@ -1927,9 +2050,7 @@ static void end_cond_wait_v1(PSI_cond_lo
   wait->m_thread->m_wait_locker_count--;
 }
 
-/** Table operations */
-
-static void start_table_wait_v1(PSI_table_locker* locker,
+static void start_table_wait_v1(PSI_table_locker* locker, uint index,
                                 const char *src_file, uint src_line)
 {
   PFS_wait_locker *pfs_locker= reinterpret_cast<PFS_wait_locker*> (locker);
@@ -1943,12 +2064,17 @@ static void start_table_wait_v1(PSI_tabl
   }
   wait->m_source_file= src_file;
   wait->m_source_line= src_line;
-  wait->m_operation= OPERATION_TYPE_LOCK;
   PFS_table_share *share= pfs_locker->m_target.m_table->m_share;
+  wait->m_object_type= share->get_object_type();
   wait->m_schema_name= share->m_schema_name;
   wait->m_schema_name_length= share->m_schema_name_length;
   wait->m_object_name= share->m_table_name;
   wait->m_object_name_length= share->m_table_name_length;
+  /* FIXME: revise this */
+  if (share->get_object_type() == OBJECT_TYPE_TEMPORARY_TABLE)
+    wait->m_index= MAX_KEY;
+  else
+    wait->m_index= index;
 }
 
 static void end_table_wait_v1(PSI_table_locker* locker)
@@ -1967,10 +2093,6 @@ static void end_table_wait_v1(PSI_table_
   if (flag_events_waits_history_long)
     insert_events_waits_history_long(wait);
 
-  PFS_table *table= pfs_locker->m_target.m_table;
-  ulonglong wait_time= wait->m_timer_end - wait->m_timer_start;
-  aggregate_single_stat_chain(&table->m_wait_stat, wait_time);
-
   /*
     There is currently no per table and per thread aggregation.
     The number of tables in the application is arbitrary, and may be high.
@@ -1995,7 +2117,6 @@ static void start_file_wait_v1(PSI_file_
 static void end_file_wait_v1(PSI_file_locker *locker,
                              size_t count);
 
-
 static PSI_file* start_file_open_wait_v1(PSI_file_locker *locker,
                                          const char *src_file,
                                          uint src_line)
@@ -2269,6 +2390,7 @@ PSI_v1 PFS_v1=
   destroy_socket_v1,
   get_table_share_v1,
   release_table_share_v1,
+  drop_table_share_v1,
   open_table_v1,
   close_table_v1,
   create_file_v1,

=== modified file 'storage/perfschema/pfs_column_types.h'
--- a/storage/perfschema/pfs_column_types.h	2010-06-22 23:15:38 +0000
+++ b/storage/perfschema/pfs_column_types.h	2010-08-03 21:14:19 +0000
@@ -111,20 +111,36 @@ enum enum_operation_type
   OPERATION_TYPE_FILERENAME= 24,
   OPERATION_TYPE_FILESYNC= 25,
 
-  OPERATION_TYPE_SOCKETCREATE = 26,
-  OPERATION_TYPE_SOCKETCONNECT = 27,
-  OPERATION_TYPE_SOCKETBIND = 28,
-  OPERATION_TYPE_SOCKETCLOSE = 29,
-  OPERATION_TYPE_SOCKETSEND = 30,
-  OPERATION_TYPE_SOCKETRECV = 31,
-  OPERATION_TYPE_SOCKETSEEK = 32,
-  OPERATION_TYPE_SOCKETOPT = 33,
-  OPERATION_TYPE_SOCKETSTAT = 34,
-  OPERATION_TYPE_SOCKETSHUTDOWN = 35
+  OPERATION_TYPE_TABLE_LOCK= 26,
+  OPERATION_TYPE_TABLE_EXTERNAL_LOCK= 27,
+  OPERATION_TYPE_TABLE_FETCH= 28,
+  OPERATION_TYPE_TABLE_WRITE_ROW= 29,
+  OPERATION_TYPE_TABLE_UPDATE_ROW= 30,
+  OPERATION_TYPE_TABLE_DELETE_ROW= 31,
+
+  OPERATION_TYPE_SOCKETCREATE = 32,
+  OPERATION_TYPE_SOCKETCONNECT = 33,
+  OPERATION_TYPE_SOCKETBIND = 34,
+  OPERATION_TYPE_SOCKETCLOSE = 35,
+  OPERATION_TYPE_SOCKETSEND = 36,
+  OPERATION_TYPE_SOCKETRECV = 37,
+  OPERATION_TYPE_SOCKETSEEK = 38,
+  OPERATION_TYPE_SOCKETOPT = 39,
+  OPERATION_TYPE_SOCKETSTAT = 40,
+  OPERATION_TYPE_SOCKETSHUTDOWN = 41
 };
 #define FIRST_OPERATION_TYPE (static_cast<int> (OPERATION_TYPE_LOCK))
-#define LAST_OPERATION_TYPE (static_cast<int> (OPERATION_TYPE_FILESYNC))
+#define LAST_OPERATION_TYPE (static_cast<int> (OPERATION_TYPE_SOCKETSHUTDOWN)
 #define COUNT_OPERATION_TYPE (LAST_OPERATION_TYPE - FIRST_OPERATION_TYPE + 1)
 
+enum enum_object_type
+{
+  OBJECT_TYPE_TABLE= 1,
+  OBJECT_TYPE_TEMPORARY_TABLE= 2
+};
+#define FIRST_OBJECT_TYPE (static_cast<int> (OBJECT_TYPE_TABLE))
+#define LAST_OBJECT_TYPE (static_cast<int> (OBJECT_TYPE_TEMPORARY_TABLE))
+#define COUNT_OBJECT_TYPE (LAST_OBJECT_TYPE - FIRST_OBJECT_TYPE + 1)
+
 #endif
 

=== modified file 'storage/perfschema/pfs_events_waits.h'
--- a/storage/perfschema/pfs_events_waits.h	2010-07-09 02:23:31 +0000
+++ b/storage/perfschema/pfs_events_waits.h	2010-08-03 21:14:19 +0000
@@ -110,6 +110,8 @@ struct PFS_events_waits
   enum timer_state m_timer_state;
   /** Event id. */
   ulonglong m_event_id;
+  /** Nesting event id. */
+  ulonglong m_nesting_event_id;
   /**
     Timer start.
     This member is populated only if m_timed is true.
@@ -124,6 +126,8 @@ struct PFS_events_waits
   const char *m_schema_name;
   /** Length in bytes of @c m_schema_name. */
   uint m_schema_name_length;
+  /** Object type */
+  enum_object_type m_object_type;
   /** Object name. */
   const char *m_object_name;
   /** Length in bytes of @c m_object_name. */
@@ -141,6 +145,13 @@ struct PFS_events_waits
     This member is populated for file READ/WRITE operations only.
   */
   size_t m_number_of_bytes;
+  /**
+    Index used.
+    This member is populated for TABLE IO operations only.
+  */
+  uint m_index;
+  /** Flags */
+  ulong m_flags;
 };
 
 /**

=== modified file 'storage/perfschema/pfs_instr.cc'
--- a/storage/perfschema/pfs_instr.cc	2010-07-09 02:23:31 +0000
+++ b/storage/perfschema/pfs_instr.cc	2010-08-03 21:14:19 +0000
@@ -1049,10 +1049,12 @@ void destroy_file(PFS_thread *thread, PF
 /**
   Create instrumentation for a table instance.
   @param share                        the table share
+  @param opening_thread               the opening thread
   @param identity                     the table address
   @return a table instance, or NULL
 */
-PFS_table* create_table(PFS_table_share *share, const void *identity)
+PFS_table* create_table(PFS_table_share *share, PFS_thread *opening_thread,
+                        const void *identity)
 {
   PFS_scan scan;
   uint random= randomized_index(identity, table_max);
@@ -1071,10 +1073,12 @@ PFS_table* create_table(PFS_table_share
         {
           pfs->m_identity= identity;
           pfs->m_share= share;
+          share->m_refcount++;
           pfs->m_wait_stat.m_control_flag=
             &flag_events_waits_summary_by_instance;
           pfs->m_wait_stat.m_parent= &share->m_wait_stat;
           reset_single_stat_link(&pfs->m_wait_stat);
+          pfs->m_opening_thread= opening_thread;
           pfs->m_lock.dirty_to_allocated();
           return pfs;
         }

=== modified file 'storage/perfschema/pfs_instr.h'
--- a/storage/perfschema/pfs_instr.h	2010-07-29 19:56:17 +0000
+++ b/storage/perfschema/pfs_instr.h	2010-08-03 21:14:19 +0000
@@ -123,6 +123,8 @@ struct PFS_file : public PFS_instr
 /** Instrumented table implementation. @see PSI_table. */
 struct PFS_table : public PFS_instr
 {
+  /** Owner. */
+  PFS_thread *m_opening_thread;
   /** Table share. */
   PFS_table_share *m_share;
   /** Table identity, typically a handler. */
@@ -289,7 +291,8 @@ PFS_file* find_or_create_file(PFS_thread
                               const char *filename, uint len);
 void release_file(PFS_file *pfs);
 void destroy_file(PFS_thread *thread, PFS_file *pfs);
-PFS_table* create_table(PFS_table_share *share, const void *identity);
+PFS_table* create_table(PFS_table_share *share, PFS_thread *opening_thread,
+                        const void *identity);
 void destroy_table(PFS_table *pfs);
 
 PFS_socket* create_socket(PFS_socket_class *socket_class, const void *identity);

=== modified file 'storage/perfschema/pfs_instr_class.cc'
--- a/storage/perfschema/pfs_instr_class.cc	2010-07-07 19:49:15 +0000
+++ b/storage/perfschema/pfs_instr_class.cc	2010-08-03 21:14:19 +0000
@@ -20,6 +20,8 @@
 
 #include "my_global.h"
 #include "my_sys.h"
+#include "structs.h"
+#include "table.h"
 #include "pfs_instr_class.h"
 #include "pfs_instr.h"
 #include "pfs_global.h"
@@ -110,15 +112,24 @@ PFS_table_share *table_share_array= NULL
 
 PFS_instr_class global_table_class=
 {
-  "wait/table", /* name */
-  10, /* name length */
+  "wait/io/table/sql/handler", /* name */
+  25, /* name length */
   0, /* flags */
   true, /* enabled */
   true, /* timed */
   { &flag_events_waits_current, NULL, 0, 0, 0, 0} /* wait stat chain */
 };
 
-/** Hash table for instrumented tables.  */
+/**
+  Hash index for instrumented table shares.
+  This index is searched by table fully qualified name (@c PFS_table_share_key),
+  and points to instrumented table shares (@c PFS_table_share).
+  @sa table_share_array
+  @sa PFS_table_share_key
+  @sa PFS_table_share
+  @sa table_share_hash_get_key
+  @sa get_table_share_hash_pins
+*/
 static LF_HASH table_share_hash;
 /** True if table_share_hash is initialized. */
 static bool table_share_hash_inited= false;
@@ -268,6 +279,9 @@ void cleanup_table_share(void)
   table_share_max= 0;
 }
 
+/**
+  get_key function for @c table_share_hash.
+*/
 static uchar *table_share_hash_get_key(const uchar *entry, size_t *length,
                                        my_bool)
 {
@@ -306,6 +320,51 @@ void cleanup_table_share_hash(void)
 }
 
 /**
+  Get the hash pins for @table_share_hash.
+  @param thread The running thread.
+  @returns The LF_HASH pins for the thread.
+*/
+LF_PINS* get_table_share_hash_pins(PFS_thread *thread)
+{
+  if (! table_share_hash_inited)
+    return NULL;
+  if (unlikely(thread->m_table_share_hash_pins == NULL))
+    thread->m_table_share_hash_pins= lf_hash_get_pins(&table_share_hash);
+  return thread->m_table_share_hash_pins;
+}
+
+/**
+  Set a table share hash key.
+  @param [out] key The key to polulate.
+  @param temporary True for TEMPORARY TABLE.
+  @param schema_name The table schema name.
+  @param schema_name_length The table schema name length.
+  @param table_name The table name.
+  @param table_name_length The table name length.
+*/
+static void set_table_share_key(PFS_table_share_key *key,
+                                bool temporary,
+                                const char *schema_name, uint schema_name_length,
+                                const char *table_name, uint table_name_length)
+{
+  DBUG_ASSERT(schema_name_length <= NAME_LEN);
+  DBUG_ASSERT(table_name_length <= NAME_LEN);
+
+  char *ptr= &key->m_hash_key[0];
+  ptr[0]= (temporary ? OBJECT_TYPE_TEMPORARY_TABLE : OBJECT_TYPE_TABLE);
+  ptr++;
+  memcpy(ptr, schema_name, schema_name_length);
+  ptr+= schema_name_length;
+  ptr[0]= 0;
+  ptr++;
+  memcpy(ptr, table_name, table_name_length);
+  ptr+= table_name_length;
+  ptr[0]= 0;
+  ptr++;
+  key->m_key_length= ptr - &key->m_hash_key[0];
+}
+
+/**
   Initialize the file class buffer.
   @param file_class_sizing            max number of file class
   @return 0 on success
@@ -797,68 +856,69 @@ PFS_socket_class *sanitize_socket_class(
 }
 
 /**
-  Find or create a table instance by name.
+  Find or create a table share instrumentation.
   @param thread                       the executing instrumented thread
-  @param schema_name                  the table schema name
-  @param schema_name_length           the table schema name length
-  @param table_name                   the table name
-  @param table_name_length            the table name length
-  @return a table instance, or NULL
+  @param temporary                    true for TEMPORARY TABLE
+  @param share                        table share
+  @return a table share, or NULL
 */
 PFS_table_share* find_or_create_table_share(PFS_thread *thread,
-                                            const char *schema_name,
-                                            uint schema_name_length,
-                                            const char *table_name,
-                                            uint table_name_length)
+                                            bool temporary,
+                                            const TABLE_SHARE *share)
 {
   /* See comments in register_mutex_class */
   int pass;
   PFS_table_share_key key;
 
-  if (! table_share_hash_inited)
+  LF_PINS *pins= get_table_share_hash_pins(thread);
+  if (unlikely(pins == NULL))
   {
-    /* Table instrumentation can be turned off. */
     table_share_lost++;
     return NULL;
   }
 
-  if (unlikely(thread->m_table_share_hash_pins == NULL))
-  {
-    thread->m_table_share_hash_pins= lf_hash_get_pins(&table_share_hash);
-    if (unlikely(thread->m_table_share_hash_pins == NULL))
-    {
-      table_share_lost++;
-      return NULL;
-    }
-  }
-
-  DBUG_ASSERT(schema_name_length <= NAME_LEN);
-  DBUG_ASSERT(table_name_length <= NAME_LEN);
-
-  char *ptr= &key.m_hash_key[0];
-  memcpy(ptr, schema_name, schema_name_length);
-  ptr+= schema_name_length;
-  ptr[0]= 0; ptr++;
-  memcpy(ptr, table_name, table_name_length);
-  ptr+= table_name_length;
-  ptr[0]= 0; ptr++;
-  key.m_key_length= ptr - &key.m_hash_key[0];
+  const char *schema_name= share->db.str;
+  uint schema_name_length= share->db.length;
+  const char *table_name= share->table_name.str;
+  uint table_name_length= share->table_name.length;
+
+  set_table_share_key(&key, temporary,
+                      schema_name, schema_name_length,
+                      table_name, table_name_length);
 
   PFS_table_share **entry;
   uint retry_count= 0;
   const uint retry_max= 3;
+  bool enabled= true;
+  bool timed= true;
+
 search:
   entry= reinterpret_cast<PFS_table_share**>
-    (lf_hash_search(&table_share_hash, thread->m_table_share_hash_pins,
-                    &key.m_hash_key[0], key.m_key_length));
+    (lf_hash_search(&table_share_hash, pins,
+                    key.m_hash_key, key.m_key_length));
   if (entry && (entry != MY_ERRPTR))
   {
     PFS_table_share *pfs;
     pfs= *entry;
-    lf_hash_search_unpin(thread->m_table_share_hash_pins);
+    pfs->m_refcount++ ;
+    lf_hash_search_unpin(pins);
     return pfs;
   }
 
+  if (retry_count == 0)
+  {
+    /* No per object lokup yet */
+    enabled= global_table_class.m_enabled;
+    timed= global_table_class.m_timed;
+
+    /*
+      Even when enabled is false, a record is added in the dictionary:
+      - It makes enabling a table already in the table cache possible,
+      - It improves performances for the next time a TABLE_SHARE is reloaded
+        in the table cache.
+    */
+  }
+
   /* table_name is not constant, just using it for noise on create */
   uint i= randomized_index(table_name, table_share_max);
 
@@ -877,21 +937,20 @@ search:
         if (pfs->m_lock.free_to_dirty())
         {
           pfs->m_key= key;
-          pfs->m_schema_name= &pfs->m_key.m_hash_key[0];
+          pfs->m_schema_name= &pfs->m_key.m_hash_key[1];
           pfs->m_schema_name_length= schema_name_length;
-          pfs->m_table_name= &pfs->m_key.m_hash_key[schema_name_length + 1];
+          pfs->m_table_name= &pfs->m_key.m_hash_key[schema_name_length + 2];
           pfs->m_table_name_length= table_name_length;
           pfs->m_wait_stat.m_control_flag=
             &flag_events_waits_summary_by_instance;
           pfs->m_wait_stat.m_parent= NULL;
           reset_single_stat_link(&pfs->m_wait_stat);
-          pfs->m_enabled= true;
-          pfs->m_timed= true;
-          pfs->m_aggregated= false;
+          pfs->m_enabled= enabled;
+          pfs->m_timed= timed;
+          pfs->m_refcount= 1;
 
           int res;
-          res= lf_hash_insert(&table_share_hash,
-                              thread->m_table_share_hash_pins, &pfs);
+          res= lf_hash_insert(&table_share_hash, pins, &pfs);
           if (likely(res == 0))
           {
             pfs->m_lock.dirty_to_allocated();
@@ -924,6 +983,63 @@ search:
   return NULL;
 }
 
+/**
+  Purge an instrumented table share from the performance schema buffers.
+  The table share is removed from the hash index, and freed.
+  @param thread The running thread
+  @param pfs The table share to purge
+*/
+void purge_table_share(PFS_thread *thread, PFS_table_share *pfs)
+{
+  if (pfs->m_refcount == 1)
+  {
+    LF_PINS* pins= get_table_share_hash_pins(thread);
+    if (likely(pins != NULL))
+      lf_hash_delete(&table_share_hash, pins,
+                     pfs->m_key.m_hash_key, pfs->m_key.m_key_length);
+    pfs->m_lock.allocated_to_free();
+  }
+}
+
+/**
+  Drop the instrumented table share associated with a table.
+  @param thread The running thread
+  @param temporary True for TEMPORARY TABLE
+  @param schema_name The table schema name
+  @param schema_name_length The table schema name length
+  @param table_name The table name
+  @parem table_name_length The table name length
+*/
+void drop_table_share(PFS_thread *thread,
+                      bool temporary,
+                      const char *schema_name, uint schema_name_length,
+                      const char *table_name, uint table_name_length)
+{
+  PFS_table_share_key key;
+  LF_PINS* pins= get_table_share_hash_pins(thread);
+  if (unlikely(pins == NULL))
+    return;
+  set_table_share_key(&key, temporary, schema_name, schema_name_length,
+                      table_name, table_name_length);
+  PFS_table_share **entry;
+  entry= reinterpret_cast<PFS_table_share**>
+    (lf_hash_search(&table_share_hash, pins,
+                    key.m_hash_key, key.m_key_length));
+  if (entry && (entry != MY_ERRPTR))
+  {
+    PFS_table_share *pfs= *entry;
+    lf_hash_search_unpin(pins);
+    lf_hash_delete(&table_share_hash, pins,
+                   pfs->m_key.m_hash_key, pfs->m_key.m_key_length);
+    pfs->m_lock.allocated_to_free();
+  }
+}
+
+/**
+  Sanitize an unsafe table_share pointer.
+  @param unsafe The possibly corrupt pointer.
+  @return A valid table_safe_pointer, or NULL.
+*/
 PFS_table_share *sanitize_table_share(PFS_table_share *unsafe)
 {
   SANITIZE_ARRAY_BODY(table_share_array, table_share_max, unsafe);

=== modified file 'storage/perfschema/pfs_instr_class.h'
--- a/storage/perfschema/pfs_instr_class.h	2010-06-22 23:15:38 +0000
+++ b/storage/perfschema/pfs_instr_class.h	2010-08-03 21:14:19 +0000
@@ -42,6 +42,7 @@
 #include <mysql/psi/psi.h>
 #include "pfs_lock.h"
 #include "pfs_stat.h"
+#include "pfs_column_types.h"
 
 /**
   @addtogroup Performance_schema_buffers
@@ -136,10 +137,10 @@ struct PFS_table_share_key
   /**
     Hash search key.
     This has to be a string for LF_HASH,
-    the format is "<schema_name><0x00><object_name><0x00>"
+    the format is "<enum_object_type><schema_name><0x00><object_name><0x00>"
     @see create_table_def_key
   */
-  char m_hash_key[NAME_LEN + 1 + NAME_LEN + 1];
+  char m_hash_key[1 + NAME_LEN + 1 + NAME_LEN + 1];
   /** Length in bytes of @c m_hash_key. */
   uint m_key_length;
 };
@@ -147,6 +148,11 @@ struct PFS_table_share_key
 /** Instrumentation metadata for a table share. */
 struct PFS_table_share
 {
+  enum_object_type get_object_type()
+  {
+    return (enum_object_type) m_key.m_hash_key[0];
+  }
+
   /** Internal lock. */
   pfs_lock m_lock;
   /** Search key. */
@@ -165,8 +171,9 @@ struct PFS_table_share
   bool m_enabled;
   /** True if this table instrument is timed. */
   bool m_timed;
-  /** True if this table instrument is aggregated. */
-  bool m_aggregated;
+  bool m_purge;
+  /** Number of opened table handles. */
+  uint m_refcount;
 };
 
 /**
@@ -241,10 +248,13 @@ PFS_socket_class *find_socket_class(PSI_
 PFS_socket_class *sanitize_socket_class(PFS_socket_class *unsafe);
 
 PFS_table_share *find_or_create_table_share(PFS_thread *thread,
-                                            const char *schema_name,
-                                            uint schema_name_length,
-                                            const char *table_name,
-                                            uint table_name_length);
+                                            bool temporary,
+                                            const TABLE_SHARE *share);
+void purge_table_share(PFS_thread *thread, PFS_table_share *pfs);
+void drop_table_share(PFS_thread *thread,
+                      bool temporary,
+                      const char *schema_name, uint schema_name_length,
+                      const char *table_name, uint table_name_length);
 
 PFS_table_share *sanitize_table_share(PFS_table_share *unsafe);
 

=== modified file 'storage/perfschema/pfs_server.h'
--- a/storage/perfschema/pfs_server.h	2010-07-07 19:49:15 +0000
+++ b/storage/perfschema/pfs_server.h	2010-08-03 21:14:19 +0000
@@ -61,10 +61,10 @@
   #define PFS_MAX_SOCKET_CLASS 50
 #endif
 #ifndef PFS_MAX_TABLE_SHARE
-  #define PFS_MAX_TABLE_SHARE 50000
+  #define PFS_MAX_TABLE_SHARE 1000
 #endif
 #ifndef PFS_MAX_TABLE
-  #define PFS_MAX_TABLE 100000
+  #define PFS_MAX_TABLE 10000
 #endif
 #ifndef PFS_WAITS_HISTORY_SIZE
   #define PFS_WAITS_HISTORY_SIZE 10
@@ -73,6 +73,7 @@
   #define PFS_WAITS_HISTORY_LONG_SIZE 10000
 #endif
 
+/** Performance schema global sizing parameters. */
 struct PFS_global_param
 {
   bool m_enabled;
@@ -80,12 +81,20 @@ struct PFS_global_param
   ulong m_rwlock_class_sizing;
   ulong m_cond_class_sizing;
   ulong m_thread_class_sizing;
+  /**
+    Maximum number of instrumented table share.
+    @sa table_share_lost.
+  */
   ulong m_table_share_sizing;
   ulong m_file_class_sizing;
   ulong m_mutex_sizing;
   ulong m_rwlock_sizing;
   ulong m_cond_sizing;
   ulong m_thread_sizing;
+  /**
+    Maximum number of instrumented table handles.
+    @sa table_lost.
+  */
   ulong m_table_sizing;
   ulong m_file_sizing;
   ulong m_file_handle_sizing;

=== modified file 'storage/perfschema/table_all_instr.h'
--- a/storage/perfschema/table_all_instr.h	2010-07-09 02:23:31 +0000
+++ b/storage/perfschema/table_all_instr.h	2010-08-03 21:14:19 +0000
@@ -24,6 +24,7 @@
 #include "pfs_instr_class.h"
 #include "pfs_instr.h"
 #include "pfs_engine_table.h"
+#include "table_helper.h"
 
 /**
   @addtogroup Performance_schema_tables

=== modified file 'storage/perfschema/table_events_waits.cc'
--- a/storage/perfschema/table_events_waits.cc	2010-06-03 13:30:54 +0000
+++ b/storage/perfschema/table_events_waits.cc	2010-08-03 21:14:19 +0000
@@ -231,6 +231,7 @@ void table_events_waits_common::make_row
 
   m_row.m_thread_internal_id= safe_thread->m_thread_internal_id;
   m_row.m_event_id= wait->m_event_id;
+  m_row.m_nesting_event_id= wait->m_nesting_event_id;
   m_row.m_timer_state= wait->m_timer_state;
   m_row.m_timer_start= wait->m_timer_start;
   m_row.m_timer_end= wait->m_timer_end;
@@ -257,8 +258,16 @@ void table_events_waits_common::make_row
     safe_class= sanitize_cond_class((PFS_cond_class*) wait->m_class);
     break;
   case WAIT_CLASS_TABLE:
-    m_row.m_object_type= "TABLE";
-    m_row.m_object_type_length= 5;
+    if (wait->m_object_type == OBJECT_TYPE_TABLE)
+    {
+      m_row.m_object_type= "TABLE";
+      m_row.m_object_type_length= 5;
+    }
+    else
+    {
+      m_row.m_object_type= "TEMPORARY TABLE";
+      m_row.m_object_type_length= 15;
+    }
     memcpy(m_row.m_object_schema, wait->m_schema_name,
            wait->m_schema_name_length);
     m_row.m_object_schema_length= wait->m_schema_name_length;
@@ -300,7 +309,7 @@ void table_events_waits_common::make_row
     m_row.m_source_length= sizeof(m_row.m_source);
   m_row.m_operation= wait->m_operation;
   m_row.m_number_of_bytes= wait->m_number_of_bytes;
-  m_row.m_flags= 0;
+  m_row.m_flags= wait->m_flags;
 
   if (thread_own_wait)
   {
@@ -361,7 +370,15 @@ static const LEX_STRING operation_names_
   { C_STRING_WITH_LEN("chsize") },
   { C_STRING_WITH_LEN("delete") },
   { C_STRING_WITH_LEN("rename") },
-  { C_STRING_WITH_LEN("sync") }
+  { C_STRING_WITH_LEN("sync") },
+
+  /* Table operations */
+  { C_STRING_WITH_LEN("lock") },
+  { C_STRING_WITH_LEN("external lock") },
+  { C_STRING_WITH_LEN("fetch") },
+  { C_STRING_WITH_LEN("insert") }, /* write row */
+  { C_STRING_WITH_LEN("update") }, /* update row */
+  { C_STRING_WITH_LEN("delete") }  /* delete row */
 };
 
 
@@ -463,7 +480,7 @@ int table_events_waits_common::read_row_
         set_field_ulonglong(f, m_row.m_object_instance_addr);
         break;
       case 12: /* NESTING_EVENT_ID */
-        f->set_null();
+        set_field_ulonglong(f, m_row.m_nesting_event_id);
         break;
       case 13: /* OPERATION */
         operation= &operation_names_map[(int) m_row.m_operation - 1];
@@ -478,7 +495,11 @@ int table_events_waits_common::read_row_
           f->set_null();
         break;
       case 15: /* FLAGS */
-        set_field_ulong(f, m_row.m_flags);
+        if ((m_row.m_operation == OPERATION_TYPE_TABLE_LOCK) ||
+            (m_row.m_operation == OPERATION_TYPE_TABLE_EXTERNAL_LOCK))
+          set_field_ulong(f, m_row.m_flags);
+        else
+          f->set_null();
         break;
       default:
         DBUG_ASSERT(false);
@@ -525,14 +546,26 @@ int table_events_waits_current::rnd_next
       We do not show nested events for now,
       this will be revised with TABLE io
     */
-#define ONLY_SHOW_ONE_WAIT
+// #define ONLY_SHOW_ONE_WAIT
 
 #ifdef ONLY_SHOW_ONE_WAIT
     if (m_pos.m_index_2 >= 1)
       continue;
 #else
-    if (m_pos.m_index_2 >= pfs_thread->m_wait_locker_count)
-      continue;
+    uint safe_locker_count= pfs_thread->m_wait_locker_count;
+
+    if (safe_locker_count == 0)
+    {
+      /* Display the last top level wait, when completed */
+      if (m_pos.m_index_2 >= 1)
+        continue;
+    }
+    else
+    {
+      /* Display all pending waits, when in progress */
+      if (m_pos.m_index_2 >= safe_locker_count)
+        continue;
+    }
 #endif
 
     wait= &pfs_thread->m_wait_locker_stack[m_pos.m_index_2].m_waits_current;
@@ -567,9 +600,24 @@ int table_events_waits_current::rnd_pos(
   if (! pfs_thread->m_lock.is_populated())
     return HA_ERR_RECORD_DELETED;
 
-#ifdef ONLY_SHOW_CURRENT_WAITS
-  if (m_pos.m_index_2 >= pfs_thread->m_wait_locker_count)
+#ifdef ONLY_SHOW_ONE_WAIT
+  if (m_pos.m_index_2 >= 1)
     return HA_ERR_RECORD_DELETED;
+#else
+  uint safe_locker_count= pfs_thread->m_wait_locker_count;
+
+  if (safe_locker_count == 0)
+  {
+    /* Display the last top level wait, when completed */
+    if (m_pos.m_index_2 >= 1)
+      return HA_ERR_RECORD_DELETED;
+  }
+  else
+  {
+    /* Display all pending waits, when in progress */
+    if (m_pos.m_index_2 >= safe_locker_count)
+      return HA_ERR_RECORD_DELETED;
+  }
 #endif
 
   DBUG_ASSERT(m_pos.m_index_2 < LOCKER_STACK_SIZE);

=== modified file 'storage/perfschema/table_events_waits.h'
--- a/storage/perfschema/table_events_waits.h	2010-06-03 13:30:54 +0000
+++ b/storage/perfschema/table_events_waits.h	2010-08-03 21:14:19 +0000
@@ -39,6 +39,8 @@ struct row_events_waits
   ulong m_thread_internal_id;
   /** Column EVENT_ID. */
   ulonglong m_event_id;
+  /** Column NESTING_EVENT_ID. */
+  ulonglong m_nesting_event_id;
   /** Column EVENT_NAME. */
   const char *m_name;
   /** Length in bytes of @c m_name. */

=== modified file 'storage/perfschema/table_events_waits_summary.h'
--- a/storage/perfschema/table_events_waits_summary.h	2010-07-09 02:23:31 +0000
+++ b/storage/perfschema/table_events_waits_summary.h	2010-08-03 21:14:19 +0000
@@ -26,6 +26,7 @@
 #include "pfs_instr_class.h"
 #include "pfs_instr.h"
 #include "table_all_instr.h"
+#include "table_helper.h"
 
 /**
   @addtogroup Performance_schema_tables

=== modified file 'storage/perfschema/table_setup_instruments.cc'
--- a/storage/perfschema/table_setup_instruments.cc	2010-07-07 19:49:15 +0000
+++ b/storage/perfschema/table_setup_instruments.cc	2010-08-03 21:14:19 +0000
@@ -143,6 +143,14 @@ int table_setup_instruments::rnd_next(vo
         return 0;
       }
       break;
+    case pos_setup_instruments::VIEW_TABLE:
+      if (m_pos.m_index_2 == 1)
+      {
+        make_row(&global_table_class);
+        m_next_pos.set_after(&m_pos);
+        return 0;
+      }
+      break;
     }
   }
 
@@ -203,6 +211,13 @@ int table_setup_instruments::rnd_pos(con
       return 0;
     }
     break;
+  case pos_setup_instruments::VIEW_TABLE:
+    if (m_pos.m_index_2 == 1)
+    {
+      make_row(&global_table_class);
+      return 0;
+    }
+    break;    
   }
 
   return HA_ERR_RECORD_DELETED;

=== modified file 'storage/perfschema/table_setup_instruments.h'
--- a/storage/perfschema/table_setup_instruments.h	2010-07-09 02:23:31 +0000
+++ b/storage/perfschema/table_setup_instruments.h	2010-08-03 21:14:19 +0000
@@ -52,8 +52,9 @@ struct pos_setup_instruments : public PF
   /** Reverved for WL#4674, PERFORMANCE_SCHEMA Setup For Actors. */
   static const uint VIEW_THREAD= 4;
   static const uint VIEW_FILE= 5;
-  static const uint VIEW_SOCKET= 6;
-  static const uint LAST_VIEW= 6;
+  static const uint VIEW_TABLE= 6 ;
+  static const uint VIEW_SOCKET= 7;
+  static const uint LAST_VIEW= 8;
 
   pos_setup_instruments()
     : PFS_double_index(FIRST_VIEW, 1)

=== modified file 'storage/perfschema/table_setup_objects.cc'
--- a/storage/perfschema/table_setup_objects.cc	2010-06-03 13:30:54 +0000
+++ b/storage/perfschema/table_setup_objects.cc	2010-08-03 21:14:19 +0000
@@ -112,59 +112,11 @@ void table_setup_objects::reset_position
 
 int table_setup_objects::rnd_next(void)
 {
-  PFS_table_share *table_share;
-
-  for (m_pos.set_at(&m_next_pos);
-       m_pos.has_more_view();
-       m_pos.next_view())
-  {
-    switch (m_pos.m_index_1) {
-    case pos_setup_objects::VIEW_TABLE:
-      for ( ; m_pos.m_index_2 < table_share_max; m_pos.m_index_2++)
-      {
-        table_share= &table_share_array[m_pos.m_index_2];
-        if (table_share->m_lock.is_populated())
-        {
-          make_row(table_share);
-          m_next_pos.set_after(&m_pos);
-          return 0;
-        }
-      }
-      break;
-    case pos_setup_objects::VIEW_EVENT:
-    case pos_setup_objects::VIEW_PROCEDURE:
-    case pos_setup_objects::VIEW_FUNCTION:
-    default:
-      break;
-    }
-  }
-
   return HA_ERR_END_OF_FILE;
 }
 
 int table_setup_objects::rnd_pos(const void *pos)
 {
-  PFS_table_share *share;
-
-  set_position(pos);
-
-  switch (m_pos.m_index_1) {
-  case pos_setup_objects::VIEW_TABLE:
-    DBUG_ASSERT(m_pos.m_index_2 < table_share_max);
-    share= &table_share_array[m_pos.m_index_2];
-    if (share->m_lock.is_populated())
-    {
-      make_row(share);
-      return 0;
-    }
-    break;
-  case pos_setup_objects::VIEW_EVENT:
-  case pos_setup_objects::VIEW_PROCEDURE:
-  case pos_setup_objects::VIEW_FUNCTION:
-  default:
-    break;
-  }
-
   return HA_ERR_RECORD_DELETED;
 }
 
@@ -184,7 +136,7 @@ void table_setup_objects::make_row(PFS_t
   m_row.m_object_name_length= share->m_table_name_length;
   m_row.m_enabled_ptr= &share->m_enabled;
   m_row.m_timed_ptr= &share->m_timed;
-  m_row.m_aggregated_ptr= &share->m_aggregated;
+  m_row.m_aggregated_ptr= NULL;
 
   if (share->m_lock.end_optimistic_lock(&lock))
     m_row_exists= true;

=== modified file 'storage/perfschema/table_setup_objects.h'
--- a/storage/perfschema/table_setup_objects.h	2010-06-03 13:30:54 +0000
+++ b/storage/perfschema/table_setup_objects.h	2010-08-03 21:14:19 +0000
@@ -23,6 +23,7 @@
 
 #include "pfs_instr_class.h"
 #include "pfs_engine_table.h"
+#include "table_helper.h"
 
 /**
   @addtogroup Performance_schema_tables
@@ -53,17 +54,17 @@ struct pos_setup_objects : public PFS_do
                            public PFS_object_view_constants
 {
   pos_setup_objects()
-    : PFS_double_index(VIEW_TABLE, 0)
+    : PFS_double_index(FIRST_VIEW, 0)
   {}
 
   inline void reset(void)
   {
-    m_index_1= VIEW_TABLE;
+    m_index_1= FIRST_VIEW;
     m_index_2= 0;
   }
 
   inline bool has_more_view(void)
-  { return (m_index_1 <= VIEW_FUNCTION); }
+  { return (m_index_1 <= LAST_VIEW); }
 
   inline void next_view(void)
   {


Attachment: [text/bzr-bundle] bzr/chris.powers@oracle.com-20100803211419-1iswz2qm86lszd2x.bundle
Thread
bzr commit into mysql-next-mr-wl4896 branch (chris.powers:3156) Christopher Powers3 Aug