MySQL 8.0.33
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 "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] id latch_id
122 @param[in] clocation location where created */
124 IF_DEBUG(latch_id_t id, ) ut::Location clocation);
125/** Calling this function is obligatory only if the memory buffer containing
126 the rw-lock is freed. Removes an rw-lock object from the global list. The
127 rw-lock is checked to be in the non-locked state. */
128void rw_lock_free_func(rw_lock_t *lock); /*!< in/out: rw-lock */
129#ifdef UNIV_DEBUG
130/** Checks that the rw-lock has been initialized and that there are no
131 simultaneous shared and exclusive locks.
132 @return true */
133[[nodiscard]] bool rw_lock_validate(const rw_lock_t *lock); /*!< in: rw-lock */
134#endif /* UNIV_DEBUG */
135
136/** Low-level function which tries to lock an rw-lock in s-mode. Performs no
137spinning.
138@param[in] lock pointer to rw-lock
139@param[in] pass pass value; != 0, if the lock will be passed
140 to another thread to unlock
141@param[in] location location where requested
142@return true if success */
143[[nodiscard]] static inline bool rw_lock_s_lock_low(rw_lock_t *lock,
144 ulint pass [[maybe_unused]],
146
147/** NOTE! Use the corresponding macro, not directly this function, except if
148you supply the file name and line number. Lock an rw-lock in shared mode for
149the current thread. If the rw-lock is locked in exclusive mode, or there is an
150exclusive lock request waiting, the function spins a preset time (controlled
151by srv_n_spin_wait_rounds), waiting for the lock, before suspending the thread.
152@param[in] lock pointer to rw-lock
153@param[in] pass pass value; != 0, if the lock will be passed to
154 another thread to unlock
155@param[in] location location where requested */
158
159/** NOTE! Use the corresponding macro, not directly this function! Lock an
160rw-lock in exclusive mode for the current thread if the lock can be obtained
161immediately.
162@param[in] lock pointer to rw-lock
163@param[in] location location where requested
164@return true if success */
165[[nodiscard]] static inline bool rw_lock_x_lock_func_nowait(
167
168/** Releases a shared mode lock.
169@param[in] pass pass value; != 0, if the lock will be passed to another
170 thread to unlock
171@param[in,out] lock rw-lock */
173 rw_lock_t *lock);
174
175/** NOTE! Use the corresponding macro, not directly this function! Lock an
176rw-lock in exclusive mode for the current thread. If the rw-lock is locked
177in shared or exclusive mode, or there is an exclusive lock request waiting,
178the function spins a preset time (controlled by srv_n_spin_wait_rounds),
179waiting for the lock, before suspending the thread. If the same thread has an
180x-lock on the rw-lock, locking succeed, with the following exception: if pass
181!= 0, only a single x-lock may be taken on the lock. NOTE: If the same thread
182has an s-lock, locking does not succeed!
183@param[in] lock pointer to rw-lock
184@param[in] pass pass value; != 0, if the lock will be passed to
185 another thread to unlock
186@param[in] location location where requested */
188
189/** Low-level function for acquiring an sx lock.
190@param[in] lock pointer to rw-lock
191@param[in] pass pass value; != 0, if the lock will be passed to
192 another thread to unlock
193@param[in] location location where requested
194@return false if did not succeed, true if success. */
195[[nodiscard]] bool rw_lock_sx_lock_low(rw_lock_t *lock, ulint pass,
197/** NOTE! Use the corresponding macro, not directly this function! Lock an
198rw-lock in SX mode for the current thread. If the rw-lock is locked
199in exclusive mode, or there is an exclusive lock request waiting,
200the function spins a preset time (controlled by SYNC_SPIN_ROUNDS), waiting
201for the lock, before suspending the thread. If the same thread has an x-lock
202on the rw-lock, locking succeed, with the following exception: if pass != 0,
203only a single sx-lock may be taken on the lock. NOTE: If the same thread has
204an s-lock, locking does not succeed!
205@param[in] lock pointer to rw-lock
206@param[in] pass pass value; != 0, if the lock will be passed to
207 another thread to unlock
208@param[in] location location where requested */
210
211/** Releases an exclusive mode lock.
212@param[in] pass pass value; != 0, if the lock will be passed to another
213 thread to unlock
214@param[in,out] lock rw-lock */
216 rw_lock_t *lock);
217
218/** Releases an sx mode lock.
219@param[in] pass pass value; != 0, if the lock will be passed to another
220 thread to unlock
221@param[in,out] lock rw-lock */
223 rw_lock_t *lock);
224
225/** This function is used in the insert buffer to move the ownership of an
226x-latch on a buffer frame to the current thread. The x-latch was set by
227the buffer read operation and it protected the buffer frame while the
228read was done. The ownership is moved because we want that the current
229thread is able to acquire a second x-latch which is stored in an mtr.
230This, in turn, is needed to pass the debug checks of index page
231operations.
232@param[in] lock lock which was x-locked in the buffer read. */
234/** Returns the value of writer_count for the lock. Does not reserve the lock
235mutex, so the caller must be sure it is not changed during the call.
236@return value of writer_count
237@param[in] lock rw-lock */
239/** Returns the number of sx-lock for the lock. Does not reserve the lock
240mutex, so the caller must be sure it is not changed during the call.
241@param[in] lock rw-lock
242@return value of writer_count */
244/** Check if there are threads waiting for the rw-lock.
245@param[in] lock rw-lock
246@return true if waiters, false otherwise */
247[[nodiscard]] static inline bool rw_lock_get_waiters(const rw_lock_t *lock);
248/** Returns the write-status of the lock - this function made more sense
249with the old rw_lock implementation.
250@param[in] lock rw-lock
251@return RW_LOCK_NOT_LOCKED, RW_LOCK_X, RW_LOCK_X_WAIT, RW_LOCK_SX */
253/** Returns the number of readers (s-locks).
254@param[in] lock rw-lock
255@return number of readers */
257
258/** Decrements lock_word the specified amount if it is greater than 0.
259This is used by both s_lock and x_lock operations.
260@param[in,out] lock rw-lock
261@param[in] amount amount to decrement
262@param[in] threshold threshold of judgement
263@return true if decr occurs */
264[[nodiscard]] static inline bool rw_lock_lock_word_decr(rw_lock_t *lock,
265 ulint amount,
266 lint threshold);
267
268/** Increments lock_word the specified amount and returns new value.
269@param[in,out] lock rw-lock
270@param[in] amount amount to decrement
271@return lock->lock_word after increment */
273
274/** This function sets the lock->writer_thread and lock->recursive fields. Sets
275lock->recursive field using atomic release after setting lock->writer thread to
276ensure proper memory ordering of the two.
277Note that it is assumed that the caller of this function effectively owns
278the lock i.e.: nobody else is allowed to modify lock->writer_thread at this
279point in time. The protocol is that lock->writer_thread MUST be updated BEFORE
280the lock->recursive flag is set.
281@param[in,out] lock lock to work on
282@param[in] recursive true if recursion allowed */
284 bool recursive);
285
286#ifdef UNIV_DEBUG
287/** Checks if the thread has locked the rw-lock in the specified mode, with
288the pass value == 0. Note that the mode is checked exactly, so if the thread
289owns RW_LOCK_X only, the rw_lock_own(..,RW_LOCK_S) will return false.
290@param[in] lock the rw-lock
291@param[in] lock_type The exact lock type to check:
292 RW_LOCK_S, RW_LOCK_SX or RW_LOCK_X
293*/
294[[nodiscard]] bool rw_lock_own(const rw_lock_t *lock, ulint lock_type);
295
296/** Checks if the thread has locked the rw-lock in the specified mode, with the
297pass value == 0.
298@param[in] lock rw-lock
299@param[in] flags specify lock types with OR of the rw_lock_flag_t values
300@return true if locked */
301[[nodiscard]] bool rw_lock_own_flagged(const rw_lock_t *lock,
303#endif /* UNIV_DEBUG */
304#endif /* !UNIV_HOTBACKUP */
305/** Checks if somebody has locked the rw-lock in the specified mode.
306@param[in] lock the rw-lock
307@param[in] lock_type The exact lock type to check:
308 RW_LOCK_S, RW_LOCK_SX or RW_LOCK_X
309@return true if locked */
310[[nodiscard]] bool rw_lock_is_locked(rw_lock_t *lock, ulint lock_type);
311#ifdef UNIV_DEBUG
312/** Prints debug info of currently locked rw-locks.
313@param[in] file file where to print */
315
316/*#####################################################################*/
317
318/** Prints info of a debug struct.
319@param[in] f Output stream
320@param[in] info Debug struct */
322
323#endif /* UNIV_DEBUG */
324
325#endif /* !UNIV_LIBRARY */
326
327#ifdef UNIV_DEBUG
328/** The structure for storing debug info of an rw-lock. All access to this
329structure must be protected by rw_lock_debug_mutex_enter(). */
331 /** The thread id of the thread which locked the rw-lock. */
333 /** Pass value given in the lock operation. */
335 /** Type of the lock: RW_LOCK_X, RW_LOCK_S, RW_LOCK_X_WAIT. */
337 /** Location where the rw-lock was locked. */
339 /** Debug structs are linked in a two-way list. */
341};
342#endif /* UNIV_DEBUG */
343
344/* NOTE! The structure appears here only for the compiler to know its size.
345Do not use its fields directly! */
346
347/** The structure used in the spin lock implementation of a read-write
348lock. Several threads may have a shared lock simultaneously in this
349lock, but only one writer may have an exclusive lock, in which case no
350shared locks are allowed. To prevent starving of a writer blocked by
351readers, a writer may queue for x-lock by decrementing lock_word: no
352new readers will be let in while the thread waits for readers to
353exit. */
354
356#ifdef UNIV_DEBUG
357 : public latch_t
358#endif /* UNIV_DEBUG */
359{
360 rw_lock_t() = default;
361 /** rw_lock_t is not a copyable object, the reasoning
362 behind this is the same as the reasoning behind why
363 std::mutex is not copyable. It is supposed to represent
364 a synchronization primitive for which copying semantics
365 do not make sense. */
366 rw_lock_t(const rw_lock_t &) = delete;
367 rw_lock_t &operator=(const rw_lock_t &) = delete;
368
369 /** Holds the state of the lock. */
370 std::atomic<int32_t> lock_word;
371
372 /** 1: there are waiters */
373 std::atomic<bool> waiters;
374
375 /** Default value false which means the lock is non-recursive.
376 The value is typically set to true making normal rw_locks recursive.
377 In case of asynchronous IO, when a non-zero value of 'pass' is
378 passed then we keep the lock non-recursive.
379
380 This flag also tells us about the state of writer_thread field.
381 If this flag is set then writer_thread MUST contain the thread
382 id of the current x-holder or wait-x thread. This flag must be
383 reset in x_unlock functions before incrementing the lock_word */
384 std::atomic<bool> recursive;
385
386 /** number of granted SX locks. */
388
389 /** Thread id of writer thread. Is only guaranteed to have non-stale value if
390 recursive flag is set, otherwise it may contain native thread ID of a
391 thread which already released or passed the lock. */
392 std::atomic<std::thread::id> writer_thread;
393
394 /** XOR of reader threads' IDs. If there is exactly one reader it should allow
395 to retrieve the thread ID of that reader. */
397
398 /** Used by sync0arr.cc for thread queueing */
400
401 /** Event for next-writer to wait on. A thread must decrement
402 lock_word before waiting. */
404
405 /** Location where lock created */
407
408 /** last s-lock file/line is not guaranteed to be correct */
409 const char *last_s_file_name;
410
411 /** File name where last x-locked */
412 const char *last_x_file_name;
413
414 /** If 1 then the rw-lock is a block lock */
416
417 /** Line number where last time s-locked */
418 uint16_t last_s_line;
419
420 /** Line number where last time x-locked */
421 uint16_t last_x_line;
422
423 /** Count of os_waits. May not be accurate */
425
426 /** All allocated rw locks are put into a list */
428
429#ifdef UNIV_PFS_RWLOCK
430 /** The instrumentation hook */
432#endif /* UNIV_PFS_RWLOCK */
433
434#ifndef UNIV_DEBUG
435 /** Destructor */
436 ~rw_lock_t();
437#else
438 /** Destructor */
439 ~rw_lock_t() override;
440
441 virtual std::string to_string() const override;
442 virtual std::string locked_from() const override;
443
444 /** For checking memory corruption. */
445 static const uint32_t MAGIC_N = 22643;
446 uint32_t magic_n = {MAGIC_N};
447
448 /** In the debug version: pointer to the debug info list of the lock */
450
451#endif /* UNIV_DEBUG */
452
453 /** Checks if there is a thread requesting an x-latch waiting for threads to
454 release their s-latches.
455 @return true iff there is an x-latcher blocked by s-latchers. */
457 const auto snapshot = lock_word.load();
458 return snapshot < 0 && -X_LOCK_DECR < snapshot &&
459 snapshot != -X_LOCK_HALF_DECR;
460 }
461};
462
463#ifndef UNIV_LIBRARY
464#ifndef UNIV_HOTBACKUP
465/* For performance schema instrumentation, a new set of rwlock
466wrap functions are created if "UNIV_PFS_RWLOCK" is defined.
467The instrumentations are not planted directly into original
468functions, so that we keep the underlying function as they
469are. And in case, user wants to "take out" some rwlock from
470instrumentation even if performance schema (UNIV_PFS_RWLOCK)
471is defined, they can do so by reinstating APIs directly link to
472original underlying functions.
473The instrumented function names have prefix of "pfs_rw_lock_" vs.
474original name prefix of "rw_lock_". Following are list of functions
475that have been instrumented:
476
477rw_lock_create()
478rw_lock_x_lock()
479rw_lock_x_lock_gen()
480rw_lock_x_lock_nowait()
481rw_lock_x_unlock_gen()
482rw_lock_s_lock()
483rw_lock_s_lock_gen()
484rw_lock_s_lock_nowait()
485rw_lock_s_unlock_gen()
486rw_lock_sx_lock()
487rw_lock_sx_unlock_gen()
488rw_lock_free()
489*/
490
491#ifdef UNIV_PFS_RWLOCK
492/** Performance schema instrumented wrap function for rw_lock_create_func()
493NOTE! Please use the corresponding macro rw_lock_create(), not directly this
494function!
495@param[in] key key registered with performance schema
496@param[in] lock rw lock
497@param[in] id latch_id
498@param[in] clocation location where created */
500 IF_DEBUG(latch_id_t id, )
501 ut::Location clocation);
502
503/** Performance schema instrumented wrap function for rw_lock_x_lock_func()
504NOTE! Please use the corresponding macro rw_lock_x_lock(), not directly this
505function!
506@param[in] lock pointer to rw-lock
507@param[in] pass pass value; != 0, if the lock will be passed
508 to another thread to unlock
509@param[in] location location where requested */
510static inline void pfs_rw_lock_x_lock_func(rw_lock_t *lock, ulint pass,
511 ut::Location location);
512
513/** Performance schema instrumented wrap function for
514rw_lock_x_lock_func_nowait()
515NOTE! Please use the corresponding macro, not directly this function!
516@param[in] lock pointer to rw-lock
517@param[in] location location where requested
518@return true if success */
519[[nodiscard]] static inline bool pfs_rw_lock_x_lock_func_nowait(
520 rw_lock_t *lock, ut::Location location);
521
522/** Performance schema instrumented wrap function for rw_lock_s_lock_func()
523NOTE! Please use the corresponding macro rw_lock_s_lock(), not directly this
524function!
525@param[in] lock pointer to rw-lock
526@param[in] pass pass value; != 0, if the lock will be passed
527 to another thread to unlock
528@param[in] location location where requested */
529static inline void pfs_rw_lock_s_lock_func(rw_lock_t *lock, ulint pass,
530 ut::Location location);
531
532/** Performance schema instrumented wrap function for rw_lock_s_lock_func()
533NOTE! Please use the corresponding macro rw_lock_s_lock(), not directly this
534function!
535@param[in] lock pointer to rw-lock
536@param[in] pass pass value; != 0, if the lock will be passed
537 to another thread to unlock
538@param[in] location location where requested
539@return true if success */
540[[nodiscard]] static inline bool pfs_rw_lock_s_lock_low(rw_lock_t *lock,
541 ulint pass,
542 ut::Location location);
543
544/** Performance schema instrumented wrap function for rw_lock_x_lock_func()
545NOTE! Please use the corresponding macro rw_lock_x_lock(), not directly this
546function!
547@param[in] lock pointer to rw-lock
548@param[in] pass pass value; != 0, if the lock will be passed
549 to another thread to unlock
550@param[in] location location where requested */
551static inline void pfs_rw_lock_x_lock_func(rw_lock_t *lock, ulint pass,
552 ut::Location location);
553
554/** Performance schema instrumented wrap function for rw_lock_s_unlock_func()
555NOTE! Please use the corresponding macro rw_lock_s_unlock(), not directly this
556function!
557 @param[in] pass pass value; != 0, if the lock may have been passed to
558 another thread to unlock
559 @param[in,out] lock rw-lock */
560static inline void pfs_rw_lock_s_unlock_func(IF_DEBUG(ulint pass, )
561 rw_lock_t *lock);
562
563/** Performance schema instrumented wrap function for rw_lock_x_unlock_func()
564NOTE! Please use the corresponding macro rw_lock_x_unlock(), not directly this
565function!
566@param[in] pass pass value; != 0, if the lock may have been passed to
567another thread to unlock
568@param[in,out] lock rw-lock */
569static inline void pfs_rw_lock_x_unlock_func(IF_DEBUG(ulint pass, )
570 rw_lock_t *lock);
571
572/** Performance schema instrumented wrap function for rw_lock_sx_lock_func()
573NOTE! Please use the corresponding macro rw_lock_sx_lock(), not directly this
574function!
575@param[in] lock pointer to rw-lock
576@param[in] pass pass value; != 0, if the lock will be passed
577 to another thread to unlock
578@param[in] location location where requested */
580 ut::Location location);
581
582/** Performance schema instrumented wrap function for rw_lock_sx_lock_nowait()
583NOTE! Please use the corresponding macro, not directly this function!
584@param[in] lock pointer to rw-lock
585@param[in] pass pass value; != 0, if the lock will be passed
586 to another thread to unlock
587@param[in] location location where requested */
588[[nodiscard]] static inline bool pfs_rw_lock_sx_lock_low(rw_lock_t *lock,
589 ulint pass,
590 ut::Location location);
591
592/** Performance schema instrumented wrap function for rw_lock_sx_unlock_func()
593NOTE! Please use the corresponding macro rw_lock_sx_unlock(), not directly this
594function!
595@param[in] pass pass value; != 0, if the lock will be passed to
596another thread to unlock
597@param[in,out] lock pointer to rw-lock */
598static inline void pfs_rw_lock_sx_unlock_func(IF_DEBUG(ulint pass, )
599 rw_lock_t *lock);
600
601/** Performance schema instrumented wrap function for rw_lock_free_func()
602 NOTE! Please use the corresponding macro rw_lock_free(), not directly
603 this function! */
604static inline void pfs_rw_lock_free_func(rw_lock_t *lock); /*!< in: rw-lock */
605#endif /* UNIV_PFS_RWLOCK */
606
607#ifndef UNIV_PFS_RWLOCK
608/** Creates, or rather, initializes an rw-lock object in a specified memory
609 location (which must be appropriately aligned). The rw-lock is initialized
610 to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free
611 is necessary only if the memory block containing it is freed.
612 if MySQL performance schema is enabled and "UNIV_PFS_RWLOCK" is
613 defined, the rwlock are instrumented with performance schema probes. */
614#ifdef UNIV_DEBUG
615#define rw_lock_create(K, L, ID) \
616 rw_lock_create_func((L), (ID), UT_LOCATION_HERE)
617#else /* UNIV_DEBUG */
618#define rw_lock_create(K, L, ID) rw_lock_create_func((L), UT_LOCATION_HERE)
619#endif /* UNIV_DEBUG */
620
621/** NOTE! The following macros should be used in rw locking and
622 unlocking, not the corresponding function. */
623
624static inline void rw_lock_s_lock(rw_lock_t *M, ut::Location L) {
626}
627
628static inline void rw_lock_s_lock_gen(rw_lock_t *M, ulint P, ut::Location L) {
630}
631
632static inline bool rw_lock_s_lock_nowait(rw_lock_t *M, ut::Location L) {
633 return rw_lock_s_lock_low(M, 0, L);
634}
635
636#ifdef UNIV_DEBUG
637static inline void rw_lock_s_unlock_gen(rw_lock_t *L, ulint P) {
639}
640#else
641static inline void rw_lock_s_unlock_gen(rw_lock_t *L, ulint P) {
643}
644#endif /* UNIV_DEBUG */
645
646static inline void rw_lock_sx_lock(rw_lock_t *L, ut::Location Loc) {
647 rw_lock_sx_lock_func(L, 0, Loc);
648}
649
650static inline void rw_lock_sx_lock_gen(rw_lock_t *M, ulint P, ut::Location L) {
652}
653
654static inline bool rw_lock_sx_lock_nowait(rw_lock_t *M, ulint P,
655 ut::Location L) {
656 return rw_lock_sx_lock_low(M, P, L);
657}
658
659#ifdef UNIV_DEBUG
660static inline void rw_lock_sx_unlock(rw_lock_t *L) {
662}
663static inline void rw_lock_sx_unlock_gen(rw_lock_t *L, ulint P) {
665}
666#else /* UNIV_DEBUG */
667static inline void rw_lock_sx_unlock(rw_lock_t *L) {
669}
670static inline void rw_lock_sx_unlock_gen(rw_lock_t *L, ulint P) {
672}
673#endif /* UNIV_DEBUG */
674
675static inline void rw_lock_x_lock(rw_lock_t *M, ut::Location L) {
677}
678
679static inline void rw_lock_x_lock_gen(rw_lock_t *M, ulint P, ut::Location L) {
681}
682
683static inline bool rw_lock_x_lock_nowait(rw_lock_t *M, ut::Location L) {
685}
686
687#ifdef UNIV_DEBUG
688static inline void rw_lock_x_unlock_gen(rw_lock_t *L, ulint P) {
690}
691#else
692static inline void rw_lock_x_unlock_gen(rw_lock_t *L, ulint P) {
694}
695#endif
696
697#define rw_lock_free(M) rw_lock_free_func(M)
698
699#else /* !UNIV_PFS_RWLOCK */
700
701/* Following macros point to Performance Schema instrumented functions. */
702#ifdef UNIV_DEBUG
703#define rw_lock_create(K, L, ID) \
704 pfs_rw_lock_create_func((K), (L), (ID), UT_LOCATION_HERE)
705#else /* UNIV_DEBUG */
706#define rw_lock_create(K, L, ID) \
707 pfs_rw_lock_create_func((K), (L), UT_LOCATION_HERE)
708#endif /* UNIV_DEBUG */
709
710/******************************************************************
711NOTE! The following macros should be used in rw locking and
712unlocking, not the corresponding function. */
713
714static inline void rw_lock_s_lock(rw_lock_t *M, ut::Location L) {
716}
717
720}
721
723 return pfs_rw_lock_s_lock_low(M, 0, L);
724}
725
726#ifdef UNIV_DEBUG
727static inline void rw_lock_s_unlock_gen(rw_lock_t *L, ulint P) {
729}
730#else
731static inline void rw_lock_s_unlock_gen(rw_lock_t *L, ulint P) {
733}
734#endif
735
736static inline void rw_lock_sx_lock(rw_lock_t *M, ut::Location L) {
738}
739
742}
743
745 ut::Location L) {
746 return pfs_rw_lock_sx_lock_low(M, P, L);
747}
748
749#ifdef UNIV_DEBUG
750static inline void rw_lock_sx_unlock(rw_lock_t *L) {
752}
753static inline void rw_lock_sx_unlock_gen(rw_lock_t *L, ulint P) {
755}
756#else
757static inline void rw_lock_sx_unlock(rw_lock_t *L) {
759}
760static inline void rw_lock_sx_unlock_gen(rw_lock_t *L, ulint P) {
762}
763#endif
764
765static inline void rw_lock_x_lock(rw_lock_t *M, ut::Location L) {
767}
768
771}
772
775}
776
777#ifdef UNIV_DEBUG
778static inline void rw_lock_x_unlock_gen(rw_lock_t *L, ulint P) {
780}
781#else
782static inline void rw_lock_x_unlock_gen(rw_lock_t *L, ulint P) {
784}
785#endif
786
788
789#endif /* !UNIV_PFS_RWLOCK */
790
791static inline void rw_lock_s_unlock(rw_lock_t *L) {
793}
794static inline void rw_lock_x_unlock(rw_lock_t *L) {
796}
797
798#include "sync0rw.ic"
799
800#endif /* !UNIV_HOTBACKUP */
801
802#endif /* !UNIV_LIBRARY */
803typedef UT_LIST_BASE_NODE_T(rw_lock_t, list) rw_lock_list_t;
804
805extern rw_lock_list_t rw_lock_list;
806
807#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:2876
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:959
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:330
ulint lock_type
Type of the lock: RW_LOCK_X, RW_LOCK_S, RW_LOCK_X_WAIT.
Definition: sync0rw.h:336
ut::Location location
Location where the rw-lock was locked.
Definition: sync0rw.h:338
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:332
ulint pass
Pass value given in the lock operation.
Definition: sync0rw.h:334
The structure used in the spin lock implementation of a read-write lock.
Definition: sync0rw.h:359
std::atomic< std::thread::id > writer_thread
Thread id of writer thread.
Definition: sync0rw.h:392
uint16_t last_x_line
Line number where last time x-locked.
Definition: sync0rw.h:421
static const uint32_t MAGIC_N
For checking memory corruption.
Definition: sync0rw.h:445
virtual std::string locked_from() const override
Print where it was locked from.
Definition: sync0rw.cc:1010
std::atomic< bool > waiters
1: there are waiters
Definition: sync0rw.h:373
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:456
const char * last_s_file_name
last s-lock file/line is not guaranteed to be correct
Definition: sync0rw.h:409
os_event_t wait_ex_event
Event for next-writer to wait on.
Definition: sync0rw.h:403
volatile ulint sx_recursive
number of granted SX locks.
Definition: sync0rw.h:387
bool is_block_lock
If 1 then the rw-lock is a block lock.
Definition: sync0rw.h:415
uint32_t count_os_wait
Count of os_waits.
Definition: sync0rw.h:424
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:418
struct PSI_rwlock * pfs_psi
The instrumentation hook.
Definition: sync0rw.h:431
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:399
const char * last_x_file_name
File name where last x-locked.
Definition: sync0rw.h:412
Atomic_xor_of_thread_id reader_thread
XOR of reader threads' IDs.
Definition: sync0rw.h:396
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:406
std::atomic< int32_t > lock_word
Holds the state of the lock.
Definition: sync0rw.h:370
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:449
uint32_t magic_n
Definition: sync0rw.h:446
std::atomic< bool > recursive
Default value false which means the lock is non-recursive.
Definition: sync0rw.h:384
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: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:791
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:765
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:769
static bool rw_lock_s_lock_nowait(rw_lock_t *M, ut::Location L)
Definition: sync0rw.h:722
static void rw_lock_x_unlock_gen(rw_lock_t *L, ulint P)
Definition: sync0rw.h:778
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:740
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:773
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:714
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:727
static void rw_lock_x_unlock(rw_lock_t *L)
Definition: sync0rw.h:794
static void rw_lock_sx_unlock_gen(rw_lock_t *L, ulint P)
Definition: sync0rw.h:753
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: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:569
static void rw_lock_sx_unlock(rw_lock_t *L)
Definition: sync0rw.h:750
static void rw_lock_s_lock_gen(rw_lock_t *M, ulint P, ut::Location L)
Definition: sync0rw.h:718
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:736
static bool rw_lock_sx_lock_nowait(rw_lock_t *M, ulint P, ut::Location L)
Definition: sync0rw.h:744
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:787
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:341
ulint rw_lock_flags_t
Definition: sync0types.h:1205
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