summaryrefslogtreecommitdiff
path: root/sql/sql_profile.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_profile.cc')
-rw-r--r--sql/sql_profile.cc76
1 files changed, 58 insertions, 18 deletions
diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc
index 1a6477e4c4d..cd06408045e 100644
--- a/sql/sql_profile.cc
+++ b/sql/sql_profile.cc
@@ -1,5 +1,4 @@
-/*
- Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2007, 2011, 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
@@ -12,8 +11,7 @@
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
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
/**
@@ -31,8 +29,12 @@
*/
-#include "mysql_priv.h"
+#include "sql_priv.h"
+#include "unireg.h" // REQUIRED: for other includes
+#include "sql_profile.h"
#include "my_sys.h"
+#include "sql_show.h" // schema_table_store_record
+#include "sql_class.h" // THD
#define TIME_FLOAT_DIGITS 9
/** two vals encoded: (dec*100)+len */
@@ -40,16 +42,13 @@
#define MAX_QUERY_LENGTH 300
-/* Reserved for systems that can't record the function name in source. */
-const char * const _unknown_func_ = "<unknown>";
-
/**
Connects Information_Schema and Profiling.
*/
int fill_query_profile_statistics_info(THD *thd, TABLE_LIST *tables,
Item *cond)
{
-#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+#if defined(ENABLED_PROFILING)
return(thd->profiling.fill_statistics_info(thd, tables, cond));
#else
my_error(ER_FEATURE_DISABLED, MYF(0), "SHOW PROFILE", "enable-profiling");
@@ -131,11 +130,31 @@ int make_profile_table_for_show(THD *thd, ST_SCHEMA_TABLE *schema_table)
}
-#if defined(ENABLED_PROFILING) && defined(COMMUNITY_SERVER)
+#if defined(ENABLED_PROFILING)
#define RUSAGE_USEC(tv) ((tv).tv_sec*1000*1000 + (tv).tv_usec)
#define RUSAGE_DIFF_USEC(tv1, tv2) (RUSAGE_USEC((tv1))-RUSAGE_USEC((tv2)))
+#ifdef _WIN32
+static ULONGLONG FileTimeToQuadWord(FILETIME *ft)
+{
+ // Overlay FILETIME onto a ULONGLONG.
+ union {
+ ULONGLONG qwTime;
+ FILETIME ft;
+ } u;
+
+ u.ft = *ft;
+ return u.qwTime;
+}
+
+
+// Get time difference between to FILETIME objects in seconds.
+static double GetTimeDiffInSeconds(FILETIME *a, FILETIME *b)
+{
+ return ((FileTimeToQuadWord(a) - FileTimeToQuadWord(b)) / 1e7);
+}
+#endif
PROF_MEASUREMENT::PROF_MEASUREMENT(QUERY_PROFILE *profile_arg, const char
*status_arg)
@@ -158,8 +177,7 @@ PROF_MEASUREMENT::PROF_MEASUREMENT(QUERY_PROFILE *profile_arg,
PROF_MEASUREMENT::~PROF_MEASUREMENT()
{
- if (allocated_status_memory != NULL)
- my_free(allocated_status_memory, MYF(0));
+ my_free(allocated_status_memory);
status= function= file= NULL;
}
@@ -226,6 +244,12 @@ void PROF_MEASUREMENT::collect()
time_usecs= (double) my_getsystime() / 10.0; /* 1 sec was 1e7, now is 1e6 */
#ifdef HAVE_GETRUSAGE
getrusage(RUSAGE_SELF, &rusage);
+#elif defined(_WIN32)
+ FILETIME ftDummy;
+ // NOTE: Get{Process|Thread}Times has a granularity of the clock interval,
+ // which is typically ~15ms. So intervals shorter than that will not be
+ // measurable by this function.
+ GetProcessTimes(GetCurrentProcess(), &ftDummy, &ftDummy, &ftKernel, &ftUser);
#endif
}
@@ -243,8 +267,7 @@ QUERY_PROFILE::~QUERY_PROFILE()
while (! entries.is_empty())
delete entries.pop();
- if (query_source != NULL)
- my_free(query_source, MYF(0));
+ my_free(query_source);
}
/**
@@ -271,7 +294,7 @@ void QUERY_PROFILE::new_status(const char *status_arg,
DBUG_ASSERT(status_arg != NULL);
if ((function_arg != NULL) && (file_arg != NULL))
- prof= new PROF_MEASUREMENT(this, status_arg, function_arg, file_arg, line_arg);
+ prof= new PROF_MEASUREMENT(this, status_arg, function_arg, base_name(file_arg), line_arg);
else
prof= new PROF_MEASUREMENT(this, status_arg);
@@ -343,7 +366,7 @@ void PROFILING::start_new_query(const char *initial_state)
finish_current_query();
}
- enabled= (((thd)->options & OPTION_PROFILING) != 0);
+ enabled= ((thd->variables.option_bits & OPTION_PROFILING) != 0);
if (! enabled) DBUG_VOID_RETURN;
@@ -381,7 +404,7 @@ void PROFILING::finish_current_query()
status_change("ending", NULL, NULL, 0);
if ((enabled) && /* ON at start? */
- ((thd->options & OPTION_PROFILING) != 0) && /* and ON at end? */
+ ((thd->variables.option_bits & OPTION_PROFILING) != 0) && /* and ON at end? */
(current->query_source != NULL) &&
(! current->entries.is_empty()))
{
@@ -417,7 +440,7 @@ bool PROFILING::show_profiles()
MYSQL_TYPE_DOUBLE));
field_list.push_back(new Item_empty_string("Query", 40));
- if (thd->protocol->send_fields(&field_list,
+ if (thd->protocol->send_result_set_metadata(&field_list,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
DBUG_RETURN(TRUE);
@@ -595,6 +618,23 @@ int PROFILING::fill_statistics_info(THD *thd_arg, TABLE_LIST *tables, Item *cond
table->field[5]->store_decimal(&cpu_stime_decimal);
table->field[4]->set_notnull();
table->field[5]->set_notnull();
+#elif defined(_WIN32)
+ my_decimal cpu_utime_decimal, cpu_stime_decimal;
+
+ double2my_decimal(E_DEC_FATAL_ERROR,
+ GetTimeDiffInSeconds(&entry->ftUser,
+ &previous->ftUser),
+ &cpu_utime_decimal);
+ double2my_decimal(E_DEC_FATAL_ERROR,
+ GetTimeDiffInSeconds(&entry->ftKernel,
+ &previous->ftKernel),
+ &cpu_stime_decimal);
+
+ // Store the result.
+ table->field[4]->store_decimal(&cpu_utime_decimal);
+ table->field[5]->store_decimal(&cpu_stime_decimal);
+ table->field[4]->set_notnull();
+ table->field[5]->set_notnull();
#else
/* TODO: Add CPU-usage info for non-BSD systems */
#endif