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 #ifndef PFS_TIMER_H
24 #define PFS_TIMER_H
25 
26 /**
27   @file storage/perfschema/pfs_timer.h
28   Performance schema timers (declarations).
29 */
30 
31 #include "my_config.h"
32 #include "my_inttypes.h"
33 #include "my_rdtsc.h"
34 #include "storage/perfschema/pfs_column_types.h"
35 #include "storage/perfschema/pfs_histogram.h"
36 
37 /** Conversion factor, from micro seconds to pico seconds. */
38 #define MICROSEC_TO_PICOSEC 1000000
39 
40 #ifndef MY_CONFIG_H
41 /* my_config.h MUST be included before testing HAVE_XXX flags. */
42 #error "This build is broken"
43 #endif
44 
45 /*
46   HAVE_SYS_TIMES_H:
47   - cmakedefine from config.h.cmake
48   - testable after #include "my_config.h"
49 
50   HAVE_GETHRTIME:
51   - cmakedefine from config.h.cmake
52   - testable after #include "my_config.h"
53 
54   HAVE_CLOCK_GETTIME:
55   - cmakedefine from config.h.cmake
56   - testable after #include "my_config.h"
57 
58   HAVE_CLOCK_REALTIME:
59   - cmakedefine from config.h.cmake
60   - testable after #include "my_config.h"
61   - not to be confused with CLOCK_REALTIME,
62     which is set in #include <times.h>
63 
64   __APPLE__:
65   __MACH__:
66 */
67 
68 /*
69   See my_timer_nanoseconds() in mysys/my_rdtsc.cc
70   This logic matches my_timer_nanoseconds(),
71   to find out at compile time if a nanosecond
72   timer is available or not.
73 */
74 
75 #if defined(HAVE_SYS_TIMES_H) && defined(HAVE_GETHRTIME)
76 #define HAVE_NANOSEC_TIMER
77 /*
78   Testing HAVE_CLOCK_REALTIME instead of CLOCK_REALTIME
79 */
80 #elif defined(HAVE_CLOCK_GETTIME) && defined(HAVE_CLOCK_REALTIME)
81 #define HAVE_NANOSEC_TIMER
82 #elif defined(__APPLE__) && defined(__MACH__)
83 #define HAVE_NANOSEC_TIMER
84 #endif
85 
86 #ifdef HAVE_NANOSEC_TIMER
87 /* Use NANOSECOND for statements and the like. */
88 #define USED_TIMER_NAME TIMER_NAME_NANOSEC
89 #define USED_TIMER my_timer_nanoseconds
90 #else
91 /* Otherwise use MICROSECOND for statements and the like. */
92 #define USED_TIMER_NAME TIMER_NAME_MICROSEC
93 #define USED_TIMER my_timer_microseconds
94 #endif
95 
get_idle_timer()96 ulonglong inline get_idle_timer() { return USED_TIMER(); }
97 
get_wait_timer()98 ulonglong inline get_wait_timer() { return my_timer_cycles(); }
99 
get_stage_timer()100 ulonglong inline get_stage_timer() { return USED_TIMER(); }
101 
get_statement_timer()102 ulonglong inline get_statement_timer() { return USED_TIMER(); }
103 
get_transaction_timer()104 ulonglong inline get_transaction_timer() { return USED_TIMER(); }
105 
106 /**
107   A time normalizer.
108   A time normalizer consist of a transformation that
109   converts raw timer values (expressed in the timer unit)
110   to normalized values, expressed in picoseconds.
111 */
112 struct time_normalizer {
113   /**
114     Get a time normalizer for the statement timer.
115     @return the normalizer for the timer
116   */
117   static time_normalizer *get_idle();
118   static time_normalizer *get_wait();
119   static time_normalizer *get_stage();
120   static time_normalizer *get_statement();
121   static time_normalizer *get_transaction();
122 
123   /** Timer value at server startup. */
124   ulonglong m_v0;
125   /** Conversion factor from timer values to pico seconds. */
126   ulonglong m_factor;
127   /** Histogram bucket timers, expressed in timer unit. */
128   ulonglong m_bucket_timer[NUMBER_OF_BUCKETS + 1];
129 
130   /**
131     Convert a wait from timer units to pico seconds.
132     @param wait a wait, expressed in timer units
133     @return the wait, expressed in pico seconds
134   */
wait_to_picotime_normalizer135   inline ulonglong wait_to_pico(ulonglong wait) { return wait * m_factor; }
136 
137   /**
138     Convert a time from timer units to pico seconds.
139     @param t a time, expressed in timer units
140     @return the time, expressed in pico seconds
141   */
time_to_picotime_normalizer142   inline ulonglong time_to_pico(ulonglong t) {
143     return (t == 0 ? 0 : (t - m_v0) * m_factor);
144   }
145 
146   /**
147     Convert start / end times from timer units to pico seconds.
148     @param start start time, expressed in timer units
149     @param end end time, expressed in timer units
150     @param[out] pico_start start time, expressed in pico seconds
151     @param[out] pico_end end time, expressed in pico seconds
152     @param[out] pico_wait wait time, expressed in pico seconds
153   */
154   void to_pico(ulonglong start, ulonglong end, ulonglong *pico_start,
155                ulonglong *pico_end, ulonglong *pico_wait);
156 
157   ulong bucket_index(ulonglong t);
158 };
159 
160 /**
161   Timer information data.
162   Characteristics about each supported timer.
163 */
164 extern MY_TIMER_INFO pfs_timer_info;
165 
166 /** Initialize the timer component. */
167 void init_timers();
168 
169 #endif
170