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