1 /* Copyright (c) 2008, 2021, Oracle and/or its affiliates.
2 
3   This program is free software; you can redistribute it and/or modify
4   it under the terms of the GNU General Public License, version 2.0,
5   as published by the Free Software Foundation.
6 
7   This program is also distributed with certain software (including
8   but not limited to OpenSSL) that is licensed under separate terms,
9   as designated in a particular file or component or in included license
10   documentation.  The authors of MySQL hereby grant you an additional
11   permission to link the program and your derivative works with the
12   separately licensed software that they have included with MySQL.
13 
14   This program is distributed in the hope that it will be useful,
15   but WITHOUT ANY WARRANTY; without even the implied warranty of
16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17   GNU General Public License, version 2.0, for more details.
18 
19   You should have received a copy of the GNU General Public License
20   along with this program; if not, write to the Free Software Foundation,
21   51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
22 
23 /**
24   @file storage/perfschema/table_performance_timers.cc
25   Table PERFORMANCE_TIMERS (implementation).
26 */
27 
28 #include "my_global.h"
29 #include "my_thread.h"
30 #include "table_performance_timers.h"
31 #include "pfs_timer.h"
32 #include "pfs_global.h"
33 #include "field.h"
34 
35 THR_LOCK table_performance_timers::m_table_lock;
36 
37 static const TABLE_FIELD_TYPE field_types[]=
38 {
39   {
40     { C_STRING_WITH_LEN("TIMER_NAME") },
41     { C_STRING_WITH_LEN("enum(\'CYCLE\',\'NANOSECOND\',\'MICROSECOND\',"
42                         "\'MILLISECOND\',\'TICK\')") },
43     { NULL, 0}
44   },
45   {
46     { C_STRING_WITH_LEN("TIMER_FREQUENCY") },
47     { C_STRING_WITH_LEN("bigint(20)") },
48     { NULL, 0}
49   },
50   {
51     { C_STRING_WITH_LEN("TIMER_RESOLUTION") },
52     { C_STRING_WITH_LEN("bigint(20)") },
53     { NULL, 0}
54   },
55   {
56     { C_STRING_WITH_LEN("TIMER_OVERHEAD") },
57     { C_STRING_WITH_LEN("bigint(20)") },
58     { NULL, 0}
59   }
60 };
61 
62 TABLE_FIELD_DEF
63 table_performance_timers::m_field_def=
64 { 4, field_types };
65 
66 PFS_engine_table_share
67 table_performance_timers::m_share=
68 {
69   { C_STRING_WITH_LEN("performance_timers") },
70   &pfs_readonly_acl,
71   table_performance_timers::create,
72   NULL, /* write_row */
73   NULL, /* delete_all_rows */
74   table_performance_timers::get_row_count,
75   sizeof(PFS_simple_index), /* ref length */
76   &m_table_lock,
77   &m_field_def,
78   false, /* checked */
79   false  /* perpetual */
80 };
81 
create(void)82 PFS_engine_table* table_performance_timers::create(void)
83 {
84   return new table_performance_timers();
85 }
86 
87 ha_rows
get_row_count(void)88 table_performance_timers::get_row_count(void)
89 {
90   return COUNT_TIMER_NAME;
91 }
92 
table_performance_timers()93 table_performance_timers::table_performance_timers()
94   : PFS_engine_table(&m_share, &m_pos),
95     m_row(NULL), m_pos(0), m_next_pos(0)
96 {
97   int index;
98 
99   index= (int)TIMER_NAME_CYCLE - FIRST_TIMER_NAME;
100   m_data[index].m_timer_name= TIMER_NAME_CYCLE;
101   m_data[index].m_info= pfs_timer_info.cycles;
102 
103   index= (int)TIMER_NAME_NANOSEC - FIRST_TIMER_NAME;
104   m_data[index].m_timer_name= TIMER_NAME_NANOSEC;
105   m_data[index].m_info= pfs_timer_info.nanoseconds;
106 
107   index= (int)TIMER_NAME_MICROSEC - FIRST_TIMER_NAME;
108   m_data[index].m_timer_name= TIMER_NAME_MICROSEC;
109   m_data[index].m_info= pfs_timer_info.microseconds;
110 
111   index= (int)TIMER_NAME_MILLISEC - FIRST_TIMER_NAME;
112   m_data[index].m_timer_name= TIMER_NAME_MILLISEC;
113   m_data[index].m_info= pfs_timer_info.milliseconds;
114 
115   index= (int)TIMER_NAME_TICK - FIRST_TIMER_NAME;
116   m_data[index].m_timer_name= TIMER_NAME_TICK;
117   m_data[index].m_info= pfs_timer_info.ticks;
118 }
119 
reset_position(void)120 void table_performance_timers::reset_position(void)
121 {
122   m_pos.m_index= 0;
123   m_next_pos.m_index= 0;
124 }
125 
rnd_next(void)126 int table_performance_timers::rnd_next(void)
127 {
128   int result;
129 
130   m_pos.set_at(&m_next_pos);
131 
132   if (m_pos.m_index < COUNT_TIMER_NAME)
133   {
134     m_row= &m_data[m_pos.m_index];
135     m_next_pos.set_after(&m_pos);
136     result= 0;
137   }
138   else
139   {
140     m_row= NULL;
141     result= HA_ERR_END_OF_FILE;
142   }
143 
144   return result;
145 }
146 
rnd_pos(const void * pos)147 int table_performance_timers::rnd_pos(const void *pos)
148 {
149   set_position(pos);
150   assert(m_pos.m_index < COUNT_TIMER_NAME);
151   m_row= &m_data[m_pos.m_index];
152   return 0;
153 }
154 
read_row_values(TABLE * table,unsigned char * buf,Field ** fields,bool read_all)155 int table_performance_timers::read_row_values(TABLE *table,
156                                               unsigned char *buf,
157                                               Field **fields,
158                                               bool read_all)
159 {
160   Field *f;
161 
162   assert(m_row);
163 
164   /* Set the null bits */
165   assert(table->s->null_bytes == 1);
166   buf[0]= 0;
167 
168   for (; (f= *fields) ; fields++)
169   {
170     if (read_all || bitmap_is_set(table->read_set, f->field_index))
171     {
172       switch(f->field_index)
173       {
174       case 0: /* TIMER_NAME */
175         set_field_enum(f, m_row->m_timer_name);
176         break;
177       case 1: /* TIMER_FREQUENCY */
178         if (m_row->m_info.routine != 0)
179           set_field_ulonglong(f, m_row->m_info.frequency);
180         else
181           f->set_null();
182         break;
183       case 2: /* TIMER_RESOLUTION */
184         if (m_row->m_info.routine != 0)
185           set_field_ulonglong(f, m_row->m_info.resolution);
186         else
187           f->set_null();
188         break;
189       case 3: /* TIMER_OVERHEAD */
190         if (m_row->m_info.routine != 0)
191           set_field_ulonglong(f, m_row->m_info.overhead);
192         else
193           f->set_null();
194         break;
195       default:
196         assert(false);
197       }
198     }
199   }
200 
201   return 0;
202 }
203 
204