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 */
626
ulint magic_n; /*!< RW_LOCK_MAGIC_N */
627
/** Value of rw_lock_struct::magic_n */
628
#define RW_LOCK_MAGIC_N 22643
629
#endif /* UNIV_DEBUG */
632
#ifdef UNIV_SYNC_DEBUG
633
/** The structure for storing debug info of an rw-lock */
634
struct rw_lock_debug_struct {
636
os_thread_id_t thread_id; /*!< The thread id of the thread which
637
locked the rw-lock */
638
ulint pass; /*!< Pass value given in the lock operation */
639
ulint lock_type; /*!< Type of the lock: RW_LOCK_EX,
640
RW_LOCK_SHARED, RW_LOCK_WAIT_EX */
641
const char* file_name;/*!< File name where the lock was obtained */
642
ulint line; /*!< Line where the rw-lock was locked */
643
UT_LIST_NODE_T(rw_lock_debug_t) list;
644
/*!< Debug structs are linked in a two-way
647
#endif /* UNIV_SYNC_DEBUG */
649
/* For performance schema instrumentation, a new set of rwlock
650
wrap functions are created if "UNIV_PFS_RWLOCK" is defined.
651
The instrumentations are not planted directly into original
652
functions, so that we keep the underlying function as they
653
are. And in case, user wants to "take out" some rwlock from
654
instrumentation even if performance schema (UNIV_PFS_RWLOCK)
655
is defined, they can do so by reinstating APIs directly link to
656
original underlying functions.
657
The instrumented function names have prefix of "pfs_rw_lock_" vs.
658
original name prefix of "rw_lock_". Following are list of functions
659
that have been instrumented:
664
rw_lock_x_lock_nowait()
665
rw_lock_x_unlock_gen()
668
rw_lock_s_lock_nowait()
669
rw_lock_s_unlock_gen()
672
Two function APIs rw_lock_x_unlock_direct() and rw_lock_s_unlock_direct()
673
do not have any caller/user, they are not instrumented.
676
#ifdef UNIV_PFS_RWLOCK
677
/******************************************************************//**
678
Performance schema instrumented wrap function for rw_lock_create_func()
679
NOTE! Please use the corresponding macro rw_lock_create(), not
680
directly this function! */
683
pfs_rw_lock_create_func(
684
/*====================*/
685
PSI_rwlock_key key, /*!< in: key registered with
686
performance schema */
687
rw_lock_t* lock, /*!< in: rw lock */
689
# ifdef UNIV_SYNC_DEBUG
690
ulint level, /*!< in: level */
691
# endif /* UNIV_SYNC_DEBUG */
692
const char* cmutex_name, /*!< in: mutex name */
693
#endif /* UNIV_DEBUG */
694
const char* cfile_name, /*!< in: file name where created */
695
ulint cline); /*!< in: file line where created */
697
/******************************************************************//**
698
Performance schema instrumented wrap function for rw_lock_x_lock_func()
699
NOTE! Please use the corresponding macro rw_lock_x_lock(), not
700
directly this function! */
703
pfs_rw_lock_x_lock_func(
704
/*====================*/
705
rw_lock_t* lock, /*!< in: pointer to rw-lock */
706
ulint pass, /*!< in: pass value; != 0, if the lock will
707
be passed to another thread to unlock */
708
const char* file_name,/*!< in: file name where lock requested */
709
ulint line); /*!< in: line where requested */
710
/******************************************************************//**
711
Performance schema instrumented wrap function for
712
rw_lock_x_lock_func_nowait()
713
NOTE! Please use the corresponding macro, not directly this function!
714
@return TRUE if success */
717
pfs_rw_lock_x_lock_func_nowait(
718
/*===========================*/
719
rw_lock_t* lock, /*!< in: pointer to rw-lock */
720
const char* file_name,/*!< in: file name where lock requested */
721
ulint line); /*!< in: line where requested */
722
/******************************************************************//**
723
Performance schema instrumented wrap function for rw_lock_s_lock_func()
724
NOTE! Please use the corresponding macro rw_lock_s_lock(), not directly
728
pfs_rw_lock_s_lock_func(
729
/*====================*/
730
rw_lock_t* lock, /*!< in: pointer to rw-lock */
731
ulint pass, /*!< in: pass value; != 0, if the lock will
732
be passed to another thread to unlock */
733
const char* file_name,/*!< in: file name where lock requested */
734
ulint line); /*!< in: line where requested */
735
/******************************************************************//**
736
Performance schema instrumented wrap function for rw_lock_s_lock_func()
737
NOTE! Please use the corresponding macro rw_lock_s_lock(), not directly
739
@return TRUE if success */
742
pfs_rw_lock_s_lock_low(
743
/*===================*/
744
rw_lock_t* lock, /*!< in: pointer to rw-lock */
745
ulint pass, /*!< in: pass value; != 0, if the
746
lock will be passed to another
748
const char* file_name, /*!< in: file name where lock requested */
749
ulint line); /*!< in: line where requested */
750
/******************************************************************//**
751
Performance schema instrumented wrap function for rw_lock_x_lock_func()
752
NOTE! Please use the corresponding macro rw_lock_x_lock(), not directly
756
pfs_rw_lock_x_lock_func(
757
/*====================*/
758
rw_lock_t* lock, /*!< in: pointer to rw-lock */
759
ulint pass, /*!< in: pass value; != 0, if the lock will
760
be passed to another thread to unlock */
761
const char* file_name,/*!< in: file name where lock requested */
762
ulint line); /*!< in: line where requested */
763
/******************************************************************//**
764
Performance schema instrumented wrap function for rw_lock_s_unlock_func()
765
NOTE! Please use the corresponding macro rw_lock_s_unlock(), not directly
769
pfs_rw_lock_s_unlock_func(
770
/*======================*/
771
#ifdef UNIV_SYNC_DEBUG
772
ulint pass, /*!< in: pass value; != 0, if the
773
lock may have been passed to another
776
rw_lock_t* lock); /*!< in/out: rw-lock */
777
/******************************************************************//**
778
Performance schema instrumented wrap function for rw_lock_s_unlock_func()
779
NOTE! Please use the corresponding macro rw_lock_x_unlock(), not directly
783
pfs_rw_lock_x_unlock_func(
784
/*======================*/
785
#ifdef UNIV_SYNC_DEBUG
786
ulint pass, /*!< in: pass value; != 0, if the
787
lock may have been passed to another
790
rw_lock_t* lock); /*!< in/out: rw-lock */
791
/******************************************************************//**
792
Performance schema instrumented wrap function for rw_lock_free_func()
793
NOTE! Please use the corresponding macro rw_lock_free(), not directly
797
pfs_rw_lock_free_func(
798
/*==================*/
799
rw_lock_t* lock); /*!< in: rw-lock */
800
#endif /* UNIV_PFS_RWLOCK */
804
#include "sync0rw.ic"
806
#endif /* !UNIV_HOTBACKUP */