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