MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
sync0rw.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (c) 1995, 2011, Oracle and/or its affiliates. All Rights Reserved.
4 Copyright (c) 2008, Google Inc.
5 
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.
11 
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.
15 
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.
19 
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.,
22 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
23 
24 *****************************************************************************/
25 
26 /**************************************************/
33 #ifndef sync0rw_h
34 #define sync0rw_h
35 
36 #include "univ.i"
37 #ifndef UNIV_HOTBACKUP
38 #include "ut0lst.h"
39 #include "ut0counter.h"
40 #include "sync0sync.h"
41 #include "os0sync.h"
42 
43 /* The following undef is to prevent a name conflict with a macro
44 in MySQL: */
45 #undef rw_lock_t
46 #endif /* !UNIV_HOTBACKUP */
47 
51 
55 
59 
63 
67 
71 
75 
79 
83 };
84 
85 /* Latch types; these are used also in btr0btr.h: keep the numerical values
86 smaller than 30 and the order of the numerical values like below! */
87 #define RW_S_LATCH 1
88 #define RW_X_LATCH 2
89 #define RW_NO_LATCH 3
90 
91 #ifndef UNIV_HOTBACKUP
92 /* We decrement lock_word by this amount for each x_lock. It is also the
93 start value for the lock_word, meaning that it limits the maximum number
94 of concurrent read locks before the rw_lock breaks. The current value of
95 0x00100000 allows 1,048,575 concurrent readers and 2047 recursive writers.*/
96 #define X_LOCK_DECR 0x00100000
97 
98 struct rw_lock_t;
99 #ifdef UNIV_SYNC_DEBUG
100 struct rw_lock_debug_t;
101 #endif /* UNIV_SYNC_DEBUG */
102 
103 typedef UT_LIST_BASE_NODE_T(rw_lock_t) rw_lock_list_t;
104 
105 extern rw_lock_list_t rw_lock_list;
106 extern ib_mutex_t rw_lock_list_mutex;
107 
108 #ifdef UNIV_SYNC_DEBUG
109 /* The global mutex which protects debug info lists of all rw-locks.
110 To modify the debug info list of an rw-lock, this mutex has to be
111 
112 acquired in addition to the mutex protecting the lock. */
113 extern ib_mutex_t rw_lock_debug_mutex;
114 extern os_event_t rw_lock_debug_event;
117 extern ibool rw_lock_debug_waiters;
119 #endif /* UNIV_SYNC_DEBUG */
120 
123 
124 #ifdef UNIV_PFS_RWLOCK
125 /* Following are rwlock keys used to register with MySQL
126 performance schema */
127 # ifdef UNIV_LOG_ARCHIVE
128 extern mysql_pfs_key_t archive_lock_key;
129 # endif /* UNIV_LOG_ARCHIVE */
130 extern mysql_pfs_key_t btr_search_latch_key;
131 extern mysql_pfs_key_t buf_block_lock_key;
132 # ifdef UNIV_SYNC_DEBUG
133 extern mysql_pfs_key_t buf_block_debug_latch_key;
134 # endif /* UNIV_SYNC_DEBUG */
135 extern mysql_pfs_key_t dict_operation_lock_key;
136 extern mysql_pfs_key_t checkpoint_lock_key;
137 extern mysql_pfs_key_t fil_space_latch_key;
138 extern mysql_pfs_key_t fts_cache_rw_lock_key;
139 extern mysql_pfs_key_t fts_cache_init_rw_lock_key;
140 extern mysql_pfs_key_t trx_i_s_cache_lock_key;
141 extern mysql_pfs_key_t trx_purge_latch_key;
142 extern mysql_pfs_key_t index_tree_rw_lock_key;
143 extern mysql_pfs_key_t index_online_log_key;
144 extern mysql_pfs_key_t dict_table_stats_latch_key;
145 extern mysql_pfs_key_t trx_sys_rw_lock_key;
146 extern mysql_pfs_key_t hash_table_rw_lock_key;
147 #endif /* UNIV_PFS_RWLOCK */
148 
149 
150 #ifndef UNIV_PFS_RWLOCK
151 /******************************************************************/
158 # ifdef UNIV_DEBUG
159 # ifdef UNIV_SYNC_DEBUG
160 # define rw_lock_create(K, L, level) \
161  rw_lock_create_func((L), (level), #L, __FILE__, __LINE__)
162 # else /* UNIV_SYNC_DEBUG */
163 # define rw_lock_create(K, L, level) \
164  rw_lock_create_func((L), #L, __FILE__, __LINE__)
165 # endif/* UNIV_SYNC_DEBUG */
166 # else /* UNIV_DEBUG */
167 # define rw_lock_create(K, L, level) \
168  rw_lock_create_func((L), __FILE__, __LINE__)
169 # endif /* UNIV_DEBUG */
170 
171 /**************************************************************/
175 # define rw_lock_s_lock(M) \
176  rw_lock_s_lock_func((M), 0, __FILE__, __LINE__)
177 
178 # define rw_lock_s_lock_inline(M, P, F, L) \
179  rw_lock_s_lock_func((M), (P), (F), (L))
180 
181 # define rw_lock_s_lock_gen(M, P) \
182  rw_lock_s_lock_func((M), (P), __FILE__, __LINE__)
183 
184 # define rw_lock_s_lock_nowait(M, F, L) \
185  rw_lock_s_lock_low((M), 0, (F), (L))
186 
187 # ifdef UNIV_SYNC_DEBUG
188 # define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(P, L)
189 # else
190 # define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(L)
191 # endif
192 
193 
194 # define rw_lock_x_lock(M) \
195  rw_lock_x_lock_func((M), 0, __FILE__, __LINE__)
196 
197 # define rw_lock_x_lock_inline(M, P, F, L) \
198  rw_lock_x_lock_func((M), (P), (F), (L))
199 
200 # define rw_lock_x_lock_gen(M, P) \
201  rw_lock_x_lock_func((M), (P), __FILE__, __LINE__)
202 
203 # define rw_lock_x_lock_nowait(M) \
204  rw_lock_x_lock_func_nowait((M), __FILE__, __LINE__)
205 
206 # define rw_lock_x_lock_func_nowait_inline(M, F, L) \
207  rw_lock_x_lock_func_nowait((M), (F), (L))
208 
209 # ifdef UNIV_SYNC_DEBUG
210 # define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(P, L)
211 # else
212 # define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(L)
213 # endif
214 
215 # define rw_lock_free(M) rw_lock_free_func(M)
216 
217 #else /* !UNIV_PFS_RWLOCK */
218 
219 /* Following macros point to Performance Schema instrumented functions. */
220 # ifdef UNIV_DEBUG
221 # ifdef UNIV_SYNC_DEBUG
222 # define rw_lock_create(K, L, level) \
223  pfs_rw_lock_create_func((K), (L), (level), #L, __FILE__, __LINE__)
224 # else /* UNIV_SYNC_DEBUG */
225 # define rw_lock_create(K, L, level) \
226  pfs_rw_lock_create_func((K), (L), #L, __FILE__, __LINE__)
227 # endif/* UNIV_SYNC_DEBUG */
228 # else /* UNIV_DEBUG */
229 # define rw_lock_create(K, L, level) \
230  pfs_rw_lock_create_func((K), (L), __FILE__, __LINE__)
231 # endif /* UNIV_DEBUG */
232 
233 /******************************************************************
234 NOTE! The following macros should be used in rw locking and
235 unlocking, not the corresponding function. */
236 
237 # define rw_lock_s_lock(M) \
238  pfs_rw_lock_s_lock_func((M), 0, __FILE__, __LINE__)
239 
240 # define rw_lock_s_lock_inline(M, P, F, L) \
241  pfs_rw_lock_s_lock_func((M), (P), (F), (L))
242 
243 # define rw_lock_s_lock_gen(M, P) \
244  pfs_rw_lock_s_lock_func((M), (P), __FILE__, __LINE__)
245 
246 # define rw_lock_s_lock_nowait(M, F, L) \
247  pfs_rw_lock_s_lock_low((M), 0, (F), (L))
248 
249 # ifdef UNIV_SYNC_DEBUG
250 # define rw_lock_s_unlock_gen(L, P) pfs_rw_lock_s_unlock_func(P, L)
251 # else
252 # define rw_lock_s_unlock_gen(L, P) pfs_rw_lock_s_unlock_func(L)
253 # endif
254 
255 # define rw_lock_x_lock(M) \
256  pfs_rw_lock_x_lock_func((M), 0, __FILE__, __LINE__)
257 
258 # define rw_lock_x_lock_inline(M, P, F, L) \
259  pfs_rw_lock_x_lock_func((M), (P), (F), (L))
260 
261 # define rw_lock_x_lock_gen(M, P) \
262  pfs_rw_lock_x_lock_func((M), (P), __FILE__, __LINE__)
263 
264 # define rw_lock_x_lock_nowait(M) \
265  pfs_rw_lock_x_lock_func_nowait((M), __FILE__, __LINE__)
266 
267 # define rw_lock_x_lock_func_nowait_inline(M, F, L) \
268  pfs_rw_lock_x_lock_func_nowait((M), (F), (L))
269 
270 # ifdef UNIV_SYNC_DEBUG
271 # define rw_lock_x_unlock_gen(L, P) pfs_rw_lock_x_unlock_func(P, L)
272 # else
273 # define rw_lock_x_unlock_gen(L, P) pfs_rw_lock_x_unlock_func(L)
274 # endif
275 
276 # define rw_lock_free(M) pfs_rw_lock_free_func(M)
277 
278 #endif /* UNIV_PFS_RWLOCK */
279 
280 #define rw_lock_s_unlock(L) rw_lock_s_unlock_gen(L, 0)
281 #define rw_lock_x_unlock(L) rw_lock_x_unlock_gen(L, 0)
282 
283 /******************************************************************/
288 UNIV_INTERN
289 void
291 /*================*/
292  rw_lock_t* lock,
293 #ifdef UNIV_DEBUG
294 # ifdef UNIV_SYNC_DEBUG
295  ulint level,
296 # endif /* UNIV_SYNC_DEBUG */
297  const char* cmutex_name,
298 #endif /* UNIV_DEBUG */
299  const char* cfile_name,
300  ulint cline);
301 /******************************************************************/
305 UNIV_INTERN
306 void
308 /*==============*/
309  rw_lock_t* lock);
310 #ifdef UNIV_DEBUG
311 /******************************************************************/
315 UNIV_INTERN
316 ibool
317 rw_lock_validate(
318 /*=============*/
319  rw_lock_t* lock);
320 #endif /* UNIV_DEBUG */
321 /******************************************************************/
325 UNIV_INLINE
326 ibool
328 /*===============*/
329  rw_lock_t* lock,
330  ulint pass __attribute__((unused)),
333  const char* file_name,
334  ulint line);
335 /******************************************************************/
342 UNIV_INLINE
343 void
345 /*================*/
346  rw_lock_t* lock,
347  ulint pass,
349  const char* file_name,
350  ulint line);
351 /******************************************************************/
356 UNIV_INLINE
357 ibool
359 /*=======================*/
360  rw_lock_t* lock,
361  const char* file_name,
362  ulint line);
363 /******************************************************************/
365 UNIV_INLINE
366 void
368 /*==================*/
369 #ifdef UNIV_SYNC_DEBUG
370  ulint pass,
372 #endif
373  rw_lock_t* lock);
375 /******************************************************************/
384 UNIV_INTERN
385 void
387 /*================*/
388  rw_lock_t* lock,
389  ulint pass,
391  const char* file_name,
392  ulint line);
393 /******************************************************************/
395 UNIV_INLINE
396 void
398 /*==================*/
399 #ifdef UNIV_SYNC_DEBUG
400  ulint pass,
402 #endif
403  rw_lock_t* lock);
404 /******************************************************************/
412 UNIV_INTERN
413 void
415 /*==========================*/
416  rw_lock_t* lock);
418 /******************************************************************/
422 UNIV_INLINE
423 ulint
425 /*=====================*/
426  const rw_lock_t* lock);
427 /********************************************************************/
430 UNIV_INLINE
431 ulint
433 /*================*/
434  const rw_lock_t* lock);
435 /******************************************************************/
439 UNIV_INLINE
440 ulint
442 /*===============*/
443  const rw_lock_t* lock);
444 /******************************************************************/
447 UNIV_INLINE
448 ulint
450 /*=====================*/
451  const rw_lock_t* lock);
452 /******************************************************************/
456 UNIV_INLINE
457 ibool
459 /*===================*/
460  rw_lock_t* lock,
461  ulint amount);
462 /******************************************************************/
465 UNIV_INLINE
466 lint
468 /*===================*/
469  rw_lock_t* lock,
470  ulint amount);
471 /******************************************************************/
480 UNIV_INLINE
481 void
483 /*=====================================*/
484  rw_lock_t* lock,
485  ibool recursive);
487 #ifdef UNIV_SYNC_DEBUG
488 /******************************************************************/
491 UNIV_INTERN
492 ibool
493 rw_lock_own(
494 /*========*/
495  rw_lock_t* lock,
496  ulint lock_type)
498  __attribute__((warn_unused_result));
499 #endif /* UNIV_SYNC_DEBUG */
500 /******************************************************************/
502 UNIV_INTERN
503 ibool
505 /*==============*/
506  rw_lock_t* lock,
507  ulint lock_type);
509 #ifdef UNIV_SYNC_DEBUG
510 /***************************************************************/
512 UNIV_INTERN
513 void
514 rw_lock_print(
515 /*==========*/
516  rw_lock_t* lock);
517 /***************************************************************/
519 UNIV_INTERN
520 void
521 rw_lock_list_print_info(
522 /*====================*/
523  FILE* file);
524 /***************************************************************/
528 UNIV_INTERN
529 ulint
530 rw_lock_n_locked(void);
531 /*==================*/
532 
533 /*#####################################################################*/
534 
535 /******************************************************************/
541 UNIV_INTERN
542 void
543 rw_lock_debug_mutex_enter(void);
544 /*===========================*/
545 /******************************************************************/
547 UNIV_INTERN
548 void
549 rw_lock_debug_mutex_exit(void);
550 /*==========================*/
551 /*********************************************************************/
553 UNIV_INTERN
554 void
555 rw_lock_debug_print(
556 /*================*/
557  FILE* f,
558  rw_lock_debug_t* info);
559 #endif /* UNIV_SYNC_DEBUG */
560 
561 /* NOTE! The structure appears here only for the compiler to know its size.
562 Do not use its fields directly! */
563 
571 struct rw_lock_t {
572  volatile lint lock_word;
574  volatile ulint waiters;
575  volatile ibool recursive;
587  volatile os_thread_id_t writer_thread;
595 #ifndef INNODB_RW_LOCKS_USE_ATOMICS
597 #endif /* INNODB_RW_LOCKS_USE_ATOMICS */
598 
602 #ifdef UNIV_SYNC_DEBUG
603  UT_LIST_BASE_NODE_T(rw_lock_debug_t) debug_list;
606  ulint level;
607 #endif /* UNIV_SYNC_DEBUG */
608 #ifdef UNIV_PFS_RWLOCK
609  struct PSI_rwlock *pfs_psi;
610 #endif
612  const char* cfile_name;
613  /* last s-lock file/line is not guaranteed to be correct */
614  const char* last_s_file_name;
615  const char* last_x_file_name;
616  ibool writer_is_wait_ex;
623  unsigned cline:14;
624  unsigned last_s_line:14;
625  unsigned last_x_line:14;
626 #ifdef UNIV_DEBUG
627  ulint magic_n;
629 #define RW_LOCK_MAGIC_N 22643
630 #endif /* UNIV_DEBUG */
631 };
632 
633 #ifdef UNIV_SYNC_DEBUG
634 
636 struct rw_lock_debug_t {
637 
638  os_thread_id_t thread_id;
640  ulint pass;
641  ulint lock_type;
643  const char* file_name;
644  ulint line;
645  UT_LIST_NODE_T(rw_lock_debug_t) list;
648 };
649 #endif /* UNIV_SYNC_DEBUG */
650 
651 /* For performance schema instrumentation, a new set of rwlock
652 wrap functions are created if "UNIV_PFS_RWLOCK" is defined.
653 The instrumentations are not planted directly into original
654 functions, so that we keep the underlying function as they
655 are. And in case, user wants to "take out" some rwlock from
656 instrumentation even if performance schema (UNIV_PFS_RWLOCK)
657 is defined, they can do so by reinstating APIs directly link to
658 original underlying functions.
659 The instrumented function names have prefix of "pfs_rw_lock_" vs.
660 original name prefix of "rw_lock_". Following are list of functions
661 that have been instrumented:
662 
663 rw_lock_create()
664 rw_lock_x_lock()
665 rw_lock_x_lock_gen()
666 rw_lock_x_lock_nowait()
667 rw_lock_x_unlock_gen()
668 rw_lock_s_lock()
669 rw_lock_s_lock_gen()
670 rw_lock_s_lock_nowait()
671 rw_lock_s_unlock_gen()
672 rw_lock_free()
673 */
674 
675 #ifdef UNIV_PFS_RWLOCK
676 /******************************************************************/
680 UNIV_INLINE
681 void
682 pfs_rw_lock_create_func(
683 /*====================*/
684  PSI_rwlock_key key,
686  rw_lock_t* lock,
687 #ifdef UNIV_DEBUG
688 # ifdef UNIV_SYNC_DEBUG
689  ulint level,
690 # endif /* UNIV_SYNC_DEBUG */
691  const char* cmutex_name,
692 #endif /* UNIV_DEBUG */
693  const char* cfile_name,
694  ulint cline);
696 /******************************************************************/
700 UNIV_INLINE
701 void
702 pfs_rw_lock_x_lock_func(
703 /*====================*/
704  rw_lock_t* lock,
705  ulint pass,
707  const char* file_name,
708  ulint line);
709 /******************************************************************/
714 UNIV_INLINE
715 ibool
716 pfs_rw_lock_x_lock_func_nowait(
717 /*===========================*/
718  rw_lock_t* lock,
719  const char* file_name,
720  ulint line);
721 /******************************************************************/
725 UNIV_INLINE
726 void
727 pfs_rw_lock_s_lock_func(
728 /*====================*/
729  rw_lock_t* lock,
730  ulint pass,
732  const char* file_name,
733  ulint line);
734 /******************************************************************/
739 UNIV_INLINE
740 ibool
741 pfs_rw_lock_s_lock_low(
742 /*===================*/
743  rw_lock_t* lock,
744  ulint pass,
747  const char* file_name,
748  ulint line);
749 /******************************************************************/
753 UNIV_INLINE
754 void
755 pfs_rw_lock_x_lock_func(
756 /*====================*/
757  rw_lock_t* lock,
758  ulint pass,
760  const char* file_name,
761  ulint line);
762 /******************************************************************/
766 UNIV_INLINE
767 void
768 pfs_rw_lock_s_unlock_func(
769 /*======================*/
770 #ifdef UNIV_SYNC_DEBUG
771  ulint pass,
774 #endif
775  rw_lock_t* lock);
776 /******************************************************************/
780 UNIV_INLINE
781 void
782 pfs_rw_lock_x_unlock_func(
783 /*======================*/
784 #ifdef UNIV_SYNC_DEBUG
785  ulint pass,
788 #endif
789  rw_lock_t* lock);
790 /******************************************************************/
794 UNIV_INLINE
795 void
796 pfs_rw_lock_free_func(
797 /*==================*/
798  rw_lock_t* lock);
799 #endif /* UNIV_PFS_RWLOCK */
800 
801 
802 #ifndef UNIV_NONINL
803 #include "sync0rw.ic"
804 #endif
805 #endif /* !UNIV_HOTBACKUP */
806 
807 #endif