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