summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Vojtovich <svoj@mariadb.org>2015-04-22 14:18:51 +0400
committerSergey Vojtovich <svoj@mariadb.org>2015-05-14 12:50:23 +0400
commit18f88d6d94ce9f65991e011c978c79d990498704 (patch)
tree6c0f589bc27bc4b0dc15a04b7bbc59a9df0d00a8
parentf8cacd03a79e56746434f7c12e2ed8dd6a534b8e (diff)
downloadmariadb-git-18f88d6d94ce9f65991e011c978c79d990498704.tar.gz
MDEV-7943 - pthread_getspecific() takes 0.76% in OLTP RO
Avoid calling current_thd from thd_kill_level(). This reduces number of pthread_getspecific() calls from 776 to 354. Also thd_kill_level(NULL) is not permitted anymore: this saves one condition.
-rw-r--r--plugin/semisync/semisync_master.cc4
-rw-r--r--sql/sql_class.cc29
2 files changed, 20 insertions, 13 deletions
diff --git a/plugin/semisync/semisync_master.cc b/plugin/semisync/semisync_master.cc
index c88c162be03..b1f7fbd8b07 100644
--- a/plugin/semisync/semisync_master.cc
+++ b/plugin/semisync/semisync_master.cc
@@ -635,7 +635,7 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
(int)is_on());
}
- while (is_on() && !thd_killed(NULL))
+ while (is_on() && !thd_killed(current_thd))
{
if (reply_file_name_inited_)
{
@@ -747,7 +747,7 @@ int ReplSemiSyncMaster::commitTrx(const char* trx_wait_binlog_name,
At this point, the binlog file and position of this transaction
must have been removed from ActiveTranx.
*/
- assert(thd_killed(NULL) ||
+ assert(thd_killed(current_thd) ||
!active_tranxs_->is_tranx_end_pos(trx_wait_binlog_name,
trx_wait_binlog_pos));
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index 5c6c45e2cbe..16e7ed1ec52 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -4205,23 +4205,30 @@ extern "C" int thd_killed(const MYSQL_THD thd)
/*
return thd->killed status to the client,
mapped to the API enum thd_kill_levels values.
+
+ @note Since this function is called quite frequently thd_kill_level(NULL) is
+ forbidden for performance reasons (saves one conditional branch). If your ever
+ need to call thd_kill_level() when THD is not available, you options are (most
+ to least preferred):
+ - try to pass THD through to thd_kill_level()
+ - add current_thd to some service and use thd_killed(current_thd)
+ - add thd_killed_current() function to kill statement service
+ - add if (!thd) thd= current_thd here
*/
extern "C" enum thd_kill_levels thd_kill_level(const MYSQL_THD thd)
{
- THD* current= current_thd;
-
- if (!thd)
- thd= current;
-
- if (thd == current)
- {
- Apc_target *apc_target= (Apc_target*)&thd->apc_target;
- if (apc_target->have_apc_requests())
- apc_target->process_apc_requests();
- }
+ DBUG_ASSERT(thd);
if (likely(thd->killed == NOT_KILLED))
+ {
+ Apc_target *apc_target= (Apc_target*) &thd->apc_target;
+ if (unlikely(apc_target->have_apc_requests()))
+ {
+ if (thd == current_thd)
+ apc_target->process_apc_requests();
+ }
return THD_IS_NOT_KILLED;
+ }
return thd->killed & KILL_HARD_BIT ? THD_ABORT_ASAP : THD_ABORT_SOFTLY;
}