Commit 813123e3 authored by Max Kellermann's avatar Max Kellermann Committed by Marko Mäkelä

MDEV-34973: innobase/lock0lock: add `noexcept`

MariaDB is compiled with C++ exceptions enabled, and that disallows
some optimizations (e.g. the stack must always be unwinding-safe).  By
adding `noexcept` to functions that are guaranteed to never throw,
some of these optimizations can be regained.  Low-level locking
functions that are called often are a good candidate for this.

This shrinks the executable a bit (tested with GCC 14 on aarch64):

    text	  data	   bss	   dec	   hex	filename
 24448910	2436488	9473185	36358583	22ac9b7	build/release/sql/mariadbd
 24448622	2436488	9473537	36358647	22ac9f7	build/release/sql/mariadbd
parent d28ac3f8
......@@ -788,28 +788,28 @@ class lock_sys_t
ATTRIBUTE_NOINLINE void rd_unlock();
#else
/** Acquire exclusive lock_sys.latch */
void wr_lock()
void wr_lock() noexcept
{
mysql_mutex_assert_not_owner(&wait_mutex);
latch.wr_lock();
}
/** Release exclusive lock_sys.latch */
void wr_unlock() { latch.wr_unlock(); }
void wr_unlock() noexcept { latch.wr_unlock(); }
/** Acquire shared lock_sys.latch */
void rd_lock()
void rd_lock() noexcept
{
mysql_mutex_assert_not_owner(&wait_mutex);
latch.rd_lock();
}
/** Release shared lock_sys.latch */
void rd_unlock() { latch.rd_unlock(); }
void rd_unlock() noexcept { latch.rd_unlock(); }
#endif
/** Try to acquire exclusive lock_sys.latch
@return whether the latch was acquired */
bool wr_lock_try() { return latch.wr_lock_try(); }
bool wr_lock_try() noexcept { return latch.wr_lock_try(); }
/** Try to acquire shared lock_sys.latch
@return whether the latch was acquired */
bool rd_lock_try() { return latch.rd_lock_try(); }
bool rd_lock_try() noexcept { return latch.rd_lock_try(); }
/** Assert that wr_lock() has been invoked by this thread */
void assert_locked() const { ut_ad(latch.have_wr()); }
......
......@@ -44,10 +44,10 @@ class pthread_mutex_wrapper final
/** whether the mutex is usable; set by init(); cleared by destroy() */
bool initialized{false};
public:
~pthread_mutex_wrapper() { ut_ad(!initialized); }
~pthread_mutex_wrapper() noexcept { ut_ad(!initialized); }
#endif
public:
void init()
void init() noexcept
{
ut_ad(!initialized);
ut_d(initialized= true);
......@@ -56,31 +56,31 @@ class pthread_mutex_wrapper final
else
pthread_mutex_init(&lock, nullptr);
}
void destroy()
void destroy() noexcept
{
ut_ad(initialized); ut_d(initialized=false);
pthread_mutex_destroy(&lock);
}
# ifdef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
void wr_lock() { ut_ad(initialized); pthread_mutex_lock(&lock); }
void wr_lock() noexcept { ut_ad(initialized); pthread_mutex_lock(&lock); }
# else
private:
void wr_wait();
void wr_wait() noexcept;
public:
inline void wr_lock();
inline void wr_lock() noexcept;
# endif
void wr_unlock() { ut_ad(initialized); pthread_mutex_unlock(&lock); }
bool wr_lock_try()
void wr_unlock() noexcept { ut_ad(initialized); pthread_mutex_unlock(&lock); }
bool wr_lock_try() noexcept
{ ut_ad(initialized); return !pthread_mutex_trylock(&lock); }
};
# ifndef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
template<> void pthread_mutex_wrapper<true>::wr_wait();
template<> void pthread_mutex_wrapper<true>::wr_wait() noexcept;
template<>
inline void pthread_mutex_wrapper<false>::wr_lock()
inline void pthread_mutex_wrapper<false>::wr_lock() noexcept
{ ut_ad(initialized); pthread_mutex_lock(&lock); }
template<>
inline void pthread_mutex_wrapper<true>::wr_lock()
inline void pthread_mutex_wrapper<true>::wr_lock() noexcept
{ if (!wr_lock_try()) wr_wait(); }
# endif
#endif
......@@ -110,22 +110,22 @@ class srw_mutex_impl final
#endif
/** Wait until the mutex has been acquired */
void wait_and_lock();
void wait_and_lock() noexcept;
/** Wait for lock!=lk */
inline void wait(uint32_t lk);
inline void wait(uint32_t lk) noexcept;
/** Wake up one wait() thread */
void wake();
void wake() noexcept;
/** Wake up all wait() threads */
inline void wake_all();
inline void wake_all() noexcept;
public:
/** @return whether the mutex is being held or waited for */
bool is_locked_or_waiting() const
bool is_locked_or_waiting() const noexcept
{ return lock.load(std::memory_order_acquire) != 0; }
/** @return whether the mutex is being held by any thread */
bool is_locked() const
bool is_locked() const noexcept
{ return (lock.load(std::memory_order_acquire) & HOLDER) != 0; }
void init()
void init() noexcept
{
DBUG_ASSERT(!is_locked_or_waiting());
#ifdef SUX_LOCK_GENERIC
......@@ -133,7 +133,7 @@ class srw_mutex_impl final
pthread_cond_init(&cond, nullptr);
#endif
}
void destroy()
void destroy() noexcept
{
DBUG_ASSERT(!is_locked_or_waiting());
#ifdef SUX_LOCK_GENERIC
......@@ -143,7 +143,7 @@ class srw_mutex_impl final
}
/** @return whether the mutex was acquired */
bool wr_lock_try()
bool wr_lock_try() noexcept
{
uint32_t lk= 0;
return lock.compare_exchange_strong(lk, HOLDER + WAITER,
......@@ -151,8 +151,8 @@ class srw_mutex_impl final
std::memory_order_relaxed);
}
void wr_lock() { if (!wr_lock_try()) wait_and_lock(); }
void wr_unlock()
void wr_lock() noexcept { if (!wr_lock_try()) wait_and_lock(); }
void wr_unlock() noexcept
{
const uint32_t lk=
lock.fetch_sub(HOLDER + WAITER, std::memory_order_release);
......@@ -198,16 +198,16 @@ class ssux_lock_impl
static constexpr uint32_t WRITER= 1U << 31;
/** Wait for readers!=lk */
inline void wait(uint32_t lk);
inline void wait(uint32_t lk) noexcept;
/** Wait for readers!=lk|WRITER */
void wr_wait(uint32_t lk);
void wr_wait(uint32_t lk) noexcept;
/** Wake up wait() on the last rd_unlock() */
void wake();
void wake() noexcept;
/** Acquire a read lock */
void rd_wait();
void rd_wait() noexcept;
public:
void init()
void init() noexcept
{
writer.init();
DBUG_ASSERT(is_vacant());
......@@ -215,7 +215,7 @@ class ssux_lock_impl
pthread_cond_init(&readers_cond, nullptr);
#endif
}
void destroy()
void destroy() noexcept
{
DBUG_ASSERT(is_vacant());
writer.destroy();
......@@ -224,17 +224,17 @@ class ssux_lock_impl
#endif
}
/** @return whether any writer is waiting */
bool is_waiting() const
bool is_waiting() const noexcept
{ return (readers.load(std::memory_order_relaxed) & WRITER) != 0; }
#ifndef DBUG_OFF
/** @return whether the lock is being held or waited for */
bool is_vacant() const { return !is_locked_or_waiting(); }
bool is_vacant() const noexcept { return !is_locked_or_waiting(); }
#endif /* !DBUG_OFF */
private:
/** Try to acquire a shared latch.
@return the lock word value if the latch was not acquired
@retval 0 if the latch was acquired */
uint32_t rd_lock_try_low()
uint32_t rd_lock_try_low() noexcept
{
uint32_t lk= 0;
while (!readers.compare_exchange_weak(lk, lk + 1,
......@@ -246,11 +246,11 @@ class ssux_lock_impl
}
public:
bool rd_lock_try() { return rd_lock_try_low() == 0; }
bool rd_lock_try() noexcept { return rd_lock_try_low() == 0; }
bool u_lock_try() { return writer.wr_lock_try(); }
bool u_lock_try() noexcept { return writer.wr_lock_try(); }
bool wr_lock_try()
bool wr_lock_try() noexcept
{
if (!writer.wr_lock_try())
return false;
......@@ -263,12 +263,12 @@ class ssux_lock_impl
return false;
}
void rd_lock() { if (!rd_lock_try()) rd_wait(); }
void u_lock()
void rd_lock() noexcept { if (!rd_lock_try()) rd_wait(); }
void u_lock() noexcept
{
writer.wr_lock();
}
void wr_lock()
void wr_lock() noexcept
{
writer.wr_lock();
#if defined __i386__||defined __x86_64__||defined _M_IX86||defined _M_X64
......@@ -289,23 +289,23 @@ class ssux_lock_impl
#endif
}
bool rd_u_upgrade_try() { return writer.wr_lock_try(); }
bool rd_u_upgrade_try() noexcept { return writer.wr_lock_try(); }
void u_wr_upgrade()
void u_wr_upgrade() noexcept
{
DBUG_ASSERT(writer.is_locked());
uint32_t lk= readers.fetch_add(WRITER, std::memory_order_acquire);
if (lk)
wr_wait(lk);
}
void wr_u_downgrade()
void wr_u_downgrade() noexcept
{
DBUG_ASSERT(writer.is_locked());
DBUG_ASSERT(is_write_locked());
readers.store(0, std::memory_order_release);
/* Note: Any pending rd_lock() will not be woken up until u_unlock() */
}
void u_rd_downgrade()
void u_rd_downgrade() noexcept
{
DBUG_ASSERT(writer.is_locked());
ut_d(uint32_t lk=) readers.fetch_add(1, std::memory_order_relaxed);
......@@ -313,18 +313,18 @@ class ssux_lock_impl
u_unlock();
}
void rd_unlock()
void rd_unlock() noexcept
{
uint32_t lk= readers.fetch_sub(1, std::memory_order_release);
ut_ad(~WRITER & lk);
if (lk == WRITER + 1)
wake();
}
void u_unlock()
void u_unlock() noexcept
{
writer.wr_unlock();
}
void wr_unlock()
void wr_unlock() noexcept
{
DBUG_ASSERT(is_write_locked());
readers.store(0, std::memory_order_release);
......@@ -340,10 +340,10 @@ class ssux_lock_impl
bool is_locked_or_waiting() const noexcept
{ return is_locked() || writer.is_locked_or_waiting(); }
void lock_shared() { rd_lock(); }
void unlock_shared() { rd_unlock(); }
void lock() { wr_lock(); }
void unlock() { wr_unlock(); }
void lock_shared() noexcept { rd_lock(); }
void unlock_shared() noexcept { rd_unlock(); }
void lock() noexcept { wr_lock(); }
void unlock() noexcept { wr_unlock(); }
};
#if defined _WIN32 || defined SUX_LOCK_GENERIC
......@@ -360,20 +360,20 @@ class srw_lock_
rw_lock_t lk;
# endif
void rd_wait();
void wr_wait();
void rd_wait() noexcept;
void wr_wait() noexcept;
public:
void init() { IF_WIN(,my_rwlock_init(&lk, nullptr)); }
void destroy() { IF_WIN(,rwlock_destroy(&lk)); }
inline void rd_lock();
inline void wr_lock();
bool rd_lock_try()
void init() noexcept { IF_WIN(,my_rwlock_init(&lk, nullptr)); }
void destroy() noexcept { IF_WIN(,rwlock_destroy(&lk)); }
inline void rd_lock() noexcept;
inline void wr_lock() noexcept;
bool rd_lock_try() noexcept
{ return IF_WIN(TryAcquireSRWLockShared(&lk), !rw_tryrdlock(&lk)); }
void rd_unlock()
void rd_unlock() noexcept
{ IF_WIN(ReleaseSRWLockShared(&lk), rw_unlock(&lk)); }
bool wr_lock_try()
bool wr_lock_try() noexcept
{ return IF_WIN(TryAcquireSRWLockExclusive(&lk), !rw_trywrlock(&lk)); }
void wr_unlock()
void wr_unlock() noexcept
{ IF_WIN(ReleaseSRWLockExclusive(&lk), rw_unlock(&lk)); }
#ifdef _WIN32
/** @return whether any lock may be held by any thread */
......@@ -387,27 +387,27 @@ class srw_lock_
return is_locked();
}
void lock_shared() { rd_lock(); }
void unlock_shared() { rd_unlock(); }
void lock() { wr_lock(); }
void unlock() { wr_unlock(); }
void lock_shared() noexcept { rd_lock(); }
void unlock_shared() noexcept { rd_unlock(); }
void lock() noexcept { wr_lock(); }
void unlock() noexcept { wr_unlock(); }
#endif
};
template<> void srw_lock_<true>::rd_wait();
template<> void srw_lock_<true>::wr_wait();
template<> void srw_lock_<true>::rd_wait() noexcept;
template<> void srw_lock_<true>::wr_wait() noexcept;
template<>
inline void srw_lock_<false>::rd_lock()
inline void srw_lock_<false>::rd_lock() noexcept
{ IF_WIN(AcquireSRWLockShared(&lk), rw_rdlock(&lk)); }
template<>
inline void srw_lock_<false>::wr_lock()
inline void srw_lock_<false>::wr_lock() noexcept
{ IF_WIN(AcquireSRWLockExclusive(&lk), rw_wrlock(&lk)); }
template<>
inline void srw_lock_<true>::rd_lock() { if (!rd_lock_try()) rd_wait(); }
inline void srw_lock_<true>::rd_lock() noexcept { if (!rd_lock_try()) rd_wait(); }
template<>
inline void srw_lock_<true>::wr_lock() { if (!wr_lock_try()) wr_wait(); }
inline void srw_lock_<true>::wr_lock() noexcept { if (!wr_lock_try()) wr_wait(); }
typedef srw_lock_<false> srw_lock_low;
typedef srw_lock_<true> srw_spin_lock_low;
......@@ -433,17 +433,17 @@ class ssux_lock
PSI_rwlock *pfs_psi;
ssux_lock_impl<true> lock;
ATTRIBUTE_NOINLINE void psi_rd_lock(const char *file, unsigned line);
ATTRIBUTE_NOINLINE void psi_wr_lock(const char *file, unsigned line);
ATTRIBUTE_NOINLINE void psi_u_lock(const char *file, unsigned line);
ATTRIBUTE_NOINLINE void psi_u_wr_upgrade(const char *file, unsigned line);
ATTRIBUTE_NOINLINE void psi_rd_lock(const char *file, unsigned line) noexcept;
ATTRIBUTE_NOINLINE void psi_wr_lock(const char *file, unsigned line) noexcept;
ATTRIBUTE_NOINLINE void psi_u_lock(const char *file, unsigned line) noexcept;
ATTRIBUTE_NOINLINE void psi_u_wr_upgrade(const char *file, unsigned line) noexcept;
public:
void init(mysql_pfs_key_t key)
void init(mysql_pfs_key_t key) noexcept
{
pfs_psi= PSI_RWLOCK_CALL(init_rwlock)(key, this);
lock.init();
}
void destroy()
void destroy() noexcept
{
if (psi_likely(pfs_psi != nullptr))
{
......@@ -452,56 +452,56 @@ class ssux_lock
}
lock.destroy();
}
void rd_lock(const char *file, unsigned line)
void rd_lock(const char *file, unsigned line) noexcept
{
if (psi_likely(pfs_psi != nullptr))
psi_rd_lock(file, line);
else
lock.rd_lock();
}
void rd_unlock()
void rd_unlock() noexcept
{
if (psi_likely(pfs_psi != nullptr))
PSI_RWLOCK_CALL(unlock_rwlock)(pfs_psi);
lock.rd_unlock();
}
void u_lock(const char *file, unsigned line)
void u_lock(const char *file, unsigned line) noexcept
{
if (psi_likely(pfs_psi != nullptr))
psi_u_lock(file, line);
else
lock.u_lock();
}
void u_unlock()
void u_unlock() noexcept
{
if (psi_likely(pfs_psi != nullptr))
PSI_RWLOCK_CALL(unlock_rwlock)(pfs_psi);
lock.u_unlock();
}
void wr_lock(const char *file, unsigned line)
void wr_lock(const char *file, unsigned line) noexcept
{
if (psi_likely(pfs_psi != nullptr))
psi_wr_lock(file, line);
else
lock.wr_lock();
}
void wr_unlock()
void wr_unlock() noexcept
{
if (psi_likely(pfs_psi != nullptr))
PSI_RWLOCK_CALL(unlock_rwlock)(pfs_psi);
lock.wr_unlock();
}
void u_wr_upgrade(const char *file, unsigned line)
void u_wr_upgrade(const char *file, unsigned line) noexcept
{
if (psi_likely(pfs_psi != nullptr))
psi_u_wr_upgrade(file, line);
else
lock.u_wr_upgrade();
}
bool rd_lock_try() { return lock.rd_lock_try(); }
bool u_lock_try() { return lock.u_lock_try(); }
bool wr_lock_try() { return lock.wr_lock_try(); }
bool is_waiting() const { return lock.is_waiting(); }
bool rd_lock_try() noexcept { return lock.rd_lock_try(); }
bool u_lock_try() noexcept { return lock.u_lock_try(); }
bool wr_lock_try() noexcept { return lock.wr_lock_try(); }
bool is_waiting() const noexcept { return lock.is_waiting(); }
};
/** Slim reader-writer lock with PERFORMANCE_SCHEMA instrumentation */
......@@ -515,15 +515,15 @@ class srw_lock_impl
ssux_lock_impl<spinloop> lock;
# endif
ATTRIBUTE_NOINLINE void psi_rd_lock(const char *file, unsigned line);
ATTRIBUTE_NOINLINE void psi_wr_lock(const char *file, unsigned line);
ATTRIBUTE_NOINLINE void psi_rd_lock(const char *file, unsigned line) noexcept;
ATTRIBUTE_NOINLINE void psi_wr_lock(const char *file, unsigned line) noexcept;
public:
void init(mysql_pfs_key_t key)
void init(mysql_pfs_key_t key) noexcept
{
pfs_psi= PSI_RWLOCK_CALL(init_rwlock)(key, this);
lock.init();
}
void destroy()
void destroy() noexcept
{
if (psi_likely(pfs_psi != nullptr))
{
......@@ -532,36 +532,36 @@ class srw_lock_impl
}
lock.destroy();
}
void rd_lock(const char *file, unsigned line)
void rd_lock(const char *file, unsigned line) noexcept
{
if (psi_likely(pfs_psi != nullptr))
psi_rd_lock(file, line);
else
lock.rd_lock();
}
void rd_unlock()
void rd_unlock() noexcept
{
if (psi_likely(pfs_psi != nullptr))
PSI_RWLOCK_CALL(unlock_rwlock)(pfs_psi);
lock.rd_unlock();
}
void wr_lock(const char *file, unsigned line)
void wr_lock(const char *file, unsigned line) noexcept
{
if (psi_likely(pfs_psi != nullptr))
psi_wr_lock(file, line);
else
lock.wr_lock();
}
void wr_unlock()
void wr_unlock() noexcept
{
if (psi_likely(pfs_psi != nullptr))
PSI_RWLOCK_CALL(unlock_rwlock)(pfs_psi);
lock.wr_unlock();
}
bool rd_lock_try() { return lock.rd_lock_try(); }
bool wr_lock_try() { return lock.wr_lock_try(); }
void lock_shared() { return rd_lock(SRW_LOCK_CALL); }
void unlock_shared() { return rd_unlock(); }
bool rd_lock_try() noexcept { return lock.rd_lock_try(); }
bool wr_lock_try() noexcept { return lock.wr_lock_try(); }
void lock_shared() noexcept { return rd_lock(SRW_LOCK_CALL); }
void unlock_shared() noexcept { return rd_unlock(); }
#ifndef SUX_LOCK_GENERIC
/** @return whether any lock may be held by any thread */
bool is_locked_or_waiting() const noexcept
......@@ -591,11 +591,11 @@ class srw_lock_debug : private srw_lock
std::atomic<std::unordered_multiset<pthread_t>*> readers;
/** Register a read lock. */
void readers_register();
void readers_register() noexcept;
public:
void SRW_LOCK_INIT(mysql_pfs_key_t key);
void destroy();
void SRW_LOCK_INIT(mysql_pfs_key_t key) noexcept;
void destroy() noexcept;
#ifndef SUX_LOCK_GENERIC
/** @return whether any lock may be held by any thread */
......@@ -606,17 +606,17 @@ class srw_lock_debug : private srw_lock
#endif
/** Acquire an exclusive lock */
void wr_lock(SRW_LOCK_ARGS(const char *file, unsigned line));
void wr_lock(SRW_LOCK_ARGS(const char *file, unsigned line)) noexcept;
/** @return whether an exclusive lock was acquired */
bool wr_lock_try();
bool wr_lock_try() noexcept;
/** Release after wr_lock() */
void wr_unlock();
void wr_unlock() noexcept;
/** Acquire a shared lock */
void rd_lock(SRW_LOCK_ARGS(const char *file, unsigned line));
void rd_lock(SRW_LOCK_ARGS(const char *file, unsigned line)) noexcept;
/** @return whether a shared lock was acquired */
bool rd_lock_try();
bool rd_lock_try() noexcept;
/** Release after rd_lock() */
void rd_unlock();
void rd_unlock() noexcept;
/** @return whether this thread is between rd_lock() and rd_unlock() */
bool have_rd() const noexcept;
/** @return whether this thread is between wr_lock() and wr_unlock() */
......
......@@ -41,7 +41,7 @@ static inline bool xtest() { return false; }
#else
# if defined __i386__||defined __x86_64__||defined _M_IX86||defined _M_X64
extern bool have_transactional_memory;
bool transactional_lock_enabled();
bool transactional_lock_enabled() noexcept;
# include <immintrin.h>
# if defined __GNUC__ && !defined __INTEL_COMPILER
......@@ -52,7 +52,7 @@ bool transactional_lock_enabled();
# define TRANSACTIONAL_INLINE /* nothing */
# endif
TRANSACTIONAL_INLINE static inline bool xbegin()
TRANSACTIONAL_INLINE static inline bool xbegin() noexcept
{
return have_transactional_memory && _xbegin() == _XBEGIN_STARTED;
}
......@@ -60,18 +60,18 @@ TRANSACTIONAL_INLINE static inline bool xbegin()
# ifdef UNIV_DEBUG
# ifdef __GNUC__
/** @return whether a memory transaction is active */
bool xtest();
bool xtest() noexcept;
# else
static inline bool xtest() { return have_transactional_memory && _xtest(); }
static inline bool xtest() noexcept { return have_transactional_memory && _xtest(); }
# endif
# endif
TRANSACTIONAL_INLINE static inline void xabort() { _xabort(0); }
TRANSACTIONAL_INLINE static inline void xabort() noexcept { _xabort(0); }
TRANSACTIONAL_INLINE static inline void xend() { _xend(); }
TRANSACTIONAL_INLINE static inline void xend() noexcept { _xend(); }
# elif defined __powerpc64__ || defined __s390__
extern bool have_transactional_memory;
bool transactional_lock_enabled();
bool transactional_lock_enabled() noexcept;
# define TRANSACTIONAL_TARGET __attribute__((hot))
# define TRANSACTIONAL_INLINE __attribute__((hot,always_inline))
......@@ -89,9 +89,9 @@ bool transactional_lock_enabled();
could be implemented here, we keep the implementation the
same as ppc64.
*/
TRANSACTIONAL_TARGET bool xbegin();
TRANSACTIONAL_TARGET void xabort();
TRANSACTIONAL_TARGET void xend();
TRANSACTIONAL_TARGET bool xbegin() noexcept;
TRANSACTIONAL_TARGET void xabort() noexcept;
TRANSACTIONAL_TARGET void xend() noexcept;
# ifdef UNIV_DEBUG
bool xtest();
# endif
......@@ -105,7 +105,7 @@ class transactional_lock_guard
mutex &m;
public:
TRANSACTIONAL_INLINE transactional_lock_guard(mutex &m) : m(m)
TRANSACTIONAL_INLINE transactional_lock_guard(mutex &m) noexcept : m(m)
{
#ifndef NO_ELISION
if (xbegin())
......@@ -117,8 +117,8 @@ class transactional_lock_guard
#endif
m.lock();
}
transactional_lock_guard(const transactional_lock_guard &)= delete;
TRANSACTIONAL_INLINE ~transactional_lock_guard()
transactional_lock_guard(const transactional_lock_guard &) noexcept= delete;
TRANSACTIONAL_INLINE ~transactional_lock_guard() noexcept
{
#ifndef NO_ELISION
if (was_elided()) xend(); else
......@@ -144,7 +144,7 @@ class transactional_shared_lock_guard
#endif
public:
TRANSACTIONAL_INLINE transactional_shared_lock_guard(mutex &m) : m(m)
TRANSACTIONAL_INLINE transactional_shared_lock_guard(mutex &m) noexcept : m(m)
{
#ifndef NO_ELISION
if (xbegin())
......@@ -160,9 +160,9 @@ class transactional_shared_lock_guard
#endif
m.lock_shared();
}
transactional_shared_lock_guard(const transactional_shared_lock_guard &)=
transactional_shared_lock_guard(const transactional_shared_lock_guard &) noexcept=
delete;
TRANSACTIONAL_INLINE ~transactional_shared_lock_guard()
TRANSACTIONAL_INLINE ~transactional_shared_lock_guard() noexcept
{
#ifndef NO_ELISION
if (was_elided()) xend(); else
......
......@@ -25,7 +25,7 @@ this program; if not, write to the Free Software Foundation, Inc.,
#elif defined _MSC_VER && (defined _M_IX86 || defined _M_X64)
# include <intrin.h>
bool have_transactional_memory;
bool transactional_lock_enabled()
bool transactional_lock_enabled() noexcept
{
int regs[4];
__cpuid(regs, 0);
......@@ -39,7 +39,7 @@ bool transactional_lock_enabled()
#elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
# include <cpuid.h>
bool have_transactional_memory;
bool transactional_lock_enabled()
bool transactional_lock_enabled() noexcept
{
if (__get_cpuid_max(0, nullptr) < 7)
return false;
......@@ -52,7 +52,7 @@ bool transactional_lock_enabled()
# ifdef UNIV_DEBUG
TRANSACTIONAL_TARGET
bool xtest() { return have_transactional_memory && _xtest(); }
bool xtest() noexcept { return have_transactional_memory && _xtest(); }
# endif
#elif defined __powerpc64__ || defined __s390__
# include <htmxlintrin.h>
......@@ -60,21 +60,21 @@ bool xtest() { return have_transactional_memory && _xtest(); }
# include <signal.h>
__attribute__((target("htm"),hot))
bool xbegin()
bool xbegin() noexcept
{
return have_transactional_memory &&
__TM_simple_begin() == _HTM_TBEGIN_STARTED;
}
__attribute__((target("htm"),hot))
void xabort() { __TM_abort(); }
void xabort() noexcept { __TM_abort(); }
__attribute__((target("htm"),hot))
void xend() { __TM_end(); }
void xend() noexcept { __TM_end(); }
bool have_transactional_memory;
static sigjmp_buf ill_jmp;
static void ill_handler(int sig)
static void ill_handler(int sig) noexcept
{
siglongjmp(ill_jmp, sig);
}
......@@ -83,7 +83,7 @@ static void ill_handler(int sig)
and a 1 instruction store can succeed.
*/
__attribute__((noinline))
static void test_tm(bool *r)
static void test_tm(bool *r) noexcept
{
if (__TM_simple_begin() == _HTM_TBEGIN_STARTED)
{
......@@ -91,7 +91,7 @@ static void test_tm(bool *r)
__TM_end();
}
}
bool transactional_lock_enabled()
bool transactional_lock_enabled() noexcept
{
bool r= false;
sigset_t oset;
......@@ -115,7 +115,7 @@ bool transactional_lock_enabled()
# ifdef UNIV_DEBUG
__attribute__((target("htm"),hot))
bool xtest()
bool xtest() noexcept
{
# ifdef __s390x__
return have_transactional_memory &&
......@@ -129,13 +129,13 @@ bool xtest()
#endif
/** @return the parameter for srw_pause() */
static inline unsigned srw_pause_delay()
static inline unsigned srw_pause_delay() noexcept
{
return my_cpu_relax_multiplier / 4 * srv_spin_wait_delay;
}
/** Pause the CPU for some time, with no memory accesses. */
static inline void srw_pause(unsigned delay)
static inline void srw_pause(unsigned delay) noexcept
{
HMT_low();
while (delay--)
......@@ -145,7 +145,7 @@ static inline void srw_pause(unsigned delay)
#ifdef SUX_LOCK_GENERIC
# ifndef PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
template<> void pthread_mutex_wrapper<true>::wr_wait()
template<> void pthread_mutex_wrapper<true>::wr_wait() noexcept
{
const unsigned delay= srw_pause_delay();
......@@ -160,13 +160,13 @@ template<> void pthread_mutex_wrapper<true>::wr_wait()
}
# endif
template void ssux_lock_impl<false>::init();
template void ssux_lock_impl<true>::init();
template void ssux_lock_impl<false>::destroy();
template void ssux_lock_impl<true>::destroy();
template void ssux_lock_impl<false>::init() noexcept;
template void ssux_lock_impl<true>::init() noexcept;
template void ssux_lock_impl<false>::destroy() noexcept;
template void ssux_lock_impl<true>::destroy() noexcept;
template<bool spinloop>
inline void srw_mutex_impl<spinloop>::wait(uint32_t lk)
inline void srw_mutex_impl<spinloop>::wait(uint32_t lk) noexcept
{
pthread_mutex_lock(&mutex);
while (lock.load(std::memory_order_relaxed) == lk)
......@@ -175,7 +175,7 @@ inline void srw_mutex_impl<spinloop>::wait(uint32_t lk)
}
template<bool spinloop>
inline void ssux_lock_impl<spinloop>::wait(uint32_t lk)
inline void ssux_lock_impl<spinloop>::wait(uint32_t lk) noexcept
{
pthread_mutex_lock(&writer.mutex);
while (readers.load(std::memory_order_relaxed) == lk)
......@@ -184,21 +184,21 @@ inline void ssux_lock_impl<spinloop>::wait(uint32_t lk)
}
template<bool spinloop>
void srw_mutex_impl<spinloop>::wake()
void srw_mutex_impl<spinloop>::wake() noexcept
{
pthread_mutex_lock(&mutex);
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
template<bool spinloop>
inline void srw_mutex_impl<spinloop>::wake_all()
inline void srw_mutex_impl<spinloop>::wake_all() noexcept
{
pthread_mutex_lock(&mutex);
pthread_cond_broadcast(&cond);
pthread_mutex_unlock(&mutex);
}
template<bool spinloop>
void ssux_lock_impl<spinloop>::wake()
void ssux_lock_impl<spinloop>::wake() noexcept
{
pthread_mutex_lock(&writer.mutex);
pthread_cond_signal(&readers_cond);
......@@ -210,18 +210,18 @@ static_assert(4 == sizeof(rw_lock), "ABI");
# include <synchapi.h>
template<bool spinloop>
inline void srw_mutex_impl<spinloop>::wait(uint32_t lk)
inline void srw_mutex_impl<spinloop>::wait(uint32_t lk) noexcept
{ WaitOnAddress(&lock, &lk, 4, INFINITE); }
template<bool spinloop>
void srw_mutex_impl<spinloop>::wake() { WakeByAddressSingle(&lock); }
void srw_mutex_impl<spinloop>::wake() noexcept { WakeByAddressSingle(&lock); }
template<bool spinloop>
inline void srw_mutex_impl<spinloop>::wake_all() { WakeByAddressAll(&lock); }
inline void srw_mutex_impl<spinloop>::wake_all() noexcept { WakeByAddressAll(&lock); }
template<bool spinloop>
inline void ssux_lock_impl<spinloop>::wait(uint32_t lk)
inline void ssux_lock_impl<spinloop>::wait(uint32_t lk) noexcept
{ WaitOnAddress(&readers, &lk, 4, INFINITE); }
template<bool spinloop>
void ssux_lock_impl<spinloop>::wake() { WakeByAddressSingle(&readers); }
void ssux_lock_impl<spinloop>::wake() noexcept { WakeByAddressSingle(&readers); }
# else
# ifdef __linux__
# include <linux/futex.h>
......@@ -249,28 +249,28 @@ void ssux_lock_impl<spinloop>::wake() { WakeByAddressSingle(&readers); }
# endif
template<bool spinloop>
inline void srw_mutex_impl<spinloop>::wait(uint32_t lk)
inline void srw_mutex_impl<spinloop>::wait(uint32_t lk) noexcept
{ SRW_FUTEX(&lock, WAIT, lk); }
template<bool spinloop>
void srw_mutex_impl<spinloop>::wake() { SRW_FUTEX(&lock, WAKE, 1); }
void srw_mutex_impl<spinloop>::wake() noexcept { SRW_FUTEX(&lock, WAKE, 1); }
template<bool spinloop>
void srw_mutex_impl<spinloop>::wake_all() { SRW_FUTEX(&lock, WAKE, INT_MAX); }
void srw_mutex_impl<spinloop>::wake_all() noexcept { SRW_FUTEX(&lock, WAKE, INT_MAX); }
template<bool spinloop>
inline void ssux_lock_impl<spinloop>::wait(uint32_t lk)
inline void ssux_lock_impl<spinloop>::wait(uint32_t lk) noexcept
{ SRW_FUTEX(&readers, WAIT, lk); }
template<bool spinloop>
void ssux_lock_impl<spinloop>::wake() { SRW_FUTEX(&readers, WAKE, 1); }
void ssux_lock_impl<spinloop>::wake() noexcept { SRW_FUTEX(&readers, WAKE, 1); }
# endif
#endif
template void srw_mutex_impl<false>::wake();
template void ssux_lock_impl<false>::wake();
template void srw_mutex_impl<true>::wake();
template void ssux_lock_impl<true>::wake();
template void srw_mutex_impl<false>::wake() noexcept;
template void ssux_lock_impl<false>::wake() noexcept;
template void srw_mutex_impl<true>::wake() noexcept;
template void ssux_lock_impl<true>::wake() noexcept;
template<bool spinloop>
void srw_mutex_impl<spinloop>::wait_and_lock()
void srw_mutex_impl<spinloop>::wait_and_lock() noexcept
{
uint32_t lk= WAITER + lock.fetch_add(WAITER, std::memory_order_relaxed);
......@@ -339,11 +339,11 @@ void srw_mutex_impl<spinloop>::wait_and_lock()
}
}
template void srw_mutex_impl<false>::wait_and_lock();
template void srw_mutex_impl<true>::wait_and_lock();
template void srw_mutex_impl<false>::wait_and_lock() noexcept;
template void srw_mutex_impl<true>::wait_and_lock() noexcept;
template<bool spinloop>
void ssux_lock_impl<spinloop>::wr_wait(uint32_t lk)
void ssux_lock_impl<spinloop>::wr_wait(uint32_t lk) noexcept
{
DBUG_ASSERT(writer.is_locked());
DBUG_ASSERT(lk);
......@@ -374,11 +374,11 @@ void ssux_lock_impl<spinloop>::wr_wait(uint32_t lk)
while (lk != WRITER);
}
template void ssux_lock_impl<true>::wr_wait(uint32_t);
template void ssux_lock_impl<false>::wr_wait(uint32_t);
template void ssux_lock_impl<true>::wr_wait(uint32_t) noexcept;
template void ssux_lock_impl<false>::wr_wait(uint32_t) noexcept;
template<bool spinloop>
void ssux_lock_impl<spinloop>::rd_wait()
void ssux_lock_impl<spinloop>::rd_wait() noexcept
{
const unsigned delay= srw_pause_delay();
......@@ -429,11 +429,11 @@ void ssux_lock_impl<spinloop>::rd_wait()
writer.wake_all();
}
template void ssux_lock_impl<true>::rd_wait();
template void ssux_lock_impl<false>::rd_wait();
template void ssux_lock_impl<true>::rd_wait() noexcept;
template void ssux_lock_impl<false>::rd_wait() noexcept;
#if defined _WIN32 || defined SUX_LOCK_GENERIC
template<> void srw_lock_<true>::rd_wait()
template<> void srw_lock_<true>::rd_wait() noexcept
{
const unsigned delay= srw_pause_delay();
......@@ -447,7 +447,7 @@ template<> void srw_lock_<true>::rd_wait()
IF_WIN(AcquireSRWLockShared(&lk), rw_rdlock(&lk));
}
template<> void srw_lock_<true>::wr_wait()
template<> void srw_lock_<true>::wr_wait() noexcept
{
const unsigned delay= srw_pause_delay();
......@@ -463,13 +463,13 @@ template<> void srw_lock_<true>::wr_wait()
#endif
#ifdef UNIV_PFS_RWLOCK
template void srw_lock_impl<false>::psi_rd_lock(const char*, unsigned);
template void srw_lock_impl<false>::psi_wr_lock(const char*, unsigned);
template void srw_lock_impl<true>::psi_rd_lock(const char*, unsigned);
template void srw_lock_impl<true>::psi_wr_lock(const char*, unsigned);
template void srw_lock_impl<false>::psi_rd_lock(const char*, unsigned) noexcept;
template void srw_lock_impl<false>::psi_wr_lock(const char*, unsigned) noexcept;
template void srw_lock_impl<true>::psi_rd_lock(const char*, unsigned) noexcept;
template void srw_lock_impl<true>::psi_wr_lock(const char*, unsigned) noexcept;
template<bool spinloop>
void srw_lock_impl<spinloop>::psi_rd_lock(const char *file, unsigned line)
void srw_lock_impl<spinloop>::psi_rd_lock(const char *file, unsigned line) noexcept
{
PSI_rwlock_locker_state state;
const bool nowait= lock.rd_lock_try();
......@@ -486,7 +486,7 @@ void srw_lock_impl<spinloop>::psi_rd_lock(const char *file, unsigned line)
}
template<bool spinloop>
void srw_lock_impl<spinloop>::psi_wr_lock(const char *file, unsigned line)
void srw_lock_impl<spinloop>::psi_wr_lock(const char *file, unsigned line) noexcept
{
PSI_rwlock_locker_state state;
# if defined _WIN32 || defined SUX_LOCK_GENERIC
......@@ -525,7 +525,7 @@ void srw_lock_impl<spinloop>::psi_wr_lock(const char *file, unsigned line)
# endif
}
void ssux_lock::psi_rd_lock(const char *file, unsigned line)
void ssux_lock::psi_rd_lock(const char *file, unsigned line) noexcept
{
PSI_rwlock_locker_state state;
const bool nowait= lock.rd_lock_try();
......@@ -541,7 +541,7 @@ void ssux_lock::psi_rd_lock(const char *file, unsigned line)
lock.rd_lock();
}
void ssux_lock::psi_u_lock(const char *file, unsigned line)
void ssux_lock::psi_u_lock(const char *file, unsigned line) noexcept
{
PSI_rwlock_locker_state state;
if (PSI_rwlock_locker *locker= PSI_RWLOCK_CALL(start_rwlock_wrwait)
......@@ -554,7 +554,7 @@ void ssux_lock::psi_u_lock(const char *file, unsigned line)
lock.u_lock();
}
void ssux_lock::psi_wr_lock(const char *file, unsigned line)
void ssux_lock::psi_wr_lock(const char *file, unsigned line) noexcept
{
PSI_rwlock_locker_state state;
# if defined _WIN32 || defined SUX_LOCK_GENERIC
......@@ -594,7 +594,7 @@ void ssux_lock::psi_wr_lock(const char *file, unsigned line)
# endif
}
void ssux_lock::psi_u_wr_upgrade(const char *file, unsigned line)
void ssux_lock::psi_u_wr_upgrade(const char *file, unsigned line) noexcept
{
PSI_rwlock_locker_state state;
DBUG_ASSERT(lock.writer.is_locked());
......@@ -616,14 +616,14 @@ void ssux_lock::psi_u_wr_upgrade(const char *file, unsigned line)
lock.u_wr_upgrade();
}
#else /* UNIV_PFS_RWLOCK */
template void ssux_lock_impl<false>::rd_lock();
template void ssux_lock_impl<false>::rd_unlock();
template void ssux_lock_impl<false>::u_unlock();
template void ssux_lock_impl<false>::wr_unlock();
template void ssux_lock_impl<false>::rd_lock() noexcept;
template void ssux_lock_impl<false>::rd_unlock() noexcept;
template void ssux_lock_impl<false>::u_unlock() noexcept;
template void ssux_lock_impl<false>::wr_unlock() noexcept;
#endif /* UNIV_PFS_RWLOCK */
#ifdef UNIV_DEBUG
void srw_lock_debug::SRW_LOCK_INIT(mysql_pfs_key_t key)
void srw_lock_debug::SRW_LOCK_INIT(mysql_pfs_key_t key) noexcept
{
srw_lock::SRW_LOCK_INIT(key);
readers_lock.init();
......@@ -631,7 +631,7 @@ void srw_lock_debug::SRW_LOCK_INIT(mysql_pfs_key_t key)
ut_ad(!have_any());
}
void srw_lock_debug::destroy()
void srw_lock_debug::destroy() noexcept
{
ut_ad(!writer);
if (auto r= readers.load(std::memory_order_relaxed))
......@@ -644,7 +644,7 @@ void srw_lock_debug::destroy()
srw_lock::destroy();
}
bool srw_lock_debug::wr_lock_try()
bool srw_lock_debug::wr_lock_try() noexcept
{
ut_ad(!have_any());
if (!srw_lock::wr_lock_try())
......@@ -654,7 +654,7 @@ bool srw_lock_debug::wr_lock_try()
return true;
}
void srw_lock_debug::wr_lock(SRW_LOCK_ARGS(const char *file, unsigned line))
void srw_lock_debug::wr_lock(SRW_LOCK_ARGS(const char *file, unsigned line)) noexcept
{
ut_ad(!have_any());
srw_lock::wr_lock(SRW_LOCK_ARGS(file, line));
......@@ -662,14 +662,14 @@ void srw_lock_debug::wr_lock(SRW_LOCK_ARGS(const char *file, unsigned line))
writer.store(pthread_self(), std::memory_order_relaxed);
}
void srw_lock_debug::wr_unlock()
void srw_lock_debug::wr_unlock() noexcept
{
ut_ad(have_wr());
writer.store(0, std::memory_order_relaxed);
srw_lock::wr_unlock();
}
void srw_lock_debug::readers_register()
void srw_lock_debug::readers_register() noexcept
{
readers_lock.wr_lock();
auto r= readers.load(std::memory_order_relaxed);
......@@ -682,7 +682,7 @@ void srw_lock_debug::readers_register()
readers_lock.wr_unlock();
}
bool srw_lock_debug::rd_lock_try()
bool srw_lock_debug::rd_lock_try() noexcept
{
ut_ad(!have_any());
if (!srw_lock::rd_lock_try())
......@@ -691,14 +691,14 @@ bool srw_lock_debug::rd_lock_try()
return true;
}
void srw_lock_debug::rd_lock(SRW_LOCK_ARGS(const char *file, unsigned line))
void srw_lock_debug::rd_lock(SRW_LOCK_ARGS(const char *file, unsigned line)) noexcept
{
ut_ad(!have_any());
srw_lock::rd_lock(SRW_LOCK_ARGS(file, line));
readers_register();
}
void srw_lock_debug::rd_unlock()
void srw_lock_debug::rd_unlock() noexcept
{
const pthread_t self= pthread_self();
ut_ad(writer != self);
......
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