summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
authorNirbhay Choubey <nirbhay@mariadb.com>2014-10-09 17:25:08 -0400
committerNirbhay Choubey <nirbhay@mariadb.com>2014-10-09 17:25:08 -0400
commit068fb8569f2300e4a5c08413a756417d923ecf5f (patch)
treeab008f1be51ee322cbeeb5aa73042430a6e63347 /storage/innobase
parent59277a7d83374bc293cd58f8be509a81792d829e (diff)
parentdbda20caffbb22115b6f30069b716bc505c49d11 (diff)
downloadmariadb-git-068fb8569f2300e4a5c08413a756417d923ecf5f.tar.gz
bzr merge -rtag:mariadb-5.5.40 maria/5.5
Diffstat (limited to 'storage/innobase')
-rw-r--r--storage/innobase/CMakeLists.txt39
-rw-r--r--storage/innobase/buf/buf0buf.c1
-rw-r--r--storage/innobase/dict/dict0dict.c15
-rw-r--r--storage/innobase/include/log0log.h7
-rw-r--r--storage/innobase/include/log0log.ic20
-rw-r--r--storage/innobase/include/os0sync.h57
-rw-r--r--storage/innobase/include/sync0rw.h8
-rw-r--r--storage/innobase/include/sync0rw.ic6
-rw-r--r--storage/innobase/include/sync0sync.ic8
-rw-r--r--storage/innobase/row/row0ins.c12
-rw-r--r--storage/innobase/srv/srv0srv.c13
-rw-r--r--storage/innobase/sync/sync0arr.c3
-rw-r--r--storage/innobase/sync/sync0rw.c54
-rw-r--r--storage/innobase/sync/sync0sync.c14
14 files changed, 191 insertions, 66 deletions
diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt
index e4455630bc8..1e1b74f82cd 100644
--- a/storage/innobase/CMakeLists.txt
+++ b/storage/innobase/CMakeLists.txt
@@ -85,12 +85,39 @@ IF(NOT CMAKE_CROSSCOMPILING)
}"
HAVE_IB_GCC_ATOMIC_BUILTINS
)
+ CHECK_C_SOURCE_RUNS(
+ "#include<stdint.h>
+ int main()
+ {
+ __sync_synchronize();
+ return(0);
+ }"
+ HAVE_IB_GCC_SYNC_SYNCHRONISE
+ )
+ CHECK_C_SOURCE_RUNS(
+ "#include<stdint.h>
+ int main()
+ {
+ __atomic_thread_fence(__ATOMIC_ACQUIRE);
+ __atomic_thread_fence(__ATOMIC_RELEASE);
+ return(0);
+ }"
+ HAVE_IB_GCC_ATOMIC_THREAD_FENCE
+ )
ENDIF()
IF(HAVE_IB_GCC_ATOMIC_BUILTINS)
ADD_DEFINITIONS(-DHAVE_IB_GCC_ATOMIC_BUILTINS=1)
ENDIF()
+IF(HAVE_IB_GCC_SYNC_SYNCHRONISE)
+ ADD_DEFINITIONS(-DHAVE_IB_GCC_SYNC_SYNCHRONISE=1)
+ENDIF()
+
+IF(HAVE_IB_GCC_ATOMIC_THREAD_FENCE)
+ ADD_DEFINITIONS(-DHAVE_IB_GCC_ATOMIC_THREAD_FENCE=1)
+ENDIF()
+
# either define HAVE_IB_ATOMIC_PTHREAD_T_GCC or not
IF(NOT CMAKE_CROSSCOMPILING)
CHECK_C_SOURCE_RUNS(
@@ -169,10 +196,21 @@ IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS")
return(0);
}
" HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS)
+ CHECK_C_SOURCE_COMPILES(
+ "#include <mbarrier.h>
+ int main() {
+ __machine_r_barrier();
+ __machine_w_barrier();
+ return(0);
+ }"
+ HAVE_IB_MACHINE_BARRIER_SOLARIS)
ENDIF()
IF(HAVE_IB_ATOMIC_PTHREAD_T_SOLARIS)
ADD_DEFINITIONS(-DHAVE_IB_ATOMIC_PTHREAD_T_SOLARIS=1)
ENDIF()
+ IF(HAVE_IB_MACHINE_BARRIER_SOLARIS)
+ ADD_DEFINITIONS(-DHAVE_IB_MACHINE_BARRIER_SOLARIS=1)
+ ENDIF()
ENDIF()
@@ -190,6 +228,7 @@ ENDIF()
IF(MSVC)
ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS)
+ ADD_DEFINITIONS(-DHAVE_WINDOWS_MM_FENCE)
ENDIF()
diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c
index a799f3b8556..b6bfcc3dbc0 100644
--- a/storage/innobase/buf/buf0buf.c
+++ b/storage/innobase/buf/buf0buf.c
@@ -3616,6 +3616,7 @@ corrupt:
" because of"
" a corrupt database page.\n",
stderr);
+
ut_error;
}
}
diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c
index c3c8fcca58c..1eb557811bd 100644
--- a/storage/innobase/dict/dict0dict.c
+++ b/storage/innobase/dict/dict0dict.c
@@ -1123,6 +1123,11 @@ dict_table_rename_in_cache(
/* The id will be changed. So remove old one */
rbt_delete(foreign->foreign_table->foreign_rbt, foreign->id);
+ if (foreign->referenced_table) {
+ rbt_delete(foreign->referenced_table->referenced_rbt,
+ foreign->id);
+ }
+
if (ut_strlen(foreign->foreign_table_name)
< ut_strlen(table->name)) {
/* Allocate a longer name buffer;
@@ -1273,6 +1278,11 @@ dict_table_rename_in_cache(
rbt_insert(foreign->foreign_table->foreign_rbt,
foreign->id, &foreign);
+ if (foreign->referenced_table) {
+ rbt_insert(foreign->referenced_table->referenced_rbt,
+ foreign->id, &foreign);
+ }
+
foreign = UT_LIST_GET_NEXT(foreign_list, foreign);
}
@@ -5383,6 +5393,11 @@ dict_find_table_by_space(
ut_ad(space_id > 0);
+ if (dict_sys == NULL) {
+ /* This could happen when it's in redo processing. */
+ return(NULL);
+ }
+
table = UT_LIST_GET_FIRST(dict_sys->table_LRU);
num_item = UT_LIST_GET_LEN(dict_sys->table_LRU);
diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h
index b0e5e9bda3b..fab91b5c5c2 100644
--- a/storage/innobase/include/log0log.h
+++ b/storage/innobase/include/log0log.h
@@ -154,6 +154,13 @@ UNIV_INLINE
ib_uint64_t
log_get_lsn(void);
/*=============*/
+/************************************************************//**
+Gets the current lsn.
+@return current lsn */
+UNIV_INLINE
+lsn_t
+log_get_lsn_nowait(void);
+/*=============*/
/****************************************************************
Gets the log group capacity. It is OK to read the value without
holding log_sys->mutex because it is constant.
diff --git a/storage/innobase/include/log0log.ic b/storage/innobase/include/log0log.ic
index 8eca3b911d0..a55bbeff789 100644
--- a/storage/innobase/include/log0log.ic
+++ b/storage/innobase/include/log0log.ic
@@ -411,6 +411,26 @@ log_get_lsn(void)
return(lsn);
}
+/************************************************************//**
+Gets the current lsn with a trylock
+@return current lsn or 0 if false*/
+UNIV_INLINE
+lsn_t
+log_get_lsn_nowait(void)
+/*=============*/
+{
+ lsn_t lsn;
+
+ if (mutex_enter_nowait(&(log_sys->mutex)))
+ return 0;
+
+ lsn = log_sys->lsn;
+
+ mutex_exit(&(log_sys->mutex));
+
+ return(lsn);
+}
+
/****************************************************************
Gets the log group capacity. It is OK to read the value without
holding log_sys->mutex because it is constant.
diff --git a/storage/innobase/include/os0sync.h b/storage/innobase/include/os0sync.h
index c6672aa73b6..d1a4c9e7c60 100644
--- a/storage/innobase/include/os0sync.h
+++ b/storage/innobase/include/os0sync.h
@@ -310,6 +310,9 @@ Returns the old value of *ptr, atomically sets *ptr to new_val */
# define os_atomic_test_and_set_byte(ptr, new_val) \
__sync_lock_test_and_set(ptr, (byte) new_val)
+# define os_atomic_lock_release_byte(ptr) \
+ __sync_lock_release(ptr)
+
#elif defined(HAVE_IB_SOLARIS_ATOMICS)
#define HAVE_ATOMIC_BUILTINS
@@ -363,6 +366,9 @@ Returns the old value of *ptr, atomically sets *ptr to new_val */
# define os_atomic_test_and_set_byte(ptr, new_val) \
atomic_swap_uchar(ptr, new_val)
+# define os_atomic_lock_release_byte(ptr) \
+ (void) atomic_swap_uchar(ptr, 0)
+
#elif defined(HAVE_WINDOWS_ATOMICS)
#define HAVE_ATOMIC_BUILTINS
@@ -416,6 +422,57 @@ clobbered */
"Mutexes and rw_locks use InnoDB's own implementation"
#endif
+/** barrier definitions for memory ordering */
+#ifdef HAVE_IB_GCC_ATOMIC_THREAD_FENCE
+# define HAVE_MEMORY_BARRIER
+# define os_rmb __atomic_thread_fence(__ATOMIC_ACQUIRE)
+# define os_wmb __atomic_thread_fence(__ATOMIC_RELEASE)
+#ifdef __powerpc__
+# define os_isync __asm __volatile ("isync":::"memory")
+#else
+#define os_isync do { } while(0)
+#endif
+
+# define IB_MEMORY_BARRIER_STARTUP_MSG \
+ "GCC builtin __atomic_thread_fence() is used for memory barrier"
+
+#elif defined(HAVE_IB_GCC_SYNC_SYNCHRONISE)
+# define HAVE_MEMORY_BARRIER
+# define os_rmb __sync_synchronize()
+# define os_wmb __sync_synchronize()
+# define os_isync __sync_synchronize()
+# define IB_MEMORY_BARRIER_STARTUP_MSG \
+ "GCC builtin __sync_synchronize() is used for memory barrier"
+
+#elif defined(HAVE_IB_MACHINE_BARRIER_SOLARIS)
+# define HAVE_MEMORY_BARRIER
+# include <mbarrier.h>
+# define os_rmb __machine_r_barrier()
+# define os_wmb __machine_w_barrier()
+# define os_isync os_rmb; os_wmb
+# define IB_MEMORY_BARRIER_STARTUP_MSG \
+ "Soralis memory ordering functions are used for memory barrier"
+
+#elif defined(HAVE_WINDOWS_MM_FENCE)
+# define HAVE_MEMORY_BARRIER
+# include <intrin.h>
+# define os_rmb _mm_lfence()
+# define os_wmb _mm_sfence()
+# define os_isync os_rmb; os_wmb
+# define IB_MEMORY_BARRIER_STARTUP_MSG \
+ "_mm_lfence() and _mm_sfence() are used for memory barrier"
+
+# define os_atomic_lock_release_byte(ptr) \
+ (void) InterlockedExchange(ptr, 0)
+
+#else
+# define os_rmb do { } while(0)
+# define os_wmb do { } while(0)
+# define os_isync do { } while(0)
+# define IB_MEMORY_BARRIER_STARTUP_MSG \
+ "Memory barrier is not used"
+#endif
+
#ifndef UNIV_NONINL
#include "os0sync.ic"
#endif
diff --git a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h
index e755436bbe0..f65d62a39fa 100644
--- a/storage/innobase/include/sync0rw.h
+++ b/storage/innobase/include/sync0rw.h
@@ -70,14 +70,8 @@ extern mutex_t rw_lock_list_mutex;
#ifdef UNIV_SYNC_DEBUG
/* The global mutex which protects debug info lists of all rw-locks.
To modify the debug info list of an rw-lock, this mutex has to be
-
acquired in addition to the mutex protecting the lock. */
-extern mutex_t rw_lock_debug_mutex;
-extern os_event_t rw_lock_debug_event; /*!< If deadlock detection does
- not get immediately the mutex it
- may wait for this event */
-extern ibool rw_lock_debug_waiters; /*!< This is set to TRUE, if
- there may be waiters for the event */
+extern os_fast_mutex_t rw_lock_debug_mutex;
#endif /* UNIV_SYNC_DEBUG */
/** number of spin waits on rw-latches,
diff --git a/storage/innobase/include/sync0rw.ic b/storage/innobase/include/sync0rw.ic
index 28d0611a673..a25aa19d3aa 100644
--- a/storage/innobase/include/sync0rw.ic
+++ b/storage/innobase/include/sync0rw.ic
@@ -200,14 +200,14 @@ rw_lock_lock_word_decr(
ulint amount) /*!< in: amount to decrement */
{
#ifdef INNODB_RW_LOCKS_USE_ATOMICS
- lint local_lock_word = lock->lock_word;
- while (local_lock_word > 0) {
+ lint local_lock_word;
+ os_rmb;
+ while ((local_lock_word= lock->lock_word) > 0) {
if (os_compare_and_swap_lint(&lock->lock_word,
local_lock_word,
local_lock_word - amount)) {
return(TRUE);
}
- local_lock_word = lock->lock_word;
}
return(FALSE);
#else /* INNODB_RW_LOCKS_USE_ATOMICS */
diff --git a/storage/innobase/include/sync0sync.ic b/storage/innobase/include/sync0sync.ic
index 6958faa5c6f..436de8c2741 100644
--- a/storage/innobase/include/sync0sync.ic
+++ b/storage/innobase/include/sync0sync.ic
@@ -92,6 +92,7 @@ mutex_test_and_set(
ut_a(mutex->lock_word == 0);
mutex->lock_word = 1;
+ os_wmb;
}
return((byte)ret);
@@ -108,10 +109,7 @@ mutex_reset_lock_word(
mutex_t* mutex) /*!< in: mutex */
{
#if defined(HAVE_ATOMIC_BUILTINS)
- /* In theory __sync_lock_release should be used to release the lock.
- Unfortunately, it does not work properly alone. The workaround is
- that more conservative __sync_lock_test_and_set is used instead. */
- os_atomic_test_and_set_byte(&mutex->lock_word, 0);
+ os_atomic_lock_release_byte(&mutex->lock_word);
#else
mutex->lock_word = 0;
@@ -147,6 +145,7 @@ mutex_get_waiters(
ptr = &(mutex->waiters);
+ os_rmb;
return(*ptr); /* Here we assume that the read of a single
word from memory is atomic */
}
@@ -181,6 +180,7 @@ mutex_exit_func(
to wake up possible hanging threads if
they are missed in mutex_signal_object. */
+ os_isync;
if (mutex_get_waiters(mutex) != 0) {
mutex_signal_object(mutex);
diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c
index a407ed67a83..c380390d62a 100644
--- a/storage/innobase/row/row0ins.c
+++ b/storage/innobase/row/row0ins.c
@@ -1729,7 +1729,7 @@ row_ins_scan_sec_index_for_duplicate(
do {
const rec_t* rec = btr_pcur_get_rec(&pcur);
const buf_block_t* block = btr_pcur_get_block(&pcur);
- ulint lock_type;
+ const ulint lock_type = LOCK_ORDINARY;
if (page_rec_is_infimum(rec)) {
@@ -1739,16 +1739,6 @@ row_ins_scan_sec_index_for_duplicate(
offsets = rec_get_offsets(rec, index, offsets,
ULINT_UNDEFINED, &heap);
- /* If the transaction isolation level is no stronger than
- READ COMMITTED, then avoid gap locks. */
- if (!page_rec_is_supremum(rec)
- && thr_get_trx(thr)->isolation_level
- <= TRX_ISO_READ_COMMITTED) {
- lock_type = LOCK_REC_NOT_GAP;
- } else {
- lock_type = LOCK_ORDINARY;
- }
-
if (allow_duplicates) {
/* If the SQL-query will update or replace
diff --git a/storage/innobase/srv/srv0srv.c b/storage/innobase/srv/srv0srv.c
index 54e9debec4d..ca3e960b842 100644
--- a/storage/innobase/srv/srv0srv.c
+++ b/storage/innobase/srv/srv0srv.c
@@ -422,7 +422,12 @@ UNIV_INTERN ibool srv_use_checksums = TRUE;
UNIV_INTERN ulong srv_replication_delay = 0;
/*-------------------------------------------*/
+#ifdef HAVE_MEMORY_BARRIER
+/* No idea to wait long with memory barriers */
+UNIV_INTERN ulong srv_n_spin_wait_rounds = 15;
+#else
UNIV_INTERN ulong srv_n_spin_wait_rounds = 30;
+#endif
UNIV_INTERN ulong srv_n_free_tickets_to_enter = 500;
UNIV_INTERN ulong srv_thread_sleep_delay = 10000;
UNIV_INTERN ulong srv_spin_wait_delay = 6;
@@ -2589,9 +2594,10 @@ loop:
/* Try to track a strange bug reported by Harald Fuchs and others,
where the lsn seems to decrease at times */
- new_lsn = log_get_lsn();
+ /* We have to use nowait to ensure we don't block */
+ new_lsn= log_get_lsn_nowait();
- if (new_lsn < old_lsn) {
+ if (new_lsn && new_lsn < old_lsn) {
ut_print_timestamp(stderr);
fprintf(stderr,
" InnoDB: Error: old log sequence number %llu"
@@ -2603,7 +2609,8 @@ loop:
ut_ad(0);
}
- old_lsn = new_lsn;
+ if (new_lsn)
+ old_lsn = new_lsn;
if (difftime(time(NULL), srv_last_monitor_time) > 60) {
/* We referesh InnoDB Monitor values so that averages are
diff --git a/storage/innobase/sync/sync0arr.c b/storage/innobase/sync/sync0arr.c
index ea4d496e6b5..ba1d5cd8e61 100644
--- a/storage/innobase/sync/sync0arr.c
+++ b/storage/innobase/sync/sync0arr.c
@@ -791,6 +791,7 @@ sync_arr_cell_can_wake_up(
lock = cell->wait_object;
+ os_rmb;
if (lock->lock_word > 0) {
/* Either unlocked or only read locked. */
@@ -802,6 +803,7 @@ sync_arr_cell_can_wake_up(
lock = cell->wait_object;
/* lock_word == 0 means all readers have left */
+ os_rmb;
if (lock->lock_word == 0) {
return(TRUE);
@@ -810,6 +812,7 @@ sync_arr_cell_can_wake_up(
lock = cell->wait_object;
/* lock_word > 0 means no writer or reserved writer */
+ os_rmb;
if (lock->lock_word > 0) {
return(TRUE);
diff --git a/storage/innobase/sync/sync0rw.c b/storage/innobase/sync/sync0rw.c
index 8de9b40ef67..50531455a4c 100644
--- a/storage/innobase/sync/sync0rw.c
+++ b/storage/innobase/sync/sync0rw.c
@@ -40,6 +40,7 @@ Created 9/11/1995 Heikki Tuuri
#include "srv0srv.h"
#include "os0sync.h" /* for INNODB_RW_LOCKS_USE_ATOMICS */
#include "ha_prototypes.h"
+#include "my_cpu.h"
/*
IMPLEMENTATION OF THE RW_LOCK
@@ -179,18 +180,12 @@ UNIV_INTERN mysql_pfs_key_t rw_lock_mutex_key;
To modify the debug info list of an rw-lock, this mutex has to be
acquired in addition to the mutex protecting the lock. */
-UNIV_INTERN mutex_t rw_lock_debug_mutex;
+UNIV_INTERN os_fast_mutex_t rw_lock_debug_mutex;
# ifdef UNIV_PFS_MUTEX
UNIV_INTERN mysql_pfs_key_t rw_lock_debug_mutex_key;
# endif
-/* If deadlock detection does not get immediately the mutex,
-it may wait for this event */
-UNIV_INTERN os_event_t rw_lock_debug_event;
-/* This is set to TRUE, if there may be waiters for the event */
-UNIV_INTERN ibool rw_lock_debug_waiters;
-
/******************************************************************//**
Creates a debug info struct. */
static
@@ -390,15 +385,19 @@ rw_lock_s_lock_spin(
lock_loop:
/* Spin waiting for the writer field to become free */
+ os_rmb;
+ HMT_low();
while (i < SYNC_SPIN_ROUNDS && lock->lock_word <= 0) {
if (srv_spin_wait_delay) {
ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));
}
i++;
+ os_rmb;
}
-
- if (i == SYNC_SPIN_ROUNDS) {
+ HMT_medium();
+ if (lock->lock_word <= 0)
+ {
os_thread_yield();
}
@@ -498,16 +497,19 @@ rw_lock_x_lock_wait(
ulint index;
ulint i = 0;
+ os_rmb;
ut_ad(lock->lock_word <= 0);
-
+ HMT_low();
while (lock->lock_word < 0) {
if (srv_spin_wait_delay) {
ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));
}
if(i < SYNC_SPIN_ROUNDS) {
i++;
+ os_rmb;
continue;
}
+ HMT_medium();
/* If there is still a reader, then go to sleep.*/
rw_x_spin_round_count += i;
@@ -544,7 +546,9 @@ rw_lock_x_lock_wait(
sync_array_free_cell(sync_primary_wait_array,
index);
}
+ HMT_low();
}
+ HMT_medium();
rw_x_spin_round_count += i;
}
@@ -582,6 +586,8 @@ rw_lock_x_lock_low(
file_name, line);
} else {
+ if (!pass)
+ os_rmb;
/* Decrement failed: relock or failed lock */
if (!pass && lock->recursive
&& os_thread_eq(lock->writer_thread, curr_thread)) {
@@ -647,6 +653,8 @@ lock_loop:
}
/* Spin waiting for the lock_word to become free */
+ os_rmb;
+ HMT_low();
while (i < SYNC_SPIN_ROUNDS
&& lock->lock_word <= 0) {
if (srv_spin_wait_delay) {
@@ -655,7 +663,9 @@ lock_loop:
}
i++;
+ os_rmb;
}
+ HMT_medium();
if (i == SYNC_SPIN_ROUNDS) {
os_thread_yield();
} else {
@@ -720,22 +730,7 @@ void
rw_lock_debug_mutex_enter(void)
/*===========================*/
{
-loop:
- if (0 == mutex_enter_nowait(&rw_lock_debug_mutex)) {
- return;
- }
-
- os_event_reset(rw_lock_debug_event);
-
- rw_lock_debug_waiters = TRUE;
-
- if (0 == mutex_enter_nowait(&rw_lock_debug_mutex)) {
- return;
- }
-
- os_event_wait(rw_lock_debug_event);
-
- goto loop;
+ os_fast_mutex_lock(&rw_lock_debug_mutex);
}
/******************************************************************//**
@@ -745,12 +740,7 @@ void
rw_lock_debug_mutex_exit(void)
/*==========================*/
{
- mutex_exit(&rw_lock_debug_mutex);
-
- if (rw_lock_debug_waiters) {
- rw_lock_debug_waiters = FALSE;
- os_event_set(rw_lock_debug_event);
- }
+ os_fast_mutex_unlock(&rw_lock_debug_mutex);
}
/******************************************************************//**
diff --git a/storage/innobase/sync/sync0sync.c b/storage/innobase/sync/sync0sync.c
index fba43ad859c..3ae77616faf 100644
--- a/storage/innobase/sync/sync0sync.c
+++ b/storage/innobase/sync/sync0sync.c
@@ -47,6 +47,7 @@ Created 9/5/1995 Heikki Tuuri
# include "srv0start.h" /* srv_is_being_started */
#endif /* UNIV_SYNC_DEBUG */
#include "ha_prototypes.h"
+#include "my_cpu.h"
/*
REASONS FOR IMPLEMENTING THE SPIN LOCK MUTEX
@@ -473,6 +474,8 @@ mutex_set_waiters(
ptr = &(mutex->waiters);
+ os_wmb;
+
*ptr = n; /* Here we assume that the write of a single
word in memory is atomic */
}
@@ -520,13 +523,15 @@ mutex_loop:
spin_loop:
ut_d(mutex->count_spin_loop++);
+ HMT_low();
while (mutex_get_lock_word(mutex) != 0 && i < SYNC_SPIN_ROUNDS) {
if (srv_spin_wait_delay) {
ut_delay(ut_rnd_interval(0, srv_spin_wait_delay));
}
-
+ os_rmb; // Ensure future reads sees new values
i++;
}
+ HMT_medium();
if (i == SYNC_SPIN_ROUNDS) {
#ifdef UNIV_DEBUG
@@ -1530,11 +1535,7 @@ sync_init(void)
SYNC_NO_ORDER_CHECK);
#ifdef UNIV_SYNC_DEBUG
- mutex_create(rw_lock_debug_mutex_key, &rw_lock_debug_mutex,
- SYNC_NO_ORDER_CHECK);
-
- rw_lock_debug_event = os_event_create(NULL);
- rw_lock_debug_waiters = FALSE;
+ os_fast_mutex_init(rw_lock_debug_mutex_key, &rw_lock_debug_mutex);
#endif /* UNIV_SYNC_DEBUG */
}
@@ -1602,6 +1603,7 @@ sync_close(void)
sync_order_checks_on = FALSE;
sync_thread_level_arrays_free();
+ os_fast_mutex_free(&rw_lock_debug_mutex);
#endif /* UNIV_SYNC_DEBUG */
sync_initialized = FALSE;