Commit 65083ba6 authored by Sergey Vojtovich's avatar Sergey Vojtovich

MDEV-17441 - InnoDB transition to C++11 atomics

Simplified mutex code. MutexDebug uses OSMutex instead of
atomic operations now.
parent e2b585c1
......@@ -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 @@ struct OSTrackMutex {
#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 @@ struct TTASFutexMutex {
#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 @@ struct TTASMutex {
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 */
......
......@@ -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:
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;
/** For passing context to SyncDebug */
struct Context : public latch_t {
/** Constructor */
Context()
:
m_mutex(),
m_filename(),
m_line(),
m_thread_id(ULINT_UNDEFINED)
void set(const Mutex *mutex, const char *filename, unsigned line,
os_thread_id_t thread_id)
{
/* No op */
m_debug_mutex.enter();
m_mutex= mutex;
m_filename= filename;
m_line= line;
m_thread_id= thread_id;
m_debug_mutex.exit();
}
/** 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
const MutexDebug get() const
{
m_mutex = mutex;
my_atomic_storelint(&m_thread_id,
ulint(os_thread_get_curr_id()));
m_filename = filename;
m_line = line;
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;
}
/** 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
/**
Called either when mutex is locked or destroyed. Thus members are protected
from concurrent modification.
*/
void assert_clean_context()
{
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";
ut_ad(!m_mutex);
ut_ad(!m_filename);
ut_ad(!m_line);
ut_ad(m_thread_id == os_thread_id_t(ULINT_UNDEFINED));
}
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
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)
{
/* No op */
ut_ad(id != LATCH_ID_NONE);
m_id= id;
m_debug_mutex.init();
set(0, 0, 0, os_thread_id_t(ULINT_UNDEFINED));
}
/* Destructor */
virtual ~MutexDebug() { }
/** Mutex is being destroyed. */
void destroy() UNIV_NOTHROW
void destroy()
{
ut_ad((ulint)my_atomic_loadlint(&m_context.m_thread_id) == ULINT_UNDEFINED);
m_magic_n = 0;
m_context.m_thread_id = 0;
assert_clean_context();
m_debug_mutex.destroy();
}
/** 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
/**
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;
@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
/**
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;
@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] 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
/**
Called when the mutex is released
@param[in] mutex Mutex that was released
*/
void release(const Mutex &mutex)
{
return(os_thread_eq(
(os_thread_id_t)my_atomic_loadlint(&m_context.m_thread_id),
os_thread_get_curr_id()));
ut_ad(is_owned());
set(0, 0, 0, os_thread_id_t(ULINT_UNDEFINED));
sync_check_unlock(this);
}
/** @return the name of the file from the mutex was acquired */
const char* get_enter_filename() const
UNIV_NOTHROW
/** @return true if thread owns the mutex */
bool is_owned() const
{
return(m_context.m_filename);
return os_thread_eq(get_thread_id(), os_thread_get_curr_id());
}
/** @return the name of the file from the mutex was acquired */
unsigned get_enter_line() const
UNIV_NOTHROW
{
return(m_context.m_line);
}
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
UNIV_NOTHROW
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
{
return((os_thread_id_t)my_atomic_loadlint(&m_context.m_thread_id));
}
std::ostringstream msg;
const MutexDebug ctx= get();
/** Magic number to check for memory corruption. */
ulint m_magic_n;
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";
/** Latch state of the mutex owner */
Context m_context;
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 @@ struct GenericPolicy
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 @@ struct GenericPolicy
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 @@ struct GenericPolicy
++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 @@ struct GenericPolicy
return(m_id);
}
/** @return the string representation */
std::string to_string() const;
std::string to_string() const
{ return sync_mutex_to_string(get_id(), sync_file_created_get(this)); }
private:
typedef latch_meta_t::CounterType Counter;
#ifdef UNIV_DEBUG
MutexDebug<Mutex> context;
#endif
private:
/** The user visible counters, registered with the meta-data. */
Counter::Count m_count;
latch_meta_t::CounterType::Count m_count;
/** Latch meta data ID */
latch_id_t m_id;
......@@ -395,29 +290,8 @@ struct GenericPolicy
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 @@ class BlockMutexPolicy
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 @@ class BlockMutexPolicy
UNIV_NOTHROW
{
m_count = NULL;
ut_d(MutexDebug<MutexType>::destroy());
}
/** Called after a successful mutex acquire.
......@@ -469,40 +340,6 @@ class BlockMutexPolicy
++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 @@ class BlockMutexPolicy
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
private:
/** The user visible counters, registered with the meta-data. */
Counter::Count* m_count;
latch_meta_t::CounterType::Count *m_count;
/** Latch meta data ID */
latch_id_t m_id;
};
#include "sync0policy.ic"
#endif /* sync0policy_h */
/*****************************************************************************
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 */
......@@ -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;
......
......@@ -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>
......
......@@ -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);
......
......@@ -219,7 +219,7 @@ struct os_event {
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 */
......
......@@ -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]
......
......@@ -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);
......
......@@ -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 */
......@@ -1458,7 +1458,9 @@ trx_commit_in_memory(
trx_mutex_exit(trx);
ut_a(trx->error_state == DB_SUCCESS);
if (!srv_read_only_mode) {
srv_wake_purge_thread_if_not_active();
}
}
/** Commit a transaction and a mini-transaction.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment