1 /***************************************************************************** 2 3 Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. 4 Copyright (c) 2008, Google Inc. 5 Copyright (c) 2012, Facebook Inc. 6 7 Portions of this file contain modifications contributed and copyrighted by 8 Google, Inc. Those modifications are gratefully acknowledged and are described 9 briefly in the InnoDB documentation. The contributions by Google are 10 incorporated with their permission, and subject to the conditions contained in 11 the file COPYING.Google. 12 13 This program is free software; you can redistribute it and/or modify 14 it under the terms of the GNU General Public License, version 2.0, 15 as published by the Free Software Foundation. 16 17 This program is also distributed with certain software (including 18 but not limited to OpenSSL) that is licensed under separate terms, 19 as designated in a particular file or component or in included license 20 documentation. The authors of MySQL hereby grant you an additional 21 permission to link the program and your derivative works with the 22 separately licensed software that they have included with MySQL. 23 24 This program is distributed in the hope that it will be useful, 25 but WITHOUT ANY WARRANTY; without even the implied warranty of 26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 27 GNU General Public License, version 2.0, for more details. 28 29 You should have received a copy of the GNU General Public License along with 30 this program; if not, write to the Free Software Foundation, Inc., 31 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA 32 33 *****************************************************************************/ 34 35 /**************************************************//** 36 @file include/sync0sync.h 37 Mutex, the basic synchronization primitive 38 39 Created 9/5/1995 Heikki Tuuri 40 *******************************************************/ 41 42 #ifndef sync0sync_h 43 #define sync0sync_h 44 45 #include "univ.i" 46 #include "sync0types.h" 47 #include "ut0lst.h" 48 #include "ut0mem.h" 49 #include "os0thread.h" 50 #include "os0sync.h" 51 #include "sync0arr.h" 52 53 #if defined(UNIV_DEBUG) && !defined(UNIV_HOTBACKUP) 54 extern "C" my_bool timed_mutexes; 55 #endif /* UNIV_DEBUG && !UNIV_HOTBACKUP */ 56 57 #if defined UNIV_PFS_MUTEX || defined UNIV_PFS_RWLOCK 58 59 /* By default, buffer mutexes and rwlocks will be excluded from 60 instrumentation due to their large number of instances. */ 61 # define PFS_SKIP_BUFFER_MUTEX_RWLOCK 62 63 /* By default, event->mutex will also be excluded from instrumentation */ 64 # define PFS_SKIP_EVENT_MUTEX 65 66 #endif /* UNIV_PFS_MUTEX || UNIV_PFS_RWLOCK */ 67 68 #ifdef UNIV_PFS_MUTEX 69 /* Key defines to register InnoDB mutexes with performance schema */ 70 extern mysql_pfs_key_t autoinc_mutex_key; 71 extern mysql_pfs_key_t buffer_block_mutex_key; 72 extern mysql_pfs_key_t buf_pool_mutex_key; 73 extern mysql_pfs_key_t buf_pool_zip_mutex_key; 74 extern mysql_pfs_key_t cache_last_read_mutex_key; 75 extern mysql_pfs_key_t dict_foreign_err_mutex_key; 76 extern mysql_pfs_key_t dict_sys_mutex_key; 77 extern mysql_pfs_key_t file_format_max_mutex_key; 78 extern mysql_pfs_key_t fil_system_mutex_key; 79 extern mysql_pfs_key_t flush_list_mutex_key; 80 extern mysql_pfs_key_t fts_bg_threads_mutex_key; 81 extern mysql_pfs_key_t fts_delete_mutex_key; 82 extern mysql_pfs_key_t fts_optimize_mutex_key; 83 extern mysql_pfs_key_t fts_doc_id_mutex_key; 84 extern mysql_pfs_key_t fts_pll_tokenize_mutex_key; 85 extern mysql_pfs_key_t hash_table_mutex_key; 86 extern mysql_pfs_key_t ibuf_bitmap_mutex_key; 87 extern mysql_pfs_key_t ibuf_mutex_key; 88 extern mysql_pfs_key_t ibuf_pessimistic_insert_mutex_key; 89 extern mysql_pfs_key_t log_sys_mutex_key; 90 extern mysql_pfs_key_t log_flush_order_mutex_key; 91 # ifndef HAVE_ATOMIC_BUILTINS 92 extern mysql_pfs_key_t server_mutex_key; 93 # endif /* !HAVE_ATOMIC_BUILTINS */ 94 # ifdef UNIV_MEM_DEBUG 95 extern mysql_pfs_key_t mem_hash_mutex_key; 96 # endif /* UNIV_MEM_DEBUG */ 97 extern mysql_pfs_key_t mem_pool_mutex_key; 98 extern mysql_pfs_key_t mutex_list_mutex_key; 99 extern mysql_pfs_key_t purge_sys_bh_mutex_key; 100 extern mysql_pfs_key_t recv_sys_mutex_key; 101 extern mysql_pfs_key_t recv_writer_mutex_key; 102 extern mysql_pfs_key_t rseg_mutex_key; 103 # ifdef UNIV_SYNC_DEBUG 104 extern mysql_pfs_key_t rw_lock_debug_mutex_key; 105 # endif /* UNIV_SYNC_DEBUG */ 106 extern mysql_pfs_key_t rw_lock_list_mutex_key; 107 extern mysql_pfs_key_t rw_lock_mutex_key; 108 extern mysql_pfs_key_t srv_dict_tmpfile_mutex_key; 109 extern mysql_pfs_key_t srv_innodb_monitor_mutex_key; 110 extern mysql_pfs_key_t srv_misc_tmpfile_mutex_key; 111 extern mysql_pfs_key_t srv_threads_mutex_key; 112 extern mysql_pfs_key_t srv_monitor_file_mutex_key; 113 # ifdef UNIV_SYNC_DEBUG 114 extern mysql_pfs_key_t sync_thread_mutex_key; 115 # endif /* UNIV_SYNC_DEBUG */ 116 extern mysql_pfs_key_t buf_dblwr_mutex_key; 117 extern mysql_pfs_key_t trx_undo_mutex_key; 118 extern mysql_pfs_key_t trx_mutex_key; 119 extern mysql_pfs_key_t lock_sys_mutex_key; 120 extern mysql_pfs_key_t lock_sys_wait_mutex_key; 121 extern mysql_pfs_key_t trx_sys_mutex_key; 122 extern mysql_pfs_key_t srv_sys_mutex_key; 123 extern mysql_pfs_key_t srv_sys_tasks_mutex_key; 124 #ifndef HAVE_ATOMIC_BUILTINS 125 extern mysql_pfs_key_t srv_conc_mutex_key; 126 #endif /* !HAVE_ATOMIC_BUILTINS */ 127 #ifndef HAVE_ATOMIC_BUILTINS_64 128 extern mysql_pfs_key_t monitor_mutex_key; 129 #endif /* !HAVE_ATOMIC_BUILTINS_64 */ 130 extern mysql_pfs_key_t event_os_mutex_key; 131 extern mysql_pfs_key_t ut_list_mutex_key; 132 extern mysql_pfs_key_t os_mutex_key; 133 extern mysql_pfs_key_t zip_pad_mutex_key; 134 #endif /* UNIV_PFS_MUTEX */ 135 136 /******************************************************************//** 137 Initializes the synchronization data structures. */ 138 UNIV_INTERN 139 void 140 sync_init(void); 141 /*===========*/ 142 /******************************************************************//** 143 Frees the resources in synchronization data structures. */ 144 UNIV_INTERN 145 void 146 sync_close(void); 147 /*===========*/ 148 149 #undef mutex_free /* Fix for MacOS X */ 150 151 #ifdef UNIV_PFS_MUTEX 152 /********************************************************************** 153 Following mutex APIs would be performance schema instrumented 154 if "UNIV_PFS_MUTEX" is defined: 155 156 mutex_create 157 mutex_enter 158 mutex_exit 159 mutex_enter_nowait 160 mutex_free 161 162 These mutex APIs will point to corresponding wrapper functions that contain 163 the performance schema instrumentation if "UNIV_PFS_MUTEX" is defined. 164 The instrumented wrapper functions have the prefix of "innodb_". 165 166 NOTE! The following macro should be used in mutex operation, not the 167 corresponding function. */ 168 169 /******************************************************************//** 170 Creates, or rather, initializes a mutex object to a specified memory 171 location (which must be appropriately aligned). The mutex is initialized 172 in the reset state. Explicit freeing of the mutex with mutex_free is 173 necessary only if the memory block containing it is freed. */ 174 # ifdef UNIV_DEBUG 175 # ifdef UNIV_SYNC_DEBUG 176 # define mutex_create(K, M, level) \ 177 pfs_mutex_create_func((K), (M), #M, (level), __FILE__, __LINE__) 178 # else 179 # define mutex_create(K, M, level) \ 180 pfs_mutex_create_func((K), (M), #M, __FILE__, __LINE__) 181 # endif/* UNIV_SYNC_DEBUG */ 182 # else 183 # define mutex_create(K, M, level) \ 184 pfs_mutex_create_func((K), (M), __FILE__, __LINE__) 185 # endif /* UNIV_DEBUG */ 186 187 # define mutex_enter(M) \ 188 pfs_mutex_enter_func((M), __FILE__, __LINE__) 189 190 # define mutex_enter_nowait(M) \ 191 pfs_mutex_enter_nowait_func((M), __FILE__, __LINE__) 192 193 # define mutex_exit(M) pfs_mutex_exit_func(M) 194 195 # define mutex_free(M) pfs_mutex_free_func(M) 196 197 #else /* UNIV_PFS_MUTEX */ 198 199 /* If "UNIV_PFS_MUTEX" is not defined, the mutex APIs point to 200 original non-instrumented functions */ 201 # ifdef UNIV_DEBUG 202 # ifdef UNIV_SYNC_DEBUG 203 # define mutex_create(K, M, level) \ 204 mutex_create_func((M), #M, (level), __FILE__, __LINE__) 205 # else /* UNIV_SYNC_DEBUG */ 206 # define mutex_create(K, M, level) \ 207 mutex_create_func((M), #M, __FILE__, __LINE__) 208 # endif /* UNIV_SYNC_DEBUG */ 209 # else /* UNIV_DEBUG */ 210 # define mutex_create(K, M, level) \ 211 mutex_create_func((M), __FILE__, __LINE__) 212 # endif /* UNIV_DEBUG */ 213 214 # define mutex_enter(M) mutex_enter_func((M), __FILE__, __LINE__) 215 216 # define mutex_enter_nowait(M) \ 217 mutex_enter_nowait_func((M), __FILE__, __LINE__) 218 219 # define mutex_exit(M) mutex_exit_func(M) 220 221 # define mutex_free(M) mutex_free_func(M) 222 223 #endif /* UNIV_PFS_MUTEX */ 224 225 /******************************************************************//** 226 Creates, or rather, initializes a mutex object in a specified memory 227 location (which must be appropriately aligned). The mutex is initialized 228 in the reset state. Explicit freeing of the mutex with mutex_free is 229 necessary only if the memory block containing it is freed. */ 230 UNIV_INTERN 231 void 232 mutex_create_func( 233 /*==============*/ 234 ib_mutex_t* mutex, /*!< in: pointer to memory */ 235 #ifdef UNIV_DEBUG 236 const char* cmutex_name, /*!< in: mutex name */ 237 # ifdef UNIV_SYNC_DEBUG 238 ulint level, /*!< in: level */ 239 # endif /* UNIV_SYNC_DEBUG */ 240 #endif /* UNIV_DEBUG */ 241 const char* cfile_name, /*!< in: file name where created */ 242 ulint cline); /*!< in: file line where created */ 243 244 /******************************************************************//** 245 NOTE! Use the corresponding macro mutex_free(), not directly this function! 246 Calling this function is obligatory only if the memory buffer containing 247 the mutex is freed. Removes a mutex object from the mutex list. The mutex 248 is checked to be in the reset state. */ 249 UNIV_INTERN 250 void 251 mutex_free_func( 252 /*============*/ 253 ib_mutex_t* mutex); /*!< in: mutex */ 254 /**************************************************************//** 255 NOTE! The following macro should be used in mutex locking, not the 256 corresponding function. */ 257 258 /* NOTE! currently same as mutex_enter! */ 259 260 #define mutex_enter_fast(M) mutex_enter_func((M), __FILE__, __LINE__) 261 /******************************************************************//** 262 NOTE! Use the corresponding macro in the header file, not this function 263 directly. Locks a mutex for the current thread. If the mutex is reserved 264 the function spins a preset time (controlled by SYNC_SPIN_ROUNDS) waiting 265 for the mutex before suspending the thread. */ 266 UNIV_INLINE 267 void 268 mutex_enter_func( 269 /*=============*/ 270 ib_mutex_t* mutex, /*!< in: pointer to mutex */ 271 const char* file_name, /*!< in: file name where locked */ 272 ulint line); /*!< in: line where locked */ 273 /********************************************************************//** 274 NOTE! Use the corresponding macro in the header file, not this function 275 directly. Tries to lock the mutex for the current thread. If the lock is not 276 acquired immediately, returns with return value 1. 277 @return 0 if succeed, 1 if not */ 278 UNIV_INTERN 279 ulint 280 mutex_enter_nowait_func( 281 /*====================*/ 282 ib_mutex_t* mutex, /*!< in: pointer to mutex */ 283 const char* file_name, /*!< in: file name where mutex 284 requested */ 285 ulint line); /*!< in: line where requested */ 286 /******************************************************************//** 287 NOTE! Use the corresponding macro mutex_exit(), not directly this function! 288 Unlocks a mutex owned by the current thread. */ 289 UNIV_INLINE 290 void 291 mutex_exit_func( 292 /*============*/ 293 ib_mutex_t* mutex); /*!< in: pointer to mutex */ 294 295 296 #ifdef UNIV_PFS_MUTEX 297 /******************************************************************//** 298 NOTE! Please use the corresponding macro mutex_create(), not directly 299 this function! 300 A wrapper function for mutex_create_func(), registers the mutex 301 with peformance schema if "UNIV_PFS_MUTEX" is defined when 302 creating the mutex */ 303 UNIV_INLINE 304 void 305 pfs_mutex_create_func( 306 /*==================*/ 307 PSI_mutex_key key, /*!< in: Performance Schema key */ 308 ib_mutex_t* mutex, /*!< in: pointer to memory */ 309 # ifdef UNIV_DEBUG 310 const char* cmutex_name, /*!< in: mutex name */ 311 # ifdef UNIV_SYNC_DEBUG 312 ulint level, /*!< in: level */ 313 # endif /* UNIV_SYNC_DEBUG */ 314 # endif /* UNIV_DEBUG */ 315 const char* cfile_name, /*!< in: file name where created */ 316 ulint cline); /*!< in: file line where created */ 317 /******************************************************************//** 318 NOTE! Please use the corresponding macro mutex_enter(), not directly 319 this function! 320 This is a performance schema instrumented wrapper function for 321 mutex_enter_func(). */ 322 UNIV_INLINE 323 void 324 pfs_mutex_enter_func( 325 /*=================*/ 326 ib_mutex_t* mutex, /*!< in: pointer to mutex */ 327 const char* file_name, /*!< in: file name where locked */ 328 ulint line); /*!< in: line where locked */ 329 /********************************************************************//** 330 NOTE! Please use the corresponding macro mutex_enter_nowait(), not directly 331 this function! 332 This is a performance schema instrumented wrapper function for 333 mutex_enter_nowait_func. 334 @return 0 if succeed, 1 if not */ 335 UNIV_INLINE 336 ulint 337 pfs_mutex_enter_nowait_func( 338 /*========================*/ 339 ib_mutex_t* mutex, /*!< in: pointer to mutex */ 340 const char* file_name, /*!< in: file name where mutex 341 requested */ 342 ulint line); /*!< in: line where requested */ 343 /******************************************************************//** 344 NOTE! Please use the corresponding macro mutex_exit(), not directly 345 this function! 346 A wrap function of mutex_exit_func() with peformance schema instrumentation. 347 Unlocks a mutex owned by the current thread. */ 348 UNIV_INLINE 349 void 350 pfs_mutex_exit_func( 351 /*================*/ 352 ib_mutex_t* mutex); /*!< in: pointer to mutex */ 353 354 /******************************************************************//** 355 NOTE! Please use the corresponding macro mutex_free(), not directly 356 this function! 357 Wrapper function for mutex_free_func(). Also destroys the performance 358 schema probes when freeing the mutex */ 359 UNIV_INLINE 360 void 361 pfs_mutex_free_func( 362 /*================*/ 363 ib_mutex_t* mutex); /*!< in: mutex */ 364 365 #endif /* UNIV_PFS_MUTEX */ 366 367 #ifdef UNIV_SYNC_DEBUG 368 /******************************************************************//** 369 Returns TRUE if no mutex or rw-lock is currently locked. 370 Works only in the debug version. 371 @return TRUE if no mutexes and rw-locks reserved */ 372 UNIV_INTERN 373 ibool 374 sync_all_freed(void); 375 /*================*/ 376 #endif /* UNIV_SYNC_DEBUG */ 377 /*##################################################################### 378 FUNCTION PROTOTYPES FOR DEBUGGING */ 379 /*******************************************************************//** 380 Prints wait info of the sync system. */ 381 UNIV_INTERN 382 void 383 sync_print_wait_info( 384 /*=================*/ 385 FILE* file); /*!< in: file where to print */ 386 /*******************************************************************//** 387 Prints info of the sync system. */ 388 UNIV_INTERN 389 void 390 sync_print( 391 /*=======*/ 392 FILE* file); /*!< in: file where to print */ 393 #ifdef UNIV_DEBUG 394 /******************************************************************//** 395 Checks that the mutex has been initialized. 396 @return TRUE */ 397 UNIV_INTERN 398 ibool 399 mutex_validate( 400 /*===========*/ 401 const ib_mutex_t* mutex); /*!< in: mutex */ 402 /******************************************************************//** 403 Checks that the current thread owns the mutex. Works only 404 in the debug version. 405 @return TRUE if owns */ 406 UNIV_INTERN 407 ibool 408 mutex_own( 409 /*======*/ 410 const ib_mutex_t* mutex) /*!< in: mutex */ 411 MY_ATTRIBUTE((warn_unused_result)); 412 #endif /* UNIV_DEBUG */ 413 #ifdef UNIV_SYNC_DEBUG 414 /******************************************************************//** 415 Adds a latch and its level in the thread level array. Allocates the memory 416 for the array if called first time for this OS thread. Makes the checks 417 against other latch levels stored in the array for this thread. */ 418 UNIV_INTERN 419 void 420 sync_thread_add_level( 421 /*==================*/ 422 void* latch, /*!< in: pointer to a mutex or an rw-lock */ 423 ulint level, /*!< in: level in the latching order; if 424 SYNC_LEVEL_VARYING, nothing is done */ 425 ibool relock) /*!< in: TRUE if re-entering an x-lock */ 426 MY_ATTRIBUTE((nonnull)); 427 /******************************************************************//** 428 Removes a latch from the thread level array if it is found there. 429 @return TRUE if found in the array; it is no error if the latch is 430 not found, as we presently are not able to determine the level for 431 every latch reservation the program does */ 432 UNIV_INTERN 433 ibool 434 sync_thread_reset_level( 435 /*====================*/ 436 void* latch); /*!< in: pointer to a mutex or an rw-lock */ 437 /******************************************************************//** 438 Checks if the level array for the current thread contains a 439 mutex or rw-latch at the specified level. 440 @return a matching latch, or NULL if not found */ 441 UNIV_INTERN 442 void* 443 sync_thread_levels_contains( 444 /*========================*/ 445 ulint level); /*!< in: latching order level 446 (SYNC_DICT, ...)*/ 447 /******************************************************************//** 448 Checks that the level array for the current thread is empty. 449 @return a latch, or NULL if empty except the exceptions specified below */ 450 UNIV_INTERN 451 void* 452 sync_thread_levels_nonempty_gen( 453 /*============================*/ 454 ibool dict_mutex_allowed) /*!< in: TRUE if dictionary mutex is 455 allowed to be owned by the thread */ 456 MY_ATTRIBUTE((warn_unused_result)); 457 /******************************************************************//** 458 Checks if the level array for the current thread is empty, 459 except for data dictionary latches. */ 460 #define sync_thread_levels_empty_except_dict() \ 461 (!sync_thread_levels_nonempty_gen(TRUE)) 462 /******************************************************************//** 463 Checks if the level array for the current thread is empty, 464 except for the btr_search_latch. 465 @return a latch, or NULL if empty except the exceptions specified below */ 466 UNIV_INTERN 467 void* 468 sync_thread_levels_nonempty_trx( 469 /*============================*/ 470 ibool has_search_latch) 471 /*!< in: TRUE if and only if the thread 472 is supposed to hold btr_search_latch */ 473 MY_ATTRIBUTE((warn_unused_result)); 474 475 /******************************************************************//** 476 Gets the debug information for a reserved mutex. */ 477 UNIV_INTERN 478 void 479 mutex_get_debug_info( 480 /*=================*/ 481 ib_mutex_t* mutex, /*!< in: mutex */ 482 const char** file_name, /*!< out: file where requested */ 483 ulint* line, /*!< out: line where requested */ 484 os_thread_id_t* thread_id); /*!< out: id of the thread which owns 485 the mutex */ 486 /******************************************************************//** 487 Counts currently reserved mutexes. Works only in the debug version. 488 @return number of reserved mutexes */ 489 UNIV_INTERN 490 ulint 491 mutex_n_reserved(void); 492 /*==================*/ 493 #endif /* UNIV_SYNC_DEBUG */ 494 /******************************************************************//** 495 NOT to be used outside this module except in debugging! Gets the value 496 of the lock word. */ 497 UNIV_INLINE 498 lock_word_t 499 mutex_get_lock_word( 500 /*================*/ 501 const ib_mutex_t* mutex); /*!< in: mutex */ 502 #ifdef UNIV_SYNC_DEBUG 503 /******************************************************************//** 504 NOT to be used outside this module except in debugging! Gets the waiters 505 field in a mutex. 506 @return value to set */ 507 UNIV_INLINE 508 ulint 509 mutex_get_waiters( 510 /*==============*/ 511 const ib_mutex_t* mutex); /*!< in: mutex */ 512 #endif /* UNIV_SYNC_DEBUG */ 513 514 /* 515 LATCHING ORDER WITHIN THE DATABASE 516 ================================== 517 518 The mutex or latch in the central memory object, for instance, a rollback 519 segment object, must be acquired before acquiring the latch or latches to 520 the corresponding file data structure. In the latching order below, these 521 file page object latches are placed immediately below the corresponding 522 central memory object latch or mutex. 523 524 Synchronization object Notes 525 ---------------------- ----- 526 527 Dictionary mutex If we have a pointer to a dictionary 528 | object, e.g., a table, it can be 529 | accessed without reserving the 530 | dictionary mutex. We must have a 531 | reservation, a memoryfix, to the 532 | appropriate table object in this case, 533 | and the table must be explicitly 534 | released later. 535 V 536 Dictionary header 537 | 538 V 539 Secondary index tree latch The tree latch protects also all 540 | the B-tree non-leaf pages. These 541 V can be read with the page only 542 Secondary index non-leaf bufferfixed to save CPU time, 543 | no s-latch is needed on the page. 544 | Modification of a page requires an 545 | x-latch on the page, however. If a 546 | thread owns an x-latch to the tree, 547 | it is allowed to latch non-leaf pages 548 | even after it has acquired the fsp 549 | latch. 550 V 551 Secondary index leaf The latch on the secondary index leaf 552 | can be kept while accessing the 553 | clustered index, to save CPU time. 554 V 555 Clustered index tree latch To increase concurrency, the tree 556 | latch is usually released when the 557 | leaf page latch has been acquired. 558 V 559 Clustered index non-leaf 560 | 561 V 562 Clustered index leaf 563 | 564 V 565 Transaction system header 566 | 567 V 568 Transaction undo mutex The undo log entry must be written 569 | before any index page is modified. 570 | Transaction undo mutex is for the undo 571 | logs the analogue of the tree latch 572 | for a B-tree. If a thread has the 573 | trx undo mutex reserved, it is allowed 574 | to latch the undo log pages in any 575 | order, and also after it has acquired 576 | the fsp latch. 577 V 578 Rollback segment mutex The rollback segment mutex must be 579 | reserved, if, e.g., a new page must 580 | be added to an undo log. The rollback 581 | segment and the undo logs in its 582 | history list can be seen as an 583 | analogue of a B-tree, and the latches 584 | reserved similarly, using a version of 585 | lock-coupling. If an undo log must be 586 | extended by a page when inserting an 587 | undo log record, this corresponds to 588 | a pessimistic insert in a B-tree. 589 V 590 Rollback segment header 591 | 592 V 593 Purge system latch 594 | 595 V 596 Undo log pages If a thread owns the trx undo mutex, 597 | or for a log in the history list, the 598 | rseg mutex, it is allowed to latch 599 | undo log pages in any order, and even 600 | after it has acquired the fsp latch. 601 | If a thread does not have the 602 | appropriate mutex, it is allowed to 603 | latch only a single undo log page in 604 | a mini-transaction. 605 V 606 File space management latch If a mini-transaction must allocate 607 | several file pages, it can do that, 608 | because it keeps the x-latch to the 609 | file space management in its memo. 610 V 611 File system pages 612 | 613 V 614 lock_sys_wait_mutex Mutex protecting lock timeout data 615 | 616 V 617 lock_sys_mutex Mutex protecting lock_sys_t 618 | 619 V 620 trx_sys->mutex Mutex protecting trx_sys_t 621 | 622 V 623 Threads mutex Background thread scheduling mutex 624 | 625 V 626 query_thr_mutex Mutex protecting query threads 627 | 628 V 629 trx_mutex Mutex protecting trx_t fields 630 | 631 V 632 Search system mutex 633 | 634 V 635 Buffer pool mutex 636 | 637 V 638 Log mutex 639 | 640 Any other latch 641 | 642 V 643 Memory pool mutex */ 644 645 /* Latching order levels. If you modify these, you have to also update 646 sync_thread_add_level(). */ 647 648 /* User transaction locks are higher than any of the latch levels below: 649 no latches are allowed when a thread goes to wait for a normal table 650 or row lock! */ 651 #define SYNC_USER_TRX_LOCK 9999 652 #define SYNC_NO_ORDER_CHECK 3000 /* this can be used to suppress 653 latching order checking */ 654 #define SYNC_LEVEL_VARYING 2000 /* Level is varying. Only used with 655 buffer pool page locks, which do not 656 have a fixed level, but instead have 657 their level set after the page is 658 locked; see e.g. 659 ibuf_bitmap_get_map_page(). */ 660 #define SYNC_TRX_I_S_RWLOCK 1910 /* Used for 661 trx_i_s_cache_t::rw_lock */ 662 #define SYNC_TRX_I_S_LAST_READ 1900 /* Used for 663 trx_i_s_cache_t::last_read_mutex */ 664 #define SYNC_FILE_FORMAT_TAG 1200 /* Used to serialize access to the 665 file format tag */ 666 #define SYNC_DICT_OPERATION 1010 /* table create, drop, etc. reserve 667 this in X-mode; implicit or backround 668 operations purge, rollback, foreign 669 key checks reserve this in S-mode */ 670 #define SYNC_FTS_CACHE 1005 /* FTS cache rwlock */ 671 #define SYNC_DICT 1000 672 #define SYNC_DICT_AUTOINC_MUTEX 999 673 #define SYNC_STATS_AUTO_RECALC 997 674 #define SYNC_DICT_HEADER 995 675 #define SYNC_IBUF_HEADER 914 676 #define SYNC_IBUF_PESS_INSERT_MUTEX 912 677 /*-------------------------------*/ 678 #define SYNC_INDEX_TREE 900 679 #define SYNC_TREE_NODE_NEW 892 680 #define SYNC_TREE_NODE_FROM_HASH 891 681 #define SYNC_TREE_NODE 890 682 #define SYNC_PURGE_LATCH 800 683 #define SYNC_TRX_UNDO 700 684 #define SYNC_RSEG 600 685 #define SYNC_RSEG_HEADER_NEW 591 686 #define SYNC_RSEG_HEADER 590 687 #define SYNC_TRX_UNDO_PAGE 570 688 #define SYNC_EXTERN_STORAGE 500 689 #define SYNC_FSP 400 690 #define SYNC_FSP_PAGE 395 691 /*------------------------------------- Change buffer headers */ 692 #define SYNC_IBUF_MUTEX 370 /* ibuf_mutex */ 693 /*------------------------------------- Change buffer tree */ 694 #define SYNC_IBUF_INDEX_TREE 360 695 #define SYNC_IBUF_TREE_NODE_NEW 359 696 #define SYNC_IBUF_TREE_NODE 358 697 #define SYNC_IBUF_BITMAP_MUTEX 351 698 #define SYNC_IBUF_BITMAP 350 699 /*------------------------------------- Change log for online create index */ 700 #define SYNC_INDEX_ONLINE_LOG 340 701 /*------------------------------------- MySQL query cache mutex */ 702 /*------------------------------------- MySQL binlog mutex */ 703 /*-------------------------------*/ 704 #define SYNC_LOCK_WAIT_SYS 300 705 #define SYNC_LOCK_SYS 299 706 #define SYNC_TRX_SYS 298 707 #define SYNC_TRX 297 708 #define SYNC_THREADS 295 709 #define SYNC_REC_LOCK 294 710 #define SYNC_TRX_SYS_HEADER 290 711 #define SYNC_PURGE_QUEUE 200 712 #define SYNC_LOG 170 713 #define SYNC_LOG_FLUSH_ORDER 147 714 #define SYNC_RECV 168 715 #define SYNC_FTS_TOKENIZE 167 716 #define SYNC_FTS_CACHE_INIT 166 /* Used for FTS cache initialization */ 717 #define SYNC_FTS_BG_THREADS 165 718 #define SYNC_FTS_OPTIMIZE 164 // FIXME: is this correct number, test 719 #define SYNC_WORK_QUEUE 162 720 #define SYNC_SEARCH_SYS 160 /* NOTE that if we have a memory 721 heap that can be extended to the 722 buffer pool, its logical level is 723 SYNC_SEARCH_SYS, as memory allocation 724 can call routines there! Otherwise 725 the level is SYNC_MEM_HASH. */ 726 #define SYNC_BUF_POOL 150 /* Buffer pool mutex */ 727 #define SYNC_BUF_PAGE_HASH 149 /* buf_pool->page_hash rw_lock */ 728 #define SYNC_BUF_BLOCK 146 /* Block mutex */ 729 #define SYNC_BUF_FLUSH_LIST 145 /* Buffer flush list mutex */ 730 #define SYNC_DOUBLEWRITE 140 731 #define SYNC_ANY_LATCH 135 732 #define SYNC_MEM_HASH 131 733 #define SYNC_MEM_POOL 130 734 735 /* Codes used to designate lock operations */ 736 #define RW_LOCK_NOT_LOCKED 350 737 #define RW_LOCK_EX 351 738 #define RW_LOCK_EXCLUSIVE 351 739 #define RW_LOCK_SHARED 352 740 #define RW_LOCK_WAIT_EX 353 741 #define SYNC_MUTEX 354 742 743 /* NOTE! The structure appears here only for the compiler to know its size. 744 Do not use its fields directly! The structure used in the spin lock 745 implementation of a mutual exclusion semaphore. */ 746 747 /** InnoDB mutex */ 748 struct ib_mutex_t { 749 os_event_t event; /*!< Used by sync0arr.cc for the wait queue */ 750 volatile lock_word_t lock_word; /*!< lock_word is the target 751 of the atomic test-and-set instruction when 752 atomic operations are enabled. */ 753 754 #if !defined(HAVE_ATOMIC_BUILTINS) 755 os_fast_mutex_t 756 os_fast_mutex; /*!< We use this OS mutex in place of lock_word 757 when atomic operations are not enabled */ 758 #endif 759 ulint waiters; /*!< This ulint is set to 1 if there are (or 760 may be) threads waiting in the global wait 761 array for this mutex to be released. 762 Otherwise, this is 0. */ 763 UT_LIST_NODE_T(ib_mutex_t) list; /*!< All allocated mutexes are put into 764 a list. Pointers to the next and prev. */ 765 #ifdef UNIV_SYNC_DEBUG 766 const char* file_name; /*!< File where the mutex was locked */ 767 ulint line; /*!< Line where the mutex was locked */ 768 ulint level; /*!< Level in the global latching order */ 769 #endif /* UNIV_SYNC_DEBUG */ 770 const char* cfile_name;/*!< File name where mutex created */ 771 ulint cline; /*!< Line where created */ 772 ulong count_os_wait; /*!< count of os_wait */ 773 #ifdef UNIV_DEBUG 774 775 /** Value of mutex_t::magic_n */ 776 # define MUTEX_MAGIC_N 979585UL 777 778 os_thread_id_t thread_id; /*!< The thread id of the thread 779 which locked the mutex. */ 780 ulint magic_n; /*!< MUTEX_MAGIC_N */ 781 const char* cmutex_name; /*!< mutex name */ 782 ulint ib_mutex_type; /*!< 0=usual mutex, 1=rw_lock mutex */ 783 #endif /* UNIV_DEBUG */ 784 #ifdef UNIV_PFS_MUTEX 785 struct PSI_mutex* pfs_psi; /*!< The performance schema 786 instrumentation hook */ 787 #endif 788 }; 789 790 /** Constant determining how long spin wait is continued before suspending 791 the thread. A value 600 rounds on a 1995 100 MHz Pentium seems to correspond 792 to 20 microseconds. */ 793 794 #define SYNC_SPIN_ROUNDS srv_n_spin_wait_rounds 795 796 /** The number of mutex_exit calls. Intended for performance monitoring. */ 797 extern ib_int64_t mutex_exit_count; 798 799 #ifdef UNIV_SYNC_DEBUG 800 /** Latching order checks start when this is set TRUE */ 801 extern ibool sync_order_checks_on; 802 #endif /* UNIV_SYNC_DEBUG */ 803 804 /** This variable is set to TRUE when sync_init is called */ 805 extern ibool sync_initialized; 806 807 /** Global list of database mutexes (not OS mutexes) created. */ 808 typedef UT_LIST_BASE_NODE_T(ib_mutex_t) ut_list_base_node_t; 809 /** Global list of database mutexes (not OS mutexes) created. */ 810 extern ut_list_base_node_t mutex_list; 811 812 /** Mutex protecting the mutex_list variable */ 813 extern ib_mutex_t mutex_list_mutex; 814 815 #ifndef HAVE_ATOMIC_BUILTINS 816 /**********************************************************//** 817 Function that uses a mutex to decrement a variable atomically */ 818 UNIV_INLINE 819 void 820 os_atomic_dec_ulint_func( 821 /*=====================*/ 822 ib_mutex_t* mutex, /*!< in: mutex guarding the 823 decrement */ 824 volatile ulint* var, /*!< in/out: variable to 825 decrement */ 826 ulint delta); /*!< in: delta to decrement */ 827 /**********************************************************//** 828 Function that uses a mutex to increment a variable atomically */ 829 UNIV_INLINE 830 void 831 os_atomic_inc_ulint_func( 832 /*=====================*/ 833 ib_mutex_t* mutex, /*!< in: mutex guarding the 834 increment */ 835 volatile ulint* var, /*!< in/out: variable to 836 increment */ 837 ulint delta); /*!< in: delta to increment */ 838 #endif /* !HAVE_ATOMIC_BUILTINS */ 839 840 #ifndef UNIV_NONINL 841 #include "sync0sync.ic" 842 #endif 843 844 #endif 845