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