Commit 6cde03ae authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-34178: Improve PERFORMANCE_SCHEMA instrumentation

When MariaDB is built with PERFORMANCE_SCHEMA support enabled
and with futex-based rw-locks (not srw_lock_), we were unnecessarily
releasing and reacquiring lock.writer in srw_lock_impl::psi_wr_lock()
and ssux_lock::psi_wr_lock().

If there is a conflict with rd_lock(), let us hold the lock.writer
and execute u_wr_upgrade() to wait for rd_unlock().

Reviewed by: Debarun Banerjee
Tested by: Matthias Leich
parent 2bd661ca
......@@ -462,17 +462,40 @@ template<bool spinloop>
void srw_lock_impl<spinloop>::psi_wr_lock(const char *file, unsigned line)
{
PSI_rwlock_locker_state state;
const bool nowait= lock.wr_lock_try();
# if defined _WIN32 || defined SUX_LOCK_GENERIC
const bool nowait2= lock.wr_lock_try();
# else
const bool nowait1= lock.writer.wr_lock_try();
uint32_t lk= 0;
const bool nowait2= nowait1 &&
lock.readers.compare_exchange_strong(lk, lock.WRITER,
std::memory_order_acquire,
std::memory_order_relaxed);
# endif
if (PSI_rwlock_locker *locker= PSI_RWLOCK_CALL(start_rwlock_wrwait)
(&state, pfs_psi,
nowait ? PSI_RWLOCK_TRYWRITELOCK : PSI_RWLOCK_WRITELOCK, file, line))
nowait2 ? PSI_RWLOCK_TRYWRITELOCK : PSI_RWLOCK_WRITELOCK, file, line))
{
if (!nowait)
# if defined _WIN32 || defined SUX_LOCK_GENERIC
if (!nowait2)
lock.wr_lock();
# else
if (!nowait1)
lock.wr_lock();
else if (!nowait2)
lock.u_wr_upgrade();
# endif
PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, 0);
}
else if (!nowait)
# if defined _WIN32 || defined SUX_LOCK_GENERIC
else if (!nowait2)
lock.wr_lock();
# else
else if (!nowait1)
lock.wr_lock();
else if (!nowait2)
lock.u_wr_upgrade();
# endif
}
void ssux_lock::psi_rd_lock(const char *file, unsigned line)
......@@ -507,18 +530,41 @@ void ssux_lock::psi_u_lock(const char *file, unsigned line)
void ssux_lock::psi_wr_lock(const char *file, unsigned line)
{
PSI_rwlock_locker_state state;
const bool nowait= lock.wr_lock_try();
# if defined _WIN32 || defined SUX_LOCK_GENERIC
const bool nowait2= lock.wr_lock_try();
# else
const bool nowait1= lock.writer.wr_lock_try();
uint32_t lk= 0;
const bool nowait2= nowait1 &&
lock.readers.compare_exchange_strong(lk, lock.WRITER,
std::memory_order_acquire,
std::memory_order_relaxed);
# endif
if (PSI_rwlock_locker *locker= PSI_RWLOCK_CALL(start_rwlock_wrwait)
(&state, pfs_psi,
nowait ? PSI_RWLOCK_TRYEXCLUSIVELOCK : PSI_RWLOCK_EXCLUSIVELOCK,
nowait2 ? PSI_RWLOCK_TRYEXCLUSIVELOCK : PSI_RWLOCK_EXCLUSIVELOCK,
file, line))
{
if (!nowait)
# if defined _WIN32 || defined SUX_LOCK_GENERIC
if (!nowait2)
lock.wr_lock();
# else
if (!nowait1)
lock.wr_lock();
else if (!nowait2)
lock.u_wr_upgrade();
# endif
PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, 0);
}
else if (!nowait)
# if defined _WIN32 || defined SUX_LOCK_GENERIC
else if (!nowait2)
lock.wr_lock();
# else
else if (!nowait1)
lock.wr_lock();
else if (!nowait2)
lock.u_wr_upgrade();
# endif
}
void ssux_lock::psi_u_wr_upgrade(const char *file, unsigned line)
......
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