diff options
Diffstat (limited to 'storage/innobase/sync')
-rw-r--r-- | storage/innobase/sync/sync0arr.cc | 8 | ||||
-rw-r--r-- | storage/innobase/sync/sync0rw.cc | 14 | ||||
-rw-r--r-- | storage/innobase/sync/sync0sync.cc | 108 |
3 files changed, 39 insertions, 91 deletions
diff --git a/storage/innobase/sync/sync0arr.cc b/storage/innobase/sync/sync0arr.cc index 10c201e990e..c7163695a3f 100644 --- a/storage/innobase/sync/sync0arr.cc +++ b/storage/innobase/sync/sync0arr.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -1101,8 +1101,8 @@ sync_array_print_info_low( os_thread_id_t r = 0; fprintf(file, - "OS WAIT ARRAY INFO: reservation count %ld\n", - (long) arr->res_count); + "OS WAIT ARRAY INFO: reservation count " ULINTPF "\n", + arr->res_count); for (i = 0; count < arr->n_reserved; ++i) { sync_cell_t* cell; @@ -1197,7 +1197,7 @@ sync_array_print( } fprintf(file, - "OS WAIT ARRAY INFO: signal count %ld\n", (long) sg_count); + "OS WAIT ARRAY INFO: signal count " ULINTPF "\n", sg_count); } diff --git a/storage/innobase/sync/sync0rw.cc b/storage/innobase/sync/sync0rw.cc index 4ff330791a0..e77c7a9b396 100644 --- a/storage/innobase/sync/sync0rw.cc +++ b/storage/innobase/sync/sync0rw.cc @@ -545,6 +545,8 @@ rw_lock_x_lock_low( const char* file_name,/*!< in: file name where lock requested */ ulint line) /*!< in: line where requested */ { + ibool local_recursive= lock->recursive; + if (rw_lock_lock_word_decr(lock, X_LOCK_DECR)) { /* lock->recursive also tells us if the writer_thread @@ -566,12 +568,12 @@ rw_lock_x_lock_low( } else { os_thread_id_t thread_id = os_thread_get_curr_id(); - if (!pass) { - os_rmb; - } - - /* Decrement failed: relock or failed lock */ - if (!pass && lock->recursive + /* Decrement failed: relock or failed lock + Note: recursive must be loaded before writer_thread see + comment for rw_lock_set_writer_id_and_recursion_flag(). + To achieve this we load it before rw_lock_lock_word_decr(), + which implies full memory barrier in current implementation. */ + if (!pass && local_recursive && os_thread_eq(lock->writer_thread, thread_id)) { /* Relock */ if (lock->lock_word == 0) { diff --git a/storage/innobase/sync/sync0sync.cc b/storage/innobase/sync/sync0sync.cc index fb559f26bd4..e0f132574c9 100644 --- a/storage/innobase/sync/sync0sync.cc +++ b/storage/innobase/sync/sync0sync.cc @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (c) 1995, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2008, Google Inc. Portions of this file contain modifications contributed and copyrighted by @@ -47,6 +47,8 @@ Created 9/5/1995 Heikki Tuuri #include "ha_prototypes.h" #include "my_cpu.h" +#include <vector> + /* REASONS FOR IMPLEMENTING THE SPIN LOCK MUTEX ============================================ @@ -224,14 +226,8 @@ UNIV_INTERN ibool sync_order_checks_on = FALSE; static const ulint SYNC_THREAD_N_LEVELS = 10000; /** Array for tracking sync levels per thread. */ -struct sync_arr_t { - ulint in_use; /*!< Number of active cells */ - ulint n_elems; /*!< Number of elements in the array */ - ulint max_elems; /*!< Maximum elements */ - ulint next_free; /*!< ULINT_UNDEFINED or index of next - free slot */ - sync_level_t* elems; /*!< Array elements */ -}; +typedef std::vector<sync_level_t> sync_arr_t; + /** Mutexes or rw-locks held by a thread */ struct sync_thread_t{ @@ -299,9 +295,9 @@ mutex_create_func( /* NOTE! The very first mutexes are not put to the mutex list */ - if ((mutex == &mutex_list_mutex) + if (mutex == &mutex_list_mutex #ifdef UNIV_SYNC_DEBUG - || (mutex == &sync_thread_mutex) + || mutex == &sync_thread_mutex #endif /* UNIV_SYNC_DEBUG */ ) { @@ -844,10 +840,10 @@ sync_thread_levels_g( { ulint i; - for (i = 0; i < arr->n_elems; i++) { + for (i = 0; i < arr->size(); i++) { const sync_level_t* slot; - slot = &arr->elems[i]; + slot = (const sync_level_t*)&(arr->at(i)); if (slot->latch != NULL && slot->level <= limit) { if (warn) { @@ -879,10 +875,10 @@ sync_thread_levels_contain( { ulint i; - for (i = 0; i < arr->n_elems; i++) { + for (i = 0; i < arr->size(); i++) { const sync_level_t* slot; - slot = &arr->elems[i]; + slot = (const sync_level_t*)&(arr->at(i)); if (slot->latch != NULL && slot->level == level) { @@ -926,10 +922,10 @@ sync_thread_levels_contains( arr = thread_slot->levels; - for (i = 0; i < arr->n_elems; i++) { + for (i = 0; i < arr->size(); i++) { sync_level_t* slot; - slot = &arr->elems[i]; + slot = (sync_level_t*)&(arr->at(i)); if (slot->latch != NULL && slot->level == level) { @@ -975,10 +971,10 @@ sync_thread_levels_nonempty_gen( arr = thread_slot->levels; - for (i = 0; i < arr->n_elems; ++i) { + for (i = 0; i < arr->size(); ++i) { const sync_level_t* slot; - slot = &arr->elems[i]; + slot = (const sync_level_t*)&(arr->at(i)); if (slot->latch != NULL && (!dict_mutex_allowed @@ -1035,10 +1031,10 @@ sync_thread_levels_nonempty_trx( arr = thread_slot->levels; - for (i = 0; i < arr->n_elems; ++i) { + for (i = 0; i < arr->size(); ++i) { const sync_level_t* slot; - slot = &arr->elems[i]; + slot = (const sync_level_t*)&(arr->at(i)); if (slot->latch != NULL && (!has_search_latch @@ -1069,10 +1065,9 @@ sync_thread_add_level( SYNC_LEVEL_VARYING, nothing is done */ ibool relock) /*!< in: TRUE if re-entering an x-lock */ { - ulint i; - sync_level_t* slot; sync_arr_t* array; sync_thread_t* thread_slot; + sync_level_t sync_level; if (!sync_order_checks_on) { @@ -1097,21 +1092,11 @@ sync_thread_add_level( thread_slot = sync_thread_level_arrays_find_slot(); if (thread_slot == NULL) { - ulint sz; - - sz = sizeof(*array) - + (sizeof(*array->elems) * SYNC_THREAD_N_LEVELS); /* We have to allocate the level array for a new thread */ - array = static_cast<sync_arr_t*>(calloc(sz, sizeof(char))); + array = new sync_arr_t(); ut_a(array != NULL); - - array->next_free = ULINT_UNDEFINED; - array->max_elems = SYNC_THREAD_N_LEVELS; - array->elems = (sync_level_t*) &array[1]; - thread_slot = sync_thread_level_arrays_find_free(); - thread_slot->levels = array; thread_slot->id = os_thread_get_curr_id(); } @@ -1321,26 +1306,10 @@ sync_thread_add_level( } levels_ok: - if (array->next_free == ULINT_UNDEFINED) { - ut_a(array->n_elems < array->max_elems); - - i = array->n_elems++; - } else { - i = array->next_free; - array->next_free = array->elems[i].level; - } - - ut_a(i < array->n_elems); - ut_a(i != ULINT_UNDEFINED); - - ++array->in_use; - slot = &array->elems[i]; - - ut_a(slot->latch == NULL); - - slot->latch = latch; - slot->level = level; + sync_level.latch = latch; + sync_level.level = level; + array->push_back(sync_level); mutex_exit(&sync_thread_mutex); } @@ -1358,7 +1327,6 @@ sync_thread_reset_level( { sync_arr_t* array; sync_thread_t* thread_slot; - ulint i; if (!sync_order_checks_on) { @@ -1387,36 +1355,15 @@ sync_thread_reset_level( array = thread_slot->levels; - for (i = 0; i < array->n_elems; i++) { - sync_level_t* slot; - - slot = &array->elems[i]; + for (std::vector<sync_level_t>::iterator it = array->begin(); it != array->end(); ++it) { + sync_level_t level = *it; - if (slot->latch != latch) { + if (level.latch != latch) { continue; } - slot->latch = NULL; - - /* Update the free slot list. See comment in sync_level_t - for the level field. */ - slot->level = array->next_free; - array->next_free = i; - - ut_a(array->in_use >= 1); - --array->in_use; - - /* If all cells are idle then reset the free - list. The assumption is that this will save - time when we need to scan up to n_elems. */ - - if (array->in_use == 0) { - array->n_elems = 0; - array->next_free = ULINT_UNDEFINED; - } - + array->erase(it); mutex_exit(&sync_thread_mutex); - return(TRUE); } @@ -1502,8 +1449,7 @@ sync_thread_level_arrays_free(void) /* If this slot was allocated then free the slot memory too. */ if (slot->levels != NULL) { - free(slot->levels); - slot->levels = NULL; + delete slot->levels; } } |