summaryrefslogtreecommitdiff
path: root/storage/innobase/sync
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/sync')
-rw-r--r--storage/innobase/sync/sync0arr.cc8
-rw-r--r--storage/innobase/sync/sync0rw.cc14
-rw-r--r--storage/innobase/sync/sync0sync.cc108
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;
}
}