MySQL 8.4.0
Source Code Documentation
sync0policy.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 2012, 2024, Oracle and/or its affiliates.
4
5This program is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License, version 2.0, as published by the
7Free Software Foundation.
8
9This program is designed to work with certain software (including
10but not limited to OpenSSL) that is licensed under separate terms,
11as designated in a particular file or component or in included license
12documentation. The authors of MySQL hereby grant you an additional
13permission to link the program and your derivative works with the
14separately licensed software that they have either included with
15the program or referenced in the documentation.
16
17This program is distributed in the hope that it will be useful, but WITHOUT
18ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
20for more details.
21
22You should have received a copy of the GNU General Public License along with
23this program; if not, write to the Free Software Foundation, Inc.,
2451 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25
26*****************************************************************************/
27
28/** @file include/sync0policy.h
29 Policies for mutexes.
30
31 Created 2012-08-21 Sunny Bains.
32 ***********************************************************************/
33
34#ifndef sync0policy_h
35#define sync0policy_h
36
37#include <string>
38#include <thread>
39
40#include "srv0mon.h"
41#include "sync0types.h"
42#include "univ.i"
43#include "ut0rnd.h"
44
45#ifndef UNIV_LIBRARY
46#ifdef UNIV_DEBUG
47
48constexpr uint32_t MUTEX_MAGIC_N{0xb251b04bU};
49
50template <typename Mutex>
52 public:
53 /** For passing context to SyncDebug */
54 struct Context : public latch_t {
55 /** Constructor */
57 : m_mutex(), m_filename(), m_line(), m_thread_id(std::thread::id{}) {
58 /* No op */
59 }
60
61 /** Create the context for SyncDebug
62 @param[in] id ID of the latch to track */
63 Context(latch_id_t id) : latch_t(id) { /* No op */
64 }
65
66 /** Set to locked state
67 @param[in] mutex The mutex to acquire
68 @param[in] filename File name from where to acquire
69 @param[in] line Line number in filename */
70 void locked(const Mutex *mutex, const char *filename,
71 ulint line) UNIV_NOTHROW {
72 m_mutex = mutex;
73
75
77
78 m_line = line;
79 }
80
81 /** Reset to unlock state */
83 m_mutex = nullptr;
84
86
87 m_filename = nullptr;
88
90 }
91
92 /** Print information about the latch
93 @return the string representation */
94 std::string to_string() const override UNIV_NOTHROW {
96
97 msg << m_mutex->policy().to_string();
98
100 msg << " addr: " << m_mutex << " acquired: " << locked_from().c_str();
101
102 } else {
103 msg << "Not locked";
104 }
105
106 return (msg.str());
107 }
108
109 /** @return the name of the file and line number in the file
110 from where the mutex was acquired "filename:line" */
111 virtual std::string locked_from() const override {
113
114 msg << sync_basename(m_filename) << ":" << m_line;
115
116 return (std::string(msg.str()));
117 }
118
119 /** Mutex to check for lock order violation */
120 const Mutex *m_mutex;
121
122 /** Filename from where enter was called */
123 const char *m_filename;
124
125 /** Line number in filename */
127
128 /** Thread ID of the thread that own(ed) the mutex */
130 };
131
132 /** Constructor. */
134 }
135
136 /* Destructor */
137 virtual ~MutexDebug() = default;
138
139 /** Mutex is being destroyed. */
143
144 m_magic_n = 0;
145
147 }
148
149 /** Called when the mutex is "created". Note: Not from the constructor
150 but when the mutex is initialised.
151 @param[in] id Mutex ID */
153
154 /** Called when an attempt is made to lock the mutex
155 @param[in] mutex Mutex instance to be locked
156 @param[in] filename Filename from where it was called
157 @param[in] line Line number from where it was called */
158 void enter(const Mutex *mutex, const char *filename, ulint line) UNIV_NOTHROW;
159
160 /** Called when the mutex is locked
161 @param[in] mutex Mutex instance that was locked
162 @param[in] filename Filename from where it was called
163 @param[in] line Line number from where it was called */
164 void locked(const Mutex *mutex, const char *filename,
165 ulint line) UNIV_NOTHROW;
166
167 /** Called when the mutex is released
168 @param[in] mutex Mutex that was released */
169 void release(const Mutex *mutex) UNIV_NOTHROW;
170
171 /** @return true if thread owns the mutex */
172 bool is_owned() const UNIV_NOTHROW {
174 }
175
176 /** @return the name of the file from the mutex was acquired */
177 const char *get_enter_filename() const UNIV_NOTHROW {
178 return m_context.m_filename;
179 }
180
181 /** @return the name of the file from the mutex was acquired */
183
184 /** @return id of the thread that was trying to acquire the mutex */
186 return m_context.m_thread_id;
187 }
188
189 /** Magic number to check for memory corruption. */
190 uint32_t m_magic_n;
191
192 /** Latch state of the mutex owner */
194};
195#endif /* UNIV_DEBUG */
196
197/* Do nothing */
198template <typename Mutex>
199struct NoPolicy {
200 /** Default constructor. */
201 NoPolicy() = default;
202
203 void init(const Mutex &, latch_id_t, const char *, uint32_t) UNIV_NOTHROW {}
205 void enter(const Mutex &, const char *, ulint line) UNIV_NOTHROW {}
206 void add(uint32_t, uint32_t) UNIV_NOTHROW {}
207 void locked(const Mutex &, const char *, ulint) UNIV_NOTHROW {}
208 void release(const Mutex &) UNIV_NOTHROW {}
209 std::string to_string() const { return (""); }
211};
212
213/** Collect the metrics per mutex instance, no aggregation. */
214template <typename Mutex>
216#ifdef UNIV_DEBUG
217 : public MutexDebug<Mutex>
218#endif /* UNIV_DEBUG */
219{
220 public:
221 typedef Mutex MutexType;
222
223 /** Constructor. */
225#ifdef UNIV_DEBUG
227#endif /* UNIV_DEBUG */
228 m_count(),
229 m_id() {
230 }
231
232 /** Destructor */
233 ~GenericPolicy() = default;
234
235 /** Called when the mutex is "created". Note: Not from the constructor
236 but when the mutex is initialised.
237 @param[in] mutex Mutex instance to track
238 @param[in] id Mutex ID
239 @param[in] filename File where mutex was created
240 @param[in] line Line in filename */
241 void init(const MutexType &mutex [[maybe_unused]], latch_id_t id,
242 const char *filename, uint32_t line) UNIV_NOTHROW {
243 m_id = id;
244
246
247 ut_ad(meta.get_id() == id);
248
249 meta.get_counter()->single_register(&m_count);
250
252
254 }
255
256 /** Called when the mutex is destroyed. */
259
260 meta.get_counter()->single_deregister(&m_count);
261
263
265 }
266
267 /** Called after a successful mutex acquire.
268 @param[in] n_spins Number of times the thread did
269 spins while trying to acquire the mutex
270 @param[in] n_waits Number of times the thread waited
271 in some type of OS queue */
272 void add(uint32_t n_spins, uint32_t n_waits) UNIV_NOTHROW {
273 /* Currently global on/off. Keeps things simple and fast */
274
275 if (!m_count.m_enabled) {
276 return;
277 }
278
279 m_count.m_spins += n_spins;
280 m_count.m_waits += n_waits;
281
282 ++m_count.m_calls;
283 }
284
285 /** Called when an attempt is made to lock the mutex
286 @param[in] mutex Mutex instance to be locked
287 @param[in] filename Filename from where it was called
288 @param[in] line Line number from where it was called */
289 void enter(const MutexType &IF_DEBUG(mutex), const char *IF_DEBUG(filename),
292 }
293
294 /** Called when the mutex is locked
295 @param[in] mutex Mutex instance that is locked
296 @param[in] filename Filename from where it was called
297 @param[in] line Line number from where it was called */
298 void locked(const MutexType &IF_DEBUG(mutex), const char *IF_DEBUG(filename),
301 }
302
303 /** Called when the mutex is released
304 @param[in] mutex Mutex instance that is released */
307 }
308
309 /** Print the information about the latch
310 @return the string representation */
311 std::string print() const UNIV_NOTHROW;
312
313 /** @return the latch ID */
314 latch_id_t get_id() const UNIV_NOTHROW { return (m_id); }
315
316 /** @return the string representation */
317 std::string to_string() const;
318
319 private:
321
322 /** The user visible counters, registered with the meta-data. */
323 Counter::Count m_count;
324
325 /** Latch meta data ID */
327};
328
329/** Track aggregate metrics policy, used by the page mutex. There are just
330too many of them to count individually. */
331template <typename Mutex>
333#ifdef UNIV_DEBUG
334 : public MutexDebug<Mutex>
335#endif /* UNIV_DEBUG */
336{
337 public:
338 typedef Mutex MutexType;
339 typedef typename latch_meta_t::CounterType::Count Count;
340
341 /** Default constructor. */
343 :
344#ifdef UNIV_DEBUG
346#endif /* UNIV_DEBUG */
347 m_count(),
348 m_id() {
349 /* Do nothing */
350 }
351
352 /** Destructor */
353 ~BlockMutexPolicy() = default;
354
355 /** Called when the mutex is "created". Note: Not from the constructor
356 but when the mutex is initialised.
357 @param[in] mutex Mutex instance to track
358 @param[in] id Mutex ID
359 @param[in] filename File where mutex was created
360 @param[in] line Line in filename */
361 void init(const MutexType &mutex [[maybe_unused]], latch_id_t id,
362 const char *filename [[maybe_unused]],
363 uint32_t line [[maybe_unused]]) UNIV_NOTHROW {
364 /* It can be LATCH_ID_BUF_BLOCK_MUTEX or
365 LATCH_ID_BUF_POOL_ZIP. Unfortunately, they
366 are mapped to the same mutex type in the
367 buffer pool code. */
368
369 m_id = id;
370
372
373 ut_ad(meta.get_id() == id);
374
375 m_count = meta.get_counter()->sum_register();
376
378 }
379
380 /** Called when the mutex is destroyed. */
383
384 ut_ad(meta.get_id() == m_id);
385
386 meta.get_counter()->sum_deregister(m_count);
387
388 m_count = nullptr;
389
391 }
392
393 /** Called after a successful mutex acquire.
394 @param[in] n_spins Number of times the thread did
395 spins while trying to acquire the mutex
396 @param[in] n_waits Number of times the thread waited
397 in some type of OS queue */
398 void add(uint32_t n_spins, uint32_t n_waits) UNIV_NOTHROW {
399 if (!m_count->m_enabled) {
400 return;
401 }
402
403 m_count->m_spins += n_spins;
404 m_count->m_waits += n_waits;
405
406 ++m_count->m_calls;
407 }
408
409 /** Called when the mutex is locked
410 @param[in] mutex Mutex instance that is locked
411 @param[in] filename Filename from where it was called
412 @param[in] line Line number from where it was called */
413 void locked(const MutexType &IF_DEBUG(mutex), const char *IF_DEBUG(filename),
416 }
417
418 /** Called when the mutex is released
419 @param[in] mutex Mutex instance that is released */
422 }
423
424 /** Called when an attempt is made to lock the mutex
425 @param[in] mutex Mutex instance to be locked
426 @param[in] filename Filename from where it was called
427 @param[in] line Line number from where it was called */
428 void enter(const MutexType &IF_DEBUG(mutex), const char *IF_DEBUG(filename),
431 }
432
433 /** Print the information about the latch
434 @return the string representation */
435 std::string print() const UNIV_NOTHROW;
436
437 /** @return the latch ID */
438 latch_id_t get_id() const { return (m_id); }
439
440 /** @return the string representation */
441 std::string to_string() const;
442
443 private:
445
446 /** The user visible counters, registered with the meta-data. */
447 Counter::Count *m_count;
448
449 /** Latch meta data ID */
451};
452
453#include "sync0policy.ic"
454
455#endif /* !UNIV_LIBRARY */
456#endif /* sync0policy_h */
Track aggregate metrics policy, used by the page mutex.
Definition: sync0policy.h:336
void init(const MutexType &mutex, latch_id_t id, const char *filename, uint32_t line) 1
Called when the mutex is "created".
Definition: sync0policy.h:361
latch_meta_t::CounterType Counter
Definition: sync0policy.h:444
void locked(const MutexType &mutex, const char *filename, ulint line) 1
Called when the mutex is locked.
Definition: sync0policy.h:413
void add(uint32_t n_spins, uint32_t n_waits) 1
Called after a successful mutex acquire.
Definition: sync0policy.h:398
void destroy() 1
Called when the mutex is destroyed.
Definition: sync0policy.h:381
std::string to_string() const
Definition: sync0policy.ic:42
std::string print() const 1
Print the information about the latch.
latch_meta_t::CounterType::Count Count
Definition: sync0policy.h:339
void enter(const MutexType &mutex, const char *filename, ulint line) 1
Called when an attempt is made to lock the mutex.
Definition: sync0policy.h:428
Counter::Count * m_count
The user visible counters, registered with the meta-data.
Definition: sync0policy.h:447
void release(const MutexType &mutex) 1
Called when the mutex is released.
Definition: sync0policy.h:420
Mutex MutexType
Definition: sync0policy.h:338
BlockMutexPolicy()
Default constructor.
Definition: sync0policy.h:342
~BlockMutexPolicy()=default
Destructor.
latch_id_t m_id
Latch meta data ID.
Definition: sync0policy.h:450
latch_id_t get_id() const
Definition: sync0policy.h:438
Latch meta data.
Definition: sync0types.h:773
Counter * get_counter()
Definition: sync0types.h:847
Counter CounterType
Definition: sync0types.h:775
latch_id_t get_id() const
Definition: sync0types.h:830
Definition: sync0policy.h:51
const char * get_enter_filename() const 1
Definition: sync0policy.h:177
bool is_owned() const 1
Definition: sync0policy.h:172
ulint get_enter_line() const 1
Definition: sync0policy.h:182
uint32_t m_magic_n
Magic number to check for memory corruption.
Definition: sync0policy.h:190
std::thread::id get_thread_id() const 1
Definition: sync0policy.h:185
void destroy() 1
Mutex is being destroyed.
Definition: sync0policy.h:140
Context m_context
Latch state of the mutex owner.
Definition: sync0policy.h:193
void enter(const Mutex *mutex, const char *filename, ulint line) 1
Called when an attempt is made to lock the mutex.
Definition: sync0policy.ic:61
void release(const Mutex *mutex) 1
Called when the mutex is released.
Definition: sync0policy.ic:87
void locked(const Mutex *mutex, const char *filename, ulint line) 1
Called when the mutex is locked.
Definition: sync0policy.ic:76
void init(latch_id_t id) 1
Called when the mutex is "created".
Definition: sync0policy.ic:52
MutexDebug()
Constructor.
Definition: sync0policy.h:133
Definition: gcs_xcom_synode.h:64
pid_type get_id()
Definition: process.h:48
std::basic_ostringstream< char, std::char_traits< char >, ut::allocator< char > > ostringstream
Specialization of basic_ostringstream which uses ut::allocator.
Definition: ut0new.h:2870
const char * filename
Definition: pfs_example_component_population.cc:67
Server monitor counter related defines.
Collect the metrics per mutex instance, no aggregation.
Definition: sync0policy.h:219
void locked(const MutexType &mutex, const char *filename, ulint line) 1
Called when the mutex is locked.
Definition: sync0policy.h:298
void destroy() 1
Called when the mutex is destroyed.
Definition: sync0policy.h:257
std::string print() const 1
Print the information about the latch.
~GenericPolicy()=default
Destructor.
latch_id_t get_id() const 1
Definition: sync0policy.h:314
void enter(const MutexType &mutex, const char *filename, ulint line) 1
Called when an attempt is made to lock the mutex.
Definition: sync0policy.h:289
Counter::Count m_count
The user visible counters, registered with the meta-data.
Definition: sync0policy.h:323
void add(uint32_t n_spins, uint32_t n_waits) 1
Called after a successful mutex acquire.
Definition: sync0policy.h:272
void release(const MutexType &mutex) 1
Called when the mutex is released.
Definition: sync0policy.h:305
latch_id_t m_id
Latch meta data ID.
Definition: sync0policy.h:326
Mutex MutexType
Definition: sync0policy.h:221
std::string to_string() const
Definition: sync0policy.ic:37
latch_meta_t::CounterType Counter
Definition: sync0policy.h:320
void init(const MutexType &mutex, latch_id_t id, const char *filename, uint32_t line) 1
Called when the mutex is "created".
Definition: sync0policy.h:241
GenericPolicy() 1
Constructor.
Definition: sync0policy.h:224
For passing context to SyncDebug.
Definition: sync0policy.h:54
std::thread::id m_thread_id
Thread ID of the thread that own(ed) the mutex.
Definition: sync0policy.h:129
std::string to_string() const override 1
Print information about the latch.
Definition: sync0policy.h:94
virtual std::string locked_from() const override
Definition: sync0policy.h:111
Context()
Constructor.
Definition: sync0policy.h:56
void release() 1
Reset to unlock state.
Definition: sync0policy.h:82
const Mutex * m_mutex
Mutex to check for lock order violation.
Definition: sync0policy.h:120
ulint m_line
Line number in filename.
Definition: sync0policy.h:126
Context(latch_id_t id)
Create the context for SyncDebug.
Definition: sync0policy.h:63
void locked(const Mutex *mutex, const char *filename, ulint line) 1
Set to locked state.
Definition: sync0policy.h:70
const char * m_filename
Filename from where enter was called.
Definition: sync0policy.h:123
Definition: sync0policy.h:199
std::string to_string() const
Definition: sync0policy.h:209
void add(uint32_t, uint32_t) 1
Definition: sync0policy.h:206
void init(const Mutex &, latch_id_t, const char *, uint32_t) 1
Definition: sync0policy.h:203
void enter(const Mutex &, const char *, ulint line) 1
Definition: sync0policy.h:205
NoPolicy()=default
Default constructor.
latch_id_t get_id() const
void release(const Mutex &) 1
Definition: sync0policy.h:208
void destroy() 1
Definition: sync0policy.h:204
void locked(const Mutex &, const char *, ulint) 1
Definition: sync0policy.h:207
All (ordered) latches, used in debugging, must derive from this class.
Definition: sync0types.h:962
constexpr uint32_t MUTEX_MAGIC_N
Definition: sync0policy.h:48
Policy for mutexes.
Global types for sync.
void sync_file_created_register(const void *ptr, const char *filename, uint16_t line)
Register a latch, called when it is created.
Definition: sync0debug.cc:1646
latch_meta_t & sync_latch_get_meta(latch_id_t id)
Get the latch meta-data from the latch ID.
Definition: sync0types.h:883
latch_id_t
Each latch has an ID.
Definition: sync0types.h:343
const char * sync_basename(const char *filename)
Print the filename "basename".
Definition: sync0sync.cc:218
void sync_file_created_deregister(const void *ptr)
Deregister a latch, called when it is destroyed.
Definition: sync0debug.cc:1653
Version control for database, common definitions, and include files.
#define IF_DEBUG(...)
Definition: univ.i:674
#define UNIV_NOTHROW
Definition: univ.i:456
unsigned long int ulint
Definition: univ.i:406
constexpr ulint ULINT_UNDEFINED
The 'undefined' value for a ulint.
Definition: univ.i:420
#define ut_ad(EXPR)
Debug assertion.
Definition: ut0dbg.h:105
#define ut_d(EXPR)
Debug statement.
Definition: ut0dbg.h:107
Random numbers and hashing.
unsigned long id[MAX_DEAD]
Definition: xcom_base.cc:510