MySQL 8.4.2
Source Code Documentation
sync0rw.h
Go to the documentation of this file.
1/*****************************************************************************
2
3Copyright (c) 1995, 2024, Oracle and/or its affiliates.
4Copyright (c) 2008, Google Inc.
5
6Portions of this file contain modifications contributed and copyrighted by
7Google, Inc. Those modifications are gratefully acknowledged and are described
8briefly in the InnoDB documentation. The contributions by Google are
9incorporated with their permission, and subject to the conditions contained in
10the file COPYING.Google.
11
12This program is free software; you can redistribute it and/or modify it under
13the terms of the GNU General Public License, version 2.0, as published by the
14Free Software Foundation.
15
16This program is designed to work with certain software (including
17but not limited to OpenSSL) that is licensed under separate terms,
18as designated in a particular file or component or in included license
19documentation. The authors of MySQL hereby grant you an additional
20permission to link the program and your derivative works with the
21separately licensed software that they have either included with
22the program or referenced in the documentation.
23
24This program is distributed in the hope that it will be useful, but WITHOUT
25ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
26FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
27for more details.
28
29You should have received a copy of the GNU General Public License along with
30this program; if not, write to the Free Software Foundation, Inc.,
3151 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
32
33*****************************************************************************/
34
35/** @file include/sync0rw.h
36 The read-write lock (for threads, not for database transactions)
37
38 Created 9/11/1995 Heikki Tuuri
39 *******************************************************/
40
41#ifndef sync0rw_h
42#define sync0rw_h
43
44#include <atomic>
45#include <cstdint>
46
47#include "univ.i"
48#ifndef UNIV_HOTBACKUP
49#include "os0event.h"
50#include "ut0counter.h"
51#endif /* !UNIV_HOTBACKUP */
52#include <atomic>
53#include "ut0mutex.h"
54
55struct rw_lock_t;
56
57#ifndef UNIV_HOTBACKUP
58
59#ifdef UNIV_LIBRARY
60
61#ifdef UNIV_DEBUG
62
63/**
64Pass-through version of rw_lock_own(), which normally checks that the
65thread has locked the rw-lock in the specified mode.
66@param[in] lock pointer to rw-lock
67@param[in] lock_type lock type: RW_LOCK_S, RW_LOCK_X
68@return true if success */
69static inline bool rw_lock_own(rw_lock_t *lock, ulint lock_type) {
70 return (lock != nullptr);
71}
72
73#define sync_check_iterate(A) true
74#endif /* UNIV_DEBUG */
75
76#define rw_lock_s_lock(L, Loc) ((void)0)
77#define rw_lock_s_lock_nowait(L, Loc) true
78#define rw_lock_s_unlock(L) ((void)0)
79#define rw_lock_x_lock(L, Loc) ((void)0)
80#define rw_lock_x_lock_nowait(L, Loc) true
81#define rw_lock_x_unlock(L) ((void)0)
82#define rw_lock_sx_lock(L, Loc) ((void)0)
83#define rw_lock_sx_unlock(L) ((void)0)
84#define rw_lock_s_lock_gen(M, P, L) ((void)0)
85#define rw_lock_x_lock_gen(M, P, L) ((void)0)
86#define rw_lock_sx_lock_gen(M, P, L) ((void)0)
87#define sync_check_lock(A, B) ((void)0)
88#define rw_lock_own_flagged(A, B) true
89#endif /* UNIV_LIBRARY */
90
91#endif /* !UNIV_HOTBACKUP */
92
93/* Latch types; these are used also in btr0btr.h and mtr0mtr.h: keep the
94numerical values smaller than 30 (smaller than BTR_MODIFY_TREE and
95MTR_MEMO_MODIFY) and the order of the numerical values like below! and they
96should be 2pow value to be used also as ORed combination of flag. */
101 RW_NO_LATCH = 8
103
104/* We decrement lock_word by X_LOCK_DECR for each x_lock. It is also the
105start value for the lock_word, meaning that it limits the maximum number
106of concurrent read locks before the rw_lock breaks. */
107/* We decrement lock_word by X_LOCK_HALF_DECR for sx_lock. */
108constexpr int32_t X_LOCK_DECR = 0x20000000;
109constexpr int32_t X_LOCK_HALF_DECR = 0x10000000;
110
111#ifdef UNIV_DEBUG
112struct rw_lock_debug_t;
113#endif /* UNIV_DEBUG */
114
115extern ib_mutex_t rw_lock_list_mutex;
116
117#ifndef UNIV_LIBRARY
118#ifndef UNIV_HOTBACKUP
119
120/** Creates, or rather, initializes an rw-lock object in a specified memory
121 location (which must be appropriately aligned). The rw-lock is initialized
122 to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free
123 is necessary only if the memory block containing it is freed.
124 @param[in] lock pointer to memory
125 @param[in] id latch_id
126 @param[in] clocation location where created */
128 IF_DEBUG(latch_id_t id, ) ut::Location clocation);
129/** Calling this function is obligatory only if the memory buffer containing
130 the rw-lock is freed. Removes an rw-lock object from the global list. The
131 rw-lock is checked to be in the non-locked state. */
132void rw_lock_free_func(rw_lock_t *lock); /*!< in/out: rw-lock */
133#ifdef UNIV_DEBUG
134/** Checks that the rw-lock has been initialized and that there are no
135 simultaneous shared and exclusive locks.
136 @return true */
137[[nodiscard]] bool rw_lock_validate(const rw_lock_t *lock); /*!< in: rw-lock */
138#endif /* UNIV_DEBUG */
139
140/** Low-level function which tries to lock an rw-lock in s-mode. Performs no
141spinning.
142@param[in] lock pointer to rw-lock
143@param[in] pass pass value; != 0, if the lock will be passed
144 to another thread to unlock
145@param[in] location location where requested
146@return true if success */
147[[nodiscard]] static inline bool rw_lock_s_lock_low(rw_lock_t *lock,
148 ulint pass [[maybe_unused]],
150
151/** NOTE! Use the corresponding macro, not directly this function, except if
152you supply the file name and line number. Lock an rw-lock in shared mode for
153the current thread. If the rw-lock is locked in exclusive mode, or there is an
154exclusive lock request waiting, the function spins a preset time (controlled
155by srv_n_spin_wait_rounds), waiting for the lock, before suspending the thread.
156@param[in] lock pointer to rw-lock
157@param[in] pass pass value; != 0, if the lock will be passed to
158 another thread to unlock
159@param[in] location location where requested */
162
163/** NOTE! Use the corresponding macro, not directly this function! Lock an
164rw-lock in exclusive mode for the current thread if the lock can be obtained
165immediately.
166@param[in] lock pointer to rw-lock
167@param[in] location location where requested
168@return true if success */
169[[nodiscard]] static inline bool rw_lock_x_lock_func_nowait(
171
172/** Releases a shared mode lock.
173@param[in] pass pass value; != 0, if the lock will be passed to another
174 thread to unlock
175@param[in,out] lock rw-lock */
177 rw_lock_t *lock);
178
179/** NOTE! Use the corresponding macro, not directly this function! Lock an
180rw-lock in exclusive mode for the current thread. If the rw-lock is locked
181in shared or exclusive mode, or there is an exclusive lock request waiting,
182the function spins a preset time (controlled by srv_n_spin_wait_rounds),
183waiting for the lock, before suspending the thread. If the same thread has an
184x-lock on the rw-lock, locking succeed, with the following exception: if pass
185!= 0, only a single x-lock may be taken on the lock. NOTE: If the same thread
186has an s-lock, locking does not succeed!
187@param[in] lock pointer to rw-lock
188@param[in] pass pass value; != 0, if the lock will be passed to
189 another thread to unlock
190@param[in] location location where requested */
192
193/** Low-level function for acquiring an sx lock.
194@param[in] lock pointer to rw-lock
195@param[in] pass pass value; != 0, if the lock will be passed to
196 another thread to unlock
197@param[in] location location where requested
198@return false if did not succeed, true if success. */
199[[nodiscard]] bool rw_lock_sx_lock_low(rw_lock_t *lock, ulint pass,
201/** NOTE! Use the corresponding macro, not directly this function! Lock an
202rw-lock in SX mode for the current thread. If the rw-lock is locked
203in exclusive mode, or there is an exclusive lock request waiting,
204the function spins a preset time (controlled by SYNC_SPIN_ROUNDS), waiting
205for the lock, before suspending the thread. If the same thread has an x-lock
206on the rw-lock, locking succeed, with the following exception: if pass != 0,
207only a single sx-lock may be taken on the lock. NOTE: If the same thread has
208an s-lock, locking does not succeed!
209@param[in] lock pointer to rw-lock
210@param[in] pass pass value; != 0, if the lock will be passed to
211 another thread to unlock
212@param[in] location location where requested */
214
215/** Releases an exclusive mode lock.
216@param[in] pass pass value; != 0, if the lock will be passed to another
217 thread to unlock
218@param[in,out] lock rw-lock */
220 rw_lock_t *lock);
221
222/** Releases an sx mode lock.
223@param[in] pass pass value; != 0, if the lock will be passed to another
224 thread to unlock
225@param[in,out] lock rw-lock */
227 rw_lock_t *lock);
228
229/** This function is used in the insert buffer to move the ownership of an
230x-latch on a buffer frame to the current thread. The x-latch was set by
231the buffer read operation and it protected the buffer frame while the
232read was done. The ownership is moved because we want that the current
233thread is able to acquire a second x-latch which is stored in an mtr.
234This, in turn, is needed to pass the debug checks of index page
235operations.
236@param[in] lock lock which was x-locked in the buffer read. */
238/** Returns the value of writer_count for the lock. Does not reserve the lock
239mutex, so the caller must be sure it is not changed during the call.
240@return value of writer_count
241@param[in] lock rw-lock */
243/** Returns the number of sx-lock for the lock. Does not reserve the lock
244mutex, so the caller must be sure it is not changed during the call.
245@param[in] lock rw-lock
246@return value of writer_count */
248/** Check if there are threads waiting for the rw-lock.
249@param[in] lock rw-lock
250@return true if waiters, false otherwise */
251[[nodiscard]] static inline bool rw_lock_get_waiters(const rw_lock_t *lock);
252/** Returns the write-status of the lock - this function made more sense
253with the old rw_lock implementation.
254@param[in] lock rw-lock
255@return RW_LOCK_NOT_LOCKED, RW_LOCK_X, RW_LOCK_X_WAIT, RW_LOCK_SX */
257/** Returns the number of readers (s-locks).
258@param[in] lock rw-lock
259@return number of readers */
261
262/** Decrements lock_word the specified amount if it is greater than 0.
263This is used by both s_lock and x_lock operations.
264@param[in,out] lock rw-lock
265@param[in] amount amount to decrement
266@param[in] threshold threshold of judgement
267@return true if decr occurs */
268[[nodiscard]] static inline bool rw_lock_lock_word_decr(rw_lock_t *lock,
269 ulint amount,
270 lint threshold);
271
272/** Increments lock_word the specified amount and returns new value.
273@param[in,out] lock rw-lock
274@param[in] amount amount to decrement
275@return lock->lock_word after increment */
277
278/** This function sets the lock->writer_thread and lock->recursive fields. Sets
279lock->recursive field using atomic release after setting lock->writer thread to
280ensure proper memory ordering of the two.
281Note that it is assumed that the caller of this function effectively owns
282the lock i.e.: nobody else is allowed to modify lock->writer_thread at this
283point in time. The protocol is that lock->writer_thread MUST be updated BEFORE
284the lock->recursive flag is set.
285@param[in,out] lock lock to work on
286@param[in] recursive true if recursion allowed */
288 bool recursive);
289
290#ifdef UNIV_DEBUG
291/** Checks if the thread has locked the rw-lock in the specified mode, with
292the pass value == 0. Note that the mode is checked exactly, so if the thread
293owns RW_LOCK_X only, the rw_lock_own(..,RW_LOCK_S) will return false.
294@param[in] lock the rw-lock
295@param[in] lock_type The exact lock type to check:
296 RW_LOCK_S, RW_LOCK_SX or RW_LOCK_X
297*/
298[[nodiscard]] bool rw_lock_own(const rw_lock_t *lock, ulint lock_type);
299
300/** Checks if the thread has locked the rw-lock in the specified mode, with the
301pass value == 0.
302@param[in] lock rw-lock
303@param[in] flags specify lock types with OR of the rw_lock_flag_t values
304@return true if locked */
305[[nodiscard]] bool rw_lock_own_flagged(const rw_lock_t *lock,
307#endif /* UNIV_DEBUG */
308#endif /* !UNIV_HOTBACKUP */
309/** Checks if somebody has locked the rw-lock in the specified mode.
310@param[in] lock the rw-lock
311@param[in] lock_type The exact lock type to check:
312 RW_LOCK_S, RW_LOCK_SX or RW_LOCK_X
313@return true if locked */
314[[nodiscard]] bool rw_lock_is_locked(rw_lock_t *lock, ulint lock_type);
315#ifdef UNIV_DEBUG
316/** Prints debug info of currently locked rw-locks.
317@param[in] file file where to print */
319
320/*#####################################################################*/
321
322/** Prints info of a debug struct.
323@param[in] f Output stream
324@param[in] info Debug struct */
325void rw_lock_debug_print(FILE *f, const rw_lock_debug_t *info);
326
327#endif /* UNIV_DEBUG */
328
329#endif /* !UNIV_LIBRARY */
330
331#ifdef UNIV_DEBUG
332/** The structure for storing debug info of an rw-lock. All access to this
333structure must be protected by rw_lock_debug_mutex_enter(). */
335 /** The thread id of the thread which locked the rw-lock. */
337 /** Pass value given in the lock operation. */
339 /** Type of the lock: RW_LOCK_X, RW_LOCK_S, RW_LOCK_X_WAIT. */
341 /** Location where the rw-lock was locked. */
343 /** Debug structs are linked in a two-way list. */
345};
346#endif /* UNIV_DEBUG */
347
348/* NOTE! The structure appears here only for the compiler to know its size.
349Do not use its fields directly! */
350
351/** The structure used in the spin lock implementation of a read-write
352lock. Several threads may have a shared lock simultaneously in this
353lock, but only one writer may have an exclusive lock, in which case no
354shared locks are allowed. To prevent starving of a writer blocked by
355readers, a writer may queue for x-lock by decrementing lock_word: no
356new readers will be let in while the thread waits for readers to
357exit. */
358
360#ifdef UNIV_DEBUG
361 : public latch_t
362#endif /* UNIV_DEBUG */
363{
364 rw_lock_t() = default;
365 /** rw_lock_t is not a copyable object, the reasoning
366 behind this is the same as the reasoning behind why
367 std::mutex is not copyable. It is supposed to represent
368 a synchronization primitive for which copying semantics
369 do not make sense. */
370 rw_lock_t(const rw_lock_t &) = delete;
371 rw_lock_t &operator=(const rw_lock_t &) = delete;
372
373 /** Holds the state of the lock. */
374 std::atomic<int32_t> lock_word;
375
376 /** 1: there are waiters */
377 std::atomic<bool> waiters;
378
379 /** Default value false which means the lock is non-recursive.
380 The value is typically set to true making normal rw_locks recursive.
381 In case of asynchronous IO, when a non-zero value of 'pass' is
382 passed then we keep the lock non-recursive.
383
384 This flag also tells us about the state of writer_thread field.
385 If this flag is set then writer_thread MUST contain the thread
386 id of the current x-holder or wait-x thread. This flag must be
387 reset in x_unlock functions before incrementing the lock_word */
388 std::atomic<bool> recursive;
389
390 /** number of granted SX locks. */
391 std::atomic<uint64_t> sx_recursive;
392
394 auto old_value = sx_recursive.load(std::memory_order_relaxed);
395 auto new_value = old_value - 1;
396 sx_recursive.store(new_value, std::memory_order_relaxed);
397 }
398
400 auto old_value = sx_recursive.load(std::memory_order_relaxed);
401 auto new_value = old_value + 1;
402 sx_recursive.store(new_value, std::memory_order_relaxed);
403 return old_value;
404 }
405
406 /** Thread id of writer thread. Is only guaranteed to have non-stale value if
407 recursive flag is set, otherwise it may contain native thread ID of a
408 thread which already released or passed the lock. */
409 std::atomic<std::thread::id> writer_thread;
410
411 /** XOR of reader threads' IDs. If there is exactly one reader it should allow
412 to retrieve the thread ID of that reader. */
414
415 /** Used by sync0arr.cc for thread queueing */
417
418 /** Event for next-writer to wait on. A thread must decrement
419 lock_word before waiting. */
421
422 /** Location where lock created */
424
425 /** last s-lock file/line is not guaranteed to be correct */
426 const char *last_s_file_name;
427
428 /** File name where last x-locked */
429 const char *last_x_file_name;
430
431 /** If 1 then the rw-lock is a block lock */
433
434 /** Line number where last time s-locked */
435 uint16_t last_s_line;
436
437 /** Line number where last time x-locked */
438 uint16_t last_x_line;
439
440 /** Count of os_waits. May not be accurate */
442
443 /** All allocated rw locks are put into a list */
445
446#ifdef UNIV_PFS_RWLOCK
447 /** The instrumentation hook */
449#endif /* UNIV_PFS_RWLOCK */
450
451#ifndef UNIV_DEBUG
452 /** Destructor */
453 ~rw_lock_t();
454#else
455 /** Destructor */
456 ~rw_lock_t() override;
457
458 virtual std::string to_string() const override;
459 virtual std::string locked_from() const override;
460
461 /** For checking memory corruption. */
462 static const uint32_t MAGIC_N = 22643;
463 uint32_t magic_n = {MAGIC_N};
464
465 /** In the debug version: pointer to the debug info list of the lock */
467
468#endif /* UNIV_DEBUG */
469
470 /** Checks if there is a thread requesting an x-latch waiting for threads to
471 release their s-latches.
472 @return true iff there is an x-latcher blocked by s-latchers. */
474 const auto snapshot = lock_word.load();
475 return snapshot < 0 && -X_LOCK_DECR < snapshot &&
476 snapshot != -X_LOCK_HALF_DECR;
477 }
478};
479
480#ifndef UNIV_LIBRARY
481#ifndef UNIV_HOTBACKUP
482/* For performance schema instrumentation, a new set of rwlock
483wrap functions are created if "UNIV_PFS_RWLOCK" is defined.
484The instrumentations are not planted directly into original
485functions, so that we keep the underlying function as they
486are. And in case, user wants to "take out" some rwlock from
487instrumentation even if performance schema (UNIV_PFS_RWLOCK)
488is defined, they can do so by reinstating APIs directly link to
489original underlying functions.
490The instrumented function names have prefix of "pfs_rw_lock_" vs.
491original name prefix of "rw_lock_". Following are list of functions
492that have been instrumented:
493
494rw_lock_create()
495rw_lock_x_lock()
496rw_lock_x_lock_gen()
497rw_lock_x_lock_nowait()
498rw_lock_x_unlock_gen()
499rw_lock_s_lock()
500rw_lock_s_lock_gen()
501rw_lock_s_lock_nowait()
502rw_lock_s_unlock_gen()
503rw_lock_sx_lock()
504rw_lock_sx_unlock_gen()
505rw_lock_free()
506*/
507
508#ifdef UNIV_PFS_RWLOCK
509/** Performance schema instrumented wrap function for rw_lock_create_func()
510NOTE! Please use the corresponding macro rw_lock_create(), not directly this
511function!
512@param[in] key key registered with performance schema
513@param[in] lock rw lock
514@param[in] id latch_id
515@param[in] clocation location where created */
517 IF_DEBUG(latch_id_t id, )
518 ut::Location clocation);
519
520/** Performance schema instrumented wrap function for rw_lock_x_lock_func()
521NOTE! Please use the corresponding macro rw_lock_x_lock(), not directly this
522function!
523@param[in] lock pointer to rw-lock
524@param[in] pass pass value; != 0, if the lock will be passed
525 to another thread to unlock
526@param[in] location location where requested */
527static inline void pfs_rw_lock_x_lock_func(rw_lock_t *lock, ulint pass,
528 ut::Location location);
529
530/** Performance schema instrumented wrap function for
531rw_lock_x_lock_func_nowait()
532NOTE! Please use the corresponding macro, not directly this function!
533@param[in] lock pointer to rw-lock
534@param[in] location location where requested
535@return true if success */
536[[nodiscard]] static inline bool pfs_rw_lock_x_lock_func_nowait(
537 rw_lock_t *lock, ut::Location location);
538
539/** Performance schema instrumented wrap function for rw_lock_s_lock_func()
540NOTE! Please use the corresponding macro rw_lock_s_lock(), not directly this
541function!
542@param[in] lock pointer to rw-lock
543@param[in] pass pass value; != 0, if the lock will be passed
544 to another thread to unlock
545@param[in] location location where requested */
546static inline void pfs_rw_lock_s_lock_func(rw_lock_t *lock, ulint pass,
547 ut::Location location);
548
549/** Performance schema instrumented wrap function for rw_lock_s_lock_func()
550NOTE! Please use the corresponding macro rw_lock_s_lock(), not directly this
551function!
552@param[in] lock pointer to rw-lock
553@param[in] pass pass value; != 0, if the lock will be passed
554 to another thread to unlock
555@param[in] location location where requested
556@return true if success */
557[[nodiscard]] static inline bool pfs_rw_lock_s_lock_low(rw_lock_t *lock,
558 ulint pass,
559 ut::Location location);
560
561/** Performance schema instrumented wrap function for rw_lock_x_lock_func()
562NOTE! Please use the corresponding macro rw_lock_x_lock(), not directly this
563function!
564@param[in] lock pointer to rw-lock
565@param[in] pass pass value; != 0, if the lock will be passed
566 to another thread to unlock
567@param[in] location location where requested */
568static inline void pfs_rw_lock_x_lock_func(rw_lock_t *lock, ulint pass,
569 ut::Location location);
570
571/** Performance schema instrumented wrap function for rw_lock_s_unlock_func()
572NOTE! Please use the corresponding macro rw_lock_s_unlock(), not directly this
573function!
574 @param[in] pass pass value; != 0, if the lock may have been passed to
575 another thread to unlock
576 @param[in,out] lock rw-lock */
577static inline void pfs_rw_lock_s_unlock_func(IF_DEBUG(ulint pass, )
578 rw_lock_t *lock);
579
580/** Performance schema instrumented wrap function for rw_lock_x_unlock_func()
581NOTE! Please use the corresponding macro rw_lock_x_unlock(), not directly this
582function!
583@param[in] pass pass value; != 0, if the lock may have been passed to
584another thread to unlock
585@param[in,out] lock rw-lock */
586static inline void pfs_rw_lock_x_unlock_func(IF_DEBUG(ulint pass, )
587 rw_lock_t *lock);
588
589/** Performance schema instrumented wrap function for rw_lock_sx_lock_func()
590NOTE! Please use the corresponding macro rw_lock_sx_lock(), not directly this
591function!
592@param[in] lock pointer to rw-lock
593@param[in] pass pass value; != 0, if the lock will be passed
594 to another thread to unlock
595@param[in] location location where requested */
597 ut::Location location);
598
599/** Performance schema instrumented wrap function for rw_lock_sx_lock_nowait()
600NOTE! Please use the corresponding macro, not directly this function!
601@param[in] lock pointer to rw-lock
602@param[in] pass pass value; != 0, if the lock will be passed
603 to another thread to unlock
604@param[in] location location where requested */
605[[nodiscard]] static inline bool pfs_rw_lock_sx_lock_low(rw_lock_t *lock,
606 ulint pass,
607 ut::Location location);
608
609/** Performance schema instrumented wrap function for rw_lock_sx_unlock_func()
610NOTE! Please use the corresponding macro rw_lock_sx_unlock(), not directly this
611function!
612@param[in] pass pass value; != 0, if the lock will be passed to
613another thread to unlock
614@param[in,out] lock pointer to rw-lock */
615static inline void pfs_rw_lock_sx_unlock_func(IF_DEBUG(ulint pass, )
616 rw_lock_t *lock);
617
618/** Performance schema instrumented wrap function for rw_lock_free_func()
619 NOTE! Please use the corresponding macro rw_lock_free(), not directly
620 this function! */
621static inline void pfs_rw_lock_free_func(rw_lock_t *lock); /*!< in: rw-lock */
622#endif /* UNIV_PFS_RWLOCK */
623
624#ifndef UNIV_PFS_RWLOCK
625/** Creates, or rather, initializes an rw-lock object in a specified memory
626 location (which must be appropriately aligned). The rw-lock is initialized
627 to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free
628 is necessary only if the memory block containing it is freed.
629 if MySQL performance schema is enabled and "UNIV_PFS_RWLOCK" is
630 defined, the rwlock are instrumented with performance schema probes. */
631#ifdef UNIV_DEBUG
632#define rw_lock_create(K, L, ID) \
633 rw_lock_create_func((L), (ID), UT_LOCATION_HERE)
634#else /* UNIV_DEBUG */
635#define rw_lock_create(K, L, ID) rw_lock_create_func((L), UT_LOCATION_HERE)
636#endif /* UNIV_DEBUG */
637
638/** NOTE! The following macros should be used in rw locking and
639 unlocking, not the corresponding function. */
640
641static inline void rw_lock_s_lock(rw_lock_t *M, ut::Location L) {
643}
644
645static inline void rw_lock_s_lock_gen(rw_lock_t *M, ulint P, ut::Location L) {
647}
648
649static inline bool rw_lock_s_lock_nowait(rw_lock_t *M, ut::Location L) {
650 return rw_lock_s_lock_low(M, 0, L);
651}
652
653#ifdef UNIV_DEBUG
654static inline void rw_lock_s_unlock_gen(rw_lock_t *L, ulint P) {
656}
657#else
658static inline void rw_lock_s_unlock_gen(rw_lock_t *L, ulint P) {
660}
661#endif /* UNIV_DEBUG */
662
663static inline void rw_lock_sx_lock(rw_lock_t *L, ut::Location Loc) {
664 rw_lock_sx_lock_func(L, 0, Loc);
665}
666
667static inline void rw_lock_sx_lock_gen(rw_lock_t *M, ulint P, ut::Location L) {
669}
670
671static inline bool rw_lock_sx_lock_nowait(rw_lock_t *M, ulint P,
672 ut::Location L) {
673 return rw_lock_sx_lock_low(M, P, L);
674}
675
676#ifdef UNIV_DEBUG
677static inline void rw_lock_sx_unlock(rw_lock_t *L) {
679}
680static inline void rw_lock_sx_unlock_gen(rw_lock_t *L, ulint P) {
682}
683#else /* UNIV_DEBUG */
684static inline void rw_lock_sx_unlock(rw_lock_t *L) {
686}
687static inline void rw_lock_sx_unlock_gen(rw_lock_t *L, ulint P) {
689}
690#endif /* UNIV_DEBUG */
691
692static inline void rw_lock_x_lock(rw_lock_t *M, ut::Location L) {
694}
695
696static inline void rw_lock_x_lock_gen(rw_lock_t *M, ulint P, ut::Location L) {
698}
699
700static inline bool rw_lock_x_lock_nowait(rw_lock_t *M, ut::Location L) {
702}
703
704#ifdef UNIV_DEBUG
705static inline void rw_lock_x_unlock_gen(rw_lock_t *L, ulint P) {
707}
708#else
709static inline void rw_lock_x_unlock_gen(rw_lock_t *L, ulint P) {
711}
712#endif
713
714#define rw_lock_free(M) rw_lock_free_func(M)
715
716#else /* !UNIV_PFS_RWLOCK */
717
718/* Following macros point to Performance Schema instrumented functions. */
719#ifdef UNIV_DEBUG
720#define rw_lock_create(K, L, ID) \
721 pfs_rw_lock_create_func((K), (L), (ID), UT_LOCATION_HERE)
722#else /* UNIV_DEBUG */
723#define rw_lock_create(K, L, ID) \
724 pfs_rw_lock_create_func((K), (L), UT_LOCATION_HERE)
725#endif /* UNIV_DEBUG */
726
727/******************************************************************
728NOTE! The following macros should be used in rw locking and
729unlocking, not the corresponding function. */
730
731static inline void rw_lock_s_lock(rw_lock_t *M, ut::Location L) {
733}
734
737}
738
740 return pfs_rw_lock_s_lock_low(M, 0, L);
741}
742
743#ifdef UNIV_DEBUG
744static inline void rw_lock_s_unlock_gen(rw_lock_t *L, ulint P) {
746}
747#else
748static inline void rw_lock_s_unlock_gen(rw_lock_t *L, ulint P) {
750}
751#endif
752
753static inline void rw_lock_sx_lock(rw_lock_t *M, ut::Location L) {
755}
756
759}
760
762 ut::Location L) {
763 return pfs_rw_lock_sx_lock_low(M, P, L);
764}
765
766#ifdef UNIV_DEBUG
767static inline void rw_lock_sx_unlock(rw_lock_t *L) {
769}
770static inline void rw_lock_sx_unlock_gen(rw_lock_t *L, ulint P) {
772}
773#else
774static inline void rw_lock_sx_unlock(rw_lock_t *L) {
776}
777static inline void rw_lock_sx_unlock_gen(rw_lock_t *L, ulint P) {
779}
780#endif
781
782static inline void rw_lock_x_lock(rw_lock_t *M, ut::Location L) {
784}
785
788}
789
792}
793
794#ifdef UNIV_DEBUG
795static inline void rw_lock_x_unlock_gen(rw_lock_t *L, ulint P) {
797}
798#else
799static inline void rw_lock_x_unlock_gen(rw_lock_t *L, ulint P) {
801}
802#endif
803
805
806#endif /* !UNIV_PFS_RWLOCK */
807
808static inline void rw_lock_s_unlock(rw_lock_t *L) {
810}
811static inline void rw_lock_x_unlock(rw_lock_t *L) {
813}
814
815#include "sync0rw.ic"
816
817#endif /* !UNIV_HOTBACKUP */
818
819#endif /* !UNIV_LIBRARY */
820typedef UT_LIST_BASE_NODE_T(rw_lock_t, list) rw_lock_list_t;
821
822extern rw_lock_list_t rw_lock_list;
823
824#endif /* sync0rw.h */
#define M
Definition: ctype-tis620.cc:73
#define L
Definition: ctype-tis620.cc:75
#define P
Definition: dtoa.cc:613
static int flags[50]
Definition: hp_test1.cc:40
const std::string FILE("FILE")
Definition: os0file.h:89
Provides atomic access in shared-exclusive modes.
Definition: shared_spin_lock.h:79
std::list< T, ut::allocator< T > > list
Specialization of list which uses ut_allocator.
Definition: ut0new.h:2878
The interface to the operating system condition variables.
required string key
Definition: replication_asynchronous_connection_failover.proto:60
Interface for an instrumented rwlock.
Definition: psi_rwlock_bits.h:71
All (ordered) latches, used in debugging, must derive from this class.
Definition: sync0types.h:962
Define for performance schema registration key.
Definition: sync0sync.h:51
InnoDB condition variable.
Definition: os0event.cc:63
The structure for storing debug info of an rw-lock.
Definition: sync0rw.h:334
ulint lock_type
Type of the lock: RW_LOCK_X, RW_LOCK_S, RW_LOCK_X_WAIT.
Definition: sync0rw.h:340
ut::Location location
Location where the rw-lock was locked.
Definition: sync0rw.h:342
UT_LIST_NODE_T(rw_lock_debug_t) list
Debug structs are linked in a two-way list.
std::thread::id thread_id
The thread id of the thread which locked the rw-lock.
Definition: sync0rw.h:336
ulint pass
Pass value given in the lock operation.
Definition: sync0rw.h:338
The structure used in the spin lock implementation of a read-write lock.
Definition: sync0rw.h:363
std::atomic< uint64_t > sx_recursive
number of granted SX locks.
Definition: sync0rw.h:391
std::atomic< std::thread::id > writer_thread
Thread id of writer thread.
Definition: sync0rw.h:409
uint16_t last_x_line
Line number where last time x-locked.
Definition: sync0rw.h:438
static const uint32_t MAGIC_N
For checking memory corruption.
Definition: sync0rw.h:462
virtual std::string locked_from() const override
Print where it was locked from.
Definition: sync0rw.cc:1011
uint64_t increment_sx_recursive()
Definition: sync0rw.h:399
std::atomic< bool > waiters
1: there are waiters
Definition: sync0rw.h:377
bool is_x_blocked_by_s()
Checks if there is a thread requesting an x-latch waiting for threads to release their s-latches.
Definition: sync0rw.h:473
const char * last_s_file_name
last s-lock file/line is not guaranteed to be correct
Definition: sync0rw.h:426
os_event_t wait_ex_event
Event for next-writer to wait on.
Definition: sync0rw.h:420
bool is_block_lock
If 1 then the rw-lock is a block lock.
Definition: sync0rw.h:432
uint32_t count_os_wait
Count of os_waits.
Definition: sync0rw.h:441
rw_lock_t(const rw_lock_t &)=delete
rw_lock_t is not a copyable object, the reasoning behind this is the same as the reasoning behind why...
uint16_t last_s_line
Line number where last time s-locked.
Definition: sync0rw.h:435
void decrement_sx_recursive()
Definition: sync0rw.h:393
struct PSI_rwlock * pfs_psi
The instrumentation hook.
Definition: sync0rw.h:448
rw_lock_t & operator=(const rw_lock_t &)=delete
rw_lock_t()=default
os_event_t event
Used by sync0arr.cc for thread queueing.
Definition: sync0rw.h:416
const char * last_x_file_name
File name where last x-locked.
Definition: sync0rw.h:429
Atomic_xor_of_thread_id reader_thread
XOR of reader threads' IDs.
Definition: sync0rw.h:413
virtual std::string to_string() const override
Print the rw-lock information.
Definition: sync0rw.cc:1037
~rw_lock_t() override
Destructor.
Definition: sync0rw.cc:254
ut::Location clocation
Location where lock created.
Definition: sync0rw.h:423
std::atomic< int32_t > lock_word
Holds the state of the lock.
Definition: sync0rw.h:374
UT_LIST_NODE_T(rw_lock_t) list
All allocated rw locks are put into a list.
UT_LIST_BASE_NODE_T(rw_lock_debug_t, list) debug_list
In the debug version: pointer to the debug info list of the lock.
Definition: sync0rw.h:466
uint32_t magic_n
Definition: sync0rw.h:463
std::atomic< bool > recursive
Default value false which means the lock is non-recursive.
Definition: sync0rw.h:388
Definition: ut0core.h:36
static bool rw_lock_lock_word_decr(rw_lock_t *lock, ulint amount, lint threshold)
Decrements lock_word the specified amount if it is greater than 0.
Definition: sync0rw.ic:211
static lint rw_lock_lock_word_incr(rw_lock_t *lock, ulint amount)
Increments lock_word the specified amount and returns new value.
bool rw_lock_is_locked(rw_lock_t *lock, ulint lock_type)
Checks if somebody has locked the rw-lock in the specified mode.
Definition: sync0rw.cc:729
void rw_lock_free_func(rw_lock_t *lock)
Calling this function is obligatory only if the memory buffer containing the rw-lock is freed.
Definition: sync0rw.cc:248
static void rw_lock_sx_unlock_func(ulint pass, rw_lock_t *lock)
Releases an sx mode lock.
static void rw_lock_s_unlock_func(ulint pass, rw_lock_t *lock)
Releases a shared mode lock.
static bool pfs_rw_lock_x_lock_func_nowait(rw_lock_t *lock, ut::Location location)
Performance schema instrumented wrap function for rw_lock_x_lock_func_nowait() NOTE!...
bool rw_lock_own(const rw_lock_t *lock, ulint lock_type)
Checks if the thread has locked the rw-lock in the specified mode, with the pass value == 0.
Definition: sync0rw.cc:858
static void rw_lock_set_writer_id_and_recursion_flag(rw_lock_t *lock, bool recursive)
This function sets the lock->writer_thread and lock->recursive fields.
static void rw_lock_s_unlock(rw_lock_t *L)
Definition: sync0rw.h:808
constexpr int32_t X_LOCK_HALF_DECR
Definition: sync0rw.h:109
static void rw_lock_x_lock(rw_lock_t *M, ut::Location L)
Definition: sync0rw.h:782
static bool pfs_rw_lock_sx_lock_low(rw_lock_t *lock, ulint pass, ut::Location location)
Performance schema instrumented wrap function for rw_lock_sx_lock_nowait() NOTE! Please use the corre...
static void pfs_rw_lock_free_func(rw_lock_t *lock)
Performance schema instrumented wrap function for rw_lock_free_func() NOTE! Please use the correspond...
static void rw_lock_x_lock_gen(rw_lock_t *M, ulint P, ut::Location L)
Definition: sync0rw.h:786
static bool rw_lock_s_lock_nowait(rw_lock_t *M, ut::Location L)
Definition: sync0rw.h:739
static void rw_lock_x_unlock_gen(rw_lock_t *L, ulint P)
Definition: sync0rw.h:795
static bool rw_lock_x_lock_func_nowait(rw_lock_t *lock, ut::Location location)
NOTE! Use the corresponding macro, not directly this function! Lock an rw-lock in exclusive mode for ...
static bool rw_lock_get_waiters(const rw_lock_t *lock)
Check if there are threads waiting for the rw-lock.
static void rw_lock_sx_lock_gen(rw_lock_t *M, ulint P, ut::Location L)
Definition: sync0rw.h:757
static ulint rw_lock_get_writer(const rw_lock_t *lock)
Returns the write-status of the lock - this function made more sense with the old rw_lock implementat...
static void pfs_rw_lock_sx_lock_func(rw_lock_t *lock, ulint pass, ut::Location location)
Performance schema instrumented wrap function for rw_lock_sx_lock_func() NOTE! Please use the corresp...
static bool rw_lock_s_lock_low(rw_lock_t *lock, ulint pass, ut::Location location)
Low-level function which tries to lock an rw-lock in s-mode.
Definition: sync0rw.ic:245
static void pfs_rw_lock_create_func(mysql_pfs_key_t key, rw_lock_t *lock, latch_id_t id, ut::Location clocation)
Performance schema instrumented wrap function for rw_lock_create_func() NOTE! Please use the correspo...
static ulint rw_lock_get_sx_lock_count(const rw_lock_t *lock)
Returns the number of sx-lock for the lock.
static bool rw_lock_x_lock_nowait(rw_lock_t *M, ut::Location L)
Definition: sync0rw.h:790
static ulint rw_lock_get_reader_count(const rw_lock_t *lock)
Returns the number of readers (s-locks).
void rw_lock_debug_print(FILE *f, const rw_lock_debug_t *info)
Prints info of a debug struct.
Definition: sync0rw.cc:978
static bool pfs_rw_lock_s_lock_low(rw_lock_t *lock, ulint pass, ut::Location location)
Performance schema instrumented wrap function for rw_lock_s_lock_func() NOTE! Please use the correspo...
rw_lock_list_t rw_lock_list
The global list of rw-locks.
Definition: sync0rw.cc:171
typedef UT_LIST_BASE_NODE_T(rw_lock_t, list) rw_lock_list_t
static void rw_lock_s_lock(rw_lock_t *M, ut::Location L)
Definition: sync0rw.h:731
static void pfs_rw_lock_x_unlock_func(ulint pass, rw_lock_t *lock)
Performance schema instrumented wrap function for rw_lock_x_unlock_func() NOTE! Please use the corres...
static void pfs_rw_lock_sx_unlock_func(ulint pass, rw_lock_t *lock)
Performance schema instrumented wrap function for rw_lock_sx_unlock_func() NOTE! Please use the corre...
bool rw_lock_sx_lock_low(rw_lock_t *lock, ulint pass, ut::Location location)
Low-level function for acquiring an sx lock.
Definition: sync0rw.cc:510
static void rw_lock_s_unlock_gen(rw_lock_t *L, ulint P)
Definition: sync0rw.h:744
static void rw_lock_x_unlock(rw_lock_t *L)
Definition: sync0rw.h:811
static void rw_lock_sx_unlock_gen(rw_lock_t *L, ulint P)
Definition: sync0rw.h:770
void rw_lock_sx_lock_func(rw_lock_t *lock, ulint pass, ut::Location location)
NOTE! Use the corresponding macro, not directly this function! Lock an rw-lock in SX mode for the cur...
Definition: sync0rw.cc:643
ib_mutex_t rw_lock_list_mutex
Definition: sync0rw.cc:172
bool rw_lock_validate(const rw_lock_t *lock)
Checks that the rw-lock has been initialized and that there are no simultaneous shared and exclusive ...
Definition: sync0rw.cc:713
void rw_lock_list_print_info(FILE *file)
Prints debug info of currently locked rw-locks.
Definition: sync0rw.cc:937
static void pfs_rw_lock_x_lock_func(rw_lock_t *lock, ulint pass, ut::Location location)
Performance schema instrumented wrap function for rw_lock_x_lock_func() NOTE! Please use the correspo...
static void rw_lock_x_unlock_func(ulint pass, rw_lock_t *lock)
Releases an exclusive mode lock.
constexpr int32_t X_LOCK_DECR
Definition: sync0rw.h:108
static ulint rw_lock_get_x_lock_count(const rw_lock_t *lock)
Returns the value of writer_count for the lock.
static void rw_lock_s_lock_func(rw_lock_t *lock, ulint pass, ut::Location location)
NOTE! Use the corresponding macro, not directly this function, except if you supply the file name and...
rw_lock_type_t
Definition: sync0rw.h:97
@ RW_SX_LATCH
Definition: sync0rw.h:100
@ RW_NO_LATCH
Definition: sync0rw.h:101
@ RW_X_LATCH
Definition: sync0rw.h:99
@ RW_S_LATCH
Definition: sync0rw.h:98
static void pfs_rw_lock_s_lock_func(rw_lock_t *lock, ulint pass, ut::Location location)
Performance schema instrumented wrap function for rw_lock_s_lock_func() NOTE! Please use the correspo...
Definition: sync0rw.ic:570
static void rw_lock_sx_unlock(rw_lock_t *L)
Definition: sync0rw.h:767
static void rw_lock_s_lock_gen(rw_lock_t *M, ulint P, ut::Location L)
Definition: sync0rw.h:735
void rw_lock_create_func(rw_lock_t *lock, latch_id_t id, ut::Location clocation)
Creates, or rather, initializes an rw-lock object in a specified memory location (which must be appro...
Definition: sync0rw.cc:191
static void rw_lock_sx_lock(rw_lock_t *M, ut::Location L)
Definition: sync0rw.h:753
static bool rw_lock_sx_lock_nowait(rw_lock_t *M, ulint P, ut::Location L)
Definition: sync0rw.h:761
static void pfs_rw_lock_s_unlock_func(ulint pass, rw_lock_t *lock)
Performance schema instrumented wrap function for rw_lock_s_unlock_func() NOTE! Please use the corres...
Definition: sync0rw.ic:722
bool rw_lock_own_flagged(const rw_lock_t *lock, rw_lock_flags_t flags)
Checks if the thread has locked the rw-lock in the specified mode, with the pass value == 0.
Definition: sync0rw.cc:898
void rw_lock_x_lock_func(rw_lock_t *lock, ulint pass, ut::Location location)
NOTE! Use the corresponding macro, not directly this function! Lock an rw-lock in exclusive mode for ...
Definition: sync0rw.cc:573
static void rw_lock_free(rw_lock_t *M)
Definition: sync0rw.h:804
void rw_lock_x_lock_move_ownership(rw_lock_t *lock)
This function is used in the insert buffer to move the ownership of an x-latch on a buffer frame to t...
Definition: sync0rw.cc:355
The read-write lock (for threads)
latch_id_t
Each latch has an ID.
Definition: sync0types.h:343
ulint rw_lock_flags_t
Definition: sync0types.h:1208
Version control for database, common definitions, and include files.
#define IF_DEBUG(...)
Definition: univ.i:674
unsigned long int ulint
Definition: univ.i:406
long int lint
Definition: univ.i:407
Counter utility class.
Policy based mutexes.
unsigned long id[MAX_DEAD]
Definition: xcom_base.cc:510