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