diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2021-03-02 14:32:37 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2021-03-02 14:32:37 +0200 |
commit | 80ac9ec1cc10d56b048272642653d5d301394779 (patch) | |
tree | 5fa56fd95766c3dbe73f25239b7c19a77f2ddd59 /mysys/my_thr_init.c | |
parent | 33aec68a87f1aa4cffbe55cbacff25acff8cbd5d (diff) | |
download | mariadb-git-80ac9ec1cc10d56b048272642653d5d301394779.tar.gz |
MDEV-24973 Performance schema duplicates rarely executed code for mutex operations
The PERFORMANCE_SCHEMA wrapper for mutex and rw-lock operations is
causing a lot of unlikely code to be inlined in each invocation.
The impact of this may have been emphasized in MariaDB 10.6, because
InnoDB now uses the common implementation of mutexes and condition
variables (MDEV-21452).
By default, we build with cmake -DPLUGIN_PERFSCHEMA enabled,
but at runtime no instrumentation will be enabled. Similar to
commit eba2d10ac53d1d2f975027ba2b2ca39d9c9b98ad
we had better avoid inlining the rarely executed code in order to reduce
the code size and to improve the efficiency of the instruction cache.
This change was extensively tested by Axel Schwenke with and without
--enable-performance-schema (with no individual instruments enabled).
Removing the inline functions did not cause any performance regression
in either case. There seemed to be a tiny improvement, possibly due
to reduced code size and better instruction cache hit rate.
Diffstat (limited to 'mysys/my_thr_init.c')
-rw-r--r-- | mysys/my_thr_init.c | 138 |
1 files changed, 137 insertions, 1 deletions
diff --git a/mysys/my_thr_init.c b/mysys/my_thr_init.c index 24b4b3aff15..cde34e5bdb9 100644 --- a/mysys/my_thr_init.c +++ b/mysys/my_thr_init.c @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2011 Oracle and/or its affiliates. - Copyright 2008-2011 Monty Program Ab + Copyright 2008, 2021, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -476,3 +476,139 @@ static void install_sigabrt_handler(void) } #endif +#ifdef HAVE_PSI_MUTEX_INTERFACE +ATTRIBUTE_COLD int psi_mutex_lock(mysql_mutex_t *that, + const char *file, uint line) +{ + PSI_mutex_locker_state state; + PSI_mutex_locker *locker= PSI_MUTEX_CALL(start_mutex_wait) + (&state, that->m_psi, PSI_MUTEX_LOCK, file, line); +# ifdef SAFE_MUTEX + int result= safe_mutex_lock(&that->m_mutex, FALSE, file, line); +# else + int result= pthread_mutex_lock(&that->m_mutex); +# endif + if (locker) + PSI_MUTEX_CALL(end_mutex_wait)(locker, result); + return result; +} + +ATTRIBUTE_COLD int psi_mutex_trylock(mysql_mutex_t *that, + const char *file, uint line) +{ + PSI_mutex_locker_state state; + PSI_mutex_locker *locker= PSI_MUTEX_CALL(start_mutex_wait) + (&state, that->m_psi, PSI_MUTEX_TRYLOCK, file, line); +# ifdef SAFE_MUTEX + int result= safe_mutex_lock(&that->m_mutex, TRUE, file, line); +# else + int result= pthread_mutex_trylock(&that->m_mutex); +# endif + if (locker) + PSI_MUTEX_CALL(end_mutex_wait)(locker, result); + return result; +} +#endif /* HAVE_PSI_MUTEX_INTERFACE */ + +#ifdef HAVE_PSI_RWLOCK_INTERFACE +ATTRIBUTE_COLD +int psi_rwlock_rdlock(mysql_rwlock_t *that, const char *file, uint line) +{ + PSI_rwlock_locker_state state; + PSI_rwlock_locker *locker= PSI_RWLOCK_CALL(start_rwlock_rdwait) + (&state, that->m_psi, PSI_RWLOCK_READLOCK, file, line); + int result= rw_rdlock(&that->m_rwlock); + if (locker) + PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, result); + return result; +} + +ATTRIBUTE_COLD +int psi_rwlock_tryrdlock(mysql_rwlock_t *that, const char *file, uint line) +{ + PSI_rwlock_locker_state state; + PSI_rwlock_locker *locker= PSI_RWLOCK_CALL(start_rwlock_rdwait) + (&state, that->m_psi, PSI_RWLOCK_TRYREADLOCK, file, line); + int result= rw_tryrdlock(&that->m_rwlock); + if (locker) + PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, result); + return result; +} + +ATTRIBUTE_COLD +int psi_rwlock_trywrlock(mysql_rwlock_t *that, const char *file, uint line) +{ + PSI_rwlock_locker_state state; + PSI_rwlock_locker *locker= PSI_RWLOCK_CALL(start_rwlock_wrwait) + (&state, that->m_psi, PSI_RWLOCK_TRYWRITELOCK, file, line); + int result= rw_trywrlock(&that->m_rwlock); + if (locker) + PSI_RWLOCK_CALL(end_rwlock_wrwait)(locker, result); + return result; +} + +ATTRIBUTE_COLD +int psi_rwlock_wrlock(mysql_rwlock_t *that, const char *file, uint line) +{ + PSI_rwlock_locker_state state; + PSI_rwlock_locker *locker= PSI_RWLOCK_CALL(start_rwlock_wrwait) + (&state, that->m_psi, PSI_RWLOCK_WRITELOCK, file, line); + int result= rw_wrlock(&that->m_rwlock); + if (locker) + PSI_RWLOCK_CALL(end_rwlock_wrwait)(locker, result); + return result; +} + +# ifndef DISABLE_MYSQL_PRLOCK_H +ATTRIBUTE_COLD +int psi_prlock_rdlock(mysql_prlock_t *that, const char *file, uint line) +{ + PSI_rwlock_locker_state state; + PSI_rwlock_locker *locker= PSI_RWLOCK_CALL(start_rwlock_rdwait) + (&state, that->m_psi, PSI_RWLOCK_READLOCK, file, line); + int result= rw_pr_rdlock(&that->m_prlock); + if (locker) + PSI_RWLOCK_CALL(end_rwlock_rdwait)(locker, result); + return result; +} + +ATTRIBUTE_COLD +int psi_prlock_wrlock(mysql_prlock_t *that, const char *file, uint line) +{ + PSI_rwlock_locker_state state; + PSI_rwlock_locker *locker= PSI_RWLOCK_CALL(start_rwlock_wrwait) + (&state, that->m_psi, PSI_RWLOCK_WRITELOCK, file, line); + int result= rw_pr_wrlock(&that->m_prlock); + if (locker) + PSI_RWLOCK_CALL(end_rwlock_wrwait)(locker, result); + return result; +} +# endif /* !DISABLE_MYSQL_PRLOCK_H */ +#endif /* HAVE_PSI_RWLOCK_INTERFACE */ + +#ifdef HAVE_PSI_COND_INTERFACE +ATTRIBUTE_COLD int psi_cond_wait(mysql_cond_t *that, mysql_mutex_t *mutex, + const char *file, uint line) +{ + PSI_cond_locker_state state; + PSI_cond_locker *locker= PSI_COND_CALL(start_cond_wait) + (&state, that->m_psi, mutex->m_psi, PSI_COND_WAIT, file, line); + int result= my_cond_wait(&that->m_cond, &mutex->m_mutex); + if (locker) + PSI_COND_CALL(end_cond_wait)(locker, result); + return result; +} + +ATTRIBUTE_COLD int psi_cond_timedwait(mysql_cond_t *that, mysql_mutex_t *mutex, + const struct timespec *abstime, + const char *file, uint line) +{ + PSI_cond_locker_state state; + PSI_cond_locker *locker= PSI_COND_CALL(start_cond_wait) + (&state, that->m_psi, mutex->m_psi, PSI_COND_TIMEDWAIT, file, line); + int result= my_cond_timedwait(&that->m_cond, &mutex->m_mutex, abstime); + if (psi_likely(locker)) + PSI_COND_CALL(end_cond_wait)(locker, result); + return result; +} +#endif /* HAVE_PSI_COND_INTERFACE */ |