Drizzled Public API Documentation

sync0rw.h
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (C) 1995, 2010, Innobase Oy. 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., 51 Franklin
22 St, Fifth Floor, Boston, MA 02110-1301 USA
23 
24 *****************************************************************************/
25 
26 /**************************************************/
33 #pragma once
34 #ifndef sync0rw_h
35 #define sync0rw_h
36 
37 #include "univ.i"
38 #ifndef UNIV_HOTBACKUP
39 #include "ut0lst.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 
48 /* Latch types; these are used also in btr0btr.h: keep the numerical values
49 smaller than 30 and the order of the numerical values like below! */
50 #define RW_S_LATCH 1
51 #define RW_X_LATCH 2
52 #define RW_NO_LATCH 3
53 
54 #ifndef UNIV_HOTBACKUP
55 /* We decrement lock_word by this amount for each x_lock. It is also the
56 start value for the lock_word, meaning that it limits the maximum number
57 of concurrent read locks before the rw_lock breaks. The current value of
58 0x00100000 allows 1,048,575 concurrent readers and 2047 recursive writers.*/
59 #define X_LOCK_DECR 0x00100000
60 
61 typedef struct rw_lock_struct rw_lock_t;
62 #ifdef UNIV_SYNC_DEBUG
63 typedef struct rw_lock_debug_struct rw_lock_debug_t;
64 #endif /* UNIV_SYNC_DEBUG */
65 
66 typedef UT_LIST_BASE_NODE_T(rw_lock_t) rw_lock_list_t;
67 
68 extern rw_lock_list_t rw_lock_list;
69 extern mutex_t rw_lock_list_mutex;
70 
71 #ifdef UNIV_SYNC_DEBUG
72 /* The global mutex which protects debug info lists of all rw-locks.
73 To modify the debug info list of an rw-lock, this mutex has to be
74 
75 acquired in addition to the mutex protecting the lock. */
76 extern mutex_t rw_lock_debug_mutex;
77 extern os_event_t rw_lock_debug_event;
80 extern ibool rw_lock_debug_waiters;
82 #endif /* UNIV_SYNC_DEBUG */
83 
86 extern ib_int64_t rw_s_spin_wait_count;
89 extern ib_int64_t rw_s_spin_round_count;
92 extern ib_int64_t rw_s_exit_count;
95 extern ib_int64_t rw_s_os_wait_count;
98 extern ib_int64_t rw_x_spin_wait_count;
101 extern ib_int64_t rw_x_spin_round_count;
104 extern ib_int64_t rw_x_os_wait_count;
107 extern ib_int64_t rw_x_exit_count;
108 
109 #ifdef UNIV_PFS_RWLOCK
110 /* Following are rwlock keys used to register with MySQL
111 performance schema */
112 # ifdef UNIV_LOG_ARCHIVE
113 extern mysql_pfs_key_t archive_lock_key;
114 # endif /* UNIV_LOG_ARCHIVE */
115 extern mysql_pfs_key_t btr_search_latch_key;
116 extern mysql_pfs_key_t buf_block_lock_key;
117 # ifdef UNIV_SYNC_DEBUG
118 extern mysql_pfs_key_t buf_block_debug_latch_key;
119 # endif /* UNIV_SYNC_DEBUG */
120 extern mysql_pfs_key_t dict_operation_lock_key;
121 extern mysql_pfs_key_t fil_space_latch_key;
122 extern mysql_pfs_key_t checkpoint_lock_key;
123 extern mysql_pfs_key_t trx_i_s_cache_lock_key;
124 extern mysql_pfs_key_t trx_purge_latch_key;
125 extern mysql_pfs_key_t index_tree_rw_lock_key;
126 #endif /* UNIV_PFS_RWLOCK */
127 
128 
129 #ifndef UNIV_PFS_RWLOCK
130 /******************************************************************/
137 # ifdef UNIV_DEBUG
138 # ifdef UNIV_SYNC_DEBUG
139 # define rw_lock_create(K, L, level) \
140  rw_lock_create_func((L), (level), #L, __FILE__, __LINE__)
141 # else /* UNIV_SYNC_DEBUG */
142 # define rw_lock_create(K, L, level) \
143  rw_lock_create_func((L), #L, __FILE__, __LINE__)
144 # endif/* UNIV_SYNC_DEBUG */
145 # else /* UNIV_DEBUG */
146 # define rw_lock_create(K, L, level) \
147  rw_lock_create_func((L), __FILE__, __LINE__)
148 # endif /* UNIV_DEBUG */
149 
150 /**************************************************************/
154 # define rw_lock_s_lock(M) \
155  rw_lock_s_lock_func((M), 0, __FILE__, __LINE__)
156 
157 # define rw_lock_s_lock_gen(M, P) \
158  rw_lock_s_lock_func((M), (P), __FILE__, __LINE__)
159 
160 # define rw_lock_s_lock_nowait(M, F, L) \
161  rw_lock_s_lock_low((M), 0, (F), (L))
162 
163 # ifdef UNIV_SYNC_DEBUG
164 # define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(P, L)
165 # else
166 # define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(L)
167 # endif
168 
169 
170 # define rw_lock_x_lock(M) \
171  rw_lock_x_lock_func((M), 0, __FILE__, __LINE__)
172 
173 # define rw_lock_x_lock_gen(M, P) \
174  rw_lock_x_lock_func((M), (P), __FILE__, __LINE__)
175 
176 # define rw_lock_x_lock_nowait(M) \
177  rw_lock_x_lock_func_nowait((M), __FILE__, __LINE__)
178 
179 # ifdef UNIV_SYNC_DEBUG
180 # define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(P, L)
181 # else
182 # define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(L)
183 # endif
184 
185 # define rw_lock_free(M) rw_lock_free_func(M)
186 
187 #else /* !UNIV_PFS_RWLOCK */
188 
189 /* Following macros point to Performance Schema instrumented functions. */
190 # ifdef UNIV_DEBUG
191 # ifdef UNIV_SYNC_DEBUG
192 # define rw_lock_create(K, L, level) \
193  pfs_rw_lock_create_func((K), (L), (level), #L, __FILE__, __LINE__)
194 # else /* UNIV_SYNC_DEBUG */
195 # define rw_lock_create(K, L, level) \
196  pfs_rw_lock_create_func((K), (L), #L, __FILE__, __LINE__)
197 # endif/* UNIV_SYNC_DEBUG */
198 # else /* UNIV_DEBUG */
199 # define rw_lock_create(K, L, level) \
200  pfs_rw_lock_create_func((K), (L), __FILE__, __LINE__)
201 # endif /* UNIV_DEBUG */
202 
203 /******************************************************************
204 NOTE! The following macros should be used in rw locking and
205 unlocking, not the corresponding function. */
206 
207 # define rw_lock_s_lock(M) \
208  pfs_rw_lock_s_lock_func((M), 0, __FILE__, __LINE__)
209 
210 # define rw_lock_s_lock_gen(M, P) \
211  pfs_rw_lock_s_lock_func((M), (P), __FILE__, __LINE__)
212 
213 # define rw_lock_s_lock_nowait(M, F, L) \
214  pfs_rw_lock_s_lock_low((M), 0, (F), (L))
215 
216 # ifdef UNIV_SYNC_DEBUG
217 # define rw_lock_s_unlock_gen(L, P) pfs_rw_lock_s_unlock_func(P, L)
218 # else
219 # define rw_lock_s_unlock_gen(L, P) pfs_rw_lock_s_unlock_func(L)
220 # endif
221 
222 # define rw_lock_x_lock(M) \
223  pfs_rw_lock_x_lock_func((M), 0, __FILE__, __LINE__)
224 
225 # define rw_lock_x_lock_gen(M, P) \
226  pfs_rw_lock_x_lock_func((M), (P), __FILE__, __LINE__)
227 
228 # define rw_lock_x_lock_nowait(M) \
229  pfs_rw_lock_x_lock_func_nowait((M), __FILE__, __LINE__)
230 
231 # ifdef UNIV_SYNC_DEBUG
232 # define rw_lock_x_unlock_gen(L, P) pfs_rw_lock_x_unlock_func(P, L)
233 # else
234 # define rw_lock_x_unlock_gen(L, P) pfs_rw_lock_x_unlock_func(L)
235 # endif
236 
237 # define rw_lock_free(M) pfs_rw_lock_free_func(M)
238 
239 #endif /* UNIV_PFS_RWLOCK */
240 
241 #define rw_lock_s_unlock(L) rw_lock_s_unlock_gen(L, 0)
242 #define rw_lock_x_unlock(L) rw_lock_x_unlock_gen(L, 0)
243 
244 /******************************************************************/
249 UNIV_INTERN
250 void
252 /*================*/
253  rw_lock_t* lock,
254 #ifdef UNIV_DEBUG
255 # ifdef UNIV_SYNC_DEBUG
256  ulint level,
257 # endif /* UNIV_SYNC_DEBUG */
258  const char* cmutex_name,
259 #endif /* UNIV_DEBUG */
260  const char* cfile_name,
261  ulint cline);
262 /******************************************************************/
266 UNIV_INTERN
267 void
269 /*==============*/
270  rw_lock_t* lock);
271 #ifdef UNIV_DEBUG
272 /******************************************************************/
276 UNIV_INTERN
277 ibool
278 rw_lock_validate(
279 /*=============*/
280  rw_lock_t* lock);
281 #endif /* UNIV_DEBUG */
282 /******************************************************************/
286 UNIV_INLINE
287 ibool
289 /*===============*/
290  rw_lock_t* lock,
291  ulint /*pass __attribute__((unused))*/,
294  const char* file_name,
295  ulint line);
296 /******************************************************************/
303 UNIV_INLINE
304 void
306 /*================*/
307  rw_lock_t* lock,
308  ulint pass,
310  const char* file_name,
311  ulint line);
312 /******************************************************************/
317 UNIV_INLINE
318 ibool
320 /*=======================*/
321  rw_lock_t* lock,
322  const char* file_name,
323  ulint line);
324 /******************************************************************/
326 UNIV_INLINE
327 void
329 /*==================*/
330 #ifdef UNIV_SYNC_DEBUG
331  ulint pass,
333 #endif
334  rw_lock_t* lock);
336 /******************************************************************/
345 UNIV_INTERN
346 void
348 /*================*/
349  rw_lock_t* lock,
350  ulint pass,
352  const char* file_name,
353  ulint line);
354 /******************************************************************/
356 UNIV_INLINE
357 void
359 /*==================*/
360 #ifdef UNIV_SYNC_DEBUG
361  ulint pass,
363 #endif
364  rw_lock_t* lock);
367 /******************************************************************/
371 UNIV_INLINE
372 void
374 /*==================*/
375  rw_lock_t* lock,
376  const char* file_name,
377  ulint line);
378 /******************************************************************/
382 UNIV_INLINE
383 void
385 /*==================*/
386  rw_lock_t* lock,
387  const char* file_name,
388  ulint line);
389 /******************************************************************/
397 UNIV_INTERN
398 void
400 /*==========================*/
401  rw_lock_t* lock);
403 /******************************************************************/
406 UNIV_INLINE
407 void
409 /*====================*/
410  rw_lock_t* lock);
411 /******************************************************************/
414 UNIV_INLINE
415 void
417 /*====================*/
418  rw_lock_t* lock);
419 /******************************************************************/
423 UNIV_INLINE
424 ulint
426 /*=====================*/
427  const rw_lock_t* lock);
428 /********************************************************************/
431 UNIV_INLINE
432 ulint
434 /*================*/
435  const rw_lock_t* lock);
436 /******************************************************************/
440 UNIV_INLINE
441 ulint
443 /*===============*/
444  const rw_lock_t* lock);
445 /******************************************************************/
448 UNIV_INLINE
449 ulint
451 /*=====================*/
452  const rw_lock_t* lock);
453 /******************************************************************/
457 UNIV_INLINE
458 ibool
460 /*===================*/
461  rw_lock_t* lock,
462  ulint amount);
463 /******************************************************************/
466 UNIV_INLINE
467 lint
469 /*===================*/
470  rw_lock_t* lock,
471  ulint amount);
472 /******************************************************************/
481 UNIV_INLINE
482 void
484 /*=====================================*/
485  rw_lock_t* lock,
486  ibool recursive);
488 #ifdef UNIV_SYNC_DEBUG
489 /******************************************************************/
492 UNIV_INTERN
493 ibool
494 rw_lock_own(
495 /*========*/
496  rw_lock_t* lock,
497  ulint lock_type)
499  __attribute__((warn_unused_result));
500 #endif /* UNIV_SYNC_DEBUG */
501 /******************************************************************/
503 UNIV_INTERN
504 ibool
506 /*==============*/
507  rw_lock_t* lock,
508  ulint lock_type);
510 #ifdef UNIV_SYNC_DEBUG
511 /***************************************************************/
513 UNIV_INTERN
514 void
515 rw_lock_print(
516 /*==========*/
517  rw_lock_t* lock);
518 /***************************************************************/
520 UNIV_INTERN
521 void
522 rw_lock_list_print_info(
523 /*====================*/
524  FILE* file);
525 /***************************************************************/
529 UNIV_INTERN
530 ulint
531 rw_lock_n_locked(void);
532 /*==================*/
533 
534 /*#####################################################################*/
535 
536 /******************************************************************/
542 UNIV_INTERN
543 void
544 rw_lock_debug_mutex_enter(void);
545 /*==========================*/
546 /******************************************************************/
548 UNIV_INTERN
549 void
550 rw_lock_debug_mutex_exit(void);
551 /*==========================*/
552 /*********************************************************************/
554 UNIV_INTERN
555 void
556 rw_lock_debug_print(
557 /*================*/
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 
572  volatile lint lock_word;
574  volatile ulint waiters;
575  volatile ibool recursive;
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;
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 
635 struct rw_lock_debug_struct {
636 
637  os_thread_id_t thread_id;
639  ulint pass;
640  ulint lock_type;
642  const char* file_name;
643  ulint line;
644  UT_LIST_NODE_T(rw_lock_debug_t) list;
647 };
648 #endif /* UNIV_SYNC_DEBUG */
649 
650 /* For performance schema instrumentation, a new set of rwlock
651 wrap functions are created if "UNIV_PFS_RWLOCK" is defined.
652 The instrumentations are not planted directly into original
653 functions, so that we keep the underlying function as they
654 are. And in case, user wants to "take out" some rwlock from
655 instrumentation even if performance schema (UNIV_PFS_RWLOCK)
656 is defined, they can do so by reinstating APIs directly link to
657 original underlying functions.
658 The instrumented function names have prefix of "pfs_rw_lock_" vs.
659 original name prefix of "rw_lock_". Following are list of functions
660 that have been instrumented:
661 
662 rw_lock_create()
663 rw_lock_x_lock()
664 rw_lock_x_lock_gen()
665 rw_lock_x_lock_nowait()
666 rw_lock_x_unlock_gen()
667 rw_lock_s_lock()
668 rw_lock_s_lock_gen()
669 rw_lock_s_lock_nowait()
670 rw_lock_s_unlock_gen()
671 rw_lock_free()
672 
673 Two function APIs rw_lock_x_unlock_direct() and rw_lock_s_unlock_direct()
674 do not have any caller/user, they are not instrumented.
675 */
676 
677 #ifdef UNIV_PFS_RWLOCK
678 /******************************************************************/
682 UNIV_INLINE
683 void
684 pfs_rw_lock_create_func(
685 /*====================*/
686  PSI_rwlock_key key,
688  rw_lock_t* lock,
689 #ifdef UNIV_DEBUG
690 # ifdef UNIV_SYNC_DEBUG
691  ulint level,
692 # endif /* UNIV_SYNC_DEBUG */
693  const char* cmutex_name,
694 #endif /* UNIV_DEBUG */
695  const char* cfile_name,
696  ulint cline);
698 /******************************************************************/
702 UNIV_INLINE
703 void
704 pfs_rw_lock_x_lock_func(
705 /*====================*/
706  rw_lock_t* lock,
707  ulint pass,
709  const char* file_name,
710  ulint line);
711 /******************************************************************/
716 UNIV_INLINE
717 ibool
718 pfs_rw_lock_x_lock_func_nowait(
719 /*===========================*/
720  rw_lock_t* lock,
721  const char* file_name,
722  ulint line);
723 /******************************************************************/
727 UNIV_INLINE
728 void
729 pfs_rw_lock_s_lock_func(
730 /*====================*/
731  rw_lock_t* lock,
732  ulint pass,
734  const char* file_name,
735  ulint line);
736 /******************************************************************/
741 UNIV_INLINE
742 ibool
743 pfs_rw_lock_s_lock_low(
744 /*===================*/
745  rw_lock_t* lock,
746  ulint pass,
749  const char* file_name,
750  ulint line);
751 /******************************************************************/
755 UNIV_INLINE
756 void
757 pfs_rw_lock_x_lock_func(
758 /*====================*/
759  rw_lock_t* lock,
760  ulint pass,
762  const char* file_name,
763  ulint line);
764 /******************************************************************/
768 UNIV_INLINE
769 void
770 pfs_rw_lock_s_unlock_func(
771 /*======================*/
772 #ifdef UNIV_SYNC_DEBUG
773  ulint pass,
776 #endif
777  rw_lock_t* lock);
778 /******************************************************************/
782 UNIV_INLINE
783 void
784 pfs_rw_lock_x_unlock_func(
785 /*======================*/
786 #ifdef UNIV_SYNC_DEBUG
787  ulint pass,
790 #endif
791  rw_lock_t* lock);
792 /******************************************************************/
796 UNIV_INLINE
797 void
798 pfs_rw_lock_free_func(
799 /*==================*/
800  rw_lock_t* lock);
801 #endif /* UNIV_PFS_RWLOCK */
802 
803 
804 #ifndef UNIV_NONINL
805 #include "sync0rw.ic"
806 #endif
807 #endif /* !UNIV_HOTBACKUP */
808 
809 #endif