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