1 /* Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved.
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
21 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
22
23 /**
24 @file storage/perfschema/table_performance_timers.cc
25 Table PERFORMANCE_TIMERS (implementation).
26 */
27
28 #include "storage/perfschema/table_performance_timers.h"
29
30 #include <stddef.h>
31
32 #include "my_dbug.h"
33 #include "my_thread.h"
34 #include "sql/field.h"
35 #include "sql/plugin_table.h"
36 #include "sql/table.h"
37 #include "storage/perfschema/pfs_global.h"
38 #include "storage/perfschema/pfs_timer.h"
39 #include "storage/perfschema/table_helper.h"
40
41 THR_LOCK table_performance_timers::m_table_lock;
42
43 Plugin_table table_performance_timers::m_table_def(
44 /* Schema name */
45 "performance_schema",
46 /* Name */
47 "performance_timers",
48 /* Definition */
49 " TIMER_NAME ENUM ('CYCLE', 'NANOSECOND', 'MICROSECOND', 'MILLISECOND') "
50 "NOT "
51 "NULL,\n"
52 " TIMER_FREQUENCY BIGINT,\n"
53 " TIMER_RESOLUTION BIGINT,\n"
54 " TIMER_OVERHEAD BIGINT\n",
55 /* Options */
56 " ENGINE=PERFORMANCE_SCHEMA",
57 /* Tablespace */
58 nullptr);
59
60 PFS_engine_table_share table_performance_timers::m_share = {
61 &pfs_readonly_acl,
62 table_performance_timers::create,
63 nullptr, /* write_row */
64 nullptr, /* delete_all_rows */
65 table_performance_timers::get_row_count,
66 sizeof(PFS_simple_index), /* ref length */
67 &m_table_lock,
68 &m_table_def,
69 false, /* perpetual */
70 PFS_engine_table_proxy(),
71 {0},
72 false /* m_in_purgatory */
73 };
74
create(PFS_engine_table_share *)75 PFS_engine_table *table_performance_timers::create(PFS_engine_table_share *) {
76 return new table_performance_timers();
77 }
78
get_row_count(void)79 ha_rows table_performance_timers::get_row_count(void) {
80 return COUNT_TIMER_NAME;
81 }
82
table_performance_timers()83 table_performance_timers::table_performance_timers()
84 : PFS_engine_table(&m_share, &m_pos),
85 m_row(nullptr),
86 m_pos(0),
87 m_next_pos(0) {
88 int index;
89
90 index = (int)TIMER_NAME_CYCLE - FIRST_TIMER_NAME;
91 m_data[index].m_timer_name = TIMER_NAME_CYCLE;
92 m_data[index].m_info = pfs_timer_info.cycles;
93
94 index = (int)TIMER_NAME_NANOSEC - FIRST_TIMER_NAME;
95 m_data[index].m_timer_name = TIMER_NAME_NANOSEC;
96 m_data[index].m_info = pfs_timer_info.nanoseconds;
97
98 index = (int)TIMER_NAME_MICROSEC - FIRST_TIMER_NAME;
99 m_data[index].m_timer_name = TIMER_NAME_MICROSEC;
100 m_data[index].m_info = pfs_timer_info.microseconds;
101
102 index = (int)TIMER_NAME_MILLISEC - FIRST_TIMER_NAME;
103 m_data[index].m_timer_name = TIMER_NAME_MILLISEC;
104 m_data[index].m_info = pfs_timer_info.milliseconds;
105 }
106
reset_position(void)107 void table_performance_timers::reset_position(void) {
108 m_pos.m_index = 0;
109 m_next_pos.m_index = 0;
110 }
111
rnd_next(void)112 int table_performance_timers::rnd_next(void) {
113 int result;
114
115 m_pos.set_at(&m_next_pos);
116
117 if (m_pos.m_index < COUNT_TIMER_NAME) {
118 m_row = &m_data[m_pos.m_index];
119 m_next_pos.set_after(&m_pos);
120 result = 0;
121 } else {
122 m_row = nullptr;
123 result = HA_ERR_END_OF_FILE;
124 }
125
126 return result;
127 }
128
rnd_pos(const void * pos)129 int table_performance_timers::rnd_pos(const void *pos) {
130 set_position(pos);
131 DBUG_ASSERT(m_pos.m_index < COUNT_TIMER_NAME);
132 m_row = &m_data[m_pos.m_index];
133 return 0;
134 }
135
read_row_values(TABLE * table,unsigned char * buf,Field ** fields,bool read_all)136 int table_performance_timers::read_row_values(TABLE *table, unsigned char *buf,
137 Field **fields, bool read_all) {
138 Field *f;
139
140 DBUG_ASSERT(m_row);
141
142 /* Set the null bits */
143 DBUG_ASSERT(table->s->null_bytes == 1);
144 buf[0] = 0;
145
146 for (; (f = *fields); fields++) {
147 if (read_all || bitmap_is_set(table->read_set, f->field_index())) {
148 switch (f->field_index()) {
149 case 0: /* TIMER_NAME */
150 set_field_enum(f, m_row->m_timer_name);
151 break;
152 case 1: /* TIMER_FREQUENCY */
153 if (m_row->m_info.routine != 0) {
154 set_field_ulonglong(f, m_row->m_info.frequency);
155 } else {
156 f->set_null();
157 }
158 break;
159 case 2: /* TIMER_RESOLUTION */
160 if (m_row->m_info.routine != 0) {
161 set_field_ulonglong(f, m_row->m_info.resolution);
162 } else {
163 f->set_null();
164 }
165 break;
166 case 3: /* TIMER_OVERHEAD */
167 if (m_row->m_info.routine != 0) {
168 set_field_ulonglong(f, m_row->m_info.overhead);
169 } else {
170 f->set_null();
171 }
172 break;
173 default:
174 DBUG_ASSERT(false);
175 }
176 }
177 }
178
179 return 0;
180 }
181