1 /* Copyright (c) 2010, 2011, 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 Foundation,
21   51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA */
22 
23 #include "my_global.h"
24 #include "my_sys.h"
25 #include "pfs_visitor.h"
26 #include "pfs_instr.h"
27 #include "pfs_instr_class.h"
28 #include "pfs_user.h"
29 #include "pfs_host.h"
30 #include "pfs_account.h"
31 
32 /**
33   @file storage/perfschema/pfs_visitor.cc
34   Visitors (implementation).
35 */
36 
37 /**
38   @addtogroup Performance_schema_buffers
39   @{
40 */
41 
42 /** Connection iterator */
visit_global(bool with_hosts,bool with_users,bool with_accounts,bool with_threads,PFS_connection_visitor * visitor)43 void PFS_connection_iterator::visit_global(bool with_hosts, bool with_users,
44                                            bool with_accounts, bool with_threads,
45                                            PFS_connection_visitor *visitor)
46 {
47   DBUG_ASSERT(visitor != NULL);
48 
49   visitor->visit_global();
50 
51   if (with_hosts)
52   {
53     PFS_host *pfs= host_array;
54     PFS_host *pfs_last= pfs + host_max;
55     for ( ; pfs < pfs_last; pfs++)
56     {
57       if (pfs->m_lock.is_populated())
58         visitor->visit_host(pfs);
59     }
60   }
61 
62   if (with_users)
63   {
64     PFS_user *pfs= user_array;
65     PFS_user *pfs_last= pfs + user_max;
66     for ( ; pfs < pfs_last; pfs++)
67     {
68       if (pfs->m_lock.is_populated())
69         visitor->visit_user(pfs);
70     }
71   }
72 
73   if (with_accounts)
74   {
75     PFS_account *pfs= account_array;
76     PFS_account *pfs_last= pfs + account_max;
77     for ( ; pfs < pfs_last; pfs++)
78     {
79       if (pfs->m_lock.is_populated())
80         visitor->visit_account(pfs);
81     }
82   }
83 
84   if (with_threads)
85   {
86     PFS_thread *pfs= thread_array;
87     PFS_thread *pfs_last= pfs + thread_max;
88     for ( ; pfs < pfs_last; pfs++)
89     {
90       if (pfs->m_lock.is_populated())
91         visitor->visit_thread(pfs);
92     }
93   }
94 }
95 
visit_host(PFS_host * host,bool with_accounts,bool with_threads,PFS_connection_visitor * visitor)96 void PFS_connection_iterator::visit_host(PFS_host *host,
97                                          bool with_accounts, bool with_threads,
98                                          PFS_connection_visitor *visitor)
99 {
100   DBUG_ASSERT(visitor != NULL);
101 
102   visitor->visit_host(host);
103 
104   if (with_accounts)
105   {
106     PFS_account *pfs= account_array;
107     PFS_account *pfs_last= pfs + account_max;
108     for ( ; pfs < pfs_last; pfs++)
109     {
110       if ((pfs->m_host == host) && pfs->m_lock.is_populated())
111       {
112         visitor->visit_account(pfs);
113       }
114     }
115   }
116 
117   if (with_threads)
118   {
119     PFS_thread *pfs= thread_array;
120     PFS_thread *pfs_last= pfs + thread_max;
121     for ( ; pfs < pfs_last; pfs++)
122     {
123       if (pfs->m_lock.is_populated())
124       {
125         PFS_account *safe_account= sanitize_account(pfs->m_account);
126         if ((safe_account != NULL) && (safe_account->m_host == host))
127         {
128           /*
129             If the thread belongs to a known user@host that belongs to this host,
130             process it.
131           */
132           visitor->visit_thread(pfs);
133         }
134         else if (pfs->m_host == host)
135         {
136           /*
137             If the thread belongs to a 'lost' user@host that belong to this host,
138             process it.
139           */
140           visitor->visit_thread(pfs);
141         }
142       }
143     }
144   }
145 }
146 
visit_user(PFS_user * user,bool with_accounts,bool with_threads,PFS_connection_visitor * visitor)147 void PFS_connection_iterator::visit_user(PFS_user *user,
148                                          bool with_accounts, bool with_threads,
149                                          PFS_connection_visitor *visitor)
150 {
151   DBUG_ASSERT(visitor != NULL);
152 
153   visitor->visit_user(user);
154 
155   if (with_accounts)
156   {
157     PFS_account *pfs= account_array;
158     PFS_account *pfs_last= pfs + account_max;
159     for ( ; pfs < pfs_last; pfs++)
160     {
161       if ((pfs->m_user == user) && pfs->m_lock.is_populated())
162       {
163         visitor->visit_account(pfs);
164       }
165     }
166   }
167 
168   if (with_threads)
169   {
170     PFS_thread *pfs= thread_array;
171     PFS_thread *pfs_last= pfs + thread_max;
172     for ( ; pfs < pfs_last; pfs++)
173     {
174       if (pfs->m_lock.is_populated())
175       {
176         PFS_account *safe_account= sanitize_account(pfs->m_account);
177         if ((safe_account != NULL) && (safe_account->m_user == user))
178         {
179           /*
180             If the thread belongs to a known user@host that belongs to this user,
181             process it.
182           */
183           visitor->visit_thread(pfs);
184         }
185         else if (pfs->m_user == user)
186         {
187           /*
188             If the thread belongs to a 'lost' user@host that belong to this user,
189             process it.
190           */
191           visitor->visit_thread(pfs);
192         }
193       }
194     }
195   }
196 }
197 
visit_account(PFS_account * account,bool with_threads,PFS_connection_visitor * visitor)198 void PFS_connection_iterator::visit_account(PFS_account *account,
199                                               bool with_threads,
200                                               PFS_connection_visitor *visitor)
201 {
202   DBUG_ASSERT(visitor != NULL);
203 
204   visitor->visit_account(account);
205 
206   if (with_threads)
207   {
208     PFS_thread *pfs= thread_array;
209     PFS_thread *pfs_last= pfs + thread_max;
210     for ( ; pfs < pfs_last; pfs++)
211     {
212       if ((pfs->m_account == account) && pfs->m_lock.is_populated())
213       {
214         visitor->visit_thread(pfs);
215       }
216     }
217   }
218 }
219 
visit_all(PFS_instance_visitor * visitor)220 void PFS_instance_iterator::visit_all(PFS_instance_visitor *visitor)
221 {
222   visit_all_mutex(visitor);
223   visit_all_rwlock(visitor);
224   visit_all_cond(visitor);
225   visit_all_file(visitor);
226 }
227 
visit_all_mutex(PFS_instance_visitor * visitor)228 void PFS_instance_iterator::visit_all_mutex(PFS_instance_visitor *visitor)
229 {
230   visit_all_mutex_classes(visitor);
231   visit_all_mutex_instances(visitor);
232 }
233 
visit_all_mutex_classes(PFS_instance_visitor * visitor)234 void PFS_instance_iterator::visit_all_mutex_classes(PFS_instance_visitor *visitor)
235 {
236   PFS_mutex_class *pfs= mutex_class_array;
237   PFS_mutex_class *pfs_last= pfs + mutex_class_max;
238   for ( ; pfs < pfs_last; pfs++)
239   {
240     if (pfs->m_name_length != 0)
241     {
242       visitor->visit_mutex_class(pfs);
243     }
244   }
245 }
246 
visit_all_mutex_instances(PFS_instance_visitor * visitor)247 void PFS_instance_iterator::visit_all_mutex_instances(PFS_instance_visitor *visitor)
248 {
249   PFS_mutex *pfs= mutex_array;
250   PFS_mutex *pfs_last= pfs + mutex_max;
251   for ( ; pfs < pfs_last; pfs++)
252   {
253     if (pfs->m_lock.is_populated())
254     {
255       visitor->visit_mutex(pfs);
256     }
257   }
258 }
259 
visit_all_rwlock(PFS_instance_visitor * visitor)260 void PFS_instance_iterator::visit_all_rwlock(PFS_instance_visitor *visitor)
261 {
262   visit_all_rwlock_classes(visitor);
263   visit_all_rwlock_instances(visitor);
264 }
265 
visit_all_rwlock_classes(PFS_instance_visitor * visitor)266 void PFS_instance_iterator::visit_all_rwlock_classes(PFS_instance_visitor *visitor)
267 {
268   PFS_rwlock_class *pfs= rwlock_class_array;
269   PFS_rwlock_class *pfs_last= pfs + rwlock_class_max;
270   for ( ; pfs < pfs_last; pfs++)
271   {
272     if (pfs->m_name_length != 0)
273     {
274       visitor->visit_rwlock_class(pfs);
275     }
276   }
277 }
278 
visit_all_rwlock_instances(PFS_instance_visitor * visitor)279 void PFS_instance_iterator::visit_all_rwlock_instances(PFS_instance_visitor *visitor)
280 {
281   PFS_rwlock *pfs= rwlock_array;
282   PFS_rwlock *pfs_last= pfs + rwlock_max;
283   for ( ; pfs < pfs_last; pfs++)
284   {
285     if (pfs->m_lock.is_populated())
286     {
287       visitor->visit_rwlock(pfs);
288     }
289   }
290 }
291 
visit_all_cond(PFS_instance_visitor * visitor)292 void PFS_instance_iterator::visit_all_cond(PFS_instance_visitor *visitor)
293 {
294   visit_all_cond_classes(visitor);
295   visit_all_cond_instances(visitor);
296 }
297 
visit_all_cond_classes(PFS_instance_visitor * visitor)298 void PFS_instance_iterator::visit_all_cond_classes(PFS_instance_visitor *visitor)
299 {
300   PFS_cond_class *pfs= cond_class_array;
301   PFS_cond_class *pfs_last= pfs + cond_class_max;
302   for ( ; pfs < pfs_last; pfs++)
303   {
304     if (pfs->m_name_length != 0)
305     {
306       visitor->visit_cond_class(pfs);
307     }
308   }
309 }
310 
visit_all_cond_instances(PFS_instance_visitor * visitor)311 void PFS_instance_iterator::visit_all_cond_instances(PFS_instance_visitor *visitor)
312 {
313   PFS_cond *pfs= cond_array;
314   PFS_cond *pfs_last= pfs + cond_max;
315   for ( ; pfs < pfs_last; pfs++)
316   {
317     if (pfs->m_lock.is_populated())
318     {
319       visitor->visit_cond(pfs);
320     }
321   }
322 }
323 
visit_all_file(PFS_instance_visitor * visitor)324 void PFS_instance_iterator::visit_all_file(PFS_instance_visitor *visitor)
325 {
326   visit_all_file_classes(visitor);
327   visit_all_file_instances(visitor);
328 }
329 
visit_all_file_classes(PFS_instance_visitor * visitor)330 void PFS_instance_iterator::visit_all_file_classes(PFS_instance_visitor *visitor)
331 {
332   PFS_file_class *pfs= file_class_array;
333   PFS_file_class *pfs_last= pfs + file_class_max;
334   for ( ; pfs < pfs_last; pfs++)
335   {
336     if (pfs->m_name_length != 0)
337     {
338       visitor->visit_file_class(pfs);
339     }
340   }
341 }
342 
visit_all_file_instances(PFS_instance_visitor * visitor)343 void PFS_instance_iterator::visit_all_file_instances(PFS_instance_visitor *visitor)
344 {
345   PFS_file *pfs= file_array;
346   PFS_file *pfs_last= pfs + file_max;
347   for ( ; pfs < pfs_last; pfs++)
348   {
349     if (pfs->m_lock.is_populated())
350     {
351       visitor->visit_file(pfs);
352     }
353   }
354 }
355 
356 /** Instance iterator */
357 
visit_mutex_instances(PFS_mutex_class * klass,PFS_instance_visitor * visitor)358 void PFS_instance_iterator::visit_mutex_instances(PFS_mutex_class *klass,
359                                                   PFS_instance_visitor *visitor)
360 {
361   DBUG_ASSERT(visitor != NULL);
362 
363   visitor->visit_mutex_class(klass);
364 
365   if (klass->is_singleton())
366   {
367     PFS_mutex *pfs= sanitize_mutex(klass->m_singleton);
368     if (likely(pfs != NULL))
369     {
370       if (likely(pfs->m_lock.is_populated()))
371       {
372         visitor->visit_mutex(pfs);
373       }
374     }
375   }
376   else
377   {
378     PFS_mutex *pfs= mutex_array;
379     PFS_mutex *pfs_last= pfs + mutex_max;
380     for ( ; pfs < pfs_last; pfs++)
381     {
382       if ((pfs->m_class == klass) && pfs->m_lock.is_populated())
383       {
384         visitor->visit_mutex(pfs);
385       }
386     }
387   }
388 }
389 
visit_rwlock_instances(PFS_rwlock_class * klass,PFS_instance_visitor * visitor)390 void PFS_instance_iterator::visit_rwlock_instances(PFS_rwlock_class *klass,
391                                                    PFS_instance_visitor *visitor)
392 {
393   DBUG_ASSERT(visitor != NULL);
394 
395   visitor->visit_rwlock_class(klass);
396 
397   if (klass->is_singleton())
398   {
399     PFS_rwlock *pfs= sanitize_rwlock(klass->m_singleton);
400     if (likely(pfs != NULL))
401     {
402       if (likely(pfs->m_lock.is_populated()))
403       {
404         visitor->visit_rwlock(pfs);
405       }
406     }
407   }
408   else
409   {
410     PFS_rwlock *pfs= rwlock_array;
411     PFS_rwlock *pfs_last= pfs + rwlock_max;
412     for ( ; pfs < pfs_last; pfs++)
413     {
414       if ((pfs->m_class == klass) && pfs->m_lock.is_populated())
415       {
416         visitor->visit_rwlock(pfs);
417       }
418     }
419   }
420 }
421 
visit_cond_instances(PFS_cond_class * klass,PFS_instance_visitor * visitor)422 void PFS_instance_iterator::visit_cond_instances(PFS_cond_class *klass,
423                                                  PFS_instance_visitor *visitor)
424 {
425   DBUG_ASSERT(visitor != NULL);
426 
427   visitor->visit_cond_class(klass);
428 
429   if (klass->is_singleton())
430   {
431     PFS_cond *pfs= sanitize_cond(klass->m_singleton);
432     if (likely(pfs != NULL))
433     {
434       if (likely(pfs->m_lock.is_populated()))
435       {
436         visitor->visit_cond(pfs);
437       }
438     }
439   }
440   else
441   {
442     PFS_cond *pfs= cond_array;
443     PFS_cond *pfs_last= pfs + cond_max;
444     for ( ; pfs < pfs_last; pfs++)
445     {
446       if ((pfs->m_class == klass) && pfs->m_lock.is_populated())
447       {
448         visitor->visit_cond(pfs);
449       }
450     }
451   }
452 }
453 
visit_file_instances(PFS_file_class * klass,PFS_instance_visitor * visitor)454 void PFS_instance_iterator::visit_file_instances(PFS_file_class *klass,
455                                                  PFS_instance_visitor *visitor)
456 {
457   DBUG_ASSERT(visitor != NULL);
458 
459   visitor->visit_file_class(klass);
460 
461   if (klass->is_singleton())
462   {
463     PFS_file *pfs= sanitize_file(klass->m_singleton);
464     if (likely(pfs != NULL))
465     {
466       if (likely(pfs->m_lock.is_populated()))
467       {
468         visitor->visit_file(pfs);
469       }
470     }
471   }
472   else
473   {
474     PFS_file *pfs= file_array;
475     PFS_file *pfs_last= pfs + file_max;
476     for ( ; pfs < pfs_last; pfs++)
477     {
478       if ((pfs->m_class == klass) && pfs->m_lock.is_populated())
479       {
480         visitor->visit_file(pfs);
481       }
482     }
483   }
484 }
485 
486 /** Socket instance iterator visting a socket class and all instances */
487 
visit_socket_instances(PFS_socket_class * klass,PFS_instance_visitor * visitor)488 void PFS_instance_iterator::visit_socket_instances(PFS_socket_class *klass,
489                                                    PFS_instance_visitor *visitor)
490 {
491   DBUG_ASSERT(visitor != NULL);
492 
493   visitor->visit_socket_class(klass);
494 
495   if (klass->is_singleton())
496   {
497     PFS_socket *pfs= sanitize_socket(klass->m_singleton);
498     if (likely(pfs != NULL))
499     {
500       if (likely(pfs->m_lock.is_populated()))
501       {
502         visitor->visit_socket(pfs);
503       }
504     }
505   }
506   else
507   {
508     PFS_socket *pfs= socket_array;
509     PFS_socket *pfs_last= pfs + socket_max;
510     for ( ; pfs < pfs_last; pfs++)
511     {
512       if ((pfs->m_class == klass) && pfs->m_lock.is_populated())
513       {
514         visitor->visit_socket(pfs);
515       }
516     }
517   }
518 }
519 
520 /** Socket instance iterator visting sockets owned by PFS_thread. */
521 
visit_socket_instances(PFS_socket_class * klass,PFS_instance_visitor * visitor,PFS_thread * thread,bool visit_class)522 void PFS_instance_iterator::visit_socket_instances(PFS_socket_class *klass,
523                                                    PFS_instance_visitor *visitor,
524                                                    PFS_thread *thread,
525                                                    bool visit_class)
526 {
527   DBUG_ASSERT(visitor != NULL);
528   DBUG_ASSERT(thread != NULL);
529 
530   if (visit_class)
531     visitor->visit_socket_class(klass);
532 
533   if (klass->is_singleton())
534   {
535     PFS_socket *pfs= sanitize_socket(klass->m_singleton);
536     if (likely(pfs != NULL))
537     {
538       if (unlikely(pfs->m_thread_owner == thread))
539         visitor->visit_socket(pfs);
540     }
541   }
542   else
543   {
544     /* Get current socket stats from each socket instance owned by this thread */
545     PFS_socket *pfs= socket_array;
546     PFS_socket *pfs_last= pfs + socket_max;
547 
548     for ( ; pfs < pfs_last; pfs++)
549     {
550       if (unlikely((pfs->m_class == klass) &&
551                    (pfs->m_thread_owner == thread)))
552       {
553         visitor->visit_socket(pfs);
554       }
555     }
556   }
557 }
558 
559 /** Generic instance iterator with PFS_thread as matching criteria */
560 
visit_instances(PFS_instr_class * klass,PFS_instance_visitor * visitor,PFS_thread * thread,bool visit_class)561 void PFS_instance_iterator::visit_instances(PFS_instr_class *klass,
562                                             PFS_instance_visitor *visitor,
563                                             PFS_thread *thread,
564                                             bool visit_class)
565 {
566   DBUG_ASSERT(visitor != NULL);
567   DBUG_ASSERT(klass != NULL);
568 
569   switch (klass->m_type)
570   {
571   case PFS_CLASS_SOCKET:
572     {
573     PFS_socket_class *socket_class= reinterpret_cast<PFS_socket_class*>(klass);
574     PFS_instance_iterator::visit_socket_instances(socket_class, visitor,
575                                                   thread, visit_class);
576     }
577     break;
578   default:
579     break;
580   }
581 }
582 
583 /** Object iterator */
visit_all(PFS_object_visitor * visitor)584 void PFS_object_iterator::visit_all(PFS_object_visitor *visitor)
585 {
586   visit_all_tables(visitor);
587 }
588 
visit_all_tables(PFS_object_visitor * visitor)589 void PFS_object_iterator::visit_all_tables(PFS_object_visitor *visitor)
590 {
591   DBUG_ASSERT(visitor != NULL);
592 
593   visitor->visit_global();
594 
595   /* For all the table shares ... */
596   PFS_table_share *share= table_share_array;
597   PFS_table_share *share_last= table_share_array + table_share_max;
598   for ( ; share < share_last; share++)
599   {
600     if (share->m_lock.is_populated())
601     {
602       visitor->visit_table_share(share);
603     }
604   }
605 
606   /* For all the table handles ... */
607   PFS_table *table= table_array;
608   PFS_table *table_last= table_array + table_max;
609   for ( ; table < table_last; table++)
610   {
611     if (table->m_lock.is_populated())
612     {
613       visitor->visit_table(table);
614     }
615   }
616 }
617 
visit_tables(PFS_table_share * share,PFS_object_visitor * visitor)618 void PFS_object_iterator::visit_tables(PFS_table_share *share,
619                                        PFS_object_visitor *visitor)
620 {
621   DBUG_ASSERT(visitor != NULL);
622 
623   visitor->visit_table_share(share);
624 
625   /* For all the table handles ... */
626   PFS_table *table= table_array;
627   PFS_table *table_last= table_array + table_max;
628   for ( ; table < table_last; table++)
629   {
630     if ((table->m_share == share) && table->m_lock.is_populated())
631     {
632       visitor->visit_table(table);
633     }
634   }
635 }
636 
visit_table_indexes(PFS_table_share * share,uint index,PFS_object_visitor * visitor)637 void PFS_object_iterator::visit_table_indexes(PFS_table_share *share,
638                                               uint index,
639                                               PFS_object_visitor *visitor)
640 {
641   DBUG_ASSERT(visitor != NULL);
642 
643   visitor->visit_table_share_index(share, index);
644 
645   /* For all the table handles ... */
646   PFS_table *table= table_array;
647   PFS_table *table_last= table_array + table_max;
648   for ( ; table < table_last; table++)
649   {
650     if ((table->m_share == share) && table->m_lock.is_populated())
651     {
652       visitor->visit_table_index(table, index);
653     }
654   }
655 }
656 
657 /** Connection wait visitor */
658 
659 PFS_connection_wait_visitor
PFS_connection_wait_visitor(PFS_instr_class * klass)660 ::PFS_connection_wait_visitor(PFS_instr_class *klass)
661 {
662   m_index= klass->m_event_name_index;
663 }
664 
~PFS_connection_wait_visitor()665 PFS_connection_wait_visitor::~PFS_connection_wait_visitor()
666 {}
667 
visit_global()668 void PFS_connection_wait_visitor::visit_global()
669 {
670   /*
671     This visitor is used only for idle instruments.
672     For waits, do not sum by connection but by instances,
673     it is more efficient.
674   */
675   DBUG_ASSERT(m_index == global_idle_class.m_event_name_index);
676   m_stat.aggregate(& global_idle_stat);
677 }
678 
visit_host(PFS_host * pfs)679 void PFS_connection_wait_visitor::visit_host(PFS_host *pfs)
680 {
681   m_stat.aggregate(& pfs->m_instr_class_waits_stats[m_index]);
682 }
683 
visit_user(PFS_user * pfs)684 void PFS_connection_wait_visitor::visit_user(PFS_user *pfs)
685 {
686   m_stat.aggregate(& pfs->m_instr_class_waits_stats[m_index]);
687 }
688 
visit_account(PFS_account * pfs)689 void PFS_connection_wait_visitor::visit_account(PFS_account *pfs)
690 {
691   m_stat.aggregate(& pfs->m_instr_class_waits_stats[m_index]);
692 }
693 
visit_thread(PFS_thread * pfs)694 void PFS_connection_wait_visitor::visit_thread(PFS_thread *pfs)
695 {
696   m_stat.aggregate(& pfs->m_instr_class_waits_stats[m_index]);
697 }
698 
699 PFS_connection_all_wait_visitor
PFS_connection_all_wait_visitor()700 ::PFS_connection_all_wait_visitor()
701 {}
702 
~PFS_connection_all_wait_visitor()703 PFS_connection_all_wait_visitor::~PFS_connection_all_wait_visitor()
704 {}
705 
visit_global()706 void PFS_connection_all_wait_visitor::visit_global()
707 {
708   /* Sum by instances, not by connection */
709   DBUG_ASSERT(false);
710 }
711 
visit_connection_slice(PFS_connection_slice * pfs)712 void PFS_connection_all_wait_visitor::visit_connection_slice(PFS_connection_slice *pfs)
713 {
714   PFS_single_stat *stat= pfs->m_instr_class_waits_stats;
715   PFS_single_stat *stat_last= stat + wait_class_max;
716   for ( ; stat < stat_last; stat++)
717   {
718     m_stat.aggregate(stat);
719   }
720 }
721 
visit_host(PFS_host * pfs)722 void PFS_connection_all_wait_visitor::visit_host(PFS_host *pfs)
723 {
724   visit_connection_slice(pfs);
725 }
726 
visit_user(PFS_user * pfs)727 void PFS_connection_all_wait_visitor::visit_user(PFS_user *pfs)
728 {
729   visit_connection_slice(pfs);
730 }
731 
visit_account(PFS_account * pfs)732 void PFS_connection_all_wait_visitor::visit_account(PFS_account *pfs)
733 {
734   visit_connection_slice(pfs);
735 }
736 
visit_thread(PFS_thread * pfs)737 void PFS_connection_all_wait_visitor::visit_thread(PFS_thread *pfs)
738 {
739   visit_connection_slice(pfs);
740 }
741 
PFS_connection_stage_visitor(PFS_stage_class * klass)742 PFS_connection_stage_visitor::PFS_connection_stage_visitor(PFS_stage_class *klass)
743 {
744   m_index= klass->m_event_name_index;
745 }
746 
~PFS_connection_stage_visitor()747 PFS_connection_stage_visitor::~PFS_connection_stage_visitor()
748 {}
749 
visit_global()750 void PFS_connection_stage_visitor::visit_global()
751 {
752   m_stat.aggregate(& global_instr_class_stages_array[m_index]);
753 }
754 
visit_host(PFS_host * pfs)755 void PFS_connection_stage_visitor::visit_host(PFS_host *pfs)
756 {
757   m_stat.aggregate(& pfs->m_instr_class_stages_stats[m_index]);
758 }
759 
visit_user(PFS_user * pfs)760 void PFS_connection_stage_visitor::visit_user(PFS_user *pfs)
761 {
762   m_stat.aggregate(& pfs->m_instr_class_stages_stats[m_index]);
763 }
764 
visit_account(PFS_account * pfs)765 void PFS_connection_stage_visitor::visit_account(PFS_account *pfs)
766 {
767   m_stat.aggregate(& pfs->m_instr_class_stages_stats[m_index]);
768 }
769 
visit_thread(PFS_thread * pfs)770 void PFS_connection_stage_visitor::visit_thread(PFS_thread *pfs)
771 {
772   m_stat.aggregate(& pfs->m_instr_class_stages_stats[m_index]);
773 }
774 
775 PFS_connection_statement_visitor
PFS_connection_statement_visitor(PFS_statement_class * klass)776 ::PFS_connection_statement_visitor(PFS_statement_class *klass)
777 {
778   m_index= klass->m_event_name_index;
779 }
780 
~PFS_connection_statement_visitor()781 PFS_connection_statement_visitor::~PFS_connection_statement_visitor()
782 {}
783 
visit_global()784 void PFS_connection_statement_visitor::visit_global()
785 {
786   m_stat.aggregate(& global_instr_class_statements_array[m_index]);
787 }
788 
visit_host(PFS_host * pfs)789 void PFS_connection_statement_visitor::visit_host(PFS_host *pfs)
790 {
791   m_stat.aggregate(& pfs->m_instr_class_statements_stats[m_index]);
792 }
793 
visit_user(PFS_user * pfs)794 void PFS_connection_statement_visitor::visit_user(PFS_user *pfs)
795 {
796   m_stat.aggregate(& pfs->m_instr_class_statements_stats[m_index]);
797 }
798 
visit_account(PFS_account * pfs)799 void PFS_connection_statement_visitor::visit_account(PFS_account *pfs)
800 {
801   m_stat.aggregate(& pfs->m_instr_class_statements_stats[m_index]);
802 }
803 
visit_thread(PFS_thread * pfs)804 void PFS_connection_statement_visitor::visit_thread(PFS_thread *pfs)
805 {
806   m_stat.aggregate(& pfs->m_instr_class_statements_stats[m_index]);
807 }
808 
809 /** Instance wait visitor */
810 PFS_connection_all_statement_visitor
PFS_connection_all_statement_visitor()811 ::PFS_connection_all_statement_visitor()
812 {}
813 
~PFS_connection_all_statement_visitor()814 PFS_connection_all_statement_visitor::~PFS_connection_all_statement_visitor()
815 {}
816 
visit_global()817 void PFS_connection_all_statement_visitor::visit_global()
818 {
819   PFS_statement_stat *stat= global_instr_class_statements_array;
820   PFS_statement_stat *stat_last= stat + statement_class_max;
821   for ( ; stat < stat_last; stat++)
822   {
823     m_stat.aggregate(stat);
824   }
825 }
826 
visit_connection_slice(PFS_connection_slice * pfs)827 void PFS_connection_all_statement_visitor::visit_connection_slice(PFS_connection_slice *pfs)
828 {
829   PFS_statement_stat *stat= pfs->m_instr_class_statements_stats;
830   PFS_statement_stat *stat_last= stat + statement_class_max;
831   for ( ; stat < stat_last; stat++)
832   {
833     m_stat.aggregate(stat);
834   }
835 }
836 
visit_host(PFS_host * pfs)837 void PFS_connection_all_statement_visitor::visit_host(PFS_host *pfs)
838 {
839   visit_connection_slice(pfs);
840 }
841 
visit_user(PFS_user * pfs)842 void PFS_connection_all_statement_visitor::visit_user(PFS_user *pfs)
843 {
844   visit_connection_slice(pfs);
845 }
846 
visit_account(PFS_account * pfs)847 void PFS_connection_all_statement_visitor::visit_account(PFS_account *pfs)
848 {
849   visit_connection_slice(pfs);
850 }
851 
visit_thread(PFS_thread * pfs)852 void PFS_connection_all_statement_visitor::visit_thread(PFS_thread *pfs)
853 {
854   visit_connection_slice(pfs);
855 }
856 
PFS_connection_stat_visitor()857 PFS_connection_stat_visitor::PFS_connection_stat_visitor()
858 {}
859 
~PFS_connection_stat_visitor()860 PFS_connection_stat_visitor::~PFS_connection_stat_visitor()
861 {}
862 
visit_global()863 void PFS_connection_stat_visitor::visit_global()
864 {}
865 
visit_host(PFS_host * pfs)866 void PFS_connection_stat_visitor::visit_host(PFS_host *pfs)
867 {
868   m_stat.aggregate_disconnected(pfs->m_disconnected_count);
869 }
870 
visit_user(PFS_user * pfs)871 void PFS_connection_stat_visitor::visit_user(PFS_user *pfs)
872 {
873   m_stat.aggregate_disconnected(pfs->m_disconnected_count);
874 }
875 
visit_account(PFS_account * pfs)876 void PFS_connection_stat_visitor::visit_account(PFS_account *pfs)
877 {
878   m_stat.aggregate_disconnected(pfs->m_disconnected_count);
879 }
880 
visit_thread(PFS_thread * pfs)881 void PFS_connection_stat_visitor::visit_thread(PFS_thread *pfs)
882 {
883   /*
884     PFS_connection_stat_visitor is used in tables accounts,
885     users and hosts. It should take into account only
886     FOREGROUND threads.
887   */
888   if (pfs->m_processlist_id != 0)
889     m_stat.aggregate_active(1);
890 }
891 
PFS_instance_wait_visitor()892 PFS_instance_wait_visitor::PFS_instance_wait_visitor()
893 {
894 }
895 
~PFS_instance_wait_visitor()896 PFS_instance_wait_visitor::~PFS_instance_wait_visitor()
897 {}
898 
visit_mutex_class(PFS_mutex_class * pfs)899 void PFS_instance_wait_visitor::visit_mutex_class(PFS_mutex_class *pfs)
900 {
901   m_stat.aggregate(&pfs->m_mutex_stat.m_wait_stat);
902 }
903 
visit_rwlock_class(PFS_rwlock_class * pfs)904 void PFS_instance_wait_visitor::visit_rwlock_class(PFS_rwlock_class *pfs)
905 {
906   m_stat.aggregate(&pfs->m_rwlock_stat.m_wait_stat);
907 }
908 
visit_cond_class(PFS_cond_class * pfs)909 void PFS_instance_wait_visitor::visit_cond_class(PFS_cond_class *pfs)
910 {
911   m_stat.aggregate(&pfs->m_cond_stat.m_wait_stat);
912 }
913 
visit_file_class(PFS_file_class * pfs)914 void PFS_instance_wait_visitor::visit_file_class(PFS_file_class *pfs)
915 {
916   pfs->m_file_stat.m_io_stat.sum_waits(&m_stat);
917 }
918 
visit_socket_class(PFS_socket_class * pfs)919 void PFS_instance_wait_visitor::visit_socket_class(PFS_socket_class *pfs)
920 {
921   pfs->m_socket_stat.m_io_stat.sum_waits(&m_stat);
922 }
923 
visit_mutex(PFS_mutex * pfs)924 void PFS_instance_wait_visitor::visit_mutex(PFS_mutex *pfs)
925 {
926   m_stat.aggregate(& pfs->m_mutex_stat.m_wait_stat);
927 }
928 
visit_rwlock(PFS_rwlock * pfs)929 void PFS_instance_wait_visitor::visit_rwlock(PFS_rwlock *pfs)
930 {
931   m_stat.aggregate(& pfs->m_rwlock_stat.m_wait_stat);
932 }
933 
visit_cond(PFS_cond * pfs)934 void PFS_instance_wait_visitor::visit_cond(PFS_cond *pfs)
935 {
936   m_stat.aggregate(& pfs->m_cond_stat.m_wait_stat);
937 }
938 
visit_file(PFS_file * pfs)939 void PFS_instance_wait_visitor::visit_file(PFS_file *pfs)
940 {
941   /* Combine per-operation file wait stats before aggregating */
942   PFS_single_stat stat;
943   pfs->m_file_stat.m_io_stat.sum_waits(&stat);
944   m_stat.aggregate(&stat);
945 }
946 
visit_socket(PFS_socket * pfs)947 void PFS_instance_wait_visitor::visit_socket(PFS_socket *pfs)
948 {
949   /* Combine per-operation socket wait stats before aggregating */
950   PFS_single_stat stat;
951   pfs->m_socket_stat.m_io_stat.sum_waits(&stat);
952   m_stat.aggregate(&stat);
953 }
954 
955 /** Table IO wait visitor */
956 
PFS_object_wait_visitor()957 PFS_object_wait_visitor::PFS_object_wait_visitor()
958 {}
959 
~PFS_object_wait_visitor()960 PFS_object_wait_visitor::~PFS_object_wait_visitor()
961 {}
962 
visit_global()963 void PFS_object_wait_visitor::visit_global()
964 {
965   global_table_io_stat.sum(& m_stat);
966   global_table_lock_stat.sum(& m_stat);
967 }
968 
visit_table_share(PFS_table_share * pfs)969 void PFS_object_wait_visitor::visit_table_share(PFS_table_share *pfs)
970 {
971   uint safe_key_count= sanitize_index_count(pfs->m_key_count);
972   pfs->m_table_stat.sum(& m_stat, safe_key_count);
973 }
974 
visit_table(PFS_table * pfs)975 void PFS_object_wait_visitor::visit_table(PFS_table *pfs)
976 {
977   PFS_table_share *table_share= sanitize_table_share(pfs->m_share);
978   if (table_share != NULL)
979   {
980     uint safe_key_count= sanitize_index_count(table_share->m_key_count);
981     pfs->m_table_stat.sum(& m_stat, safe_key_count);
982   }
983 }
984 
PFS_table_io_wait_visitor()985 PFS_table_io_wait_visitor::PFS_table_io_wait_visitor()
986 {}
987 
~PFS_table_io_wait_visitor()988 PFS_table_io_wait_visitor::~PFS_table_io_wait_visitor()
989 {}
990 
visit_global()991 void PFS_table_io_wait_visitor::visit_global()
992 {
993   global_table_io_stat.sum(& m_stat);
994 }
995 
visit_table_share(PFS_table_share * pfs)996 void PFS_table_io_wait_visitor::visit_table_share(PFS_table_share *pfs)
997 {
998   PFS_table_io_stat io_stat;
999   uint safe_key_count= sanitize_index_count(pfs->m_key_count);
1000   uint index;
1001 
1002   /* Aggregate index stats */
1003   for (index= 0; index < safe_key_count; index++)
1004     io_stat.aggregate(& pfs->m_table_stat.m_index_stat[index]);
1005 
1006   /* Aggregate global stats */
1007   io_stat.aggregate(& pfs->m_table_stat.m_index_stat[MAX_INDEXES]);
1008 
1009   io_stat.sum(& m_stat);
1010 }
1011 
visit_table(PFS_table * pfs)1012 void PFS_table_io_wait_visitor::visit_table(PFS_table *pfs)
1013 {
1014   PFS_table_share *safe_share= sanitize_table_share(pfs->m_share);
1015 
1016   if (likely(safe_share != NULL))
1017   {
1018     PFS_table_io_stat io_stat;
1019     uint safe_key_count= sanitize_index_count(safe_share->m_key_count);
1020     uint index;
1021 
1022     /* Aggregate index stats */
1023     for (index= 0; index < safe_key_count; index++)
1024       io_stat.aggregate(& pfs->m_table_stat.m_index_stat[index]);
1025 
1026     /* Aggregate global stats */
1027     io_stat.aggregate(& pfs->m_table_stat.m_index_stat[MAX_INDEXES]);
1028 
1029     io_stat.sum(& m_stat);
1030   }
1031 }
1032 
1033 /** Table IO stat visitor */
1034 
PFS_table_io_stat_visitor()1035 PFS_table_io_stat_visitor::PFS_table_io_stat_visitor()
1036 {}
1037 
~PFS_table_io_stat_visitor()1038 PFS_table_io_stat_visitor::~PFS_table_io_stat_visitor()
1039 {}
1040 
visit_table_share(PFS_table_share * pfs)1041 void PFS_table_io_stat_visitor::visit_table_share(PFS_table_share *pfs)
1042 {
1043   uint safe_key_count= sanitize_index_count(pfs->m_key_count);
1044   uint index;
1045 
1046   /* Aggregate index stats */
1047   for (index= 0; index < safe_key_count; index++)
1048     m_stat.aggregate(& pfs->m_table_stat.m_index_stat[index]);
1049 
1050   /* Aggregate global stats */
1051   m_stat.aggregate(& pfs->m_table_stat.m_index_stat[MAX_INDEXES]);
1052 }
1053 
visit_table(PFS_table * pfs)1054 void PFS_table_io_stat_visitor::visit_table(PFS_table *pfs)
1055 {
1056   PFS_table_share *safe_share= sanitize_table_share(pfs->m_share);
1057 
1058   if (likely(safe_share != NULL))
1059   {
1060     uint safe_key_count= sanitize_index_count(safe_share->m_key_count);
1061     uint index;
1062 
1063     /* Aggregate index stats */
1064     for (index= 0; index < safe_key_count; index++)
1065       m_stat.aggregate(& pfs->m_table_stat.m_index_stat[index]);
1066 
1067     /* Aggregate global stats */
1068     m_stat.aggregate(& pfs->m_table_stat.m_index_stat[MAX_INDEXES]);
1069   }
1070 }
1071 
1072 /** Index IO stat visitor */
1073 
PFS_index_io_stat_visitor()1074 PFS_index_io_stat_visitor::PFS_index_io_stat_visitor()
1075 {}
1076 
~PFS_index_io_stat_visitor()1077 PFS_index_io_stat_visitor::~PFS_index_io_stat_visitor()
1078 {}
1079 
visit_table_share_index(PFS_table_share * pfs,uint index)1080 void PFS_index_io_stat_visitor::visit_table_share_index(PFS_table_share *pfs, uint index)
1081 {
1082   m_stat.aggregate(& pfs->m_table_stat.m_index_stat[index]);
1083 }
1084 
visit_table_index(PFS_table * pfs,uint index)1085 void PFS_index_io_stat_visitor::visit_table_index(PFS_table *pfs, uint index)
1086 {
1087   m_stat.aggregate(& pfs->m_table_stat.m_index_stat[index]);
1088 }
1089 
1090 /** Table lock wait visitor */
1091 
PFS_table_lock_wait_visitor()1092 PFS_table_lock_wait_visitor::PFS_table_lock_wait_visitor()
1093 {}
1094 
~PFS_table_lock_wait_visitor()1095 PFS_table_lock_wait_visitor::~PFS_table_lock_wait_visitor()
1096 {}
1097 
visit_global()1098 void PFS_table_lock_wait_visitor::visit_global()
1099 {
1100   global_table_lock_stat.sum(& m_stat);
1101 }
1102 
visit_table_share(PFS_table_share * pfs)1103 void PFS_table_lock_wait_visitor::visit_table_share(PFS_table_share *pfs)
1104 {
1105   pfs->m_table_stat.sum_lock(& m_stat);
1106 }
1107 
visit_table(PFS_table * pfs)1108 void PFS_table_lock_wait_visitor::visit_table(PFS_table *pfs)
1109 {
1110   pfs->m_table_stat.sum_lock(& m_stat);
1111 }
1112 
1113 /** Table lock stat visitor */
1114 
PFS_table_lock_stat_visitor()1115 PFS_table_lock_stat_visitor::PFS_table_lock_stat_visitor()
1116 {}
1117 
~PFS_table_lock_stat_visitor()1118 PFS_table_lock_stat_visitor::~PFS_table_lock_stat_visitor()
1119 {}
1120 
visit_table_share(PFS_table_share * pfs)1121 void PFS_table_lock_stat_visitor::visit_table_share(PFS_table_share *pfs)
1122 {
1123   m_stat.aggregate(& pfs->m_table_stat.m_lock_stat);
1124 }
1125 
visit_table(PFS_table * pfs)1126 void PFS_table_lock_stat_visitor::visit_table(PFS_table *pfs)
1127 {
1128   m_stat.aggregate(& pfs->m_table_stat.m_lock_stat);
1129 }
1130 
PFS_instance_socket_io_stat_visitor()1131 PFS_instance_socket_io_stat_visitor::PFS_instance_socket_io_stat_visitor()
1132 {}
1133 
~PFS_instance_socket_io_stat_visitor()1134 PFS_instance_socket_io_stat_visitor::~PFS_instance_socket_io_stat_visitor()
1135 {}
1136 
visit_socket_class(PFS_socket_class * pfs)1137 void PFS_instance_socket_io_stat_visitor::visit_socket_class(PFS_socket_class *pfs)
1138 {
1139   /* Aggregate wait times, event counts and byte counts */
1140   m_socket_io_stat.aggregate(&pfs->m_socket_stat.m_io_stat);
1141 }
1142 
visit_socket(PFS_socket * pfs)1143 void PFS_instance_socket_io_stat_visitor::visit_socket(PFS_socket *pfs)
1144 {
1145   /* Aggregate wait times, event counts and byte counts */
1146   m_socket_io_stat.aggregate(&pfs->m_socket_stat.m_io_stat);
1147 }
1148 
1149 
PFS_instance_file_io_stat_visitor()1150 PFS_instance_file_io_stat_visitor::PFS_instance_file_io_stat_visitor()
1151 {}
1152 
~PFS_instance_file_io_stat_visitor()1153 PFS_instance_file_io_stat_visitor::~PFS_instance_file_io_stat_visitor()
1154 {}
1155 
visit_file_class(PFS_file_class * pfs)1156 void PFS_instance_file_io_stat_visitor::visit_file_class(PFS_file_class *pfs)
1157 {
1158   /* Aggregate wait times, event counts and byte counts */
1159   m_file_io_stat.aggregate(&pfs->m_file_stat.m_io_stat);
1160 }
1161 
visit_file(PFS_file * pfs)1162 void PFS_instance_file_io_stat_visitor::visit_file(PFS_file *pfs)
1163 {
1164   /* Aggregate wait times, event counts and byte counts */
1165   m_file_io_stat.aggregate(&pfs->m_file_stat.m_io_stat);
1166 }
1167 /** @} */
1168