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 COMPONENTS_SERVICES_PSI_MUTEX_BITS_H
24 #define COMPONENTS_SERVICES_PSI_MUTEX_BITS_H
25 
26 /**
27   @file
28   Instrumentation helpers for mutexes.
29   This header file provides the necessary declarations
30   to use the mutex API with the performance schema instrumentation.
31   In some compilers (SunStudio), 'static inline' functions, when declared
32   but not used, are not optimized away (because they are unused) by default,
33   so that including a static inline function from a header file does
34   create unwanted dependencies, causing unresolved symbols at link time.
35   Other compilers, like gcc, optimize these dependencies by default.
36 */
37 
38 /**
39   @defgroup psi_abi_mutex Mutex Instrumentation (ABI)
40   @ingroup psi_abi
41   @{
42 */
43 
44 /**
45   Instrumented mutex key.
46   To instrument a mutex, a mutex key must be obtained using @c register_mutex.
47   Using a zero key always disable the instrumentation.
48 */
49 typedef unsigned int PSI_mutex_key;
50 
51 /**
52   @def PSI_MUTEX_VERSION_1
53   Performance Schema Mutex Interface number for version 1.
54   This version is supported.
55 */
56 #define PSI_MUTEX_VERSION_1 1
57 
58 /**
59   @def PSI_CURRENT_MUTEX_VERSION
60   Performance Schema Mutex Interface number for the most recent version.
61   The most current version is @c PSI_MUTEX_VERSION_1
62 */
63 #define PSI_CURRENT_MUTEX_VERSION 1
64 
65 /**
66   Mutex information.
67   @since PSI_MUTEX_VERSION_1
68   This structure is used to register an instrumented mutex.
69 */
70 struct PSI_mutex_info_v1 {
71   /**
72     Pointer to the key assigned to the registered mutex.
73   */
74   PSI_mutex_key *m_key;
75   /**
76     The name of the mutex to register.
77   */
78   const char *m_name;
79   /**
80     The flags of the mutex to register.
81     @sa PSI_FLAG_SINGLETON
82   */
83   unsigned int m_flags;
84   /** Volatility index. */
85   int m_volatility;
86   /** Documentation. */
87   const char *m_documentation;
88 };
89 
90 /**
91   Interface for an instrumented mutex.
92   This is an opaque structure.
93 */
94 struct PSI_mutex;
95 typedef struct PSI_mutex PSI_mutex;
96 
97 /**
98   Interface for an instrumented mutex operation.
99   This is an opaque structure.
100 */
101 struct PSI_mutex_locker;
102 typedef struct PSI_mutex_locker PSI_mutex_locker;
103 
104 /** Operation performed on an instrumented mutex. */
105 enum PSI_mutex_operation {
106   /** Lock. */
107   PSI_MUTEX_LOCK = 0,
108   /** Lock attempt. */
109   PSI_MUTEX_TRYLOCK = 1
110 };
111 typedef enum PSI_mutex_operation PSI_mutex_operation;
112 
113 /**
114   State data storage for @c start_mutex_wait_v1_t.
115   This structure provide temporary storage to a mutex locker.
116   The content of this structure is considered opaque,
117   the fields are only hints of what an implementation
118   of the psi interface can use.
119   This memory is provided by the instrumented code for performance reasons.
120   @sa start_mutex_wait_v1_t
121 */
122 struct PSI_mutex_locker_state_v1 {
123   /** Internal state. */
124   unsigned int m_flags;
125   /** Current operation. */
126   enum PSI_mutex_operation m_operation;
127   /** Current mutex. */
128   struct PSI_mutex *m_mutex;
129   /** Current thread. */
130   struct PSI_thread *m_thread;
131   /** Timer start. */
132   unsigned long long m_timer_start{0};
133   /** Timer function. */
134   unsigned long long (*m_timer)(void);
135   /** Internal data. */
136   void *m_wait{nullptr};
137 };
138 typedef struct PSI_mutex_locker_state_v1 PSI_mutex_locker_state_v1;
139 
140 /**
141   Mutex registration API.
142   @param category a category name (typically a plugin name)
143   @param info an array of mutex info to register
144   @param count the size of the info array
145 */
146 typedef void (*register_mutex_v1_t)(const char *category,
147                                     struct PSI_mutex_info_v1 *info, int count);
148 
149 /**
150   Mutex instrumentation initialization API.
151   @param key the registered mutex key
152   @param identity the address of the mutex itself
153   @return an instrumented mutex
154 */
155 typedef struct PSI_mutex *(*init_mutex_v1_t)(PSI_mutex_key key,
156                                              const void *identity);
157 
158 /**
159   Mutex instrumentation destruction API.
160   @param mutex the mutex to destroy
161 */
162 typedef void (*destroy_mutex_v1_t)(struct PSI_mutex *mutex);
163 
164 /**
165   Record a mutex instrumentation unlock event.
166   @param mutex the mutex instrumentation
167 */
168 typedef void (*unlock_mutex_v1_t)(struct PSI_mutex *mutex);
169 
170 /**
171   Record a mutex instrumentation wait start event.
172   @param state data storage for the locker
173   @param mutex the instrumented mutex to lock
174   @param op the operation to perform
175   @param src_file the source file name
176   @param src_line the source line number
177   @return a mutex locker, or NULL
178 */
179 typedef struct PSI_mutex_locker *(*start_mutex_wait_v1_t)(
180     struct PSI_mutex_locker_state_v1 *state, struct PSI_mutex *mutex,
181     enum PSI_mutex_operation op, const char *src_file, unsigned int src_line);
182 
183 /**
184   Record a mutex instrumentation wait end event.
185   @param locker a thread locker for the running thread
186   @param rc the wait operation return code
187 */
188 typedef void (*end_mutex_wait_v1_t)(struct PSI_mutex_locker *locker, int rc);
189 
190 typedef struct PSI_mutex_info_v1 PSI_mutex_info_v1;
191 typedef PSI_mutex_info_v1 PSI_mutex_info;
192 typedef struct PSI_mutex_locker_state_v1 PSI_mutex_locker_state;
193 
194 /** @} (end of group psi_abi_mutex) */
195 
196 #endif /* COMPONENTS_SERVICES_PSI_MUTEX_BITS_H */
197