Drizzled Public API Documentation

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., 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 extern mysql_pfs_key_t dict_table_stats_latch_key;
127 #endif /* UNIV_PFS_RWLOCK */
128 
129 
130 #ifndef UNIV_PFS_RWLOCK
131 /******************************************************************/
138 # ifdef UNIV_DEBUG
139 # ifdef UNIV_SYNC_DEBUG
140 # define rw_lock_create(K, L, level) \
141  rw_lock_create_func((L), (level), #L, __FILE__, __LINE__)
142 # else /* UNIV_SYNC_DEBUG */
143 # define rw_lock_create(K, L, level) \
144  rw_lock_create_func((L), #L, __FILE__, __LINE__)
145 # endif/* UNIV_SYNC_DEBUG */
146 # else /* UNIV_DEBUG */
147 # define rw_lock_create(K, L, level) \
148  rw_lock_create_func((L), __FILE__, __LINE__)
149 # endif /* UNIV_DEBUG */
150 
151 /**************************************************************/
155 # define rw_lock_s_lock(M) \
156  rw_lock_s_lock_func((M), 0, __FILE__, __LINE__)
157 
158 # define rw_lock_s_lock_gen(M, P) \
159  rw_lock_s_lock_func((M), (P), __FILE__, __LINE__)
160 
161 # define rw_lock_s_lock_nowait(M, F, L) \
162  rw_lock_s_lock_low((M), 0, (F), (L))
163 
164 # ifdef UNIV_SYNC_DEBUG
165 # define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(P, L)
166 # else
167 # define rw_lock_s_unlock_gen(L, P) rw_lock_s_unlock_func(L)
168 # endif
169 
170 
171 # define rw_lock_x_lock(M) \
172  rw_lock_x_lock_func((M), 0, __FILE__, __LINE__)
173 
174 # define rw_lock_x_lock_gen(M, P) \
175  rw_lock_x_lock_func((M), (P), __FILE__, __LINE__)
176 
177 # define rw_lock_x_lock_nowait(M) \
178  rw_lock_x_lock_func_nowait((M), __FILE__, __LINE__)
179 
180 # ifdef UNIV_SYNC_DEBUG
181 # define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(P, L)
182 # else
183 # define rw_lock_x_unlock_gen(L, P) rw_lock_x_unlock_func(L)
184 # endif
185 
186 # define rw_lock_free(M) rw_lock_free_func(M)
187 
188 #else /* !UNIV_PFS_RWLOCK */
189 
190 /* Following macros point to Performance Schema instrumented functions. */
191 # ifdef UNIV_DEBUG
192 # ifdef UNIV_SYNC_DEBUG
193 # define rw_lock_create(K, L, level) \
194  pfs_rw_lock_create_func((K), (L), (level), #L, __FILE__, __LINE__)
195 # else /* UNIV_SYNC_DEBUG */
196 # define rw_lock_create(K, L, level) \
197  pfs_rw_lock_create_func((K), (L), #L, __FILE__, __LINE__)
198 # endif/* UNIV_SYNC_DEBUG */
199 # else /* UNIV_DEBUG */
200 # define rw_lock_create(K, L, level) \
201  pfs_rw_lock_create_func((K), (L), __FILE__, __LINE__)
202 # endif /* UNIV_DEBUG */
203 
204 /******************************************************************
205 NOTE! The following macros should be used in rw locking and
206 unlocking, not the corresponding function. */
207 
208 # define rw_lock_s_lock(M) \
209  pfs_rw_lock_s_lock_func((M), 0, __FILE__, __LINE__)
210 
211 # define rw_lock_s_lock_gen(M, P) \
212  pfs_rw_lock_s_lock_func((M), (P), __FILE__, __LINE__)
213 
214 # define rw_lock_s_lock_nowait(M, F, L) \
215  pfs_rw_lock_s_lock_low((M), 0, (F), (L))
216 
217 # ifdef UNIV_SYNC_DEBUG
218 # define rw_lock_s_unlock_gen(L, P) pfs_rw_lock_s_unlock_func(P, L)
219 # else
220 # define rw_lock_s_unlock_gen(L, P) pfs_rw_lock_s_unlock_func(L)
221 # endif
222 
223 # define rw_lock_x_lock(M) \
224  pfs_rw_lock_x_lock_func((M), 0, __FILE__, __LINE__)
225 
226 # define rw_lock_x_lock_gen(M, P) \
227  pfs_rw_lock_x_lock_func((M), (P), __FILE__, __LINE__)
228 
229 # define rw_lock_x_lock_nowait(M) \
230  pfs_rw_lock_x_lock_func_nowait((M), __FILE__, __LINE__)
231 
232 # ifdef UNIV_SYNC_DEBUG
233 # define rw_lock_x_unlock_gen(L, P) pfs_rw_lock_x_unlock_func(P, L)
234 # else
235 # define rw_lock_x_unlock_gen(L, P) pfs_rw_lock_x_unlock_func(L)
236 # endif
237 
238 # define rw_lock_free(M) pfs_rw_lock_free_func(M)
239 
240 #endif /* UNIV_PFS_RWLOCK */
241 
242 #define rw_lock_s_unlock(L) rw_lock_s_unlock_gen(L, 0)
243 #define rw_lock_x_unlock(L) rw_lock_x_unlock_gen(L, 0)
244 
245 /******************************************************************/
250 UNIV_INTERN
251 void
253 /*================*/
254  rw_lock_t* lock,
255 #ifdef UNIV_DEBUG
256 # ifdef UNIV_SYNC_DEBUG
257  ulint level,
258 # endif /* UNIV_SYNC_DEBUG */
259  const char* cmutex_name,
260 #endif /* UNIV_DEBUG */
261  const char* cfile_name,
262  ulint cline);
263 /******************************************************************/
267 UNIV_INTERN
268 void
270 /*==============*/
271  rw_lock_t* lock);
272 #ifdef UNIV_DEBUG
273 /******************************************************************/
277 UNIV_INTERN
278 ibool
279 rw_lock_validate(
280 /*=============*/
281  rw_lock_t* lock);
282 #endif /* UNIV_DEBUG */
283 /******************************************************************/
287 UNIV_INLINE
288 ibool
290 /*===============*/
291  rw_lock_t* lock,
292  ulint /*pass __attribute__((unused))*/,
295  const char* file_name,
296  ulint line);
297 /******************************************************************/
304 UNIV_INLINE
305 void
307 /*================*/
308  rw_lock_t* lock,
309  ulint pass,
311  const char* file_name,
312  ulint line);
313 /******************************************************************/
318 UNIV_INLINE
319 ibool
321 /*=======================*/
322  rw_lock_t* lock,
323  const char* file_name,
324  ulint line);
325 /******************************************************************/
327 UNIV_INLINE
328 void
330 /*==================*/
331 #ifdef UNIV_SYNC_DEBUG
332  ulint pass,
334 #endif
335  rw_lock_t* lock);
337 /******************************************************************/
346 UNIV_INTERN
347 void
349 /*================*/
350  rw_lock_t* lock,
351  ulint pass,
353  const char* file_name,
354  ulint line);
355 /******************************************************************/
357 UNIV_INLINE
358 void
360 /*==================*/
361 #ifdef UNIV_SYNC_DEBUG
362  ulint pass,
364 #endif
365  rw_lock_t* lock);
368 /******************************************************************/
372 UNIV_INLINE
373 void
375 /*==================*/
376  rw_lock_t* lock,
377  const char* file_name,
378  ulint line);
379 /******************************************************************/
383 UNIV_INLINE
384 void
386 /*==================*/
387  rw_lock_t* lock,
388  const char* file_name,
389  ulint line);
390 /******************************************************************/
398 UNIV_INTERN
399 void
401 /*==========================*/
402  rw_lock_t* lock);
404 /******************************************************************/
407 UNIV_INLINE
408 void
410 /*====================*/
411  rw_lock_t* lock);
412 /******************************************************************/
415 UNIV_INLINE
416 void
418 /*====================*/
419  rw_lock_t* lock);
420 /******************************************************************/
424 UNIV_INLINE
425 ulint
427 /*=====================*/
428  const rw_lock_t* lock);
429 /********************************************************************/
432 UNIV_INLINE
433 ulint
435 /*================*/
436  const rw_lock_t* lock);
437 /******************************************************************/
441 UNIV_INLINE
442 ulint
444 /*===============*/
445  const rw_lock_t* lock);
446 /******************************************************************/
449 UNIV_INLINE
450 ulint
452 /*=====================*/
453  const rw_lock_t* lock);
454 /******************************************************************/
458 UNIV_INLINE
459 ibool
461 /*===================*/
462  rw_lock_t* lock,
463  ulint amount);
464 /******************************************************************/
467 UNIV_INLINE
468 lint
470 /*===================*/
471  rw_lock_t* lock,
472  ulint amount);
473 /******************************************************************/
482 UNIV_INLINE
483 void
485 /*=====================================*/
486  rw_lock_t* lock,
487  ibool recursive);
489 #ifdef UNIV_SYNC_DEBUG
490 /******************************************************************/
493 UNIV_INTERN
494 ibool
495 rw_lock_own(
496 /*========*/
497  rw_lock_t* lock,
498  ulint lock_type)
500  __attribute__((warn_unused_result));
501 #endif /* UNIV_SYNC_DEBUG */
502 /******************************************************************/
504 UNIV_INTERN
505 ibool
507 /*==============*/
508  rw_lock_t* lock,
509  ulint lock_type);
511 #ifdef UNIV_SYNC_DEBUG
512 /***************************************************************/
514 UNIV_INTERN
515 void
516 rw_lock_print(
517 /*==========*/
518  rw_lock_t* lock);
519 /***************************************************************/
521 UNIV_INTERN
522 void
523 rw_lock_list_print_info(
524 /*====================*/
525  FILE* file);
526 /***************************************************************/
530 UNIV_INTERN
531 ulint
532 rw_lock_n_locked(void);
533 /*==================*/
534 
535 /*#####################################################################*/
536 
537 /******************************************************************/
543 UNIV_INTERN
544 void
545 rw_lock_debug_mutex_enter(void);
546 /*==========================*/
547 /******************************************************************/
549 UNIV_INTERN
550 void
551 rw_lock_debug_mutex_exit(void);
552 /*==========================*/
553 /*********************************************************************/
555 UNIV_INTERN
556 void
557 rw_lock_debug_print(
558 /*================*/
559  FILE* f,
560  rw_lock_debug_t* info);
561 #endif /* UNIV_SYNC_DEBUG */
562 
563 /* NOTE! The structure appears here only for the compiler to know its size.
564 Do not use its fields directly! */
565 
574  volatile lint lock_word;
576  volatile ulint waiters;
577  volatile ibool recursive;
597 #ifndef INNODB_RW_LOCKS_USE_ATOMICS
599 #endif /* INNODB_RW_LOCKS_USE_ATOMICS */
600 
604 #ifdef UNIV_SYNC_DEBUG
605  UT_LIST_BASE_NODE_T(rw_lock_debug_t) debug_list;
608  ulint level;
609 #endif /* UNIV_SYNC_DEBUG */
610 #ifdef UNIV_PFS_RWLOCK
611  struct PSI_rwlock *pfs_psi;
612 #endif
614  const char* cfile_name;
615  /* last s-lock file/line is not guaranteed to be correct */
616  const char* last_s_file_name;
617  const char* last_x_file_name;
625  unsigned cline:14;
626  unsigned last_s_line:14;
627  unsigned last_x_line:14;
628 #ifdef UNIV_DEBUG
629  ulint magic_n;
631 #define RW_LOCK_MAGIC_N 22643
632 #endif /* UNIV_DEBUG */
633 };
634 
635 #ifdef UNIV_SYNC_DEBUG
636 
637 struct rw_lock_debug_struct {
638 
639  os_thread_id_t thread_id;
641  ulint pass;
642  ulint lock_type;
644  const char* file_name;
645  ulint line;
646  UT_LIST_NODE_T(rw_lock_debug_t) list;
649 };
650 #endif /* UNIV_SYNC_DEBUG */
651 
652 /* For performance schema instrumentation, a new set of rwlock
653 wrap functions are created if "UNIV_PFS_RWLOCK" is defined.
654 The instrumentations are not planted directly into original
655 functions, so that we keep the underlying function as they
656 are. And in case, user wants to "take out" some rwlock from
657 instrumentation even if performance schema (UNIV_PFS_RWLOCK)
658 is defined, they can do so by reinstating APIs directly link to
659 original underlying functions.
660 The instrumented function names have prefix of "pfs_rw_lock_" vs.
661 original name prefix of "rw_lock_". Following are list of functions
662 that have been instrumented:
663 
664 rw_lock_create()
665 rw_lock_x_lock()
666 rw_lock_x_lock_gen()
667 rw_lock_x_lock_nowait()
668 rw_lock_x_unlock_gen()
669 rw_lock_s_lock()
670 rw_lock_s_lock_gen()
671 rw_lock_s_lock_nowait()
672 rw_lock_s_unlock_gen()
673 rw_lock_free()
674 
675 Two function APIs rw_lock_x_unlock_direct() and rw_lock_s_unlock_direct()
676 do not have any caller/user, they are not instrumented.
677 */
678 
679 #ifdef UNIV_PFS_RWLOCK
680 /******************************************************************/
684 UNIV_INLINE
685 void
686 pfs_rw_lock_create_func(
687 /*====================*/
688  PSI_rwlock_key key,
690  rw_lock_t* lock,
691 #ifdef UNIV_DEBUG
692 # ifdef UNIV_SYNC_DEBUG
693  ulint level,
694 # endif /* UNIV_SYNC_DEBUG */
695  const char* cmutex_name,
696 #endif /* UNIV_DEBUG */
697  const char* cfile_name,
698  ulint cline);
700 /******************************************************************/
704 UNIV_INLINE
705 void
706 pfs_rw_lock_x_lock_func(
707 /*====================*/
708  rw_lock_t* lock,
709  ulint pass,
711  const char* file_name,
712  ulint line);
713 /******************************************************************/
718 UNIV_INLINE
719 ibool
720 pfs_rw_lock_x_lock_func_nowait(
721 /*===========================*/
722  rw_lock_t* lock,
723  const char* file_name,
724  ulint line);
725 /******************************************************************/
729 UNIV_INLINE
730 void
731 pfs_rw_lock_s_lock_func(
732 /*====================*/
733  rw_lock_t* lock,
734  ulint pass,
736  const char* file_name,
737  ulint line);
738 /******************************************************************/
743 UNIV_INLINE
744 ibool
745 pfs_rw_lock_s_lock_low(
746 /*===================*/
747  rw_lock_t* lock,
748  ulint pass,
751  const char* file_name,
752  ulint line);
753 /******************************************************************/
757 UNIV_INLINE
758 void
759 pfs_rw_lock_x_lock_func(
760 /*====================*/
761  rw_lock_t* lock,
762  ulint pass,
764  const char* file_name,
765  ulint line);
766 /******************************************************************/
770 UNIV_INLINE
771 void
772 pfs_rw_lock_s_unlock_func(
773 /*======================*/
774 #ifdef UNIV_SYNC_DEBUG
775  ulint pass,
778 #endif
779  rw_lock_t* lock);
780 /******************************************************************/
784 UNIV_INLINE
785 void
786 pfs_rw_lock_x_unlock_func(
787 /*======================*/
788 #ifdef UNIV_SYNC_DEBUG
789  ulint pass,
792 #endif
793  rw_lock_t* lock);
794 /******************************************************************/
798 UNIV_INLINE
799 void
800 pfs_rw_lock_free_func(
801 /*==================*/
802  rw_lock_t* lock);
803 #endif /* UNIV_PFS_RWLOCK */
804 
805 
806 #ifndef UNIV_NONINL
807 #include "sync0rw.ic"
808 #endif
809 #endif /* !UNIV_HOTBACKUP */
810 
811 #endif