1 /* Copyright (c) 2011, 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_mems_by_thread_by_event_name.cc
25 Table MEMORY_SUMMARY_BY_THREAD_BY_EVENT_NAME (implementation).
26 */
27
28 #include "my_global.h"
29 #include "my_thread.h"
30 #include "pfs_instr_class.h"
31 #include "pfs_column_types.h"
32 #include "pfs_column_values.h"
33 #include "table_mems_by_thread_by_event_name.h"
34 #include "pfs_global.h"
35 #include "pfs_visitor.h"
36 #include "pfs_memory.h"
37 #include "pfs_buffer_container.h"
38 #include "field.h"
39
40 THR_LOCK table_mems_by_thread_by_event_name::m_table_lock;
41
42 static const TABLE_FIELD_TYPE field_types[]=
43 {
44 {
45 { C_STRING_WITH_LEN("THREAD_ID") },
46 { C_STRING_WITH_LEN("bigint(20)") },
47 { NULL, 0}
48 },
49 {
50 { C_STRING_WITH_LEN("EVENT_NAME") },
51 { C_STRING_WITH_LEN("varchar(128)") },
52 { NULL, 0}
53 },
54 {
55 { C_STRING_WITH_LEN("COUNT_ALLOC") },
56 { C_STRING_WITH_LEN("bigint(20)") },
57 { NULL, 0}
58 },
59 {
60 { C_STRING_WITH_LEN("COUNT_FREE") },
61 { C_STRING_WITH_LEN("bigint(20)") },
62 { NULL, 0}
63 },
64 {
65 { C_STRING_WITH_LEN("SUM_NUMBER_OF_BYTES_ALLOC") },
66 { C_STRING_WITH_LEN("bigint(20)") },
67 { NULL, 0}
68 },
69 {
70 { C_STRING_WITH_LEN("SUM_NUMBER_OF_BYTES_FREE") },
71 { C_STRING_WITH_LEN("bigint(20)") },
72 { NULL, 0}
73 },
74 {
75 { C_STRING_WITH_LEN("LOW_COUNT_USED") },
76 { C_STRING_WITH_LEN("bigint(20)") },
77 { NULL, 0}
78 },
79 {
80 { C_STRING_WITH_LEN("CURRENT_COUNT_USED") },
81 { C_STRING_WITH_LEN("bigint(20)") },
82 { NULL, 0}
83 },
84 {
85 { C_STRING_WITH_LEN("HIGH_COUNT_USED") },
86 { C_STRING_WITH_LEN("bigint(20)") },
87 { NULL, 0}
88 },
89 {
90 { C_STRING_WITH_LEN("LOW_NUMBER_OF_BYTES_USED") },
91 { C_STRING_WITH_LEN("bigint(20)") },
92 { NULL, 0}
93 },
94 {
95 { C_STRING_WITH_LEN("CURRENT_NUMBER_OF_BYTES_USED") },
96 { C_STRING_WITH_LEN("bigint(20)") },
97 { NULL, 0}
98 },
99 {
100 { C_STRING_WITH_LEN("HIGH_NUMBER_OF_BYTES_USED") },
101 { C_STRING_WITH_LEN("bigint(20)") },
102 { NULL, 0}
103 }
104 };
105
106 TABLE_FIELD_DEF
107 table_mems_by_thread_by_event_name::m_field_def=
108 { 12, field_types };
109
110 PFS_engine_table_share
111 table_mems_by_thread_by_event_name::m_share=
112 {
113 { C_STRING_WITH_LEN("memory_summary_by_thread_by_event_name") },
114 &pfs_readonly_acl,
115 table_mems_by_thread_by_event_name::create,
116 NULL, /* write_row */
117 table_mems_by_thread_by_event_name::delete_all_rows,
118 table_mems_by_thread_by_event_name::get_row_count,
119 sizeof(PFS_simple_index),
120 &m_table_lock,
121 &m_field_def,
122 false, /* checked */
123 false /* perpetual */
124 };
125
create(void)126 PFS_engine_table* table_mems_by_thread_by_event_name::create(void)
127 {
128 return new table_mems_by_thread_by_event_name();
129 }
130
131 int
delete_all_rows(void)132 table_mems_by_thread_by_event_name::delete_all_rows(void)
133 {
134 reset_memory_by_thread();
135 return 0;
136 }
137
138 ha_rows
get_row_count(void)139 table_mems_by_thread_by_event_name::get_row_count(void)
140 {
141 return global_thread_container.get_row_count() * memory_class_max;
142 }
143
table_mems_by_thread_by_event_name()144 table_mems_by_thread_by_event_name::table_mems_by_thread_by_event_name()
145 : PFS_engine_table(&m_share, &m_pos),
146 m_row_exists(false), m_pos(), m_next_pos()
147 {}
148
reset_position(void)149 void table_mems_by_thread_by_event_name::reset_position(void)
150 {
151 m_pos.reset();
152 m_next_pos.reset();
153 }
154
rnd_next(void)155 int table_mems_by_thread_by_event_name::rnd_next(void)
156 {
157 PFS_thread *thread;
158 PFS_memory_class *memory_class;
159 bool has_more_thread= true;
160
161 for (m_pos.set_at(&m_next_pos);
162 has_more_thread;
163 m_pos.next_thread())
164 {
165 thread= global_thread_container.get(m_pos.m_index_1, & has_more_thread);
166 if (thread != NULL)
167 {
168 do
169 {
170 memory_class= find_memory_class(m_pos.m_index_2);
171 if (memory_class != NULL)
172 {
173 if (! memory_class->is_global())
174 {
175 make_row(thread, memory_class);
176 m_next_pos.set_after(&m_pos);
177 return 0;
178 }
179
180 m_pos.next_class();
181 }
182 }
183 while (memory_class != NULL);
184 }
185 }
186
187 return HA_ERR_END_OF_FILE;
188 }
189
rnd_pos(const void * pos)190 int table_mems_by_thread_by_event_name::rnd_pos(const void *pos)
191 {
192 PFS_thread *thread;
193 PFS_memory_class *memory_class;
194
195 set_position(pos);
196
197 thread= global_thread_container.get(m_pos.m_index_1);
198 if (thread != NULL)
199 {
200 memory_class= find_memory_class(m_pos.m_index_2);
201 if (memory_class != NULL)
202 {
203 if (! memory_class->is_global())
204 {
205 make_row(thread, memory_class);
206 return 0;
207 }
208 }
209 }
210
211 return HA_ERR_RECORD_DELETED;
212 }
213
214 void table_mems_by_thread_by_event_name
make_row(PFS_thread * thread,PFS_memory_class * klass)215 ::make_row(PFS_thread *thread, PFS_memory_class *klass)
216 {
217 pfs_optimistic_state lock;
218 m_row_exists= false;
219
220 /* Protect this reader against a thread termination */
221 thread->m_lock.begin_optimistic_lock(&lock);
222
223 m_row.m_thread_internal_id= thread->m_thread_internal_id;
224
225 m_row.m_event_name.make_row(klass);
226
227 PFS_connection_memory_visitor visitor(klass);
228 PFS_connection_iterator::visit_thread(thread, & visitor);
229
230 if (! thread->m_lock.end_optimistic_lock(&lock))
231 return;
232
233 m_row_exists= true;
234 m_row.m_stat.set(& visitor.m_stat);
235 }
236
read_row_values(TABLE * table,unsigned char *,Field ** fields,bool read_all)237 int table_mems_by_thread_by_event_name::read_row_values(TABLE *table,
238 unsigned char *,
239 Field **fields,
240 bool read_all)
241 {
242 Field *f;
243
244 if (unlikely(! m_row_exists))
245 return HA_ERR_RECORD_DELETED;
246
247 /* Set the null bits */
248 assert(table->s->null_bytes == 0);
249
250 for (; (f= *fields) ; fields++)
251 {
252 if (read_all || bitmap_is_set(table->read_set, f->field_index))
253 {
254 switch(f->field_index)
255 {
256 case 0: /* THREAD_ID */
257 set_field_ulonglong(f, m_row.m_thread_internal_id);
258 break;
259 case 1: /* EVENT_NAME */
260 m_row.m_event_name.set_field(f);
261 break;
262 default: /* 2, ... HIGH_NUMBER_OF_BYTES_USED */
263 m_row.m_stat.set_field(f->field_index - 2, f);
264 break;
265 }
266 }
267 }
268
269 return 0;
270 }
271
272