1
1
/*****************************************************************************
3
Copyright (C) 1995, 2010, Innobase Oy. All Rights Reserved.
4
Copyright (C) 2008, Google Inc.
3
Copyright (c) 1995, 2009, Innobase Oy. All Rights Reserved.
4
Copyright (c) 2008, Google Inc.
6
6
Portions of this file contain modifications contributed and copyrighted by
7
7
Google, Inc. Those modifications are gratefully acknowledged and are described
202
199
/** Mutex protecting sync_thread_level_arrays */
203
200
UNIV_INTERN mutex_t sync_thread_mutex;
205
# ifdef UNIV_PFS_MUTEX
206
UNIV_INTERN mysql_pfs_key_t sync_thread_mutex_key;
207
# endif /* UNIV_PFS_MUTEX */
208
201
#endif /* UNIV_SYNC_DEBUG */
210
203
/** Global list of database mutexes (not OS mutexes) created. */
213
206
/** Mutex protecting the mutex_list variable */
214
207
UNIV_INTERN mutex_t mutex_list_mutex;
216
#ifdef UNIV_PFS_MUTEX
217
UNIV_INTERN mysql_pfs_key_t mutex_list_mutex_key;
218
#endif /* UNIV_PFS_MUTEX */
220
209
#ifdef UNIV_SYNC_DEBUG
221
210
/** Latching order checks start when this is set TRUE */
222
211
UNIV_INTERN ibool sync_order_checks_on = FALSE;
315
304
/******************************************************************//**
316
NOTE! Use the corresponding macro mutex_free(), not directly this function!
317
305
Calling this function is obligatory only if the memory buffer containing
318
306
the mutex is freed. Removes a mutex object from the mutex list. The mutex
319
307
is checked to be in the reset state. */
324
312
mutex_t* mutex) /*!< in: mutex */
326
314
ut_ad(mutex_validate(mutex));
327
315
ut_a(mutex_get_lock_word(mutex) == 0);
328
316
ut_a(mutex_get_waiters(mutex) == 0);
330
#ifdef UNIV_MEM_DEBUG
331
if (mutex == &mem_hash_mutex) {
332
ut_ad(UT_LIST_GET_LEN(mutex_list) == 1);
333
ut_ad(UT_LIST_GET_FIRST(mutex_list) == &mem_hash_mutex);
334
UT_LIST_REMOVE(list, mutex_list, mutex);
337
#endif /* UNIV_MEM_DEBUG */
339
318
if (mutex != &mutex_list_mutex
340
319
#ifdef UNIV_SYNC_DEBUG
341
320
&& mutex != &sync_thread_mutex
381
358
mutex_enter_nowait_func(
382
359
/*====================*/
383
360
mutex_t* mutex, /*!< in: pointer to mutex */
384
const char* /*file_name __attribute__((unused))*/,
361
const char* file_name __attribute__((unused)),
385
362
/*!< in: file name where mutex
387
ulint /*line __attribute__((unused))*/)
364
ulint line __attribute__((unused)))
388
365
/*!< in: line where requested */
390
367
ut_ad(mutex_validate(mutex));
972
949
/******************************************************************//**
973
Checks if the level array for the current thread contains a
974
mutex or rw-latch at the specified level.
975
@return a matching latch, or NULL if not found */
978
sync_thread_levels_contains(
979
/*========================*/
980
ulint level) /*!< in: latching order level
984
sync_thread_t* thread_slot;
988
if (!sync_order_checks_on) {
993
mutex_enter(&sync_thread_mutex);
995
thread_slot = sync_thread_level_arrays_find_slot();
997
if (thread_slot == NULL) {
999
mutex_exit(&sync_thread_mutex);
1004
arr = thread_slot->levels;
1006
for (i = 0; i < SYNC_THREAD_N_LEVELS; i++) {
1008
slot = sync_thread_levels_get_nth(arr, i);
1010
if (slot->latch != NULL && slot->level == level) {
1012
mutex_exit(&sync_thread_mutex);
1013
return(slot->latch);
1017
mutex_exit(&sync_thread_mutex);
1022
/******************************************************************//**
1023
950
Checks that the level array for the current thread is empty.
1024
@return a latch, or NULL if empty except the exceptions specified below */
951
@return TRUE if empty except the exceptions specified below */
1027
sync_thread_levels_nonempty_gen(
1028
/*============================*/
954
sync_thread_levels_empty_gen(
955
/*=========================*/
1029
956
ibool dict_mutex_allowed) /*!< in: TRUE if dictionary mutex is
1030
957
allowed to be owned by the thread,
1031
958
also purge_is_running mutex is
1155
1082
case SYNC_TREE_NODE_FROM_HASH:
1156
1083
/* Do no order checking */
1158
case SYNC_TRX_SYS_HEADER:
1159
if (srv_is_being_started) {
1160
/* This is violated during trx_sys_create_rsegs()
1161
when creating additional rollback segments when
1162
upgrading in innobase_start_or_create_for_mysql(). */
1165
1085
case SYNC_MEM_POOL:
1166
1086
case SYNC_MEM_HASH:
1167
1087
case SYNC_RECV:
1168
1088
case SYNC_WORK_QUEUE:
1170
case SYNC_LOG_FLUSH_ORDER:
1171
1090
case SYNC_THR_LOCAL:
1172
1091
case SYNC_ANY_LATCH:
1092
case SYNC_TRX_SYS_HEADER:
1173
1093
case SYNC_FILE_FORMAT_TAG:
1174
1094
case SYNC_DOUBLEWRITE:
1175
1096
case SYNC_SEARCH_SYS:
1176
1097
case SYNC_SEARCH_SYS_CONF:
1177
1098
case SYNC_TRX_LOCK_HEAP:
1196
case SYNC_BUF_FLUSH_LIST:
1198
/* We can have multiple mutexes of this type therefore we
1199
can only check whether the greater than condition holds. */
1200
if (!sync_thread_levels_g(array, level-1, TRUE)) {
1202
"InnoDB: sync_thread_levels_g(array, %lu)"
1203
" does not hold!\n", level-1);
1208
1117
case SYNC_BUF_BLOCK:
1209
1118
/* Either the thread must own the buffer pool mutex
1210
(buf_pool->mutex), or it is allowed to latch only ONE
1211
buffer block (block->mutex or buf_pool->zip_mutex). */
1119
(buf_pool_mutex), or it is allowed to latch only ONE
1120
buffer block (block->mutex or buf_pool_zip_mutex). */
1212
1121
if (!sync_thread_levels_g(array, level, FALSE)) {
1213
1122
ut_a(sync_thread_levels_g(array, level - 1, TRUE));
1214
1123
ut_a(sync_thread_levels_contain(array, SYNC_BUF_POOL));
1231
1140
ut_a(sync_thread_levels_g(array, SYNC_IBUF_BITMAP - 1,
1234
/* This is violated during trx_sys_create_rsegs()
1235
when creating additional rollback segments when
1236
upgrading in innobase_start_or_create_for_mysql(). */
1237
ut_a(srv_is_being_started
1238
|| sync_thread_levels_g(array, SYNC_IBUF_BITMAP,
1143
ut_a(sync_thread_levels_g(array, SYNC_IBUF_BITMAP,
1242
1147
case SYNC_FSP_PAGE:
1432
1337
/* Init the mutex list and create the mutex to protect it. */
1434
1339
UT_LIST_INIT(mutex_list);
1435
mutex_create(mutex_list_mutex_key, &mutex_list_mutex,
1436
SYNC_NO_ORDER_CHECK);
1340
mutex_create(&mutex_list_mutex, SYNC_NO_ORDER_CHECK);
1437
1341
#ifdef UNIV_SYNC_DEBUG
1438
mutex_create(sync_thread_mutex_key, &sync_thread_mutex,
1439
SYNC_NO_ORDER_CHECK);
1342
mutex_create(&sync_thread_mutex, SYNC_NO_ORDER_CHECK);
1440
1343
#endif /* UNIV_SYNC_DEBUG */
1442
1345
/* Init the rw-lock list and create the mutex to protect it. */
1444
1347
UT_LIST_INIT(rw_lock_list);
1445
mutex_create(rw_lock_list_mutex_key, &rw_lock_list_mutex,
1446
SYNC_NO_ORDER_CHECK);
1348
mutex_create(&rw_lock_list_mutex, SYNC_NO_ORDER_CHECK);
1448
1350
#ifdef UNIV_SYNC_DEBUG
1449
mutex_create(rw_lock_debug_mutex_key, &rw_lock_debug_mutex,
1450
SYNC_NO_ORDER_CHECK);
1351
mutex_create(&rw_lock_debug_mutex, SYNC_NO_ORDER_CHECK);
1452
1353
rw_lock_debug_event = os_event_create(NULL);
1453
1354
rw_lock_debug_waiters = FALSE;
1469
1370
mutex = UT_LIST_GET_FIRST(mutex_list);
1471
1372
while (mutex) {
1472
#ifdef UNIV_MEM_DEBUG
1473
if (mutex == &mem_hash_mutex) {
1474
mutex = UT_LIST_GET_NEXT(list, mutex);
1477
#endif /* UNIV_MEM_DEBUG */
1478
1373
mutex_free(mutex);
1479
1374
mutex = UT_LIST_GET_FIRST(mutex_list);
1507
1402
"Mutex spin waits %"PRId64", rounds %"PRId64", "
1508
1403
"OS waits %"PRId64"\n"
1509
"RW-shared spins %"PRId64", rounds %"PRId64", OS waits %"PRId64";"
1510
" RW-excl spins %"PRId64", rounds %"PRId64", OS waits %"PRId64"\n",
1404
"RW-shared spins %"PRId64", OS waits %"PRId64";"
1405
" RW-excl spins %"PRId64", OS waits %"PRId64"\n",
1511
1406
mutex_spin_wait_count,
1512
1407
mutex_spin_round_count,
1513
1408
mutex_os_wait_count,
1514
1409
rw_s_spin_wait_count,
1515
rw_s_spin_round_count,
1516
1410
rw_s_os_wait_count,
1517
1411
rw_x_spin_wait_count,
1518
rw_x_spin_round_count,
1519
1412
rw_x_os_wait_count);