~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/sync/sync0sync.c

  • Committer: Brian Aker
  • Date: 2010-10-28 17:12:01 UTC
  • mfrom: (1887.1.3 merge)
  • Revision ID: brian@tangent.org-20101028171201-baj6l1bnntn1s4ad
Merge in POTFILES changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
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.
5
5
 
6
6
Portions of this file contain modifications contributed and copyrighted by
7
7
Google, Inc. Those modifications are gratefully acknowledged and are described
40
40
#include "srv0srv.h"
41
41
#include "buf0types.h"
42
42
#include "os0sync.h" /* for HAVE_ATOMIC_BUILTINS */
43
 
#ifdef UNIV_SYNC_DEBUG
44
 
# include "srv0start.h" /* srv_is_being_started */
45
 
#endif /* UNIV_SYNC_DEBUG */
46
43
 
47
44
/*
48
45
        REASONS FOR IMPLEMENTING THE SPIN LOCK MUTEX
201
198
 
202
199
/** Mutex protecting sync_thread_level_arrays */
203
200
UNIV_INTERN mutex_t             sync_thread_mutex;
204
 
 
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 */
209
202
 
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;
215
208
 
216
 
#ifdef UNIV_PFS_MUTEX
217
 
UNIV_INTERN mysql_pfs_key_t     mutex_list_mutex_key;
218
 
#endif /* UNIV_PFS_MUTEX */
219
 
 
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;
313
302
}
314
303
 
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. */
320
308
UNIV_INTERN
321
309
void
322
 
mutex_free_func(
323
 
/*============*/
 
310
mutex_free(
 
311
/*=======*/
324
312
        mutex_t*        mutex)  /*!< in: mutex */
325
313
{
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);
329
317
 
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);
335
 
                goto func_exit;
336
 
        }
337
 
#endif /* UNIV_MEM_DEBUG */
338
 
 
339
318
        if (mutex != &mutex_list_mutex
340
319
#ifdef UNIV_SYNC_DEBUG
341
320
            && mutex != &sync_thread_mutex
357
336
        }
358
337
 
359
338
        os_event_free(mutex->event);
360
 
#ifdef UNIV_MEM_DEBUG
361
 
func_exit:
362
 
#endif /* UNIV_MEM_DEBUG */
 
339
 
363
340
#if !defined(HAVE_ATOMIC_BUILTINS)
364
341
        os_fast_mutex_free(&(mutex->os_fast_mutex));
365
342
#endif
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
386
363
                                        requested */
387
 
        ulint           /*line __attribute__((unused))*/)
 
364
        ulint           line __attribute__((unused)))
388
365
                                        /*!< in: line where requested */
389
366
{
390
367
        ut_ad(mutex_validate(mutex));
970
947
}
971
948
 
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 */
976
 
UNIV_INTERN
977
 
void*
978
 
sync_thread_levels_contains(
979
 
/*========================*/
980
 
        ulint   level)                  /*!< in: latching order level
981
 
                                        (SYNC_DICT, ...)*/
982
 
{
983
 
        sync_level_t*   arr;
984
 
        sync_thread_t*  thread_slot;
985
 
        sync_level_t*   slot;
986
 
        ulint           i;
987
 
 
988
 
        if (!sync_order_checks_on) {
989
 
 
990
 
                return(NULL);
991
 
        }
992
 
 
993
 
        mutex_enter(&sync_thread_mutex);
994
 
 
995
 
        thread_slot = sync_thread_level_arrays_find_slot();
996
 
 
997
 
        if (thread_slot == NULL) {
998
 
 
999
 
                mutex_exit(&sync_thread_mutex);
1000
 
 
1001
 
                return(NULL);
1002
 
        }
1003
 
 
1004
 
        arr = thread_slot->levels;
1005
 
 
1006
 
        for (i = 0; i < SYNC_THREAD_N_LEVELS; i++) {
1007
 
 
1008
 
                slot = sync_thread_levels_get_nth(arr, i);
1009
 
 
1010
 
                if (slot->latch != NULL && slot->level == level) {
1011
 
 
1012
 
                        mutex_exit(&sync_thread_mutex);
1013
 
                        return(slot->latch);
1014
 
                }
1015
 
        }
1016
 
 
1017
 
        mutex_exit(&sync_thread_mutex);
1018
 
 
1019
 
        return(NULL);
1020
 
}
1021
 
 
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 */
1025
952
UNIV_INTERN
1026
 
void*
1027
 
sync_thread_levels_nonempty_gen(
1028
 
/*============================*/
 
953
ibool
 
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
1038
965
 
1039
966
        if (!sync_order_checks_on) {
1040
967
 
1041
 
                return(NULL);
 
968
                return(TRUE);
1042
969
        }
1043
970
 
1044
971
        mutex_enter(&sync_thread_mutex);
1049
976
 
1050
977
                mutex_exit(&sync_thread_mutex);
1051
978
 
1052
 
                return(NULL);
 
979
                return(TRUE);
1053
980
        }
1054
981
 
1055
982
        arr = thread_slot->levels;
1066
993
                        mutex_exit(&sync_thread_mutex);
1067
994
                        ut_error;
1068
995
 
1069
 
                        return(slot->latch);
 
996
                        return(FALSE);
1070
997
                }
1071
998
        }
1072
999
 
1073
1000
        mutex_exit(&sync_thread_mutex);
1074
1001
 
1075
 
        return(NULL);
 
1002
        return(TRUE);
1076
1003
}
1077
1004
 
1078
1005
/******************************************************************//**
1155
1082
        case SYNC_TREE_NODE_FROM_HASH:
1156
1083
                /* Do no order checking */
1157
1084
                break;
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(). */
1163
 
                        break;
1164
 
                }
1165
1085
        case SYNC_MEM_POOL:
1166
1086
        case SYNC_MEM_HASH:
1167
1087
        case SYNC_RECV:
1168
1088
        case SYNC_WORK_QUEUE:
1169
1089
        case SYNC_LOG:
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:
 
1095
        case SYNC_BUF_POOL:
1175
1096
        case SYNC_SEARCH_SYS:
1176
1097
        case SYNC_SEARCH_SYS_CONF:
1177
1098
        case SYNC_TRX_LOCK_HEAP:
1193
1114
                        ut_error;
1194
1115
                }
1195
1116
                break;
1196
 
        case SYNC_BUF_FLUSH_LIST:
1197
 
        case SYNC_BUF_POOL:
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)) {
1201
 
                        fprintf(stderr,
1202
 
                                "InnoDB: sync_thread_levels_g(array, %lu)"
1203
 
                                " does not hold!\n", level-1);
1204
 
                        ut_error;
1205
 
                }
1206
 
                break;
1207
 
 
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,
1232
1141
                                                  TRUE));
1233
1142
                } else {
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,
1239
 
                                                     TRUE));
 
1143
                        ut_a(sync_thread_levels_g(array, SYNC_IBUF_BITMAP,
 
1144
                                                  TRUE));
1240
1145
                }
1241
1146
                break;
1242
1147
        case SYNC_FSP_PAGE:
1432
1337
        /* Init the mutex list and create the mutex to protect it. */
1433
1338
 
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 */
1441
1344
 
1442
1345
        /* Init the rw-lock list and create the mutex to protect it. */
1443
1346
 
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);
1447
1349
 
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);
1451
1352
 
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);
1470
1371
 
1471
1372
        while (mutex) {
1472
 
#ifdef UNIV_MEM_DEBUG
1473
 
                if (mutex == &mem_hash_mutex) {
1474
 
                        mutex = UT_LIST_GET_NEXT(list, mutex);
1475
 
                        continue;
1476
 
                }
1477
 
#endif /* UNIV_MEM_DEBUG */
1478
1373
                mutex_free(mutex);
1479
1374
                mutex = UT_LIST_GET_FIRST(mutex_list);
1480
1375
        }
1506
1401
        fprintf(file,
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);
1520
1413
 
1521
1414
        fprintf(file,