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()); }
......
This diff is collapsed.
...@@ -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
......
This diff is collapsed.
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