1
/*****************************************************************************
3
Copyright (c) 1995, 2010, Innobase Oy. All Rights Reserved.
4
Copyright (c) 2008, Google Inc.
6
Portions of this file contain modifications contributed and copyrighted by
7
Google, Inc. Those modifications are gratefully acknowledged and are described
8
briefly in the InnoDB documentation. The contributions by Google are
9
incorporated with their permission, and subject to the conditions contained in
10
the file COPYING.Google.
12
This program is free software; you can redistribute it and/or modify it under
13
the terms of the GNU General Public License as published by the Free Software
14
Foundation; version 2 of the License.
16
This program is distributed in the hope that it will be useful, but WITHOUT
17
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
20
You should have received a copy of the GNU General Public License along with
21
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
22
St, Fifth Floor, Boston, MA 02110-1301 USA
24
*****************************************************************************/
26
/**************************************************//**
27
@file include/sync0rw.h
28
The read-write lock (for threads, not for database transactions)
30
Created 9/11/1995 Heikki Tuuri
31
*******************************************************/
37
#ifndef UNIV_HOTBACKUP
39
#include "sync0sync.h"
42
/* The following undef is to prevent a name conflict with a macro
45
#endif /* !UNIV_HOTBACKUP */
47
/* Latch types; these are used also in btr0btr.h: keep the numerical values
48
smaller than 30 and the order of the numerical values like below! */
53
#ifndef UNIV_HOTBACKUP
54
/* We decrement lock_word by this amount for each x_lock. It is also the
55
start value for the lock_word, meaning that it limits the maximum number
56
of concurrent read locks before the rw_lock breaks. The current value of
57
0x00100000 allows 1,048,575 concurrent readers and 2047 recursive writers.*/
58
#define X_LOCK_DECR 0x00100000
60
typedef struct rw_lock_struct rw_lock_t;
61
#ifdef UNIV_SYNC_DEBUG
62
typedef struct rw_lock_debug_struct rw_lock_debug_t;
63
#endif /* UNIV_SYNC_DEBUG */
65
typedef UT_LIST_BASE_NODE_T(rw_lock_t) rw_lock_list_t;
67
extern rw_lock_list_t rw_lock_list;
68
extern mutex_t rw_lock_list_mutex;
70
#ifdef UNIV_SYNC_DEBUG
71
/* The global mutex which protects debug info lists of all rw-locks.
72
To modify the debug info list of an rw-lock, this mutex has to be
74
acquired in addition to the mutex protecting the lock. */
75
extern mutex_t rw_lock_debug_mutex;
76
extern os_event_t rw_lock_debug_event; /*!< If deadlock detection does
77
not get immediately the mutex it
78
may wait for this event */
79
extern ibool rw_lock_debug_waiters; /*!< This is set to TRUE, if
80
there may be waiters for the event */
81
#endif /* UNIV_SYNC_DEBUG */
83
/** number of spin waits on rw-latches,
84
resulted during exclusive (write) locks */
85
extern ib_int64_t rw_s_spin_wait_count;
86
/** number of spin loop rounds on rw-latches,
87
resulted during exclusive (write) locks */
88
extern ib_int64_t rw_s_spin_round_count;
89
/** number of unlocks (that unlock shared locks),
90
set only when UNIV_SYNC_PERF_STAT is defined */
91
extern ib_int64_t rw_s_exit_count;
92
/** number of OS waits on rw-latches,
93
resulted during shared (read) locks */
94
extern ib_int64_t rw_s_os_wait_count;
95
/** number of spin waits on rw-latches,
96
resulted during shared (read) locks */
97
extern ib_int64_t rw_x_spin_wait_count;
98
/** number of spin loop rounds on rw-latches,
99
resulted during shared (read) locks */
100
extern ib_int64_t rw_x_spin_round_count;
101
/** number of OS waits on rw-latches,
102
resulted during exclusive (write) locks */
103
extern ib_int64_t rw_x_os_wait_count;
104
/** number of unlocks (that unlock exclusive locks),
105
set only when UNIV_SYNC_PERF_STAT is defined */
106
extern ib_int64_t rw_x_exit_count;
108
#ifdef UNIV_PFS_RWLOCK
109
/* Following are rwlock keys used to register with MySQL
110
performance schema */
111
# ifdef UNIV_LOG_ARCHIVE
112
extern mysql_pfs_key_t archive_lock_key;
113
# endif /* UNIV_LOG_ARCHIVE */
114
extern mysql_pfs_key_t btr_search_latch_key;
115
extern mysql_pfs_key_t buf_block_lock_key;
116
# ifdef UNIV_SYNC_DEBUG
117
extern mysql_pfs_key_t buf_block_debug_latch_key;
118
# endif /* UNIV_SYNC_DEBUG */
119
extern mysql_pfs_key_t dict_operation_lock_key;
120
extern mysql_pfs_key_t fil_space_latch_key;
121
extern mysql_pfs_key_t checkpoint_lock_key;
122
extern mysql_pfs_key_t trx_i_s_cache_lock_key;
123
extern mysql_pfs_key_t trx_purge_latch_key;
124
extern mysql_pfs_key_t index_tree_rw_lock_key;
125
#endif /* UNIV_PFS_RWLOCK */
128
#ifndef UNIV_PFS_RWLOCK
129
/******************************************************************//**
130
Creates, or rather, initializes an rw-lock object in a specified memory
131
location (which must be appropriately aligned). The rw-lock is initialized
132
to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free
133
is necessary only if the memory block containing it is freed.
134
if MySQL performance schema is enabled and "UNIV_PFS_RWLOCK" is
135
defined, the rwlock are instrumented with performance schema probes. */
137
# ifdef UNIV_SYNC_DEBUG
138
# define rw_lock_create(K, L, level) \
139
rw_lock_create_func((L), (level), #L, __FILE__, __LINE__)
140
# else /* UNIV_SYNC_DEBUG */
141
# define rw_lock_create(K, L, level) \
142
rw_lock_create_func((L), #L, __FILE__, __LINE__)
143
# endif/* UNIV_SYNC_DEBUG */
144
# else /* UNIV_DEBUG */
145
# define rw_lock_create(K, L, level) \
146
rw_lock_create_func((L), __FILE__, __LINE__)
147
# endif /* UNIV_DEBUG */
149
/**************************************************************//**
150
NOTE! The following macros should be used in rw locking and
151
unlocking, not the corresponding function. */
153
# define rw_lock_s_lock(M) \
154
rw_lock_s_lock_func((M), 0, __FILE__, __LINE__)
156
# define rw_lock_s_lock_gen(M, P) \
157
rw_lock_s_lock_func((M), (P), __FILE__, __LINE__)
159
# define rw_lock_s_lock_nowait(M, F, L) \
160
rw_lock_s_lock_low((M), 0, (F), (L))
162
# ifdef UNIV_SYNC_DEBUG
163
# define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(P, L)
165
# define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(L)
169
# define rw_lock_x_lock(M) \
170
rw_lock_x_lock_func((M), 0, __FILE__, __LINE__)
172
# define rw_lock_x_lock_gen(M, P) \
173
rw_lock_x_lock_func((M), (P), __FILE__, __LINE__)
175
# define rw_lock_x_lock_nowait(M) \
176
rw_lock_x_lock_func_nowait((M), __FILE__, __LINE__)
178
# ifdef UNIV_SYNC_DEBUG
179
# define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(P, L)
181
# define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(L)
184
# define rw_lock_free(M) rw_lock_free_func(M)
186
#else /* !UNIV_PFS_RWLOCK */
188
/* Following macros point to Performance Schema instrumented functions. */
190
# ifdef UNIV_SYNC_DEBUG
191
# define rw_lock_create(K, L, level) \
192
pfs_rw_lock_create_func((K), (L), (level), #L, __FILE__, __LINE__)
193
# else /* UNIV_SYNC_DEBUG */
194
# define rw_lock_create(K, L, level) \
195
pfs_rw_lock_create_func((K), (L), #L, __FILE__, __LINE__)
196
# endif/* UNIV_SYNC_DEBUG */
197
# else /* UNIV_DEBUG */
198
# define rw_lock_create(K, L, level) \
199
pfs_rw_lock_create_func((K), (L), __FILE__, __LINE__)
200
# endif /* UNIV_DEBUG */
202
/******************************************************************
203
NOTE! The following macros should be used in rw locking and
204
unlocking, not the corresponding function. */
206
# define rw_lock_s_lock(M) \
207
pfs_rw_lock_s_lock_func((M), 0, __FILE__, __LINE__)
209
# define rw_lock_s_lock_gen(M, P) \
210
pfs_rw_lock_s_lock_func((M), (P), __FILE__, __LINE__)
212
# define rw_lock_s_lock_nowait(M, F, L) \
213
pfs_rw_lock_s_lock_low((M), 0, (F), (L))
215
# ifdef UNIV_SYNC_DEBUG
216
# define rw_lock_s_unlock_gen(L, P) pfs_rw_lock_s_unlock_func(P, L)
218
# define rw_lock_s_unlock_gen(L, P) pfs_rw_lock_s_unlock_func(L)
221
# define rw_lock_x_lock(M) \
222
pfs_rw_lock_x_lock_func((M), 0, __FILE__, __LINE__)
224
# define rw_lock_x_lock_gen(M, P) \
225
pfs_rw_lock_x_lock_func((M), (P), __FILE__, __LINE__)
227
# define rw_lock_x_lock_nowait(M) \
228
pfs_rw_lock_x_lock_func_nowait((M), __FILE__, __LINE__)
230
# ifdef UNIV_SYNC_DEBUG
231
# define rw_lock_x_unlock_gen(L, P) pfs_rw_lock_x_unlock_func(P, L)
233
# define rw_lock_x_unlock_gen(L, P) pfs_rw_lock_x_unlock_func(L)
236
# define rw_lock_free(M) pfs_rw_lock_free_func(M)
238
#endif /* UNIV_PFS_RWLOCK */
240
#define rw_lock_s_unlock(L) rw_lock_s_unlock_gen(L, 0)
241
#define rw_lock_x_unlock(L) rw_lock_x_unlock_gen(L, 0)
243
/******************************************************************//**
244
Creates, or rather, initializes an rw-lock object in a specified memory
245
location (which must be appropriately aligned). The rw-lock is initialized
246
to the non-locked state. Explicit freeing of the rw-lock with rw_lock_free
247
is necessary only if the memory block containing it is freed. */
252
rw_lock_t* lock, /*!< in: pointer to memory */
254
# ifdef UNIV_SYNC_DEBUG
255
ulint level, /*!< in: level */
256
# endif /* UNIV_SYNC_DEBUG */
257
const char* cmutex_name, /*!< in: mutex name */
258
#endif /* UNIV_DEBUG */
259
const char* cfile_name, /*!< in: file name where created */
260
ulint cline); /*!< in: file line where created */
261
/******************************************************************//**
262
Calling this function is obligatory only if the memory buffer containing
263
the rw-lock is freed. Removes an rw-lock object from the global list. The
264
rw-lock is checked to be in the non-locked state. */
269
rw_lock_t* lock); /*!< in: rw-lock */
271
/******************************************************************//**
272
Checks that the rw-lock has been initialized and that there are no
273
simultaneous shared and exclusive locks.
279
rw_lock_t* lock); /*!< in: rw-lock */
280
#endif /* UNIV_DEBUG */
281
/******************************************************************//**
282
Low-level function which tries to lock an rw-lock in s-mode. Performs no
284
@return TRUE if success */
289
rw_lock_t* lock, /*!< in: pointer to rw-lock */
290
ulint pass __attribute__((unused)),
291
/*!< in: pass value; != 0, if the lock will be
292
passed to another thread to unlock */
293
const char* file_name, /*!< in: file name where lock requested */
294
ulint line); /*!< in: line where requested */
295
/******************************************************************//**
296
NOTE! Use the corresponding macro, not directly this function, except if
297
you supply the file name and line number. Lock an rw-lock in shared mode
298
for the current thread. If the rw-lock is locked in exclusive mode, or
299
there is an exclusive lock request waiting, the function spins a preset
300
time (controlled by SYNC_SPIN_ROUNDS), waiting for the lock, before
301
suspending the thread. */
306
rw_lock_t* lock, /*!< in: pointer to rw-lock */
307
ulint pass, /*!< in: pass value; != 0, if the lock will
308
be passed to another thread to unlock */
309
const char* file_name,/*!< in: file name where lock requested */
310
ulint line); /*!< in: line where requested */
311
/******************************************************************//**
312
NOTE! Use the corresponding macro, not directly this function! Lock an
313
rw-lock in exclusive mode for the current thread if the lock can be
314
obtained immediately.
315
@return TRUE if success */
318
rw_lock_x_lock_func_nowait(
319
/*=======================*/
320
rw_lock_t* lock, /*!< in: pointer to rw-lock */
321
const char* file_name,/*!< in: file name where lock requested */
322
ulint line); /*!< in: line where requested */
323
/******************************************************************//**
324
Releases a shared mode lock. */
327
rw_lock_s_unlock_func(
328
/*==================*/
329
#ifdef UNIV_SYNC_DEBUG
330
ulint pass, /*!< in: pass value; != 0, if the lock may have
331
been passed to another thread to unlock */
333
rw_lock_t* lock); /*!< in/out: rw-lock */
335
/******************************************************************//**
336
NOTE! Use the corresponding macro, not directly this function! Lock an
337
rw-lock in exclusive mode for the current thread. If the rw-lock is locked
338
in shared or exclusive mode, or there is an exclusive lock request waiting,
339
the function spins a preset time (controlled by SYNC_SPIN_ROUNDS), waiting
340
for the lock, before suspending the thread. If the same thread has an x-lock
341
on the rw-lock, locking succeed, with the following exception: if pass != 0,
342
only a single x-lock may be taken on the lock. NOTE: If the same thread has
343
an s-lock, locking does not succeed! */
348
rw_lock_t* lock, /*!< in: pointer to rw-lock */
349
ulint pass, /*!< in: pass value; != 0, if the lock will
350
be passed to another thread to unlock */
351
const char* file_name,/*!< in: file name where lock requested */
352
ulint line); /*!< in: line where requested */
353
/******************************************************************//**
354
Releases an exclusive mode lock. */
357
rw_lock_x_unlock_func(
358
/*==================*/
359
#ifdef UNIV_SYNC_DEBUG
360
ulint pass, /*!< in: pass value; != 0, if the lock may have
361
been passed to another thread to unlock */
363
rw_lock_t* lock); /*!< in/out: rw-lock */
366
/******************************************************************//**
367
Low-level function which locks an rw-lock in s-mode when we know that it
368
is possible and none else is currently accessing the rw-lock structure.
369
Then we can do the locking without reserving the mutex. */
372
rw_lock_s_lock_direct(
373
/*==================*/
374
rw_lock_t* lock, /*!< in/out: rw-lock */
375
const char* file_name, /*!< in: file name where requested */
376
ulint line); /*!< in: line where lock requested */
377
/******************************************************************//**
378
Low-level function which locks an rw-lock in x-mode when we know that it
379
is not locked and none else is currently accessing the rw-lock structure.
380
Then we can do the locking without reserving the mutex. */
383
rw_lock_x_lock_direct(
384
/*==================*/
385
rw_lock_t* lock, /*!< in/out: rw-lock */
386
const char* file_name, /*!< in: file name where requested */
387
ulint line); /*!< in: line where lock requested */
388
/******************************************************************//**
389
This function is used in the insert buffer to move the ownership of an
390
x-latch on a buffer frame to the current thread. The x-latch was set by
391
the buffer read operation and it protected the buffer frame while the
392
read was done. The ownership is moved because we want that the current
393
thread is able to acquire a second x-latch which is stored in an mtr.
394
This, in turn, is needed to pass the debug checks of index page
398
rw_lock_x_lock_move_ownership(
399
/*==========================*/
400
rw_lock_t* lock); /*!< in: lock which was x-locked in the
402
/******************************************************************//**
403
Releases a shared mode lock when we know there are no waiters and none
404
else will access the lock during the time this function is executed. */
407
rw_lock_s_unlock_direct(
408
/*====================*/
409
rw_lock_t* lock); /*!< in/out: rw-lock */
410
/******************************************************************//**
411
Releases an exclusive mode lock when we know there are no waiters, and
412
none else will access the lock durint the time this function is executed. */
415
rw_lock_x_unlock_direct(
416
/*====================*/
417
rw_lock_t* lock); /*!< in/out: rw-lock */
418
/******************************************************************//**
419
Returns the value of writer_count for the lock. Does not reserve the lock
420
mutex, so the caller must be sure it is not changed during the call.
421
@return value of writer_count */
424
rw_lock_get_x_lock_count(
425
/*=====================*/
426
const rw_lock_t* lock); /*!< in: rw-lock */
427
/********************************************************************//**
428
Check if there are threads waiting for the rw-lock.
429
@return 1 if waiters, 0 otherwise */
434
const rw_lock_t* lock); /*!< in: rw-lock */
435
/******************************************************************//**
436
Returns the write-status of the lock - this function made more sense
437
with the old rw_lock implementation.
438
@return RW_LOCK_NOT_LOCKED, RW_LOCK_EX, RW_LOCK_WAIT_EX */
443
const rw_lock_t* lock); /*!< in: rw-lock */
444
/******************************************************************//**
445
Returns the number of readers.
446
@return number of readers */
449
rw_lock_get_reader_count(
450
/*=====================*/
451
const rw_lock_t* lock); /*!< in: rw-lock */
452
/******************************************************************//**
453
Decrements lock_word the specified amount if it is greater than 0.
454
This is used by both s_lock and x_lock operations.
455
@return TRUE if decr occurs */
458
rw_lock_lock_word_decr(
459
/*===================*/
460
rw_lock_t* lock, /*!< in/out: rw-lock */
461
ulint amount); /*!< in: amount to decrement */
462
/******************************************************************//**
463
Increments lock_word the specified amount and returns new value.
464
@return lock->lock_word after increment */
467
rw_lock_lock_word_incr(
468
/*===================*/
469
rw_lock_t* lock, /*!< in/out: rw-lock */
470
ulint amount); /*!< in: amount to increment */
471
/******************************************************************//**
472
This function sets the lock->writer_thread and lock->recursive fields.
473
For platforms where we are using atomic builtins instead of lock->mutex
474
it sets the lock->writer_thread field using atomics to ensure memory
475
ordering. Note that it is assumed that the caller of this function
476
effectively owns the lock i.e.: nobody else is allowed to modify
477
lock->writer_thread at this point in time.
478
The protocol is that lock->writer_thread MUST be updated BEFORE the
479
lock->recursive flag is set. */
482
rw_lock_set_writer_id_and_recursion_flag(
483
/*=====================================*/
484
rw_lock_t* lock, /*!< in/out: lock to work on */
485
ibool recursive); /*!< in: TRUE if recursion
487
#ifdef UNIV_SYNC_DEBUG
488
/******************************************************************//**
489
Checks if the thread has locked the rw-lock in the specified mode, with
490
the pass value == 0. */
495
rw_lock_t* lock, /*!< in: rw-lock */
496
ulint lock_type) /*!< in: lock type: RW_LOCK_SHARED,
498
__attribute__((warn_unused_result));
499
#endif /* UNIV_SYNC_DEBUG */
500
/******************************************************************//**
501
Checks if somebody has locked the rw-lock in the specified mode. */
506
rw_lock_t* lock, /*!< in: rw-lock */
507
ulint lock_type); /*!< in: lock type: RW_LOCK_SHARED,
509
#ifdef UNIV_SYNC_DEBUG
510
/***************************************************************//**
511
Prints debug info of an rw-lock. */
516
rw_lock_t* lock); /*!< in: rw-lock */
517
/***************************************************************//**
518
Prints debug info of currently locked rw-locks. */
521
rw_lock_list_print_info(
522
/*====================*/
523
FILE* file); /*!< in: file where to print */
524
/***************************************************************//**
525
Returns the number of currently locked rw-locks.
526
Works only in the debug version.
527
@return number of locked rw-locks */
530
rw_lock_n_locked(void);
531
/*==================*/
533
/*#####################################################################*/
535
/******************************************************************//**
536
Acquires the debug mutex. We cannot use the mutex defined in sync0sync,
537
because the debug mutex is also acquired in sync0arr while holding the OS
538
mutex protecting the sync array, and the ordinary mutex_enter might
539
recursively call routines in sync0arr, leading to a deadlock on the OS
543
rw_lock_debug_mutex_enter(void);
544
/*==========================*/
545
/******************************************************************//**
546
Releases the debug mutex. */
549
rw_lock_debug_mutex_exit(void);
550
/*==========================*/
551
/*********************************************************************//**
552
Prints info of a debug struct. */
557
rw_lock_debug_t* info); /*!< in: debug struct */
558
#endif /* UNIV_SYNC_DEBUG */
560
/* NOTE! The structure appears here only for the compiler to know its size.
561
Do not use its fields directly! */
563
/** The structure used in the spin lock implementation of a read-write
564
lock. Several threads may have a shared lock simultaneously in this
565
lock, but only one writer may have an exclusive lock, in which case no
566
shared locks are allowed. To prevent starving of a writer blocked by
567
readers, a writer may queue for x-lock by decrementing lock_word: no
568
new readers will be let in while the thread waits for readers to
570
struct rw_lock_struct {
571
volatile lint lock_word;
572
/*!< Holds the state of the lock. */
573
volatile ulint waiters;/*!< 1: there are waiters */
574
volatile ibool recursive;/*!< Default value FALSE which means the lock
575
is non-recursive. The value is typically set
576
to TRUE making normal rw_locks recursive. In
577
case of asynchronous IO, when a non-zero
578
value of 'pass' is passed then we keep the
580
This flag also tells us about the state of
581
writer_thread field. If this flag is set
582
then writer_thread MUST contain the thread
583
id of the current x-holder or wait-x thread.
584
This flag must be reset in x_unlock
585
functions before incrementing the lock_word */
586
volatile os_thread_id_t writer_thread;
587
/*!< Thread id of writer thread. Is only
588
guaranteed to have sane and non-stale
589
value iff recursive flag is set. */
590
os_event_t event; /*!< Used by sync0arr.c for thread queueing */
591
os_event_t wait_ex_event;
592
/*!< Event for next-writer to wait on. A thread
593
must decrement lock_word before waiting. */
594
#ifndef INNODB_RW_LOCKS_USE_ATOMICS
595
mutex_t mutex; /*!< The mutex protecting rw_lock_struct */
596
#endif /* INNODB_RW_LOCKS_USE_ATOMICS */
598
UT_LIST_NODE_T(rw_lock_t) list;
599
/*!< All allocated rw locks are put into a
601
#ifdef UNIV_SYNC_DEBUG
602
UT_LIST_BASE_NODE_T(rw_lock_debug_t) debug_list;
603
/*!< In the debug version: pointer to the debug
604
info list of the lock */
605
ulint level; /*!< Level in the global latching order. */
606
#endif /* UNIV_SYNC_DEBUG */
607
#ifdef UNIV_PFS_RWLOCK
608
struct PSI_rwlock *pfs_psi;/*!< The instrumentation hook */
610
ulint count_os_wait; /*!< Count of os_waits. May not be accurate */
611
const char* cfile_name;/*!< File name where lock created */
612
/* last s-lock file/line is not guaranteed to be correct */
613
const char* last_s_file_name;/*!< File name where last s-locked */
614
const char* last_x_file_name;/*!< File name where last x-locked */
615
ibool writer_is_wait_ex;
616
/*!< This is TRUE if the writer field is
617
RW_LOCK_WAIT_EX; this field is located far
618
from the memory update hotspot fields which
619
are at the start of this struct, thus we can
620
peek this field without causing much memory
622
unsigned cline:14; /*!< Line where created */
623
unsigned last_s_line:14; /*!< Line number where last time s-locked */
624
unsigned last_x_line:14; /*!< Line number where last time x-locked */
625
ulint magic_n; /*!< RW_LOCK_MAGIC_N */
628
/** Value of rw_lock_struct::magic_n */
629
#define RW_LOCK_MAGIC_N 22643
631
#ifdef UNIV_SYNC_DEBUG
632
/** The structure for storing debug info of an rw-lock */
633
struct rw_lock_debug_struct {
635
os_thread_id_t thread_id; /*!< The thread id of the thread which
636
locked the rw-lock */
637
ulint pass; /*!< Pass value given in the lock operation */
638
ulint lock_type; /*!< Type of the lock: RW_LOCK_EX,
639
RW_LOCK_SHARED, RW_LOCK_WAIT_EX */
640
const char* file_name;/*!< File name where the lock was obtained */
641
ulint line; /*!< Line where the rw-lock was locked */
642
UT_LIST_NODE_T(rw_lock_debug_t) list;
643
/*!< Debug structs are linked in a two-way
646
#endif /* UNIV_SYNC_DEBUG */
648
/* For performance schema instrumentation, a new set of rwlock
649
wrap functions are created if "UNIV_PFS_RWLOCK" is defined.
650
The instrumentations are not planted directly into original
651
functions, so that we keep the underlying function as they
652
are. And in case, user wants to "take out" some rwlock from
653
instrumentation even if performance schema (UNIV_PFS_RWLOCK)
654
is defined, they can do so by reinstating APIs directly link to
655
original underlying functions.
656
The instrumented function names have prefix of "pfs_rw_lock_" vs.
657
original name prefix of "rw_lock_". Following are list of functions
658
that have been instrumented:
663
rw_lock_x_lock_nowait()
664
rw_lock_x_unlock_gen()
667
rw_lock_s_lock_nowait()
668
rw_lock_s_unlock_gen()
671
Two function APIs rw_lock_x_unlock_direct() and rw_lock_s_unlock_direct()
672
do not have any caller/user, they are not instrumented.
675
#ifdef UNIV_PFS_RWLOCK
676
/******************************************************************//**
677
Performance schema instrumented wrap function for rw_lock_create_func()
678
NOTE! Please use the corresponding macro rw_lock_create(), not
679
directly this function! */
682
pfs_rw_lock_create_func(
683
/*====================*/
684
PSI_rwlock_key key, /*!< in: key registered with
685
performance schema */
686
rw_lock_t* lock, /*!< in: rw lock */
688
# ifdef UNIV_SYNC_DEBUG
689
ulint level, /*!< in: level */
690
# endif /* UNIV_SYNC_DEBUG */
691
const char* cmutex_name, /*!< in: mutex name */
692
#endif /* UNIV_DEBUG */
693
const char* cfile_name, /*!< in: file name where created */
694
ulint cline); /*!< in: file line where created */
696
/******************************************************************//**
697
Performance schema instrumented wrap function for rw_lock_x_lock_func()
698
NOTE! Please use the corresponding macro rw_lock_x_lock(), not
699
directly this function! */
702
pfs_rw_lock_x_lock_func(
703
/*====================*/
704
rw_lock_t* lock, /*!< in: pointer to rw-lock */
705
ulint pass, /*!< in: pass value; != 0, if the lock will
706
be passed to another thread to unlock */
707
const char* file_name,/*!< in: file name where lock requested */
708
ulint line); /*!< in: line where requested */
709
/******************************************************************//**
710
Performance schema instrumented wrap function for
711
rw_lock_x_lock_func_nowait()
712
NOTE! Please use the corresponding macro, not directly this function!
713
@return TRUE if success */
716
pfs_rw_lock_x_lock_func_nowait(
717
/*===========================*/
718
rw_lock_t* lock, /*!< in: pointer to rw-lock */
719
const char* file_name,/*!< in: file name where lock requested */
720
ulint line); /*!< in: line where requested */
721
/******************************************************************//**
722
Performance schema instrumented wrap function for rw_lock_s_lock_func()
723
NOTE! Please use the corresponding macro rw_lock_s_lock(), not directly
727
pfs_rw_lock_s_lock_func(
728
/*====================*/
729
rw_lock_t* lock, /*!< in: pointer to rw-lock */
730
ulint pass, /*!< in: pass value; != 0, if the lock will
731
be passed to another thread to unlock */
732
const char* file_name,/*!< in: file name where lock requested */
733
ulint line); /*!< in: line where requested */
734
/******************************************************************//**
735
Performance schema instrumented wrap function for rw_lock_s_lock_func()
736
NOTE! Please use the corresponding macro rw_lock_s_lock(), not directly
738
@return TRUE if success */
741
pfs_rw_lock_s_lock_low(
742
/*===================*/
743
rw_lock_t* lock, /*!< in: pointer to rw-lock */
744
ulint pass, /*!< in: pass value; != 0, if the
745
lock will be passed to another
747
const char* file_name, /*!< in: file name where lock requested */
748
ulint line); /*!< in: line where requested */
749
/******************************************************************//**
750
Performance schema instrumented wrap function for rw_lock_x_lock_func()
751
NOTE! Please use the corresponding macro rw_lock_x_lock(), not directly
755
pfs_rw_lock_x_lock_func(
756
/*====================*/
757
rw_lock_t* lock, /*!< in: pointer to rw-lock */
758
ulint pass, /*!< in: pass value; != 0, if the lock will
759
be passed to another thread to unlock */
760
const char* file_name,/*!< in: file name where lock requested */
761
ulint line); /*!< in: line where requested */
762
/******************************************************************//**
763
Performance schema instrumented wrap function for rw_lock_s_unlock_func()
764
NOTE! Please use the corresponding macro rw_lock_s_unlock(), not directly
768
pfs_rw_lock_s_unlock_func(
769
/*======================*/
770
#ifdef UNIV_SYNC_DEBUG
771
ulint pass, /*!< in: pass value; != 0, if the
772
lock may have been passed to another
775
rw_lock_t* lock); /*!< in/out: rw-lock */
776
/******************************************************************//**
777
Performance schema instrumented wrap function for rw_lock_s_unlock_func()
778
NOTE! Please use the corresponding macro rw_lock_x_unlock(), not directly
782
pfs_rw_lock_x_unlock_func(
783
/*======================*/
784
#ifdef UNIV_SYNC_DEBUG
785
ulint pass, /*!< in: pass value; != 0, if the
786
lock may have been passed to another
789
rw_lock_t* lock); /*!< in/out: rw-lock */
790
/******************************************************************//**
791
Performance schema instrumented wrap function for rw_lock_free_func()
792
NOTE! Please use the corresponding macro rw_lock_free(), not directly
796
pfs_rw_lock_free_func(
797
/*==================*/
798
rw_lock_t* lock); /*!< in: rw-lock */
799
#endif /* UNIV_PFS_RWLOCK */
803
#include "sync0rw.ic"
805
#endif /* !UNIV_HOTBACKUP */