diff options
author | Sergey Vojtovich <svoj@mariadb.org> | 2019-01-08 01:30:13 +0400 |
---|---|---|
committer | Sergey Vojtovich <svoj@mariadb.org> | 2019-01-09 12:31:01 +0400 |
commit | 8e653eed14f427926b91a957ef27f56faabe88f4 (patch) | |
tree | f173dd013cd419ccbf8625b9fe2b4dd18b7836df /storage | |
parent | 30da40bb8c303159747b1cf1d74411b049b6d252 (diff) | |
download | mariadb-git-8e653eed14f427926b91a957ef27f56faabe88f4.tar.gz |
MDEV-17441 - InnoDB transition to C++11 atomicsbb-10.4-MDEV-17441
Simplified mutex code. MutexDebug uses OSMutex instead of
atomic operations now.
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/include/ib0mutex.h | 23 | ||||
-rw-r--r-- | storage/innobase/include/sync0policy.h | 522 | ||||
-rw-r--r-- | storage/innobase/include/sync0policy.ic | 101 | ||||
-rw-r--r-- | storage/innobase/include/sync0rw.h | 1 | ||||
-rw-r--r-- | storage/innobase/include/sync0types.h | 30 | ||||
-rw-r--r-- | storage/innobase/include/ut0mutex.h | 2 | ||||
-rw-r--r-- | storage/innobase/os/os0event.cc | 2 | ||||
-rw-r--r-- | storage/innobase/srv/srv0srv.cc | 11 | ||||
-rw-r--r-- | storage/innobase/sync/sync0arr.cc | 24 | ||||
-rw-r--r-- | storage/innobase/sync/sync0rw.cc | 24 | ||||
-rw-r--r-- | storage/innobase/trx/trx0trx.cc | 4 |
11 files changed, 222 insertions, 522 deletions
diff --git a/storage/innobase/include/ib0mutex.h b/storage/innobase/include/ib0mutex.h index e6b903a4ba4..f4ba8a81275 100644 --- a/storage/innobase/include/ib0mutex.h +++ b/storage/innobase/include/ib0mutex.h @@ -35,7 +35,7 @@ Created 2013-03-26 Sunny Bains. #include "sync0arr.h" /** OS mutex for tracking lock/unlock for debugging */ -template <template <typename> class Policy = NoPolicy> +template <template <typename> class Policy> struct OSTrackMutex { typedef Policy<OSTrackMutex> MutexPolicy; @@ -152,7 +152,7 @@ private: #include <sys/syscall.h> /** Mutex implementation that used the Linux futex. */ -template <template <typename> class Policy = NoPolicy> +template <template <typename> class Policy> struct TTASFutexMutex { typedef Policy<TTASFutexMutex> MutexPolicy; @@ -264,7 +264,7 @@ private: #endif /* HAVE_IB_LINUX_FUTEX */ -template <template <typename> class Policy = NoPolicy> +template <template <typename> class Policy> struct TTASMutex { typedef Policy<TTASMutex> MutexPolicy; @@ -364,7 +364,7 @@ private: std::atomic<uint32_t> m_lock_word; }; -template <template <typename> class Policy = NoPolicy> +template <template <typename> class Policy> struct TTASEventMutex { typedef Policy<TTASEventMutex> MutexPolicy; @@ -534,7 +534,6 @@ with the Performance Schema instrumentation. */ template <typename MutexImpl> struct PolicyMutex { - typedef MutexImpl MutexType; typedef typename MutexImpl::MutexPolicy Policy; PolicyMutex() UNIV_NOTHROW : m_impl() @@ -565,7 +564,7 @@ struct PolicyMutex pfs_exit(); #endif /* UNIV_PFS_MUTEX */ - policy().release(m_impl); + ut_d(policy().context.release(m_impl)); m_impl.exit(); } @@ -591,11 +590,11 @@ struct PolicyMutex locker = pfs_begin_lock(&state, name, line); #endif /* UNIV_PFS_MUTEX */ - policy().enter(m_impl, name, line); + ut_d(policy().context.enter(m_impl, name, line)); m_impl.enter(n_spins, n_delay, name, line); - policy().locked(m_impl, name, line); + ut_d(policy().context.locked(m_impl, name, line)); #ifdef UNIV_PFS_MUTEX pfs_end(locker, 0); #endif /* UNIV_PFS_MUTEX */ @@ -624,9 +623,9 @@ struct PolicyMutex if (ret == 0) { - policy().enter(m_impl, name, line); + ut_d(policy().context.enter(m_impl, name, line)); - policy().locked(m_impl, name, line); + ut_d(policy().context.locked(m_impl, name, line)); } #ifdef UNIV_PFS_MUTEX @@ -640,7 +639,7 @@ struct PolicyMutex /** @return true if the thread owns the mutex. */ bool is_owned() const UNIV_NOTHROW { - return(policy().is_owned()); + return(policy().context.is_owned()); } #endif /* UNIV_DEBUG */ @@ -662,6 +661,7 @@ struct PolicyMutex m_impl.init(id, filename, line); policy().init(m_impl, id, filename, line); + ut_d(policy().context.init(id)); } /** Free resources (if any) */ @@ -672,6 +672,7 @@ struct PolicyMutex #endif /* UNIV_PFS_MUTEX */ m_impl.destroy(); policy().destroy(); + ut_d(policy().context.destroy()); } /** Required for os_event_t */ diff --git a/storage/innobase/include/sync0policy.h b/storage/innobase/include/sync0policy.h index 93a56e24040..090f83f46e2 100644 --- a/storage/innobase/include/sync0policy.h +++ b/storage/innobase/include/sync0policy.h @@ -30,247 +30,176 @@ Created 2012-08-21 Sunny Bains. #include "ut0rnd.h" #include "os0thread.h" #include "srv0mon.h" +#include "sync0debug.h" #ifdef UNIV_DEBUG -# define MUTEX_MAGIC_N 979585UL - -template <typename Mutex> -class MutexDebug { -public: - - /** For passing context to SyncDebug */ - struct Context : public latch_t { - - /** Constructor */ - Context() - : - m_mutex(), - m_filename(), - m_line(), - m_thread_id(ULINT_UNDEFINED) - { - /* No op */ - } - - /** Create the context for SyncDebug - @param[in] id ID of the latch to track */ - Context(latch_id_t id) - : - latch_t(id) - { - ut_ad(id != LATCH_ID_NONE); - } - - /** Set to locked state - @param[in] mutex The mutex to acquire - @param[in] filename File name from where to acquire - @param[in] line Line number in filename */ - void locked( - const Mutex* mutex, - const char* filename, - unsigned line) - UNIV_NOTHROW - { - m_mutex = mutex; - - my_atomic_storelint(&m_thread_id, - ulint(os_thread_get_curr_id())); - - m_filename = filename; - - m_line = line; - } - - /** Reset to unlock state */ - void release() - UNIV_NOTHROW - { - m_mutex = NULL; - - my_atomic_storelint(&m_thread_id, ULINT_UNDEFINED); - - m_filename = NULL; - - m_line = 0; - } - - /** Print information about the latch - @return the string representation */ - virtual std::string to_string() const - UNIV_NOTHROW - { - std::ostringstream msg; - - msg << m_mutex->policy().to_string(); - - if (m_thread_id != ULINT_UNDEFINED) { - - msg << " addr: " << m_mutex - << " acquired: " << locked_from().c_str(); - - } else { - msg << "Not locked"; - } - - return(msg.str()); - } - - /** @return the name of the file and line number in the file - from where the mutex was acquired "filename:line" */ - virtual std::string locked_from() const - { - std::ostringstream msg; - - msg << sync_basename(m_filename) << ":" << m_line; - - return(std::string(msg.str())); - } - - /** Mutex to check for lock order violation */ - const Mutex* m_mutex; - - /** Filename from where enter was called */ - const char* m_filename; - - /** Line mumber in filename */ - unsigned m_line; - - /** Thread ID of the thread that own(ed) the mutex */ - ulint m_thread_id; - }; - - /** Constructor. */ - MutexDebug() - : - m_magic_n(), - m_context() - UNIV_NOTHROW - { - /* No op */ - } - - /* Destructor */ - virtual ~MutexDebug() { } - - /** Mutex is being destroyed. */ - void destroy() UNIV_NOTHROW - { - ut_ad((ulint)my_atomic_loadlint(&m_context.m_thread_id) == ULINT_UNDEFINED); - - m_magic_n = 0; - - m_context.m_thread_id = 0; - } - - /** Called when the mutex is "created". Note: Not from the constructor - but when the mutex is initialised. - @param[in] id Mutex ID */ - void init(latch_id_t id) UNIV_NOTHROW; - - /** Called when an attempt is made to lock the mutex - @param[in] mutex Mutex instance to be locked - @param[in] filename Filename from where it was called - @param[in] line Line number from where it was called */ - void enter( - const Mutex* mutex, - const char* filename, - unsigned line) - UNIV_NOTHROW; - - /** Called when the mutex is locked - @param[in] mutex Mutex instance that was locked - @param[in] filename Filename from where it was called - @param[in] line Line number from where it was called */ - void locked( - const Mutex* mutex, - const char* filename, - unsigned line) - UNIV_NOTHROW; - - /** Called when the mutex is released - @param[in] mutx Mutex that was released */ - void release(const Mutex* mutex) - UNIV_NOTHROW; - - /** @return true if thread owns the mutex */ - bool is_owned() const UNIV_NOTHROW - { - return(os_thread_eq( - (os_thread_id_t)my_atomic_loadlint(&m_context.m_thread_id), - os_thread_get_curr_id())); - } - - /** @return the name of the file from the mutex was acquired */ - const char* get_enter_filename() const - UNIV_NOTHROW - { - return(m_context.m_filename); - } - - /** @return the name of the file from the mutex was acquired */ - unsigned get_enter_line() const - UNIV_NOTHROW - { - return(m_context.m_line); - } - - /** @return id of the thread that was trying to acquire the mutex */ - os_thread_id_t get_thread_id() const - UNIV_NOTHROW - { - return((os_thread_id_t)my_atomic_loadlint(&m_context.m_thread_id)); - } +template <typename Mutex> class MutexDebug: public latch_t +{ + /** Mutex to check for lock order violation */ + const Mutex *m_mutex; + /** Filename from where enter was called */ + const char *m_filename; + /** Line mumber in filename */ + unsigned m_line; + /** Thread ID of the thread that owns the mutex */ + os_thread_id_t m_thread_id; + /** Mutex protecting the above members */ + mutable OSMutex m_debug_mutex; + + + void set(const Mutex *mutex, const char *filename, unsigned line, + os_thread_id_t thread_id) + { + m_debug_mutex.enter(); + m_mutex= mutex; + m_filename= filename; + m_line= line; + m_thread_id= thread_id; + m_debug_mutex.exit(); + } + + + const MutexDebug get() const + { + MutexDebug ret; + m_debug_mutex.enter(); + ret.m_mutex= m_mutex; + ret.m_filename= m_filename; + ret.m_line= m_line; + ret.m_thread_id= m_thread_id; + m_debug_mutex.exit(); + return ret; + } + + + /** + Called either when mutex is locked or destroyed. Thus members are protected + from concurrent modification. + */ + void assert_clean_context() + { + ut_ad(!m_mutex); + ut_ad(!m_filename); + ut_ad(!m_line); + ut_ad(m_thread_id == os_thread_id_t(ULINT_UNDEFINED)); + } - /** Magic number to check for memory corruption. */ - ulint m_magic_n; - /** Latch state of the mutex owner */ - Context m_context; +public: + /** + Called when the mutex is "created". Note: Not from the constructor + but when the mutex is initialised. + @param[in] id Mutex ID + */ + void init(latch_id_t id) + { + ut_ad(id != LATCH_ID_NONE); + m_id= id; + m_debug_mutex.init(); + set(0, 0, 0, os_thread_id_t(ULINT_UNDEFINED)); + } + + + /** Mutex is being destroyed. */ + void destroy() + { + assert_clean_context(); + m_debug_mutex.destroy(); + } + + + /** + Called when an attempt is made to lock the mutex + @param[in] mutex Mutex instance to be locked + @param[in] filename Filename from where it was called + @param[in] line Line number from where it was called + */ + void enter(const Mutex &mutex, const char *filename, unsigned line) + { + MutexDebug context; + ut_ad(!is_owned()); + context.init(m_id); + context.set(&mutex, filename, line, os_thread_get_curr_id()); + /* Check for latch order violation. */ + sync_check_lock_validate(&context); + context.set(0, 0, 0, os_thread_id_t(ULINT_UNDEFINED)); + context.destroy(); + } + + + /** + Called when the mutex is locked + @param[in] mutex Mutex instance that was locked + @param[in] filename Filename from where it was called + @param[in] line Line number from where it was called + */ + void locked(const Mutex &mutex, const char *filename, unsigned line) + { + assert_clean_context(); + set(&mutex, filename, line, os_thread_get_curr_id()); + sync_check_lock_granted(this); + } + + + /** + Called when the mutex is released + @param[in] mutex Mutex that was released + */ + void release(const Mutex &mutex) + { + ut_ad(is_owned()); + set(0, 0, 0, os_thread_id_t(ULINT_UNDEFINED)); + sync_check_unlock(this); + } + + + /** @return true if thread owns the mutex */ + bool is_owned() const + { + return os_thread_eq(get_thread_id(), os_thread_get_curr_id()); + } + + + /** @return the name of the file from the mutex was acquired */ + const char* get_enter_filename() const { return get().m_filename; } + + + /** @return the name of the file from the mutex was acquired */ + unsigned get_enter_line() const { return get().m_line; } + + + /** @return id of the thread that was trying to acquire the mutex */ + os_thread_id_t get_thread_id() const { return get().m_thread_id; } + + + /** + Print information about the latch + @return the string representation + */ + virtual std::string to_string() const + { + std::ostringstream msg; + const MutexDebug ctx= get(); + + msg << m_mutex->policy().to_string(); + if (ctx.m_mutex) + msg << " addr: " << ctx.m_mutex << " acquired: " + << sync_basename(ctx.get_enter_filename()) << ":" + << ctx.get_enter_line(); + else + msg << "Not locked"; + + return(msg.str()); + } }; #endif /* UNIV_DEBUG */ -/* Do nothing */ -template <typename Mutex> -struct NoPolicy { - /** Default constructor. */ - NoPolicy() { } - - void init(const Mutex&, latch_id_t, const char*, uint32_t) - UNIV_NOTHROW { } - void destroy() UNIV_NOTHROW { } - void enter(const Mutex&, const char*, unsigned) UNIV_NOTHROW { } - void add(uint32_t, uint32_t) UNIV_NOTHROW { } - void locked(const Mutex&, const char*, ulint) UNIV_NOTHROW { } - void release(const Mutex&) UNIV_NOTHROW { } - std::string to_string() const { return(""); }; - latch_id_t get_id() const; -}; - /** Collect the metrics per mutex instance, no aggregation. */ template <typename Mutex> struct GenericPolicy -#ifdef UNIV_DEBUG -: public MutexDebug<Mutex> -#endif /* UNIV_DEBUG */ { public: - typedef Mutex MutexType; - - /** Constructor. */ - GenericPolicy() - UNIV_NOTHROW - : -#ifdef UNIV_DEBUG - MutexDebug<MutexType>(), -#endif /* UNIV_DEBUG */ - m_count(), - m_id() - { } - - /** Destructor */ - ~GenericPolicy() { } - /** Called when the mutex is "created". Note: Not from the constructor but when the mutex is initialised. @param[in] id Mutex ID @@ -292,8 +221,6 @@ public: meta.get_counter()->single_register(&m_count); sync_file_created_register(this, filename, uint16_t(line)); - - ut_d(MutexDebug<MutexType>::init(m_id)); } /** Called when the mutex is destroyed. */ @@ -305,8 +232,6 @@ public: meta.get_counter()->single_deregister(&m_count); sync_file_created_deregister(this); - - ut_d(MutexDebug<MutexType>::destroy()); } /** Called after a successful mutex acquire. @@ -332,40 +257,6 @@ public: ++m_count.m_calls; } - /** Called when an attempt is made to lock the mutex - @param[in] mutex Mutex instance to be locked - @param[in] filename Filename from where it was called - @param[in] line Line number from where it was called */ - void enter( - const MutexType& mutex, - const char* filename, - unsigned line) - UNIV_NOTHROW - { - ut_d(MutexDebug<MutexType>::enter(&mutex, filename, line)); - } - - /** Called when the mutex is locked - @param[in] mutex Mutex instance that is locked - @param[in] filename Filename from where it was called - @param[in] line Line number from where it was called */ - void locked( - const MutexType& mutex, - const char* filename, - unsigned line) - UNIV_NOTHROW - { - ut_d(MutexDebug<MutexType>::locked(&mutex, filename, line)); - } - - /** Called when the mutex is released - @param[in] mutex Mutex instance that is released */ - void release(const MutexType& mutex) - UNIV_NOTHROW - { - ut_d(MutexDebug<MutexType>::release(&mutex)); - } - /** Print the information about the latch @return the string representation */ std::string print() const @@ -378,14 +269,18 @@ public: return(m_id); } - /** @return the string representation */ - std::string to_string() const; -private: - typedef latch_meta_t::CounterType Counter; + /** @return the string representation */ + std::string to_string() const + { return sync_mutex_to_string(get_id(), sync_file_created_get(this)); } - /** The user visible counters, registered with the meta-data. */ - Counter::Count m_count; +#ifdef UNIV_DEBUG + MutexDebug<Mutex> context; +#endif + +private: + /** The user visible counters, registered with the meta-data. */ + latch_meta_t::CounterType::Count m_count; /** Latch meta data ID */ latch_id_t m_id; @@ -395,29 +290,8 @@ private: too many of them to count individually. */ template <typename Mutex> class BlockMutexPolicy -#ifdef UNIV_DEBUG -: public MutexDebug<Mutex> -#endif /* UNIV_DEBUG */ { public: - typedef Mutex MutexType; - typedef typename latch_meta_t::CounterType::Count Count; - - /** Default constructor. */ - BlockMutexPolicy() - : -#ifdef UNIV_DEBUG - MutexDebug<MutexType>(), -#endif /* UNIV_DEBUG */ - m_count(), - m_id() - { - /* Do nothing */ - } - - /** Destructor */ - ~BlockMutexPolicy() { } - /** Called when the mutex is "created". Note: Not from the constructor but when the mutex is initialised. @param[in] id Mutex ID */ @@ -436,8 +310,6 @@ public: ut_ad(meta.get_id() == id); m_count = meta.get_counter()->sum_register(); - - ut_d(MutexDebug<MutexType>::init(m_id)); } /** Called when the mutex is destroyed. */ @@ -445,7 +317,6 @@ public: UNIV_NOTHROW { m_count = NULL; - ut_d(MutexDebug<MutexType>::destroy()); } /** Called after a successful mutex acquire. @@ -469,40 +340,6 @@ public: ++m_count->m_calls; } - /** Called when the mutex is locked - @param[in] mutex Mutex instance that is locked - @param[in] filename Filename from where it was called - @param[in] line Line number from where it was called */ - void locked( - const MutexType& mutex, - const char* filename, - unsigned line) - UNIV_NOTHROW - { - ut_d(MutexDebug<MutexType>::locked(&mutex, filename, line)); - } - - /** Called when the mutex is released - @param[in] mutex Mutex instance that is released */ - void release(const MutexType& mutex) - UNIV_NOTHROW - { - ut_d(MutexDebug<MutexType>::release(&mutex)); - } - - /** Called when an attempt is made to lock the mutex - @param[in] mutex Mutex instance to be locked - @param[in] filename Filename from where it was called - @param[in] line Line number from where it was called */ - void enter( - const MutexType& mutex, - const char* filename, - unsigned line) - UNIV_NOTHROW - { - ut_d(MutexDebug<MutexType>::enter(&mutex, filename, line)); - } - /** Print the information about the latch @return the string representation */ std::string print() const @@ -514,19 +351,26 @@ public: return(m_id); } - /** @return the string representation */ - std::string to_string() const; -private: - typedef latch_meta_t::CounterType Counter; + /** + I don't think it makes sense to keep track of the file name + and line number for each block mutex. Too much of overhead. Use the + latch id to figure out the location from the source. + + @return the string representation + */ + std::string to_string() const + { return(sync_mutex_to_string(get_id(), "buf0buf.cc:0")); } + +#ifdef UNIV_DEBUG + MutexDebug<Mutex> context; +#endif - /** The user visible counters, registered with the meta-data. */ - Counter::Count* m_count; +private: + /** The user visible counters, registered with the meta-data. */ + latch_meta_t::CounterType::Count *m_count; /** Latch meta data ID */ latch_id_t m_id; }; - -#include "sync0policy.ic" - #endif /* sync0policy_h */ diff --git a/storage/innobase/include/sync0policy.ic b/storage/innobase/include/sync0policy.ic deleted file mode 100644 index a28e3c382b4..00000000000 --- a/storage/innobase/include/sync0policy.ic +++ /dev/null @@ -1,101 +0,0 @@ -/***************************************************************************** - -Copyright (c) 2013, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. - -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 Street, Suite 500, Boston, MA 02110-1335 USA - -*****************************************************************************/ - -/******************************************************************//** -@file include/sync0policy.ic -Policy for mutexes. - -Created 2012-08-21 Sunny Bains. -***********************************************************************/ - -#include "sync0debug.h" - -template <typename Mutex> -std::string GenericPolicy<Mutex>::to_string() const -{ - return(sync_mutex_to_string(get_id(), sync_file_created_get(this))); -} - -template <typename Mutex> -std::string BlockMutexPolicy<Mutex>::to_string() const -{ - /* I don't think it makes sense to keep track of the file name - and line number for each block mutex. Too much of overhead. Use the - latch id to figure out the location from the source. */ - return(sync_mutex_to_string(get_id(), "buf0buf.cc:0")); -} - -#ifdef UNIV_DEBUG - -template <typename Mutex> -void MutexDebug<Mutex>::init(latch_id_t id) - UNIV_NOTHROW -{ - m_context.m_id = id; - - m_context.release(); - - m_magic_n = MUTEX_MAGIC_N; -} - -template <typename Mutex> -void MutexDebug<Mutex>::enter( - const Mutex* mutex, - const char* name, - unsigned line) - UNIV_NOTHROW -{ - ut_ad(!is_owned()); - - Context context(m_context.get_id()); - - context.locked(mutex, name, line); - - /* Check for latch order violation. */ - - sync_check_lock_validate(&context); -} - -template <typename Mutex> -void MutexDebug<Mutex>::locked( - const Mutex* mutex, - const char* name, - unsigned line) - UNIV_NOTHROW -{ - ut_ad(!is_owned()); - ut_ad(m_context.m_thread_id == ULINT_UNDEFINED); - - m_context.locked(mutex, name, line); - - sync_check_lock_granted(&m_context); -} - -template <typename Mutex> -void MutexDebug<Mutex>::release(const Mutex*) - UNIV_NOTHROW -{ - ut_ad(is_owned()); - - m_context.release(); - - sync_check_unlock(&m_context); -} - -#endif /* UNIV_DEBUG */ diff --git a/storage/innobase/include/sync0rw.h b/storage/innobase/include/sync0rw.h index 664a0ddd868..4f23e81185c 100644 --- a/storage/innobase/include/sync0rw.h +++ b/storage/innobase/include/sync0rw.h @@ -642,7 +642,6 @@ struct rw_lock_t } virtual std::string to_string() const; - virtual std::string locked_from() const; /** For checking memory corruption. */ ulint magic_n; diff --git a/storage/innobase/include/sync0types.h b/storage/innobase/include/sync0types.h index e7d1326d6a5..5fa7691e771 100644 --- a/storage/innobase/include/sync0types.h +++ b/storage/innobase/include/sync0types.h @@ -999,9 +999,6 @@ struct latch_t { @return the string representation */ virtual std::string to_string() const = 0; - /** @return "filename:line" from where the latch was last locked */ - virtual std::string locked_from() const = 0; - /** @return the latch level */ latch_level_t get_level() const UNIV_NOTHROW @@ -1117,33 +1114,6 @@ enum rw_lock_flag_t { #endif /* UNIV_INNOCHECKSUM */ -static inline ulint my_atomic_loadlint(const ulint *A) -{ -#ifdef _WIN64 - return ulint(my_atomic_load64((volatile int64*)A)); -#else - return ulint(my_atomic_loadlong(A)); -#endif -} - -static inline lint my_atomic_loadlint(const lint *A) -{ -#ifdef _WIN64 - return lint(my_atomic_load64((volatile int64*)A)); -#else - return my_atomic_loadlong(A); -#endif -} - -static inline void my_atomic_storelint(ulint *A, ulint B) -{ -#ifdef _WIN64 - my_atomic_store64((volatile int64*)A, B); -#else - my_atomic_storelong(A, B); -#endif -} - /** Simple non-atomic counter aligned to CACHE_LINE_SIZE @tparam Type the integer type of the counter */ template <typename Type> diff --git a/storage/innobase/include/ut0mutex.h b/storage/innobase/include/ut0mutex.h index 3dbd7919a2f..3155151c73a 100644 --- a/storage/innobase/include/ut0mutex.h +++ b/storage/innobase/include/ut0mutex.h @@ -38,8 +38,6 @@ Created 2012-03-24 Sunny Bains. @param[in] T The resulting typedef alias */ #define UT_MUTEX_TYPE(M, P, T) typedef PolicyMutex<M<P> > T; -typedef OSMutex EventMutex; - # ifdef HAVE_IB_LINUX_FUTEX UT_MUTEX_TYPE(TTASFutexMutex, GenericPolicy, FutexMutex); UT_MUTEX_TYPE(TTASFutexMutex, BlockMutexPolicy, BlockFutexMutex); diff --git a/storage/innobase/os/os0event.cc b/storage/innobase/os/os0event.cc index 7588020c8db..c350c7b81dd 100644 --- a/storage/innobase/os/os0event.cc +++ b/storage/innobase/os/os0event.cc @@ -219,7 +219,7 @@ private: int64_t signal_count; /*!< this is incremented each time the event becomes signaled */ - mutable EventMutex mutex; /*!< this mutex protects + mutable OSMutex mutex; /*!< this mutex protects the next fields */ diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index bf347562c71..890bd969670 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -497,10 +497,6 @@ UNIV_INTERN ulong srv_buf_dump_status_frequency; mutex_enter(&srv_sys.mutex); \ } while (0) -/** Test if the system mutex is owned. */ -#define srv_sys_mutex_own() (mutex_own(&srv_sys.mutex) \ - && !srv_read_only_mode) - /** Release the system mutex. */ #define srv_sys_mutex_exit() do { \ mutex_exit(&srv_sys.mutex); \ @@ -829,7 +825,7 @@ srv_suspend_thread_low( srv_slot_t* slot) /*!< in/out: thread slot */ { ut_ad(!srv_read_only_mode); - ut_ad(srv_sys_mutex_own()); + ut_ad(mutex_own(&srv_sys.mutex)); ut_ad(slot->in_use); @@ -1907,7 +1903,7 @@ void srv_active_wake_master_thread_low() { ut_ad(!srv_read_only_mode); - ut_ad(!srv_sys_mutex_own()); + ut_ad(!mutex_own(&srv_sys.mutex)); srv_inc_activity_count(); @@ -1933,7 +1929,8 @@ srv_active_wake_master_thread_low() void srv_wake_purge_thread_if_not_active() { - ut_ad(!srv_sys_mutex_own()); + ut_ad(!srv_read_only_mode); + ut_ad(!mutex_own(&srv_sys.mutex)); if (purge_sys.enabled() && !purge_sys.paused() && !srv_sys.n_threads_active[SRV_PURGE] diff --git a/storage/innobase/sync/sync0arr.cc b/storage/innobase/sync/sync0arr.cc index 9fead862fa1..9221a643213 100644 --- a/storage/innobase/sync/sync0arr.cc +++ b/storage/innobase/sync/sync0arr.cc @@ -76,8 +76,8 @@ keep the global wait array for the sake of diagnostics and also to avoid infinite wait The error_monitor thread scans the global wait array to signal any waiting threads who have missed the signal. */ -typedef SyncArrayMutex::MutexType WaitMutex; -typedef BlockSyncArrayMutex::MutexType BlockWaitMutex; +typedef TTASEventMutex<GenericPolicy> WaitMutex; +typedef TTASEventMutex<BlockMutexPolicy> BlockWaitMutex; /** The latch types that use the sync array. */ union sync_object_t { @@ -499,7 +499,7 @@ sync_array_cell_print( WaitMutex* mutex = cell->latch.mutex; const WaitMutex::MutexPolicy& policy = mutex->policy(); #ifdef UNIV_DEBUG - const char* name = policy.get_enter_filename(); + const char* name = policy.context.get_enter_filename(); if (name == NULL) { /* The mutex might have been released. */ name = "NULL"; @@ -518,7 +518,7 @@ sync_array_cell_print( mutex->state() #ifdef UNIV_DEBUG ,name, - policy.get_enter_line() + policy.context.get_enter_line() #endif /* UNIV_DEBUG */ ); } @@ -528,7 +528,7 @@ sync_array_cell_print( const BlockWaitMutex::MutexPolicy& policy = mutex->policy(); #ifdef UNIV_DEBUG - const char* name = policy.get_enter_filename(); + const char* name = policy.context.get_enter_filename(); if (name == NULL) { /* The mutex might have been released. */ name = "NULL"; @@ -546,7 +546,7 @@ sync_array_cell_print( (ulong) mutex->state() #ifdef UNIV_DEBUG ,name, - (ulong) policy.get_enter_line() + (ulong) policy.context.get_enter_line() #endif /* UNIV_DEBUG */ ); } else if (type == RW_LOCK_X @@ -738,7 +738,7 @@ sync_array_detect_deadlock( const WaitMutex::MutexPolicy& policy = mutex->policy(); if (mutex->state() != MUTEX_STATE_UNLOCKED) { - thread = policy.get_thread_id(); + thread = policy.context.get_thread_id(); /* Note that mutex->thread_id above may be also OS_THREAD_ID_UNDEFINED, because the @@ -753,7 +753,7 @@ sync_array_detect_deadlock( if (ret) { const char* name; - name = policy.get_enter_filename(); + name = policy.context.get_enter_filename(); if (name == NULL) { /* The mutex might have been @@ -765,7 +765,7 @@ sync_array_detect_deadlock( << "Mutex " << mutex << " owned by" " thread " << os_thread_pf(thread) << " file " << name << " line " - << policy.get_enter_line(); + << policy.context.get_enter_line(); sync_array_cell_print(stderr, cell); @@ -785,7 +785,7 @@ sync_array_detect_deadlock( mutex->policy(); if (mutex->state() != MUTEX_STATE_UNLOCKED) { - thread = policy.get_thread_id(); + thread = policy.context.get_thread_id(); /* Note that mutex->thread_id above may be also OS_THREAD_ID_UNDEFINED, because the @@ -800,7 +800,7 @@ sync_array_detect_deadlock( if (ret) { const char* name; - name = policy.get_enter_filename(); + name = policy.context.get_enter_filename(); if (name == NULL) { /* The mutex might have been @@ -812,7 +812,7 @@ sync_array_detect_deadlock( << "Mutex " << mutex << " owned by" " thread " << os_thread_pf(thread) << " file " << name << " line " - << policy.get_enter_line(); + << policy.context.get_enter_line(); return(true); diff --git a/storage/innobase/sync/sync0rw.cc b/storage/innobase/sync/sync0rw.cc index 89f84aada04..0f78136c71c 100644 --- a/storage/innobase/sync/sync0rw.cc +++ b/storage/innobase/sync/sync0rw.cc @@ -1156,10 +1156,10 @@ rw_lock_debug_print( fprintf(f, "\n"); } -/** Print where it was locked from +/** Print the rw-lock information. @return the string representation */ std::string -rw_lock_t::locked_from() const +rw_lock_t::to_string() const { /* Note: For X locks it can be locked form multiple places because the same thread can call X lock recursively. */ @@ -1169,6 +1169,11 @@ rw_lock_t::locked_from() const ut_ad(rw_lock_validate(this)); + msg << "RW-LATCH: " + << "thread id " << os_thread_pf(os_thread_get_curr_id()) + << " addr: " << this + << " Locked from: "; + rw_lock_debug_mutex_enter(); for (rw_lock_debug_t* info = UT_LIST_GET_FIRST(debug_list); @@ -1191,19 +1196,4 @@ rw_lock_t::locked_from() const return(msg.str()); } - -/** Print the rw-lock information. -@return the string representation */ -std::string -rw_lock_t::to_string() const -{ - std::ostringstream msg; - - msg << "RW-LATCH: " - << "thread id " << os_thread_pf(os_thread_get_curr_id()) - << " addr: " << this - << " Locked from: " << locked_from().c_str(); - - return(msg.str()); -} #endif /* UNIV_DEBUG */ diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc index a0ceb44b8d1..aaf21004568 100644 --- a/storage/innobase/trx/trx0trx.cc +++ b/storage/innobase/trx/trx0trx.cc @@ -1458,7 +1458,9 @@ trx_commit_in_memory( trx_mutex_exit(trx); ut_a(trx->error_state == DB_SUCCESS); - srv_wake_purge_thread_if_not_active(); + if (!srv_read_only_mode) { + srv_wake_purge_thread_if_not_active(); + } } /** Commit a transaction and a mini-transaction. |