MySQL Lists are EOL. Please join:

List:Commits« Previous MessageNext Message »
From:Marc Alff Date:May 21 2009 7:42pm
Subject:bzr commit into mysql-6.0-perfschema branch (marc.alff:3150)
View as plain text  
#At file:///home/malff/BZR-TREE/mysql-6.0-perfschema/ based on revid:marc.alff@stripped

 3150 Marc Alff	2009-05-21
      Implemented code review comments, continued.
      
      Reworked all the thread instrumentation:
      - reverted the THD::store_global(bool) change implemented earlier,
      - removed the init_and_bind_psi_thread calls
      
      Instead, instrumented threads by intercepting the pthread_create()
      call with an instrumented mysql_thread_create().
modified:
  include/mysql/psi/mysql_mutex.h
  include/mysql/psi/psi.h
  include/mysql/psi/psi_abi_v1.h.pp
  libmysqld/lib_sql.cc
  mysql-test/suite/perfschema/r/no_threads.result
  sql/backup/be_thread.cc
  sql/event_scheduler.cc
  sql/events.cc
  sql/ha_ndbcluster.cc
  sql/ha_ndbcluster_binlog.cc
  sql/mysql_priv.h
  sql/mysqld.cc
  sql/scheduler.cc
  sql/slave.cc
  sql/slave.h
  sql/sql_acl.cc
  sql/sql_base.cc
  sql/sql_class.cc
  sql/sql_class.h
  sql/sql_connect.cc
  sql/sql_insert.cc
  sql/sql_manager.cc
  sql/sql_parse.cc
  sql/sql_plugin.cc
  sql/sql_servers.cc
  sql/sql_table.cc
  sql/sql_udf.cc
  sql/tztime.cc
  storage/maria/ma_check.c
  storage/maria/ma_checkpoint.c
  storage/maria/ma_sort.c
  storage/maria/ma_static.c
  storage/maria/maria_backup_engine.cc
  storage/maria/maria_def.h
  storage/myisam/myisam_backup_engine.cc
  storage/perfschema/pfs.cc
  storage/perfschema/pfs_instr.cc
  storage/perfschema/pfs_instr.h
  storage/perfschema/pfs_instr_class.cc
  storage/perfschema/pfs_instr_class.h
  storage/perfschema/table_setup_instruments.cc
  storage/perfschema/unittest/pfs-t.cc
  storage/perfschema/unittest/pfs_instr-t.cc

=== modified file 'include/mysql/psi/mysql_mutex.h'
--- a/include/mysql/psi/mysql_mutex.h	2009-05-12 03:15:02 +0000
+++ b/include/mysql/psi/mysql_mutex.h	2009-05-21 19:42:38 +0000
@@ -738,6 +738,65 @@ static inline int inline_mysql_cond_broa
   return result;
 }
 
+#ifdef HAVE_PSI_INTERFACE
+  #define mysql_thread_create(K,P1,P2,P3,P4) inline_mysql_thread_create(K,P1,P2,P3,P4)
+#else
+  #define mysql_thread_create(K,P1,P2,P3,P4) pthread_create(P1,P2,P3,P4)
+#endif
+
+#ifdef HAVE_PSI_INTERFACE
+  #define mysql_thread_set_id(I) inline_mysql_thread_set_id(I)
+#else
+  #define mysql_thread_set_id(I) do while (0)
+#endif
+
+#ifdef HAVE_PSI_INTERFACE
+  #define mysql_thread_prepare(P1,P2,P3,P4) inline_mysql_thread_prepare(P1,P2,P3,P4)
+#else
+  #define mysql_thread_prepare(P1,P2,P3,P4) inline_mysql_thread_prepare(P4)
+#endif
+
+#ifdef HAVE_PSI_INTERFACE
+static inline int inline_mysql_thread_create(
+  PSI_thread_key key,
+  pthread_t *thread, const pthread_attr_t *attr,
+  void *(*start_routine)(void*), void *arg)
+{
+  int result;
+  if (PSI_server)
+    result= PSI_server->spawn_thread(key, thread, attr, start_routine, arg);
+  else
+    result= pthread_create(thread, attr, start_routine, arg);
+  return result;
+}
+
+static inline void inline_mysql_thread_set_id(ulong id)
+{
+  if (PSI_server)
+  {
+    struct PSI_thread *psi= PSI_server->get_thread();
+    if (psi)
+      PSI_server->set_thread_id(psi, id);
+  }
+}
+
+#endif
+
+static inline void inline_mysql_thread_prepare(
+#ifdef HAVE_PSI_INTERFACE
+  PSI_thread_key key, const void *identity, ulong thread_id,
+#endif
+  struct PSI_thread **hdl)
+{
+#ifdef HAVE_PSI_INTERFACE
+  if (PSI_server)
+    *hdl= PSI_server->new_thread(key, identity, thread_id);
+  else
+#endif
+    *hdl= NULL;
+}
+
+
 /**
   @} (end of group Mutex_instrumentation)
 */

=== modified file 'include/mysql/psi/psi.h'
--- a/include/mysql/psi/psi.h	2009-05-13 16:44:00 +0000
+++ b/include/mysql/psi/psi.h	2009-05-21 19:42:38 +0000
@@ -563,14 +563,18 @@ typedef void (*close_table_v1_t)(struct
 */
 typedef void (*create_file_v1_t)(PSI_file_key key, const char *name, File file);
 
+typedef int (*spawn_thread_v1_t)(PSI_thread_key key,
+                                 pthread_t *thread, const pthread_attr_t *attr,
+                                 void *(*start_routine)(void*), void *arg);
+
 /**
   Create instrumentation for a thread.
   @param key the registered key
-  @param identity the address of the rwlock itself
+  @param identity an address typical of the thread
   @return an instrumented thread
 */
 typedef struct PSI_thread* (*new_thread_v1_t)
-  (PSI_thread_key key, const void *identity);
+  (PSI_thread_key key, const void *identity, ulong thread_id);
 
 /**
   Assign an id to an instrumented thread.
@@ -865,6 +869,8 @@ struct PSI_v1
   close_table_v1_t close_table;
   /** @sa create_file_v1_t. */
   create_file_v1_t create_file;
+  /** @sa spawn_thread_v1_t. */
+  spawn_thread_v1_t spawn_thread;
   /** @sa new_thread_v1_t. */
   new_thread_v1_t new_thread;
   /** @sa set_thread_id_v1_t. */

=== modified file 'include/mysql/psi/psi_abi_v1.h.pp'
--- a/include/mysql/psi/psi_abi_v1.h.pp	2009-05-13 16:44:00 +0000
+++ b/include/mysql/psi/psi_abi_v1.h.pp	2009-05-21 19:42:38 +0000
@@ -114,8 +114,11 @@ typedef struct PSI_table* (*open_table_v
   (struct PSI_table_share *share, const void *identity);
 typedef void (*close_table_v1_t)(struct PSI_table *table);
 typedef void (*create_file_v1_t)(PSI_file_key key, const char *name, File file);
+typedef int (*spawn_thread_v1_t)(PSI_thread_key key,
+                                 pthread_t *thread, const pthread_attr_t *attr,
+                                 void *(*start_routine)(void*), void *arg);
 typedef struct PSI_thread* (*new_thread_v1_t)
-  (PSI_thread_key key, const void *identity);
+  (PSI_thread_key key, const void *identity, ulong thread_id);
 typedef void (*set_thread_id_v1_t)(struct PSI_thread *thread, unsigned long id);
 typedef struct PSI_thread* (*get_thread_v1_t)(void);
 typedef void (*set_thread_v1_t)(struct PSI_thread *thread);
@@ -188,6 +191,7 @@ struct PSI_v1
   open_table_v1_t open_table;
   close_table_v1_t close_table;
   create_file_v1_t create_file;
+  spawn_thread_v1_t spawn_thread;
   new_thread_v1_t new_thread;
   set_thread_id_v1_t set_thread_id;
   get_thread_v1_t get_thread;

=== modified file 'libmysqld/lib_sql.cc'
--- a/libmysqld/lib_sql.cc	2009-04-17 18:44:53 +0000
+++ b/libmysqld/lib_sql.cc	2009-05-21 19:42:38 +0000
@@ -118,7 +118,7 @@ emb_advanced_command(MYSQL *mysql, enum
   net_clear_error(net);
   thd->current_stmt= stmt;
 
-  thd->store_globals(false);				// Fix if more than one connect
+  thd->store_globals();				// Fix if more than one connect
   lex_start(thd);
   /* 
      We have to call free_old_query before we start to fill mysql->fields 
@@ -391,7 +391,7 @@ static void emb_free_embedded_thd(MYSQL
   THD *thd= (THD*)mysql->thd;
   thd->clear_data_list();
   thread_count--;
-  thd->store_globals(false);
+  thd->store_globals();
   thd->unlink();
   delete thd;
   my_pthread_setspecific_ptr(THR_THD,  0);
@@ -602,7 +602,7 @@ void *create_embedded_thd(int client_fla
   thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
 
   thd->thread_stack= (char*) &thd;
-  if (thd->store_globals(false))
+  if (thd->store_globals())
   {
     fprintf(stderr,"store_globals failed.\n");
     goto err;

=== modified file 'mysql-test/suite/perfschema/r/no_threads.result'
--- a/mysql-test/suite/perfschema/r/no_threads.result	2009-05-02 07:15:38 +0000
+++ b/mysql-test/suite/perfschema/r/no_threads.result	2009-05-21 19:42:38 +0000
@@ -24,7 +24,7 @@ count(*)
 select count(*) from performance_schema.PROCESSLIST
 where name like "thread/sql/OneConnection";
 count(*)
-1
+2
 select event_name, operation, source
 from performance_schema.EVENTS_WAITS_CURRENT;
 event_name	operation	source

=== modified file 'sql/backup/be_thread.cc'
--- a/sql/backup/be_thread.cc	2009-05-12 03:15:02 +0000
+++ b/sql/backup/be_thread.cc	2009-05-21 19:42:38 +0000
@@ -51,20 +51,14 @@ THD *create_new_thd()
     DBUG_RETURN(0);
   THD_CHECK_SENTRY(thd);
 
-#ifdef HAVE_PSI_INTERFACE
-  thd->m_psi= init_and_bind_psi_thread_with_id(key_thread_backup, thd, 0);
-#endif
-
   thd->thread_stack = (char*)&thd; // remember where our stack is  
   mysql_mutex_lock(&LOCK_thread_count);
   thd->thread_id= thread_id++;
   mysql_mutex_unlock(&LOCK_thread_count);
 
-#ifdef HAVE_PSI_INTERFACE
-  set_psi_thread_id(thd, thd->thread_id);
-#endif
+  mysql_thread_set_id(thd->thread_id);
 
-  if (unlikely(thd->store_globals(true))) // for a proper MEM_ROOT  
+  if (unlikely(thd->store_globals())) // for a proper MEM_ROOT  
   {
     thd->cleanup();
     delete thd;
@@ -303,8 +297,9 @@ result_t Locking_thread_st::start_lockin
   DBUG_ENTER("Locking_thread_st::start_locking_thread");
   pthread_t th;
   thd_name.append(tname);
-  if (pthread_create(&th, &connection_attrib,
-                     backup_thread_for_locking, this))
+  if (mysql_thread_create(key_thread_backup,
+                          &th, &connection_attrib,
+                          backup_thread_for_locking, this))
     SET_STATE_TO_ERROR_AND_DBUG_RETURN;
   m_thread_started= TRUE;
   DBUG_RETURN(backup::OK);

=== modified file 'sql/event_scheduler.cc'
--- a/sql/event_scheduler.cc	2009-05-12 03:15:02 +0000
+++ b/sql/event_scheduler.cc	2009-05-21 19:42:38 +0000
@@ -123,7 +123,7 @@ bool
 post_init_event_thread(THD *thd)
 {
   (void) init_new_connection_handler_thread();
-  if (init_thr_lock() || thd->store_globals(true))
+  if (init_thr_lock() || thd->store_globals())
   {
     thd->cleanup();
     return TRUE;
@@ -228,10 +228,7 @@ event_scheduler_thread(void *arg)
 
   thd->thread_stack= (char *)&thd;              // remember where our stack is
 
-#ifdef HAVE_PSI_INTERFACE
-  thd->m_psi= init_and_bind_psi_thread_with_id(key_thread_event_scheduler,
-                                               thd, thd->thread_id);
-#endif
+  mysql_thread_set_id(thd->thread_id);
 
   res= post_init_event_thread(thd);
 
@@ -265,10 +262,7 @@ event_worker_thread(void *arg)
 
   thd= event->thd;
 
-#ifdef HAVE_PSI_INTERFACE
-  thd->m_psi= init_and_bind_psi_thread_with_id(key_thread_event_worker,
-                                               thd, thd->thread_id);
-#endif
+  mysql_thread_set_id(thd->thread_id);
 
   Event_worker_thread worker_thread;
   worker_thread.run(thd, event);
@@ -423,8 +417,9 @@ Event_scheduler::start()
   DBUG_PRINT("info", ("Setting state go RUNNING"));
   state= RUNNING;
   DBUG_PRINT("info", ("Forking new thread for scheduler. THD: %p", new_thd));
-  if (pthread_create(&th, &connection_attrib, event_scheduler_thread,
-                    (void*)scheduler_param_value))
+  if (mysql_thread_create(key_thread_event_scheduler,
+                          &th, &connection_attrib, event_scheduler_thread,
+                          (void*)scheduler_param_value))
   {
     DBUG_PRINT("error", ("cannot create a new thread"));
     state= INITIALIZED;
@@ -550,8 +545,9 @@ Event_scheduler::execute_top(Event_queue
     reasonable level.
   */
   /* Major failure */
-  if ((res= pthread_create(&th, &connection_attrib, event_worker_thread,
-                           event_name)))
+  if ((res= mysql_thread_create(key_thread_event_worker,
+                                &th, &connection_attrib, event_worker_thread,
+                                event_name)))
     goto error;
 
   ++started_events;

=== modified file 'sql/events.cc'
--- a/sql/events.cc	2009-05-12 03:15:02 +0000
+++ b/sql/events.cc	2009-05-21 19:42:38 +0000
@@ -861,7 +861,7 @@ Events::init(my_bool opt_noacl)
     no value.
   */
   thd->thread_stack= (char*) &thd;
-  thd->store_globals(false);
+  thd->store_globals();
 
   /*
     We will need Event_db_repository anyway, even if the scheduler is

=== modified file 'sql/ha_ndbcluster.cc'
--- a/sql/ha_ndbcluster.cc	2009-05-12 03:15:02 +0000
+++ b/sql/ha_ndbcluster.cc	2009-05-21 19:42:38 +0000
@@ -7823,7 +7823,8 @@ static int ndbcluster_init(void *p)
   ndb_cache_check_time = opt_ndb_cache_check_time;
   // Create utility thread
   pthread_t tmp;
-  if (pthread_create(&tmp, &connection_attrib, ndb_util_thread_func, 0))
+  if (mysql_thread_create(key_thread_ndb_util,
+                          &tmp, &connection_attrib, ndb_util_thread_func, 0))
   {
     DBUG_PRINT("error", ("Could not create ndb utility thread"));
     my_hash_free(&ndbcluster_open_tables);
@@ -10166,10 +10167,7 @@ pthread_handler_t ndb_util_thread_func(v
   }
 
 /* FIXME: waiting for Bug#40899 */
-#ifdef HAVE_PSI_INTERFACE
-  thd->m_psi= init_and_bind_psi_thread_with_id(key_thread_ndb_util,
-                                               thd, thd->thread_id);
-#endif
+  mysql_thread_set_id(thd->thread_id);
 
   mysql_mutex_lock(&LOCK_ndb_util_thread);
 
@@ -10178,7 +10176,7 @@ pthread_handler_t ndb_util_thread_func(v
   ndb_util_thread= pthread_self();
 
   thd->thread_stack= (char*)&thd; /* remember where our stack is */
-  if (thd->store_globals(true))
+  if (thd->store_globals())
     goto ndb_util_thread_fail;
   lex_start(thd);
   thd->init_for_queries();

=== modified file 'sql/ha_ndbcluster_binlog.cc'
--- a/sql/ha_ndbcluster_binlog.cc	2009-05-12 03:15:02 +0000
+++ b/sql/ha_ndbcluster_binlog.cc	2009-05-21 19:42:38 +0000
@@ -3155,8 +3155,8 @@ int ndbcluster_binlog_start()
   mysql_mutex_init(key_ndb_schema_share_mutex, &ndb_schema_share_mutex, MY_MUTEX_INIT_FAST);
 
   /* Create injector thread */
-  if (pthread_create(&ndb_binlog_thread, &connection_attrib,
-                     ndb_binlog_thread_func, 0))
+  if (mysql_thread_create(key_thread_ndb_binlog, &ndb_binlog_thread, &connection_attrib,
+                          ndb_binlog_thread_func, 0))
   {
     DBUG_PRINT("error", ("Could not create ndb injector thread"));
     mysql_cond_destroy(&injector_cond);
@@ -4697,13 +4697,10 @@ pthread_handler_t ndb_binlog_thread_func
   thd->thread_id= thread_id++;
   mysql_mutex_unlock(&LOCK_thread_count);
 
-#ifdef HAVE_PSI_INTERFACE
-  thd->m_psi= init_and_bind_psi_thread_with_id(key_thread_ndb_binlog,
-                                               thd, thd->thread_id);
-#endif
+  mysql_thread_set_id(thd->thread_id);
 
   thd->thread_stack= (char*) &thd; /* remember where our stack is */
-  if (thd->store_globals(true))
+  if (thd->store_globals())
   {
     thd->cleanup();
     delete thd;

=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h	2009-05-18 15:36:08 +0000
+++ b/sql/mysql_priv.h	2009-05-21 19:42:38 +0000
@@ -2248,36 +2248,6 @@ extern PSI_file_key key_file_global_ddl_
   Initialise all the performance schema instrumentation points used by the server.
 */
 void init_server_psi_keys();
-
-/**
-  Create an instrumented thread.
-  @param key the instrumentation thread key
-  @param identity the thread identity
-  @param id the thread identifier
-  @return an instrumented thread, or NULL.
-*/
-PSI_thread* init_psi_thread_with_id(PSI_thread_key key,
-                                    void* identity,
-                                    ulong id);
-
-/**
-  Create an instrumented thread, and bind it to the running thread.
-  @param key the instrumentation thread key
-  @param identity the thread identity
-  @param id the thread identifier
-  @return an instrumented thread, or NULL.
-*/
-PSI_thread* init_and_bind_psi_thread_with_id(PSI_thread_key key,
-                                             void* identity,
-                                             ulong id);
-
-/**
-  Set the thread identifier in the instrumentation.
-  @param thd a thread
-  @param id the thread identifier
-*/
-void set_psi_thread_id(THD *thd, ulong id);
-
 #endif /* HAVE_PSI_INTERFACE */
 
 extern mysql_mutex_t LOCK_mysql_create_db, LOCK_open, LOCK_lock_db,

=== modified file 'sql/mysqld.cc'
--- a/sql/mysqld.cc	2009-05-18 15:36:08 +0000
+++ b/sql/mysqld.cc	2009-05-21 19:42:38 +0000
@@ -1193,8 +1193,9 @@ void kill_mysql(void)
   {
     pthread_t tmp;
     abort_loop=1;
-    if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
-			   (void*) 0))
+    if (mysql_thread_create(key_thread_kill_server,
+                            &tmp, &connection_attrib, kill_server_thread,
+                            (void*) 0))
       sql_print_error("Can't create thread to kill server");
   }
 #endif
@@ -1277,10 +1278,6 @@ pthread_handler_t kill_server_thread(voi
 {
   my_thread_init();				// Initialize new thread
 
-#ifdef HAVE_PSI_INTERFACE
-  (void) init_and_bind_psi_thread_with_id(key_thread_kill_server, NULL, 0);
-#endif
-
   kill_server(0);
   /* purecov: begin deadcode */
   my_thread_end();
@@ -2078,7 +2075,7 @@ static bool cache_thread()
       wake_thread--;
       thd= thread_cache.get();
       thd->thread_stack= (char*) &thd;          // For store_globals
-      (void) thd->store_globals(true);
+      (void) thd->store_globals();
       /*
         THD::mysys_var::abort is associated with physical thread rather
         than with THD object. So we need to reset this flag before using
@@ -2841,7 +2838,8 @@ static void start_signal_handler(void)
 #endif
 
   (void) mysql_mutex_lock(&LOCK_thread_count);
-  if ((error=pthread_create(&signal_thread,&thr_attr,signal_hand,0)))
+  if ((error= mysql_thread_create(key_thread_signal_hand,
+                                  &signal_thread, &thr_attr, signal_hand, 0)))
   {
     sql_print_error("Can't create interrupt-thread (error %d, errno: %d)",
 		    error,errno);
@@ -2865,10 +2863,6 @@ pthread_handler_t signal_hand(void *arg
   DBUG_ENTER("signal_hand");
   signal_thread_in_use= 1;
 
-#ifdef HAVE_PSI_INTERFACE
-  (void) init_and_bind_psi_thread_with_id(key_thread_signal_hand, NULL, 0);
-#endif
-
   /*
     Setup alarm handler
     This should actually be '+ max_number_of_slaves' instead of +10,
@@ -2953,8 +2947,9 @@ pthread_handler_t signal_hand(void *arg
 	abort_loop=1;				// mark abort for threads
 #ifdef USE_ONE_SIGNAL_HAND
 	pthread_t tmp;
-	if (pthread_create(&tmp,&connection_attrib, kill_server_thread,
-			   (void*) &sig))
+	if (mysql_thread_create(key_thread_kill_server,
+                                &tmp, &connection_attrib, kill_server_thread,
+                                (void*) &sig))
 	  sql_print_error("Can't create thread to kill server");
 #else
 	kill_server((void*) sig);	// MIT THREAD has a alarm thread
@@ -3112,10 +3107,6 @@ pthread_handler_t handle_shutdown(void *
   MSG msg;
   my_thread_init();
 
-#ifdef HAVE_PSI_INTERFACE
-  (void) init_and_bind_psi_thread_with_id(key_thread_handle_shutdown, NULL, 0);
-#endif
-
   /* this call should create the message queue for this thread */
   PeekMessage(&msg, NULL, 1, 65534,PM_NOREMOVE);
 #if !defined(EMBEDDED_LIBRARY)
@@ -4378,7 +4369,8 @@ static void create_shutdown_thread()
 #ifdef __WIN__
   hEventShutdown=CreateEvent(0, FALSE, FALSE, shutdown_event_name);
   pthread_t hThread;
-  if (pthread_create(&hThread,&connection_attrib,handle_shutdown,0))
+  if (mysql_thread_create(key_thread_handle_shutdown,
+                          &hThread,&connection_attrib, handle_shutdown, 0))
     sql_print_warning("Can't create thread to handle shutdown requests");
 
   // On "Stop Service" we have to do regular shutdown
@@ -4418,8 +4410,9 @@ static void handle_connections_methods()
   if (hPipe != INVALID_HANDLE_VALUE)
   {
     handler_count++;
-    if (pthread_create(&hThread,&connection_attrib,
-		       handle_connections_namedpipes, 0))
+    if (mysql_thread_create(key_thread_handle_con_namedpipes,
+                            &hThread, &connection_attrib,
+		            handle_connections_namedpipes, 0))
     {
       sql_print_warning("Can't create thread to handle named pipes");
       handler_count--;
@@ -4429,8 +4422,9 @@ static void handle_connections_methods()
   if (have_tcpip && !opt_disable_networking)
   {
     handler_count++;
-    if (pthread_create(&hThread,&connection_attrib, 
-                       handle_connections_sockets_thread, 0))
+    if (mysql_thread_create(key_thread_handle_socket_con,
+                            &hThread, &connection_attrib,
+                            handle_connections_sockets_thread, 0))
     {
       sql_print_warning("Can't create thread to handle TCP/IP");
       handler_count--;
@@ -4440,8 +4434,9 @@ static void handle_connections_methods()
   if (opt_enable_shared_memory)
   {
     handler_count++;
-    if (pthread_create(&hThread,&connection_attrib,
-		       handle_connections_shared_memory, 0))
+    if (mysql_thread_create(key_thread_handle_con_sharedmem,
+                            &hThread, &connection_attrib,
+		            handle_connections_shared_memory, 0))
     {
       sql_print_warning("Can't create thread to handle shared memory");
       handler_count--;
@@ -4561,7 +4556,9 @@ int main(int argc, char **argv)
     my_init_mysys_psi_keys();
     init_server_psi_keys();
     /* Instrument the main thread */
-    (void) init_and_bind_psi_thread_with_id(key_thread_main, NULL, 0);
+    PSI_thread *psi= PSI_server->new_thread(key_thread_main, NULL, 0);
+    if (psi)
+      PSI_server->set_thread(psi);
 
 #ifndef HAVE_WL4876
     /* TODO: remove with WL#4876: rework the out of order mysys initialization */
@@ -5058,8 +5055,9 @@ static void bootstrap(MYSQL_FILE *file)
 
   bootstrap_file=file;
 #ifndef EMBEDDED_LIBRARY			// TODO:  Enable this
-  if (pthread_create(&thd->real_id,&connection_attrib,handle_bootstrap,
-		     (void*) thd))
+  if (mysql_thread_create(key_thread_bootstrap,
+                          &thd->real_id, &connection_attrib, handle_bootstrap,
+                          (void*) thd))
   {
     sql_print_warning("Can't create thread to handle bootstrap");
     bootstrap_error=-1;
@@ -5109,11 +5107,7 @@ static bool read_init_file(char *file_na
 
 void handle_connection_in_main_thread(THD *thd)
 {
-#ifdef HAVE_PSI_INTERFACE
-  thd->m_psi= init_psi_thread_with_id(key_thread_one_connection, thd, thd->thread_id);
-#else
-  thd->m_psi= NULL;
-#endif
+  mysql_thread_prepare(key_thread_one_connection, thd, thd->thread_id, & thd->m_psi);
 
   mysql_mutex_assert_owner(&LOCK_thread_count);
   thread_cache_size=0;			// Safety
@@ -5131,11 +5125,7 @@ void create_thread_to_handle_connection(
 {
   if (cached_thread_count > wake_thread)
   {
-#ifdef HAVE_PSI_INTERFACE
-    thd->m_psi= init_psi_thread_with_id(key_thread_one_connection, thd, thd->thread_id);
-#else
-    thd->m_psi= NULL;
-#endif
+    mysql_thread_prepare(key_thread_one_connection, thd, thd->thread_id, & thd->m_psi);
 
     /* Get thread from cache */
     thread_cache.append(thd);
@@ -5151,9 +5141,9 @@ void create_thread_to_handle_connection(
     threads.append(thd);
     DBUG_PRINT("info",(("creating thread %lu"), thd->thread_id));
     thd->connect_utime= thd->start_utime= my_micro_time();
-    if ((error=pthread_create(&thd->real_id,&connection_attrib,
-                              handle_one_connection,
-                              (void*) thd)))
+    if ((error= mysql_thread_create(key_thread_one_connection,
+                                    &thd->real_id, &connection_attrib,
+                                    handle_one_connection, (void*) thd)))
     {
       /* purecov: begin inspected */
       DBUG_PRINT("error",
@@ -5479,10 +5469,6 @@ void handle_connections_sockets()
 #ifdef _WIN32
 pthread_handler_t handle_connections_sockets_thread(void *arg)
 {
-#ifdef HAVE_PSI_INTERFACE
-  (void) init_and_bind_psi_thread_with_id(key_thread_handle_socket_con, NULL, 0);
-#endif
-
   my_thread_init();
   handle_connections_sockets();
   decrement_handler_count();
@@ -5499,10 +5485,6 @@ pthread_handler_t handle_connections_nam
 
   DBUG_PRINT("general",("Waiting for named pipe connections."));
 
-#ifdef HAVE_PSI_INTERFACE
-  (void) init_and_bind_psi_thread_with_id(key_thread_handle_con_namedpipes, NULL, 0);
-#endif
-
   while (!abort_loop)
   {
     /* wait for named pipe connection */
@@ -5599,10 +5581,6 @@ pthread_handler_t handle_connections_sha
   DBUG_ENTER("handle_connections_shared_memorys");
   DBUG_PRINT("general",("Waiting for allocated shared memory."));
 
-#ifdef HAVE_PSI_INTERFACE
-  (void) init_and_bind_psi_thread_with_id(key_thread_handle_con_sharedmem, NULL, 0);
-#endif
-
   /*
      get enough space base-name + '_' + longest suffix we might ever send
    */
@@ -9882,47 +9860,5 @@ void init_server_psi_keys()
   count= array_elements(all_server_files);
   PSI_server->register_file(category, all_server_files, count);
 }
-
-PSI_thread *init_psi_thread_with_id(PSI_thread_key key, void* identity,
-                                    ulong id)
-{
-  PSI_thread *psi= NULL;
-  if (PSI_server)
-  {
-    /*
-      Create an instrumented thread and set it's id.
-    */
-    psi= PSI_server->new_thread(key, identity);
-    if (psi)
-      PSI_server->set_thread_id(psi, id);
-  }
-  return psi;
-}
-
-PSI_thread* init_and_bind_psi_thread_with_id(PSI_thread_key key,
-                                             void* identity,
-                                             ulong id)
-{
-  PSI_thread *psi= NULL;
-  if (PSI_server)
-  {
-    /*
-      Create an instrumented thread, set it's id,
-      and bind it in Thread Local Storage.
-    */
-    psi= PSI_server->new_thread(key, identity);
-    if (psi)
-      PSI_server->set_thread_id(psi, id);
-    PSI_server->set_thread(psi);
-  }
-  return psi;
-}
-
-void set_psi_thread_id(THD *thd, ulong id)
-{
-  if (PSI_server && thd->m_psi)
-    PSI_server->set_thread_id(thd->m_psi, id);
-}
-
 #endif
 

=== modified file 'sql/scheduler.cc'
--- a/sql/scheduler.cc	2009-05-16 00:41:08 +0000
+++ b/sql/scheduler.cc	2009-05-21 19:42:38 +0000
@@ -210,19 +210,21 @@ bool thd_scheduler::thread_attach()
 {
   DBUG_ASSERT(!thread_attached);
 
+  THD* thd = (THD*)list.data;
+
 #ifdef HAVE_PSI_INTERFACE
   {
     /*
       Until now, this thread is running under the libevent instrumentation.
-      Save this instrumentation before binding to the job instrumentation,
-      THD::m_psi, in setup_connection_thread_globals().
+      Save this instrumentation, and bind to the job instrumentation, THD::m_psi.
     */
     PSI_thread *psi= (PSI_server ? PSI_server->get_thread() : NULL);
     my_pthread_setspecific_ptr(THR_PSI_backup, psi);
+    if (PSI_server)
+      PSI_server->set_thread(thd->m_psi);
   }
 #endif
 
-  THD* thd = (THD*)list.data;
   if (libevent_should_close_connection(thd) ||
       setup_connection_thread_globals(thd))
   {
@@ -360,8 +362,9 @@ static bool libevent_init(void)
   {
     pthread_t thread;
     int error;
-    if ((error= pthread_create(&thread, &connection_attrib,
-                               libevent_thread_proc, 0)))
+    if ((error= mysql_thread_create(key_thread_libevent,
+                                    &thread, &connection_attrib,
+                                    libevent_thread_proc, 0)))
     {
       sql_print_error("Can't create completion port thread (error %d)",
                       error);
@@ -513,11 +516,7 @@ static void libevent_add_connection(THD
     DBUG_VOID_RETURN;
   }
 
-#ifdef HAVE_PSI_INTERFACE
-  thd->m_psi= init_psi_thread_with_id(key_thread_one_connection, thd, thd->thread_id);
-#else
-  thd->m_psi= NULL;
-#endif
+  mysql_thread_prepare(key_thread_one_connection, thd, thd->thread_id, & thd->m_psi);
 
   thd->set_time();
   thd->thr_create_utime= my_micro_time();
@@ -599,10 +598,6 @@ static bool libevent_should_close_connec
 
 pthread_handler_t libevent_thread_proc(void *arg)
 {
-#ifdef HAVE_PSI_INTERFACE
-  (void) init_and_bind_psi_thread_with_id(key_thread_libevent, NULL, 0);
-#endif
-
   if (init_new_connection_handler_thread())
   {
     my_thread_global_end();

=== modified file 'sql/slave.cc'
--- a/sql/slave.cc	2009-05-18 15:36:08 +0000
+++ b/sql/slave.cc	2009-05-21 19:42:38 +0000
@@ -696,7 +696,11 @@ terminate_slave_thread(THD *thd,
 }
 
 
-int start_slave_thread(pthread_handler h_func, mysql_mutex_t *start_lock,
+int start_slave_thread(
+#ifdef HAVE_PSI_INTERFACE
+                       PSI_thread_key key,
+#endif
+                       pthread_handler h_func, mysql_mutex_t *start_lock,
                        mysql_mutex_t *cond_lock,
                        mysql_cond_t *start_cond,
                        volatile uint *slave_running,
@@ -731,7 +735,7 @@ int start_slave_thread(pthread_handler h
   }
   start_id= *slave_run_id;
   DBUG_PRINT("info",("Creating new slave thread"));
-  if (pthread_create(&th, &connection_attrib, h_func, (void*)mi))
+  if (mysql_thread_create(key, &th, &connection_attrib, h_func, (void*)mi))
   {
     if (start_lock)
       mysql_mutex_unlock(start_lock);
@@ -793,13 +797,21 @@ int start_slave_threads(bool need_slave_
   }
 
   if (thread_mask & SLAVE_IO)
-    error=start_slave_thread(handle_slave_io,lock_io,lock_cond_io,
+    error=start_slave_thread(
+#ifdef HAVE_PSI_INTERFACE
+                             key_thread_slave_io,
+#endif
+                             handle_slave_io,lock_io,lock_cond_io,
                              cond_io,
                              &mi->slave_running, &mi->slave_run_id,
                              mi);
   if (!error && (thread_mask & SLAVE_SQL))
   {
-    error=start_slave_thread(handle_slave_sql,lock_sql,lock_cond_sql,
+    error=start_slave_thread(
+#ifdef HAVE_PSI_INTERFACE
+                             key_thread_slave_sql,
+#endif
+                             handle_slave_sql,lock_sql,lock_cond_sql,
                              cond_sql,
                              &mi->rli->slave_running, &mi->rli->slave_run_id,
                              mi);
@@ -1850,9 +1862,9 @@ static int init_slave_thread(THD* thd, S
   DBUG_EXECUTE_IF("simulate_sql_slave_error_on_init",
                   simulate_error|= (1 << SLAVE_THD_SQL););
 #if !defined(DBUG_OFF)
-  if (init_thr_lock() || thd->store_globals(true) || simulate_error & (1<< thd_type))
+  if (init_thr_lock() || thd->store_globals() || simulate_error & (1<< thd_type))
 #else
-  if (init_thr_lock() || thd->store_globals(true))
+  if (init_thr_lock() || thd->store_globals())
 #endif
   {
     thd->cleanup();
@@ -2521,10 +2533,6 @@ pthread_handler_t handle_slave_io(void *
   thd= new THD; // note that constructor of THD uses DBUG_ !
   THD_CHECK_SENTRY(thd);
 
-#ifdef HAVE_PSI_INTERFACE
-  thd->m_psi= init_and_bind_psi_thread_with_id(key_thread_slave_io, thd, 0);
-#endif
-
   DBUG_ASSERT(mi->inited);
   mysql= NULL ;
   retry_count= 0;
@@ -2897,10 +2905,6 @@ pthread_handler_t handle_slave_sql(void
   thd = new THD; // note that constructor of THD uses DBUG_ !
   thd->thread_stack = (char*)&thd; // remember where our stack is
 
-#ifdef HAVE_PSI_INTERFACE
-  thd->m_psi= init_and_bind_psi_thread_with_id(key_thread_slave_sql, thd, 0);
-#endif
-
   DBUG_ASSERT(rli->inited);
   mysql_mutex_lock(&rli->run_lock);
   DBUG_ASSERT(!rli->slave_running);

=== modified file 'sql/slave.h'
--- a/sql/slave.h	2009-05-12 03:15:02 +0000
+++ b/sql/slave.h	2009-05-21 19:42:38 +0000
@@ -161,7 +161,11 @@ int start_slave_threads(bool need_slave_
   inside the start_lock section, but at the same time we want a
   mysql_cond_wait() on start_cond,start_lock
 */
-int start_slave_thread(pthread_handler h_func, mysql_mutex_t* start_lock,
+int start_slave_thread(
+#ifdef HAVE_PSI_INTERFACE
+                       PSI_thread_key key,
+#endif
+                       pthread_handler h_func, mysql_mutex_t* start_lock,
 		       mysql_mutex_t *cond_lock,
 		       mysql_cond_t* start_cond,
 		       volatile uint *slave_running,

=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc	2009-05-18 15:36:08 +0000
+++ b/sql/sql_acl.cc	2009-05-21 19:42:38 +0000
@@ -277,7 +277,7 @@ my_bool acl_init(bool dont_read_acl_tabl
   if (!(thd=new THD))
     DBUG_RETURN(1); /* purecov: inspected */
   thd->thread_stack= (char*) &thd;
-  thd->store_globals(false);
+  thd->store_globals();
   /*
     It is safe to call acl_reload() since acl_* arrays and hashes which
     will be freed there are global static objects and thus are initialized
@@ -3520,7 +3520,7 @@ my_bool grant_init()
   if (!(thd= new THD))
     DBUG_RETURN(1);				/* purecov: deadcode */
   thd->thread_stack= (char*) &thd;
-  thd->store_globals(false);
+  thd->store_globals();
   return_val=  grant_reload(thd);
   delete thd;
   /* Remember that we don't have a THD */

=== modified file 'sql/sql_base.cc'
--- a/sql/sql_base.cc	2009-05-18 15:36:08 +0000
+++ b/sql/sql_base.cc	2009-05-21 19:42:38 +0000
@@ -7526,7 +7526,7 @@ my_bool mysql_rm_tmp_tables(void)
   if (!(thd= new THD))
     DBUG_RETURN(1);
   thd->thread_stack= (char*) &thd;
-  thd->store_globals(false);
+  thd->store_globals();
 
   for (i=0; i<=mysql_tmpdir_list.max; i++)
   {

=== modified file 'sql/sql_class.cc'
--- a/sql/sql_class.cc	2009-05-18 15:36:08 +0000
+++ b/sql/sql_class.cc	2009-05-21 19:42:38 +0000
@@ -1126,15 +1126,6 @@ THD::~THD()
 
   free_root(&main_mem_root, MYF(0));
 
-#ifdef HAVE_PSI_INTERFACE
-  /*
-    For fake threads (see THD::store_globals()),
-    m_psi is NULL, do not delete the instrumentation already in place.
-  */
-  if (PSI_server && m_psi)
-    PSI_server->delete_current_thread();
-#endif
-
   DBUG_VOID_RETURN;
 }
 
@@ -1292,7 +1283,7 @@ void THD::awake(THD::killed_state state_
   sql_alloc() and the structure for the net buffer
 */
 
-bool THD::store_globals(bool real_thread)
+bool THD::store_globals()
 {
   DBUG_ENTER("THD::store_globals");
   /*
@@ -1301,24 +1292,6 @@ bool THD::store_globals(bool real_thread
   */
   DBUG_ASSERT(thread_stack);
 
-#ifdef HAVE_PSI_INTERFACE
-  /*
-    For 'real' threads, where this THD object is executed by a pthread,
-    bind the instrumentation to the thread.
-    For 'fake' threads, where this THD object is used without a dedicated pthread
-    but with the pthread of the caller, use the caller instrumentation.
-  */
-  if (real_thread)
-  {
-    if (PSI_server)
-      PSI_server->set_thread(m_psi);
-  }
-  else
-  {
-    m_psi= NULL;
-  }
-#endif
-
   if (my_pthread_setspecific_ptr(THR_THD,  this) ||
       my_pthread_setspecific_ptr(THR_MALLOC, &mem_root))
     DBUG_RETURN(1);

=== modified file 'sql/sql_class.h'
--- a/sql/sql_class.h	2009-05-18 15:36:08 +0000
+++ b/sql/sql_class.h	2009-05-21 19:42:38 +0000
@@ -1936,7 +1936,7 @@ public:
   void change_user(void);
   void cleanup(void);
   void cleanup_after_query();
-  bool store_globals(bool real_thread);
+  bool store_globals();
 #ifdef SIGNAL_WITH_VIO_CLOSE
   inline void set_active_vio(Vio* vio)
   {

=== modified file 'sql/sql_connect.cc'
--- a/sql/sql_connect.cc	2009-05-18 15:36:08 +0000
+++ b/sql/sql_connect.cc	2009-05-21 19:42:38 +0000
@@ -933,7 +933,7 @@ static int check_connection(THD *thd)
 
 bool setup_connection_thread_globals(THD *thd)
 {
-  if (thd->store_globals(true))
+  if (thd->store_globals())
   {
     close_connection(thd, ER_OUT_OF_RESOURCES, 1);
     statistic_increment(aborted_connects,&LOCK_status);
@@ -1103,12 +1103,7 @@ pthread_handler_t handle_one_connection(
 {
   THD *thd= (THD*) arg;
 
-#ifdef HAVE_PSI_INTERFACE
-  thd->m_psi= init_and_bind_psi_thread_with_id(key_thread_one_connection,
-                                               thd, thd->thread_id);
-#else
-  thd->m_psi= NULL;
-#endif
+  mysql_thread_set_id(thd->thread_id);
 
   do_handle_one_connection(thd);
   return 0;

=== modified file 'sql/sql_insert.cc'
--- a/sql/sql_insert.cc	2009-05-18 15:36:08 +0000
+++ b/sql/sql_insert.cc	2009-05-21 19:42:38 +0000
@@ -1935,8 +1935,9 @@ bool delayed_get_table(THD *thd, TABLE_L
       di->table_list.db= di->thd.db;
       di->lock();
       mysql_mutex_lock(&di->mutex);
-      if ((error= pthread_create(&di->thd.real_id, &connection_attrib,
-                                 handle_delayed_insert, (void*) di)))
+      if ((error= mysql_thread_create(key_thread_delayed_insert,
+                                      &di->thd.real_id, &connection_attrib,
+                                      handle_delayed_insert, (void*) di)))
       {
 	DBUG_PRINT("error",
 		   ("Can't create thread to handle delayed insert (error %d)",
@@ -2333,10 +2334,6 @@ pthread_handler_t handle_delayed_insert(
 
   pthread_detach_this_thread();
 
-#ifdef HAVE_PSI_INTERFACE
-  thd->m_psi= init_and_bind_psi_thread_with_id(key_thread_delayed_insert, thd, 0);
-#endif
-
   /* Add thread to THD list so that's it's visible in 'show processlist' */
   mysql_mutex_lock(&LOCK_thread_count);
   thd->thread_id= thd->variables.pseudo_thread_id= thread_id++;
@@ -2345,9 +2342,7 @@ pthread_handler_t handle_delayed_insert(
   thd->killed=abort_loop ? THD::KILL_CONNECTION : THD::NOT_KILLED;
   mysql_mutex_unlock(&LOCK_thread_count);
 
-#ifdef HAVE_PSI_INTERFACE
-  set_psi_thread_id(thd, thd->thread_id);
-#endif
+  mysql_thread_set_id(thd->thread_id);
 
   /*
     Wait until the client runs into mysql_cond_wait(),
@@ -2367,7 +2362,7 @@ pthread_handler_t handle_delayed_insert(
   }
   DBUG_ENTER("handle_delayed_insert");
   thd->thread_stack= (char*) &thd;
-  if (init_thr_lock() || thd->store_globals(true))
+  if (init_thr_lock() || thd->store_globals())
   {
     /* Can't use my_error since store_globals has perhaps failed */
     thd->stmt_da->set_error_status(thd, ER_OUT_OF_RESOURCES,

=== modified file 'sql/sql_manager.cc'
--- a/sql/sql_manager.cc	2009-05-12 03:15:02 +0000
+++ b/sql/sql_manager.cc	2009-05-21 19:42:38 +0000
@@ -70,10 +70,6 @@ pthread_handler_t handle_manager(void *a
   my_thread_init();
   DBUG_ENTER("handle_manager");
 
-#ifdef HAVE_PSI_INTERFACE
-  (void) init_and_bind_psi_thread_with_id(key_thread_handle_manager, NULL, 0);
-#endif
-
   pthread_detach_this_thread();
   manager_thread = pthread_self();
   manager_thread_in_use = 1;
@@ -138,7 +134,8 @@ void start_handle_manager()
   if (flush_time && flush_time != ~(ulong) 0L)
   {
     pthread_t hThread;
-    if (pthread_create(&hThread,&connection_attrib,handle_manager,0))
+    if (mysql_thread_create(key_thread_handle_manager,
+                            &hThread,&connection_attrib,handle_manager,0))
       sql_print_warning("Can't create handle_manager thread");
   }
   DBUG_VOID_RETURN;

=== modified file 'sql/sql_parse.cc'
--- a/sql/sql_parse.cc	2009-05-18 15:36:08 +0000
+++ b/sql/sql_parse.cc	2009-05-21 19:42:38 +0000
@@ -461,10 +461,7 @@ pthread_handler_t handle_bootstrap(void
 {
   THD *thd= (THD*) arg;
 
-#ifdef HAVE_PSI_INTERFACE
-  thd->m_psi= init_and_bind_psi_thread_with_id(key_thread_bootstrap,
-                                               thd, thd->thread_id);
-#endif
+  mysql_thread_set_id(thd->thread_id);
 
   do_handle_bootstrap(thd);
   return 0;
@@ -481,7 +478,7 @@ void do_handle_bootstrap(THD *arg)
 
   /* The following must be called before DBUG_ENTER */
   thd->thread_stack= (char*) &thd;
-  if (my_thread_init() || thd->store_globals(true))
+  if (my_thread_init() || thd->store_globals())
   {
 #ifndef EMBEDDED_LIBRARY
     close_connection(thd, ER_OUT_OF_RESOURCES, 1);
@@ -6833,7 +6830,7 @@ bool reload_acl_and_cache(THD *thd, ulon
     if (!thd && (thd= (tmp_thd= new THD)))
     {
       thd->thread_stack= (char*) &tmp_thd;
-      thd->store_globals(false);
+      thd->store_globals();
     }
     
     if (thd)

=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc	2009-05-18 15:36:08 +0000
+++ b/sql/sql_plugin.cc	2009-05-21 19:42:38 +0000
@@ -1343,7 +1343,7 @@ static void plugin_load(MEM_ROOT *tmp_ro
   DBUG_ENTER("plugin_load");
 
   new_thd->thread_stack= (char*) &tables;
-  new_thd->store_globals(false);
+  new_thd->store_globals();
   new_thd->db= my_strdup("mysql", MYF(0));
   new_thd->db_length= 5;
   bzero((char*) &thd.net, sizeof(thd.net));

=== modified file 'sql/sql_servers.cc'
--- a/sql/sql_servers.cc	2009-05-12 03:15:02 +0000
+++ b/sql/sql_servers.cc	2009-05-21 19:42:38 +0000
@@ -143,7 +143,7 @@ bool servers_init(bool dont_read_servers
   if (!(thd=new THD))
     DBUG_RETURN(TRUE);
   thd->thread_stack= (char*) &thd;
-  thd->store_globals(false);
+  thd->store_globals();
   /*
     It is safe to call servers_reload() since servers_* arrays and hashes which
     will be freed there are global static objects and thus are initialized

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2009-05-18 15:36:08 +0000
+++ b/sql/sql_table.cc	2009-05-21 19:42:38 +0000
@@ -1138,7 +1138,7 @@ void execute_ddl_log_recovery()
   if (!(thd=new THD))
     DBUG_VOID_RETURN;
   thd->thread_stack= (char*) &thd;
-  thd->store_globals(false);
+  thd->store_globals();
 
   num_entries= read_ddl_log_header();
   for (i= 1; i < num_entries + 1; i++)

=== modified file 'sql/sql_udf.cc'
--- a/sql/sql_udf.cc	2009-05-12 03:15:02 +0000
+++ b/sql/sql_udf.cc	2009-05-21 19:42:38 +0000
@@ -138,7 +138,7 @@ void udf_init()
   }
   initialized = 1;
   new_thd->thread_stack= (char*) &new_thd;
-  new_thd->store_globals(false);
+  new_thd->store_globals();
   new_thd->set_db(db, sizeof(db)-1);
 
   bzero((uchar*) &tables,sizeof(tables));

=== modified file 'sql/tztime.cc'
--- a/sql/tztime.cc	2009-05-12 03:15:02 +0000
+++ b/sql/tztime.cc	2009-05-21 19:42:38 +0000
@@ -1577,7 +1577,7 @@ my_tz_init(THD *org_thd, const char *def
   if (!(thd= new THD))
     DBUG_RETURN(1);
   thd->thread_stack= (char*) &thd;
-  thd->store_globals(false);
+  thd->store_globals();
 
   /* Init all memory structures that require explicit destruction */
   if (my_hash_init(&tz_names, &my_charset_latin1, 20,
@@ -1749,7 +1749,7 @@ end_with_cleanup:
 end:
   delete thd;
   if (org_thd)
-    org_thd->store_globals(true);			/* purecov: inspected */
+    org_thd->store_globals();			/* purecov: inspected */
   else
   {
     /* Remember that we don't have a THD */

=== modified file 'storage/maria/ma_check.c'
--- a/storage/maria/ma_check.c	2009-05-12 03:15:02 +0000
+++ b/storage/maria/ma_check.c	2009-05-21 19:42:38 +0000
@@ -4293,9 +4293,10 @@ int maria_repair_parallel(HA_CHECK *para
 #else
       param->sort_buffer_length*sort_param[i].key_length/total_key_length;
 #endif
-    if (pthread_create(&sort_param[i].thr, &thr_attr,
-		       _ma_thr_find_all_keys,
-		       (void *) (sort_param+i)))
+    if (mysql_thread_create(ma_key_thread_find_all_keys,
+                            &sort_param[i].thr, &thr_attr,
+		            _ma_thr_find_all_keys,
+		            (void *) (sort_param+i)))
     {
       _ma_check_print_error(param,"Cannot start a repair thread");
       /* Cleanup: Detach from the share. Avoid others to be blocked. */

=== modified file 'storage/maria/ma_checkpoint.c'
--- a/storage/maria/ma_checkpoint.c	2009-05-12 03:15:02 +0000
+++ b/storage/maria/ma_checkpoint.c	2009-05-21 19:42:38 +0000
@@ -335,8 +335,9 @@ int ma_checkpoint_init(ulong interval)
   else if (interval > 0)
   {
     compile_time_assert(sizeof(void *) >= sizeof(ulong));
-    if (!(res= pthread_create(&th, NULL, ma_checkpoint_background,
-                              (void *)interval)))
+    if (!(res= mysql_thread_create(ma_key_thread_checkpoint_background,
+                                   &th, NULL, ma_checkpoint_background,
+                                   (void *)interval)))
       checkpoint_thread_die= 0; /* thread lives, will have to be killed */
   }
   DBUG_RETURN(res);
@@ -574,9 +575,6 @@ pthread_handler_t ma_checkpoint_backgrou
   LINT_INIT(pages_bunch_size);
 
   my_thread_init();
-#ifdef HAVE_PSI_INTERFACE
-  ma_init_and_bind_psi_thread(ma_key_thread_checkpoint_background, arg);
-#endif
 
   DBUG_PRINT("info",("Maria background checkpoint thread starts"));
   DBUG_ASSERT(interval > 0);

=== modified file 'storage/maria/ma_sort.c'
--- a/storage/maria/ma_sort.c	2009-05-12 03:15:02 +0000
+++ b/storage/maria/ma_sort.c	2009-05-21 19:42:38 +0000
@@ -328,10 +328,6 @@ pthread_handler_t _ma_thr_find_all_keys(
 
   LINT_INIT(keys);
 
-#ifdef HAVE_PSI_INTERFACE
-  ma_init_and_bind_psi_thread(ma_key_thread_find_all_keys, arg);
-#endif
-
   error=1;
 
   if (my_thread_init())

=== modified file 'storage/maria/ma_static.c'
--- a/storage/maria/ma_static.c	2009-05-07 06:42:31 +0000
+++ b/storage/maria/ma_static.c	2009-05-21 19:42:38 +0000
@@ -241,22 +241,6 @@ void init_maria_psi_keys()
   count= array_elements(all_maria_files);
   PSI_server->register_file(category, all_maria_files, count);
 }
-
-void ma_init_and_bind_psi_thread(PSI_thread_key key, void* identity)
-{
-  struct PSI_thread *psi= NULL;
-  if (PSI_server)
-  {
-    /*
-      Create an instrumented thread,
-      and bind it in Thread Local Storage.
-    */
-    psi= PSI_server->new_thread(key, identity);
-    if (psi)
-      PSI_server->set_thread(psi);
-  }
-}
-
 #endif
 
 

=== modified file 'storage/maria/maria_backup_engine.cc'
--- a/storage/maria/maria_backup_engine.cc	2009-05-18 15:36:08 +0000
+++ b/storage/maria/maria_backup_engine.cc	2009-05-21 19:42:38 +0000
@@ -821,19 +821,13 @@ void Backup::lock_tables_TL_READ_NO_INSE
     goto end2;
   thd->thread_stack = reinterpret_cast< char *>(&thd);
 
-#ifdef HAVE_PSI_INTERFACE
-  thd->m_psi= init_and_bind_psi_thread_with_id(ma_key_thread_backup, thd, 0);
-#endif
-
   mysql_mutex_lock(&LOCK_thread_count);
   thd->thread_id= thread_id++;
   mysql_mutex_unlock(&LOCK_thread_count);
 
-#ifdef HAVE_PSI_INTERFACE
-  set_psi_thread_id(thd, thd->thread_id);
-#endif
+  mysql_thread_set_id(thd->thread_id);
 
-  if (unlikely(thd->store_globals(true))) // for a proper MEM_ROOT
+  if (unlikely(thd->store_globals())) // for a proper MEM_ROOT
     goto end2;
   thd->init_for_queries(); // opening tables needs a proper LEX
   thd->command= COM_DAEMON;
@@ -946,8 +940,9 @@ result_t Backup::prelock()
   lock_state= LOCK_STARTED;
   {
     pthread_t th;
-    if (pthread_create(&th, &connection_attrib,
-                       maria_backup_separate_thread_for_locking, this))
+    if (mysql_thread_create(ma_key_thread_backup,
+                            &th, &connection_attrib,
+                            maria_backup_separate_thread_for_locking, this))
     {
       lock_state= LOCK_ERROR;
       SET_STATE_TO_ERROR_AND_DBUG_RETURN;

=== modified file 'storage/maria/maria_def.h'
--- a/storage/maria/maria_def.h	2009-05-18 15:36:08 +0000
+++ b/storage/maria/maria_def.h	2009-05-21 19:42:38 +0000
@@ -1416,7 +1416,6 @@ extern PSI_file_key ma_key_file_backup_l
 extern PSI_thread_key ma_key_thread_backup;
 
 void init_maria_psi_keys();
-void ma_init_and_bind_psi_thread(PSI_thread_key key, void *identity);
 C_MODE_END
 #endif
 

=== modified file 'storage/myisam/myisam_backup_engine.cc'
--- a/storage/myisam/myisam_backup_engine.cc	2009-05-18 15:36:08 +0000
+++ b/storage/myisam/myisam_backup_engine.cc	2009-05-21 19:42:38 +0000
@@ -813,19 +813,13 @@ void Backup::lock_tables_TL_READ_NO_INSE
     goto end2;
   thd->thread_stack = reinterpret_cast< char *>(&thd);
 
-#ifdef HAVE_PSI_INTERFACE
-  thd->m_psi= init_and_bind_psi_thread_with_id(mi_key_thread_backup, thd, 0);
-#endif
-
   mysql_mutex_lock(&LOCK_thread_count);
   thd->thread_id= thread_id++;
   mysql_mutex_unlock(&LOCK_thread_count);
 
-#ifdef HAVE_PSI_INTERFACE
-  set_psi_thread_id(thd, thd->thread_id);
-#endif
+  mysql_thread_set_id(thd->thread_id);
 
-  if (unlikely(thd->store_globals(true))) // for a proper MEM_ROOT
+  if (unlikely(thd->store_globals())) // for a proper MEM_ROOT
     goto end2;
   thd->init_for_queries(); // opening tables needs a proper LEX
   thd->command= COM_DAEMON;
@@ -938,8 +932,9 @@ result_t Backup::prelock()
   lock_state= LOCK_STARTED;
   {
     pthread_t th;
-    if (pthread_create(&th, &connection_attrib,
-                       myisam_backup_separate_thread_for_locking, this))
+    if (mysql_thread_create(mi_key_thread_backup,
+                            &th, &connection_attrib,
+                            myisam_backup_separate_thread_for_locking, this))
     {
       lock_state= LOCK_ERROR;
       SET_STATE_TO_ERROR_AND_DBUG_RETURN;

=== modified file 'storage/perfschema/pfs.cc'
--- a/storage/perfschema/pfs.cc	2009-05-19 15:56:07 +0000
+++ b/storage/perfschema/pfs.cc	2009-05-21 19:42:38 +0000
@@ -977,15 +977,65 @@ static void create_file_v1(PSI_file_key
     file_lost++;
 }
 
+struct PFS_spawn_thread_arg
+{
+  PFS_thread *m_parent_thread;
+  PSI_thread_key m_child_key;
+  const void *m_child_identity;
+  void *(*m_user_start_routine)(void*);
+  void *m_user_arg;
+};
+
+void* pfs_spawn_thread(void *arg)
+{
+  PFS_spawn_thread_arg *typed_arg= (PFS_spawn_thread_arg*) arg;
+  PFS_thread_class *klass;
+  PFS_thread *pfs;
+
+  /* First, attach instrumentation to this newly created pthread. */
+  klass= find_thread_class(typed_arg->m_child_key);
+  if (klass)
+    pfs= create_thread(klass, typed_arg->m_child_identity, 0);
+  else
+    pfs = NULL;
+  my_pthread_setspecific_ptr(THR_PFS, pfs);
+
+  /* Then, execute the user code for this thread. */
+  typed_arg->m_user_start_routine(typed_arg->m_user_arg);
+
+  free(typed_arg);
+  return NULL;
+}
+
+static int spawn_thread_v1(PSI_thread_key key,
+                           pthread_t *thread, const pthread_attr_t *attr,
+                           void *(*start_routine)(void*), void *arg)
+{
+  PFS_spawn_thread_arg *psi_arg;
+
+  /* psi_arg can not be global, and can not be a local variable. */
+  psi_arg= (PFS_spawn_thread_arg*) malloc(sizeof(PFS_spawn_thread_arg));
+  if (psi_arg == NULL)
+    return EAGAIN;
+
+  psi_arg->m_parent_thread= my_pthread_getspecific_ptr(PFS_thread*, THR_PFS);
+  psi_arg->m_child_key= key;
+  psi_arg->m_child_identity= (arg ? arg : thread);
+  psi_arg->m_user_start_routine= start_routine;
+  psi_arg->m_user_arg= arg;
+
+  return pthread_create(thread, attr, pfs_spawn_thread, psi_arg);
+}
+
 static PSI_thread*
-new_thread_v1(PSI_thread_key key, const void *identity)
+new_thread_v1(PSI_thread_key key, const void *identity, ulong thread_id)
 {
   PFS_thread_class *klass;
   PFS_thread *pfs;
 
   klass= find_thread_class(key);
   if (klass)
-    pfs= create_thread(klass, identity);
+    pfs= create_thread(klass, identity, thread_id);
   else
     pfs = NULL;
 
@@ -1907,6 +1957,7 @@ PSI_v1 PFS_v1=
   open_table_v1,
   close_table_v1,
   create_file_v1,
+  spawn_thread_v1,
   new_thread_v1,
   set_thread_id_v1,
   get_thread_v1,

=== modified file 'storage/perfschema/pfs_instr.cc'
--- a/storage/perfschema/pfs_instr.cc	2009-05-19 14:50:00 +0000
+++ b/storage/perfschema/pfs_instr.cc	2009-05-21 19:42:38 +0000
@@ -458,7 +458,7 @@ void destroy_cond(PFS_cond *pfs)
   pfs->m_lock.allocated_to_free();
 }
 
-PFS_thread* create_thread(PFS_thread_class *klass, const void *identity)
+PFS_thread* create_thread(PFS_thread_class *klass, const void *identity, ulong thread_id)
 {
   int pass;
   PFS_thread *pfs;
@@ -479,7 +479,7 @@ PFS_thread* create_thread(PFS_thread_cla
         {
           // TODO: atomic here
           pfs->m_thread_internal_id= thread_internal_id_counter++;
-          pfs->m_thread_id= 0;
+          pfs->m_thread_id= thread_id;
           pfs->m_event_id= 1;
           pfs->m_enabled= true;
           pfs->m_class= klass;

=== modified file 'storage/perfschema/pfs_instr.h'
--- a/storage/perfschema/pfs_instr.h	2009-05-19 14:50:00 +0000
+++ b/storage/perfschema/pfs_instr.h	2009-05-21 19:42:38 +0000
@@ -289,9 +289,10 @@ void destroy_cond(PFS_cond *pfs);
   Create instrumentation for a thread instance.
   @param klass the thread class
   @param identity the thread address, or a value characteristic of this thread
+  @param thread_id the PROCESSLIST thread id, or 0 if unknown
   @return a thread instance, or NULL
 */
-PFS_thread* create_thread(PFS_thread_class *klass, const void *identity);
+PFS_thread* create_thread(PFS_thread_class *klass, const void *identity, ulong thread_id);
 
 /**
   Destroy instrumentation for a thread instance.

=== modified file 'storage/perfschema/pfs_instr_class.cc'
--- a/storage/perfschema/pfs_instr_class.cc	2009-05-19 14:50:00 +0000
+++ b/storage/perfschema/pfs_instr_class.cc	2009-05-21 19:42:38 +0000
@@ -528,7 +528,6 @@ PFS_thread_key register_thread_class(con
     strncpy(entry->m_name, name, name_length);
     entry->m_name_length= name_length;
     entry->m_enabled= true;
-    entry->m_timed= true;
     my_atomic_add32(&thread_class_public_count, 1);
     return (index+1);
   }

=== modified file 'storage/perfschema/pfs_instr_class.h'
--- a/storage/perfschema/pfs_instr_class.h	2009-05-19 14:50:00 +0000
+++ b/storage/perfschema/pfs_instr_class.h	2009-05-21 19:42:38 +0000
@@ -125,8 +125,6 @@ struct PFS_thread_class
   uint m_name_length;
   /** True if this thread instrument is enabled. */
   bool m_enabled;
-  /** True if this thread instrument is timed. */
-  bool m_timed;
 };
 
 /**

=== modified file 'storage/perfschema/table_setup_instruments.cc'
--- a/storage/perfschema/table_setup_instruments.cc	2009-05-19 14:50:00 +0000
+++ b/storage/perfschema/table_setup_instruments.cc	2009-05-21 19:42:38 +0000
@@ -183,7 +183,7 @@ void table_setup_instruments::make_row(P
   m_row.m_name= & klass->m_name[0];
   m_row.m_name_length= klass->m_name_length;
   m_row.m_enabled_ptr= & klass->m_enabled;
-  m_row.m_timed_ptr= & klass->m_timed;
+  m_row.m_timed_ptr= NULL;
 }
 
 int table_setup_instruments::read_row_values(TABLE *table,
@@ -220,7 +220,10 @@ int table_setup_instruments::read_row_va
       case 2:
         DBUG_ASSERT(f->real_type() == MYSQL_TYPE_ENUM);
         col_timed= (Field_enum*) f;
-        col_timed->store_type((*m_row.m_timed_ptr) ? ENUM_YES : ENUM_NO);
+        if (m_row.m_timed_ptr)
+          col_timed->store_type((*m_row.m_timed_ptr) ? ENUM_YES : ENUM_NO);
+        else
+          col_timed->store_type(ENUM_NO);
         break;
       default:
         DBUG_ASSERT(false);
@@ -260,7 +263,8 @@ int table_setup_instruments::update_row_
         DBUG_ASSERT(f->real_type() == MYSQL_TYPE_ENUM);
         col_timed= (Field_enum*) f;
         value= (enum_yes_no) col_timed->val_int();
-        *m_row.m_timed_ptr= (value == ENUM_YES) ? true : false;
+        if (m_row.m_timed_ptr)
+          *m_row.m_timed_ptr= (value == ENUM_YES) ? true : false;
         break;
       default:
         DBUG_ASSERT(false);

=== modified file 'storage/perfschema/unittest/pfs-t.cc'
--- a/storage/perfschema/unittest/pfs-t.cc	2009-05-19 14:50:00 +0000
+++ b/storage/perfschema/unittest/pfs-t.cc	2009-05-21 19:42:38 +0000
@@ -517,7 +517,7 @@ void test_init_disabled()
 
   /* Preparation */
 
-  thread_1= psi->new_thread(thread_key_1, NULL);
+  thread_1= psi->new_thread(thread_key_1, NULL, 0);
   ok(thread_1 != NULL, "T-1");
   psi->set_thread_id(thread_1, 1);
 
@@ -879,7 +879,7 @@ void test_locker_disabled()
 
   /* Preparation */
 
-  thread_1= psi->new_thread(thread_key_1, NULL);
+  thread_1= psi->new_thread(thread_key_1, NULL, 0);
   ok(thread_1 != NULL, "T-1");
   psi->set_thread_id(thread_1, 1);
 
@@ -1086,7 +1086,7 @@ void test_file_instrumentation_leak()
 
   /* Preparation */
 
-  thread_1= psi->new_thread(thread_key_1, NULL);
+  thread_1= psi->new_thread(thread_key_1, NULL, 0);
   ok(thread_1 != NULL, "T-1");
   psi->set_thread_id(thread_1, 1);
 

=== modified file 'storage/perfschema/unittest/pfs_instr-t.cc'
--- a/storage/perfschema/unittest/pfs_instr-t.cc	2009-05-16 00:41:08 +0000
+++ b/storage/perfschema/unittest/pfs_instr-t.cc	2009-05-21 19:42:38 +0000
@@ -103,10 +103,10 @@ void test_no_instances()
   ok(cond == NULL, "no cond");
   ok(cond_lost == 2, "lost 2");
 
-  thread= create_thread(& dummy_thread_class, NULL);
+  thread= create_thread(& dummy_thread_class, NULL, 0);
   ok(thread == NULL, "no thread");
   ok(thread_lost == 1, "lost 1");
-  thread= create_thread(& dummy_thread_class, NULL);
+  thread= create_thread(& dummy_thread_class, NULL, 0);
   ok(thread == NULL, "no thread");
   ok(thread_lost == 2, "lost 2");
 
@@ -233,17 +233,17 @@ void test_with_instances()
   ok(cond_2 != NULL, "cond");
   ok(cond_lost == 1, "no new loss");
 
-  thread_1= create_thread(& dummy_thread_class, NULL);
+  thread_1= create_thread(& dummy_thread_class, NULL, 0);
   ok(thread_1 != NULL, "thread");
   ok(thread_lost == 0, "not lost");
-  thread_2= create_thread(& dummy_thread_class, NULL);
+  thread_2= create_thread(& dummy_thread_class, NULL, 0);
   ok(thread_2 != NULL, "thread");
   ok(thread_lost == 0, "not lost");
-  thread_2= create_thread(& dummy_thread_class, NULL);
+  thread_2= create_thread(& dummy_thread_class, NULL, 0);
   ok(thread_2 == NULL, "no thread");
   ok(thread_lost == 1, "lost 1");
   destroy_thread(thread_1);
-  thread_2= create_thread(& dummy_thread_class, NULL);
+  thread_2= create_thread(& dummy_thread_class, NULL, 0);
   ok(thread_2 != NULL, "thread");
   ok(thread_lost == 1, "no new loss");
 
@@ -346,7 +346,7 @@ void test_per_thread_wait()
   rc= init_instruments(& param);
   ok(rc == 0, "instances init");
 
-  thread= create_thread(& dummy_thread_class, NULL);
+  thread= create_thread(& dummy_thread_class, NULL, 0);
   ok(thread != NULL, "thread");
   ok(thread_lost == 0, "not lost");
 

Thread
bzr commit into mysql-6.0-perfschema branch (marc.alff:3150) Marc Alff21 May
  • Re: bzr commit into mysql-6.0-perfschema branch (marc.alff:3150)Guilhem Bichot26 May
    • Re: bzr commit into mysql-6.0-perfschema branch (marc.alff:3150)Marc Alff26 May
      • Re: bzr commit into mysql-6.0-perfschema branch (marc.alff:3150)Guilhem Bichot28 May
        • Re: bzr commit into mysql-6.0-perfschema branch (marc.alff:3150)Marc Alff1 Jul
          • Re: bzr commit into mysql-6.0-perfschema branch (marc.alff:3150)Guilhem Bichot10 Jul
            • Re: bzr commit into mysql-6.0-perfschema branch (marc.alff:3150)Marc Alff10 Jul
              • Re: bzr commit into mysql-6.0-perfschema branch (marc.alff:3150)Guilhem Bichot27 Jul
                • Re: bzr commit into mysql-6.0-perfschema branch (marc.alff:3150)Marc Alff28 Jul
                  • Re: bzr commit into mysql-6.0-perfschema branch (marc.alff:3150)Guilhem Bichot28 Jul