diff options
Diffstat (limited to 'sql/sql_profile.cc')
-rw-r--r-- | sql/sql_profile.cc | 76 |
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 |