summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Widenius <monty@mariadb.org>2014-08-19 21:35:14 +0300
committerMichael Widenius <monty@mariadb.org>2014-08-19 21:35:14 +0300
commitbd2117d154b9cc367b708932de5d6064a339462d (patch)
tree6c0fac6d84a3f88acb40ca9e410bd7724440af86
parentcfa1ce81bb7992c362958bb95f41325ce2109834 (diff)
parent5569132ffebba3fd2e37964543f658ed24d8caaf (diff)
downloadmariadb-git-bd2117d154b9cc367b708932de5d6064a339462d.tar.gz
Automatic merge from 5.5
Fixed 2 failing tests by replacing result files
-rw-r--r--VERSION1
-rw-r--r--include/my_cpu.h44
-rw-r--r--mysql-test/r/ctype_upgrade.result14
-rw-r--r--mysql-test/r/log_tables_upgrade.result7
-rwxr-xr-x[-rw-r--r--]mysql-test/suite/rpl/extension/checksum.pl0
-rw-r--r--sql/CMakeLists.txt21
-rw-r--r--storage/innobase/CMakeLists.txt39
-rw-r--r--storage/innobase/include/log0log.h7
-rw-r--r--storage/innobase/include/log0log.ic20
-rw-r--r--storage/innobase/include/os0sync.h48
-rw-r--r--storage/innobase/include/sync0rw.ic6
-rw-r--r--storage/innobase/include/sync0sync.ic3
-rw-r--r--storage/innobase/srv/srv0srv.cc13
-rw-r--r--storage/innobase/sync/sync0arr.cc3
-rw-r--r--storage/innobase/sync/sync0rw.cc20
-rw-r--r--storage/innobase/sync/sync0sync.cc7
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_released.test4
-rw-r--r--storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks_released.test4
-rw-r--r--storage/xtradb/CMakeLists.txt39
-rw-r--r--storage/xtradb/include/log0log.h7
-rw-r--r--storage/xtradb/include/log0log.ic20
-rw-r--r--storage/xtradb/include/os0sync.h48
-rw-r--r--storage/xtradb/include/sync0rw.ic6
-rw-r--r--storage/xtradb/include/sync0sync.ic3
-rw-r--r--storage/xtradb/srv/srv0srv.cc13
-rw-r--r--storage/xtradb/sync/sync0arr.cc3
-rw-r--r--storage/xtradb/sync/sync0rw.cc20
-rw-r--r--storage/xtradb/sync/sync0sync.cc7
28 files changed, 384 insertions, 43 deletions
diff --git a/VERSION b/VERSION
index d0e11a358c5..8b9f91dd819 100644
--- a/VERSION
+++ b/VERSION
@@ -1,4 +1,3 @@
MYSQL_VERSION_MAJOR=10
MYSQL_VERSION_MINOR=0
MYSQL_VERSION_PATCH=14
-MYSQL_VERSION_EXTRA=
diff --git a/include/my_cpu.h b/include/my_cpu.h
new file mode 100644
index 00000000000..026b92c1b74
--- /dev/null
+++ b/include/my_cpu.h
@@ -0,0 +1,44 @@
+/* Copyright (c) 2013, MariaDB foundation Ab and SkySQL
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; version 2 of the License.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1307 USA
+*/
+
+/* instructions for specific cpu's */
+
+/*
+ Macros for adjusting thread priority (hardware multi-threading)
+ The defines are the same ones used by the linux kernel
+*/
+
+#if defined(__powerpc__)
+/* Very low priority */
+#define HMT_very_low() asm volatile("or 31,31,31")
+/* Low priority */
+#define HMT_low() asm volatile("or 1,1,1")
+/* Medium low priority */
+#define HMT_medium_low() asm volatile("or 6,6,6")
+/* Medium priority */
+#define HMT_medium() asm volatile("or 2,2,2")
+/* Medium high priority */
+#define HMT_medium_high() asm volatile("or 5,5,5")
+/* High priority */
+#define HMT_high() asm volatile("or 3,3,3")
+#else
+#define HMT_very_low()
+#define HMT_low()
+#define HMT_medium_low()
+#define HMT_medium()
+#define HMT_medium_high()
+#define HMT_high()
+#endif
diff --git a/mysql-test/r/ctype_upgrade.result b/mysql-test/r/ctype_upgrade.result
index 3d23280c2e8..825ad8dac21 100644
--- a/mysql-test/r/ctype_upgrade.result
+++ b/mysql-test/r/ctype_upgrade.result
@@ -227,7 +227,7 @@ DROP TABLE mysql050614_xxx_croatian_ci;
# Checking mysql_upgrade
#
# Running mysql_upgrade
-Phase 1/3: Running 'mysql_fix_privilege_tables'...
+Phase 1/4: Checking mysql database
Processing databases
mysql
mysql.column_stats OK
@@ -258,8 +258,9 @@ mysql.time_zone_name OK
mysql.time_zone_transition OK
mysql.time_zone_transition_type OK
mysql.user OK
-Phase 2/3: Fixing table and database names
-Phase 3/3: Checking and upgrading tables
+Phase 2/4: Running 'mysql_fix_privilege_tables'...
+Phase 3/4: Fixing table and database names
+Phase 4/4: Checking and upgrading tables
Processing databases
information_schema
mtr
@@ -281,7 +282,7 @@ test.maria100004_xxx_croatian_ci OK
OK
# Running mysql_upgrade for the second time
# This should report OK for all tables
-Phase 1/3: Running 'mysql_fix_privilege_tables'...
+Phase 1/4: Checking mysql database
Processing databases
mysql
mysql.column_stats OK
@@ -312,8 +313,9 @@ mysql.time_zone_name OK
mysql.time_zone_transition OK
mysql.time_zone_transition_type OK
mysql.user OK
-Phase 2/3: Fixing table and database names
-Phase 3/3: Checking and upgrading tables
+Phase 2/4: Running 'mysql_fix_privilege_tables'...
+Phase 3/4: Fixing table and database names
+Phase 4/4: Checking and upgrading tables
Processing databases
information_schema
mtr
diff --git a/mysql-test/r/log_tables_upgrade.result b/mysql-test/r/log_tables_upgrade.result
index d25fc018cdf..9900f6d6b5a 100644
--- a/mysql-test/r/log_tables_upgrade.result
+++ b/mysql-test/r/log_tables_upgrade.result
@@ -11,7 +11,7 @@ Table Op Msg_type Msg_text
test.bug49823 repair status OK
RENAME TABLE general_log TO renamed_general_log;
RENAME TABLE test.bug49823 TO general_log;
-Phase 1/3: Running 'mysql_fix_privilege_tables'...
+Phase 1/4: Checking mysql database
Processing databases
mysql
mysql.column_stats OK
@@ -43,8 +43,9 @@ mysql.time_zone_name OK
mysql.time_zone_transition OK
mysql.time_zone_transition_type OK
mysql.user OK
-Phase 2/3: Fixing table and database names
-Phase 3/3: Checking and upgrading tables
+Phase 2/4: Running 'mysql_fix_privilege_tables'...
+Phase 3/4: Fixing table and database names
+Phase 4/4: Checking and upgrading tables
Processing databases
information_schema
mtr
diff --git a/mysql-test/suite/rpl/extension/checksum.pl b/mysql-test/suite/rpl/extension/checksum.pl
index 60dca18c8f8..60dca18c8f8 100644..100755
--- a/mysql-test/suite/rpl/extension/checksum.pl
+++ b/mysql-test/suite/rpl/extension/checksum.pl
diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt
index d07b2106f07..c59ae3b7846 100644
--- a/sql/CMakeLists.txt
+++ b/sql/CMakeLists.txt
@@ -32,13 +32,6 @@ SET_SOURCE_FILES_PROPERTIES(${GEN_SOURCES} PROPERTIES GENERATED 1)
ADD_DEFINITIONS(-DMYSQL_SERVER -DHAVE_EVENT_SCHEDULER)
-IF (CMAKE_SYSTEM_NAME MATCHES "Linux" OR
- CMAKE_SYSTEM_NAME MATCHES "Windows" OR
- CMAKE_SYSTEM_NAME MATCHES "SunOS" OR
- HAVE_KQUEUE)
- ADD_DEFINITIONS(-DHAVE_POOL_OF_THREADS)
-ENDIF()
-
IF(SSL_DEFINES)
ADD_DEFINITIONS(${SSL_DEFINES})
ENDIF()
@@ -105,10 +98,16 @@ SET (SQL_SOURCE
${MYSYS_LIBWRAP_SOURCE}
)
-IF(WIN32)
- SET(SQL_SOURCE ${SQL_SOURCE} threadpool_win.cc)
-ELSE()
- SET(SQL_SOURCE ${SQL_SOURCE} threadpool_unix.cc)
+IF (CMAKE_SYSTEM_NAME MATCHES "Linux" OR
+ CMAKE_SYSTEM_NAME MATCHES "Windows" OR
+ CMAKE_SYSTEM_NAME MATCHES "SunOS" OR
+ HAVE_KQUEUE)
+ ADD_DEFINITIONS(-DHAVE_POOL_OF_THREADS)
+ IF(WIN32)
+ SET(SQL_SOURCE ${SQL_SOURCE} threadpool_win.cc)
+ ELSE()
+ SET(SQL_SOURCE ${SQL_SOURCE} threadpool_unix.cc)
+ ENDIF()
ENDIF()
MYSQL_ADD_PLUGIN(partition ha_partition.cc STORAGE_ENGINE DEFAULT STATIC_ONLY
diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt
index 50fdb36495d..e227d953133 100644
--- a/storage/innobase/CMakeLists.txt
+++ b/storage/innobase/CMakeLists.txt
@@ -123,6 +123,25 @@ IF(NOT CMAKE_CROSSCOMPILING)
}"
HAVE_IB_GCC_ATOMIC_BUILTINS_64
)
+ 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)
@@ -133,6 +152,14 @@ IF(HAVE_IB_GCC_ATOMIC_BUILTINS_64)
ADD_DEFINITIONS(-DHAVE_IB_GCC_ATOMIC_BUILTINS_64=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(
@@ -214,10 +241,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()
@@ -235,6 +273,7 @@ ENDIF()
IF(MSVC)
ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS)
+ ADD_DEFINITIONS(-DHAVE_WINDOWS_MM_FENCE)
ENDIF()
diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h
index 61318e34561..0182d9b00b6 100644
--- a/storage/innobase/include/log0log.h
+++ b/storage/innobase/include/log0log.h
@@ -147,6 +147,13 @@ lsn_t
log_get_lsn(void);
/*=============*/
/************************************************************//**
+Gets the current lsn.
+@return current lsn */
+UNIV_INLINE
+lsn_t
+log_get_lsn_nowait(void);
+/*=============*/
+/************************************************************//**
Gets the last lsn that is fully flushed to disk.
@return last flushed lsn */
UNIV_INLINE
diff --git a/storage/innobase/include/log0log.ic b/storage/innobase/include/log0log.ic
index 67792395ac9..7c79eb96ca9 100644
--- a/storage/innobase/include/log0log.ic
+++ b/storage/innobase/include/log0log.ic
@@ -434,6 +434,26 @@ log_get_flush_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 6d3dd850e08..f62278a1259 100644
--- a/storage/innobase/include/os0sync.h
+++ b/storage/innobase/include/os0sync.h
@@ -694,6 +694,54 @@ for synchronization */
os_decrement_counter_by_amount(mutex, counter, 1);\
} while (0);
+/** 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 <mmintrin.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"
+
+#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.ic b/storage/innobase/include/sync0rw.ic
index 467a8b4eb44..7ea910b4719 100644
--- a/storage/innobase/include/sync0rw.ic
+++ b/storage/innobase/include/sync0rw.ic
@@ -199,14 +199,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 73b22396967..9c7f3d2cd4b 100644
--- a/storage/innobase/include/sync0sync.ic
+++ b/storage/innobase/include/sync0sync.ic
@@ -92,6 +92,7 @@ ib_mutex_test_and_set(
ut_a(mutex->lock_word == 0);
mutex->lock_word = 1;
+ os_wmb;
}
return((byte) ret);
@@ -144,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 */
}
@@ -178,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/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index d9ace828348..bc0e8e625e3 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -356,7 +356,12 @@ UNIV_INTERN ibool srv_use_posix_fallocate = 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_spin_wait_delay = 6;
UNIV_INTERN ibool srv_priority_boost = TRUE;
@@ -1709,9 +1714,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 " LSN_PF
@@ -1723,7 +1729,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.cc b/storage/innobase/sync/sync0arr.cc
index 986010039f9..6fad5f7d9ba 100644
--- a/storage/innobase/sync/sync0arr.cc
+++ b/storage/innobase/sync/sync0arr.cc
@@ -758,6 +758,7 @@ sync_arr_cell_can_wake_up(
lock = static_cast<rw_lock_t*>(cell->wait_object);
+ os_rmb;
if (lock->lock_word > 0) {
/* Either unlocked or only read locked. */
@@ -769,6 +770,7 @@ sync_arr_cell_can_wake_up(
lock = static_cast<rw_lock_t*>(cell->wait_object);
/* lock_word == 0 means all readers have left */
+ os_rmb;
if (lock->lock_word == 0) {
return(TRUE);
@@ -777,6 +779,7 @@ sync_arr_cell_can_wake_up(
lock = static_cast<rw_lock_t*>(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.cc b/storage/innobase/sync/sync0rw.cc
index e129d39fc9d..49d2a2e21ea 100644
--- a/storage/innobase/sync/sync0rw.cc
+++ b/storage/innobase/sync/sync0rw.cc
@@ -41,6 +41,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
@@ -375,15 +376,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();
}
@@ -472,14 +477,18 @@ rw_lock_x_lock_wait(
ut_ad(lock->lock_word <= 0);
+ os_rmb;
+ 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_lock_stats.rw_x_spin_round_count.add(counter_index, i);
@@ -516,7 +525,9 @@ rw_lock_x_lock_wait(
} else {
sync_array_free_cell(sync_arr, index);
}
+ HMT_low();
}
+ HMT_medium();
rw_lock_stats.rw_x_spin_round_count.add(counter_index, i);
}
@@ -553,7 +564,8 @@ 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
&& os_thread_eq(lock->writer_thread, thread_id)) {
@@ -632,6 +644,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) {
@@ -640,7 +654,9 @@ lock_loop:
}
i++;
+ os_rmb;
}
+ HMT_medium();
if (i == SYNC_SPIN_ROUNDS) {
os_thread_yield();
} else {
diff --git a/storage/innobase/sync/sync0sync.cc b/storage/innobase/sync/sync0sync.cc
index 54018471abc..cc852b99497 100644
--- a/storage/innobase/sync/sync0sync.cc
+++ b/storage/innobase/sync/sync0sync.cc
@@ -45,6 +45,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
@@ -456,6 +457,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 */
}
@@ -500,13 +503,15 @@ mutex_loop:
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) {
os_thread_yield();
diff --git a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_released.test b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_released.test
index 3b56660ff83..003e98a4c3e 100644
--- a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_released.test
+++ b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_lock_waits_released.test
@@ -1,7 +1,7 @@
# verify that information_schema.tokudb_locks gets populated with locks, information_schema.tokudb_lock_waits gets
-if (`select @@tokudb_version <= "7.1.6"`)
+if (`select @@tokudb_version <= "7.1.7"`)
{
- --skip Race condition in the test in TokuDB 7.1.6 or earlier
+ --skip Race condition in the test in TokuDB 7.1.7 or earlier
}
# populated with 1 lock_wait and all transactions are present in information_schema.tokudb_trx for 2 clients
diff --git a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks_released.test b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks_released.test
index f2ca9b8ed9c..1bd2c6614ac 100644
--- a/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks_released.test
+++ b/storage/tokudb/mysql-test/tokudb/t/i_s_tokudb_locks_released.test
@@ -1,6 +1,6 @@
-if (`select @@tokudb_version <= "7.1.6"`)
+if (`select @@tokudb_version <= "7.1.7"`)
{
- --skip Race condition in the test in TokuDB 7.1.6 or earlier
+ --skip Race condition in the test in TokuDB 7.1.7 or earlier
}
# verify that information_schema.tokudb_locks gets populated with locks for 2 clients
diff --git a/storage/xtradb/CMakeLists.txt b/storage/xtradb/CMakeLists.txt
index b3751b269c3..161c1519983 100644
--- a/storage/xtradb/CMakeLists.txt
+++ b/storage/xtradb/CMakeLists.txt
@@ -129,6 +129,25 @@ IF(NOT CMAKE_CROSSCOMPILING)
}"
HAVE_IB_GCC_ATOMIC_BUILTINS_64
)
+ 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)
@@ -140,6 +159,14 @@ IF(HAVE_IB_GCC_ATOMIC_BUILTINS_64)
ADD_DEFINITIONS(-DHAVE_IB_GCC_ATOMIC_BUILTINS_64=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(
@@ -222,10 +249,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()
@@ -243,6 +281,7 @@ ENDIF()
IF(MSVC)
ADD_DEFINITIONS(-DHAVE_WINDOWS_ATOMICS)
+ ADD_DEFINITIONS(-DHAVE_WINDOWS_MM_FENCE)
SET(XTRADB_OK 1)
# Avoid "unreferenced label" warning in generated file
diff --git a/storage/xtradb/include/log0log.h b/storage/xtradb/include/log0log.h
index b9e0c2ef516..641d5b5e663 100644
--- a/storage/xtradb/include/log0log.h
+++ b/storage/xtradb/include/log0log.h
@@ -168,6 +168,13 @@ lsn_t
log_get_lsn(void);
/*=============*/
/************************************************************//**
+Gets the current lsn.
+@return current lsn */
+UNIV_INLINE
+lsn_t
+log_get_lsn_nowait(void);
+/*=============*/
+/************************************************************//**
Gets the last lsn that is fully flushed to disk.
@return last flushed lsn */
UNIV_INLINE
diff --git a/storage/xtradb/include/log0log.ic b/storage/xtradb/include/log0log.ic
index 7724d94b51a..7f2ea04ac07 100644
--- a/storage/xtradb/include/log0log.ic
+++ b/storage/xtradb/include/log0log.ic
@@ -486,6 +486,26 @@ log_get_flush_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/xtradb/include/os0sync.h b/storage/xtradb/include/os0sync.h
index ba22c02a5a9..ed805db7393 100644
--- a/storage/xtradb/include/os0sync.h
+++ b/storage/xtradb/include/os0sync.h
@@ -694,6 +694,54 @@ for synchronization */
os_decrement_counter_by_amount(mutex, counter, 1);\
} while (0);
+/** 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 <mmintrin.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"
+
+#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/xtradb/include/sync0rw.ic b/storage/xtradb/include/sync0rw.ic
index d1675f0a9c9..4051cb72e7c 100644
--- a/storage/xtradb/include/sync0rw.ic
+++ b/storage/xtradb/include/sync0rw.ic
@@ -256,14 +256,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/xtradb/include/sync0sync.ic b/storage/xtradb/include/sync0sync.ic
index d6922da7852..19dee950cca 100644
--- a/storage/xtradb/include/sync0sync.ic
+++ b/storage/xtradb/include/sync0sync.ic
@@ -95,6 +95,7 @@ ib_mutex_test_and_set(
ut_a(mutex->lock_word == 0);
mutex->lock_word = 1;
+ os_wmb;
}
return((byte) ret);
@@ -147,6 +148,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 +183,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/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc
index 90cdfe0e0b5..03788d753d0 100644
--- a/storage/xtradb/srv/srv0srv.cc
+++ b/storage/xtradb/srv/srv0srv.cc
@@ -477,7 +477,12 @@ UNIV_INTERN ulong srv_log_checksum_algorithm =
SRV_CHECKSUM_ALGORITHM_INNODB;
/*-------------------------------------------*/
+#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_spin_wait_delay = 6;
UNIV_INTERN ibool srv_priority_boost = TRUE;
@@ -2094,9 +2099,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 " LSN_PF
@@ -2108,7 +2114,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/xtradb/sync/sync0arr.cc b/storage/xtradb/sync/sync0arr.cc
index 95ecf496e82..6e30ccf07df 100644
--- a/storage/xtradb/sync/sync0arr.cc
+++ b/storage/xtradb/sync/sync0arr.cc
@@ -849,6 +849,7 @@ sync_arr_cell_can_wake_up(
lock = static_cast<rw_lock_t*>(cell->wait_object);
+ os_rmb;
if (lock->lock_word > 0) {
/* Either unlocked or only read locked. */
@@ -860,6 +861,7 @@ sync_arr_cell_can_wake_up(
lock = static_cast<rw_lock_t*>(cell->wait_object);
/* lock_word == 0 means all readers have left */
+ os_rmb;
if (lock->lock_word == 0) {
return(TRUE);
@@ -869,6 +871,7 @@ sync_arr_cell_can_wake_up(
lock = static_cast<rw_lock_t*>(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/xtradb/sync/sync0rw.cc b/storage/xtradb/sync/sync0rw.cc
index 79741e3cdce..d5a069b96d3 100644
--- a/storage/xtradb/sync/sync0rw.cc
+++ b/storage/xtradb/sync/sync0rw.cc
@@ -41,6 +41,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
@@ -448,6 +449,8 @@ lock_loop:
lock)) {
/* 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,
@@ -455,9 +458,11 @@ lock_loop:
}
i++;
+ os_rmb;
}
- if (i == SYNC_SPIN_ROUNDS) {
+ HMT_medium();
+ if (lock->lock_word <= 0) {
os_thread_yield();
}
@@ -605,14 +610,18 @@ rw_lock_x_lock_wait(
ut_ad(lock->lock_word <= 0);
+ os_rmb;
+ 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_lock_stats.rw_x_spin_round_count.add(counter_index, i);
@@ -660,7 +669,9 @@ rw_lock_x_lock_wait(
prio_rw_lock->high_priority_wait_ex_waiter = 0;
}
}
+ HMT_low();
}
+ HMT_medium();
rw_lock_stats.rw_x_spin_round_count.add(counter_index, i);
}
@@ -701,7 +712,8 @@ 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
&& os_thread_eq(lock->writer_thread, thread_id)) {
@@ -792,6 +804,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) {
@@ -800,7 +814,9 @@ lock_loop:
}
i++;
+ os_rmb;
}
+ HMT_medium();
if (i == SYNC_SPIN_ROUNDS) {
os_thread_yield();
} else {
diff --git a/storage/xtradb/sync/sync0sync.cc b/storage/xtradb/sync/sync0sync.cc
index e078f223efc..661cdb4395e 100644
--- a/storage/xtradb/sync/sync0sync.cc
+++ b/storage/xtradb/sync/sync0sync.cc
@@ -46,6 +46,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
@@ -535,6 +536,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 */
}
@@ -587,13 +590,15 @@ mutex_loop:
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) {
os_thread_yield();