My Project
|
00001 /* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; version 2 of the License. 00006 00007 This program is distributed in the hope that it will be useful, 00008 but WITHOUT ANY WARRANTY; without even the implied warranty of 00009 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00010 GNU General Public License for more details. 00011 00012 You should have received a copy of the GNU General Public License 00013 along with this program; if not, write to the Free Software Foundation, 00014 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */ 00015 00016 #ifndef _SQL_PROFILE_H 00017 #define _SQL_PROFILE_H 00018 00019 class Item; 00020 struct TABLE_LIST; 00021 class THD; 00022 typedef struct st_field_info ST_FIELD_INFO; 00023 typedef struct st_schema_table ST_SCHEMA_TABLE; 00024 00025 extern ST_FIELD_INFO query_profile_statistics_info[]; 00026 int fill_query_profile_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond); 00027 int make_profile_table_for_show(THD *thd, ST_SCHEMA_TABLE *schema_table); 00028 00029 00030 #define PROFILE_NONE (uint)0 00031 #define PROFILE_CPU (uint)(1<<0) 00032 #define PROFILE_MEMORY (uint)(1<<1) 00033 #define PROFILE_BLOCK_IO (uint)(1<<2) 00034 #define PROFILE_CONTEXT (uint)(1<<3) 00035 #define PROFILE_PAGE_FAULTS (uint)(1<<4) 00036 #define PROFILE_IPC (uint)(1<<5) 00037 #define PROFILE_SWAPS (uint)(1<<6) 00038 #define PROFILE_SOURCE (uint)(1<<16) 00039 #define PROFILE_ALL (uint)(~0) 00040 00041 00042 #if defined(ENABLED_PROFILING) 00043 #include "sql_priv.h" 00044 #include "unireg.h" 00045 00046 #ifdef HAVE_SYS_RESOURCE_H 00047 #include <sys/resource.h> 00048 #endif 00049 00050 00051 class PROF_MEASUREMENT; 00052 class QUERY_PROFILE; 00053 class PROFILING; 00054 00055 00060 template <class T> class Queue 00061 { 00062 private: 00063 00064 struct queue_item 00065 { 00066 T *payload; 00067 struct queue_item *next, *previous; 00068 }; 00069 00070 struct queue_item *first, *last; 00071 00072 public: 00073 Queue() 00074 { 00075 elements= 0; 00076 first= last= NULL; 00077 } 00078 00079 void empty() 00080 { 00081 struct queue_item *i, *after_i; 00082 for (i= first; i != NULL; i= after_i) 00083 { 00084 after_i= i->next; 00085 my_free(i); 00086 } 00087 elements= 0; 00088 } 00089 00090 ulong elements; /* The count of items in the Queue */ 00091 00092 void push_back(T *payload) 00093 { 00094 struct queue_item *new_item; 00095 00096 new_item= (struct queue_item *) my_malloc(sizeof(struct queue_item), MYF(0)); 00097 00098 new_item->payload= payload; 00099 00100 if (first == NULL) 00101 first= new_item; 00102 if (last != NULL) 00103 { 00104 DBUG_ASSERT(last->next == NULL); 00105 last->next= new_item; 00106 } 00107 new_item->previous= last; 00108 new_item->next= NULL; 00109 last= new_item; 00110 00111 elements++; 00112 } 00113 00114 T *pop() 00115 { 00116 struct queue_item *old_item= first; 00117 T *ret= NULL; 00118 00119 if (first == NULL) 00120 { 00121 DBUG_PRINT("warning", ("tried to pop nonexistent item from Queue")); 00122 return NULL; 00123 } 00124 00125 ret= old_item->payload; 00126 if (first->next != NULL) 00127 first->next->previous= NULL; 00128 else 00129 last= NULL; 00130 first= first->next; 00131 00132 my_free(old_item); 00133 elements--; 00134 00135 return ret; 00136 } 00137 00138 bool is_empty() 00139 { 00140 DBUG_ASSERT(((elements > 0) && (first != NULL)) || ((elements == 0) || (first == NULL))); 00141 return (elements == 0); 00142 } 00143 00144 void *new_iterator() 00145 { 00146 return first; 00147 } 00148 00149 void *iterator_next(void *current) 00150 { 00151 return ((struct queue_item *) current)->next; 00152 } 00153 00154 T *iterator_value(void *current) 00155 { 00156 return ((struct queue_item *) current)->payload; 00157 } 00158 00159 }; 00160 00161 00165 class PROF_MEASUREMENT 00166 { 00167 private: 00168 friend class QUERY_PROFILE; 00169 friend class PROFILING; 00170 00171 QUERY_PROFILE *profile; 00172 char *status; 00173 #ifdef HAVE_GETRUSAGE 00174 struct rusage rusage; 00175 #elif defined(_WIN32) 00176 FILETIME ftKernel, ftUser; 00177 #endif 00178 00179 char *function; 00180 char *file; 00181 unsigned int line; 00182 00183 ulong m_seq; 00184 double time_usecs; 00185 char *allocated_status_memory; 00186 00187 void set_label(const char *status_arg, const char *function_arg, 00188 const char *file_arg, unsigned int line_arg); 00189 void clean_up(); 00190 00191 PROF_MEASUREMENT(); 00192 PROF_MEASUREMENT(QUERY_PROFILE *profile_arg, const char *status_arg); 00193 PROF_MEASUREMENT(QUERY_PROFILE *profile_arg, const char *status_arg, 00194 const char *function_arg, 00195 const char *file_arg, unsigned int line_arg); 00196 ~PROF_MEASUREMENT(); 00197 void collect(); 00198 }; 00199 00200 00205 class QUERY_PROFILE 00206 { 00207 private: 00208 friend class PROFILING; 00209 00210 PROFILING *profiling; 00211 00212 query_id_t profiling_query_id; /* Session-specific id. */ 00213 char *query_source; 00214 00215 double m_start_time_usecs; 00216 double m_end_time_usecs; 00217 ulong m_seq_counter; 00218 Queue<PROF_MEASUREMENT> entries; 00219 00220 00221 QUERY_PROFILE(PROFILING *profiling_arg, const char *status_arg); 00222 ~QUERY_PROFILE(); 00223 00224 void set_query_source(char *query_source_arg, uint query_length_arg); 00225 00226 /* Add a profile status change to the current profile. */ 00227 void new_status(const char *status_arg, 00228 const char *function_arg, 00229 const char *file_arg, unsigned int line_arg); 00230 00231 /* Reset the contents of this profile entry. */ 00232 void reset(); 00233 00234 /* Show this profile. This is called by PROFILING. */ 00235 bool show(uint options); 00236 }; 00237 00238 00242 class PROFILING 00243 { 00244 private: 00245 friend class PROF_MEASUREMENT; 00246 friend class QUERY_PROFILE; 00247 00248 /* 00249 Not the system query_id, but a counter unique to profiling. 00250 */ 00251 query_id_t profile_id_counter; 00252 THD *thd; 00253 bool keeping; 00254 bool enabled; 00255 00256 QUERY_PROFILE *current; 00257 QUERY_PROFILE *last; 00258 Queue<QUERY_PROFILE> history; 00259 00260 query_id_t next_profile_id() { return(profile_id_counter++); } 00261 00262 public: 00263 PROFILING(); 00264 ~PROFILING(); 00265 void set_query_source(char *query_source_arg, uint query_length_arg); 00266 00267 void start_new_query(const char *initial_state= "starting"); 00268 00269 void discard_current_query(); 00270 00271 void finish_current_query(); 00272 00273 void status_change(const char *status_arg, 00274 const char *function_arg, 00275 const char *file_arg, unsigned int line_arg); 00276 00277 inline void set_thd(THD *thd_arg) { thd= thd_arg; }; 00278 00279 /* SHOW PROFILES */ 00280 bool show_profiles(); 00281 00282 /* ... from INFORMATION_SCHEMA.PROFILING ... */ 00283 int fill_statistics_info(THD *thd, TABLE_LIST *tables, Item *cond); 00284 }; 00285 00286 # endif /* HAVE_PROFILING */ 00287 #endif /* _SQL_PROFILE_H */