Commit f50abab1 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-31048 PERFORMANCE_SCHEMA lakcs InnoDB read_slots and write_slots

tpool::cache::m_mtx: Add PERFORMANCE_SCHEMA instrumentation
(wait/synch/mutex/innodb/tpool_cache_mutex). This covers the
InnoDB read_slots and write_slots for asynchronous data page I/O.
parent c0eeb725
...@@ -542,6 +542,7 @@ mysql_pfs_key_t trx_pool_manager_mutex_key; ...@@ -542,6 +542,7 @@ mysql_pfs_key_t trx_pool_manager_mutex_key;
mysql_pfs_key_t lock_wait_mutex_key; mysql_pfs_key_t lock_wait_mutex_key;
mysql_pfs_key_t trx_sys_mutex_key; mysql_pfs_key_t trx_sys_mutex_key;
mysql_pfs_key_t srv_threads_mutex_key; mysql_pfs_key_t srv_threads_mutex_key;
mysql_pfs_key_t tpool_cache_mutex_key;
/* all_innodb_mutexes array contains mutexes that are /* all_innodb_mutexes array contains mutexes that are
performance schema instrumented if "UNIV_PFS_MUTEX" performance schema instrumented if "UNIV_PFS_MUTEX"
...@@ -577,6 +578,7 @@ static PSI_mutex_info all_innodb_mutexes[] = { ...@@ -577,6 +578,7 @@ static PSI_mutex_info all_innodb_mutexes[] = {
PSI_KEY(rtr_match_mutex), PSI_KEY(rtr_match_mutex),
PSI_KEY(rtr_path_mutex), PSI_KEY(rtr_path_mutex),
PSI_KEY(trx_sys_mutex), PSI_KEY(trx_sys_mutex),
PSI_KEY(tpool_cache_mutex),
}; };
# endif /* UNIV_PFS_MUTEX */ # endif /* UNIV_PFS_MUTEX */
......
...@@ -132,7 +132,7 @@ class io_slots ...@@ -132,7 +132,7 @@ class io_slots
wait(); wait();
} }
std::mutex& mutex() mysql_mutex_t& mutex()
{ {
return m_cache.mutex(); return m_cache.mutex();
} }
...@@ -3668,8 +3668,10 @@ void os_aio_wait_until_no_pending_writes() ...@@ -3668,8 +3668,10 @@ void os_aio_wait_until_no_pending_writes()
/** @return number of pending reads */ /** @return number of pending reads */
size_t os_aio_pending_reads() size_t os_aio_pending_reads()
{ {
std::unique_lock<std::mutex> lk(read_slots->mutex()); mysql_mutex_lock(&read_slots->mutex());
return read_slots->pending_io_count(); size_t pending= read_slots->pending_io_count();
mysql_mutex_unlock(&read_slots->mutex());
return pending;
} }
/** @return approximate number of pending reads */ /** @return approximate number of pending reads */
...@@ -3681,8 +3683,10 @@ size_t os_aio_pending_reads_approx() ...@@ -3681,8 +3683,10 @@ size_t os_aio_pending_reads_approx()
/** @return number of pending writes */ /** @return number of pending writes */
size_t os_aio_pending_writes() size_t os_aio_pending_writes()
{ {
std::unique_lock<std::mutex> lk(write_slots->mutex()); mysql_mutex_lock(&write_slots->mutex());
return write_slots->pending_io_count(); size_t pending= write_slots->pending_io_count();
mysql_mutex_unlock(&write_slots->mutex());
return pending;
} }
/** Wait until all pending asynchronous reads have completed. */ /** Wait until all pending asynchronous reads have completed. */
......
...@@ -14,14 +14,13 @@ along with this program; if not, write to the Free Software ...@@ -14,14 +14,13 @@ along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 - 1301 USA*/ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 - 1301 USA*/
#pragma once #pragma once
#include <my_global.h>
#include <my_pthread.h>
#include <vector> #include <vector>
#include <stack> #include <stack>
#include <mutex>
#include <condition_variable>
#include <assert.h> #include <assert.h>
#include <algorithm> #include <algorithm>
/* Suppress TSAN warnings, that we believe are not critical. */ /* Suppress TSAN warnings, that we believe are not critical. */
#if defined(__has_feature) #if defined(__has_feature)
#define TPOOL_HAS_FEATURE(...) __has_feature(__VA_ARGS__) #define TPOOL_HAS_FEATURE(...) __has_feature(__VA_ARGS__)
...@@ -37,6 +36,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 - 1301 USA*/ ...@@ -37,6 +36,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 - 1301 USA*/
#define TPOOL_SUPPRESS_TSAN #define TPOOL_SUPPRESS_TSAN
#endif #endif
#ifdef HAVE_PSI_INTERFACE
typedef unsigned int mysql_pfs_key_t;
extern mysql_pfs_key_t tpool_cache_mutex_key;
#endif
namespace tpool namespace tpool
{ {
...@@ -55,13 +59,13 @@ namespace tpool ...@@ -55,13 +59,13 @@ namespace tpool
template<typename T> class cache template<typename T> class cache
{ {
/** Protects updates of m_pos and m_cache members */ /** Protects updates of m_pos and m_cache members */
std::mutex m_mtx; mysql_mutex_t m_mtx;
/** /**
Notify waiting threads about "cache full" or "cache not empty" conditions Notify waiting threads about "cache full" or "cache not empty" conditions
@see get() and wait() @see get() and wait()
*/ */
std::condition_variable m_cv; pthread_cond_t m_cv;
/** Cached items vector.Does not change after construction */ /** Cached items vector.Does not change after construction */
std::vector<T> m_base; std::vector<T> m_base;
...@@ -108,13 +112,22 @@ template<typename T> class cache ...@@ -108,13 +112,22 @@ template<typename T> class cache
Constructor Constructor
@param size - maximum number of items in cache @param size - maximum number of items in cache
*/ */
cache(size_t size) : m_mtx(), m_cv(), m_base(size), m_cache(size), cache(size_t size) : m_base(size), m_cache(size),
m_waiters(), m_pos(0) m_waiters(), m_pos(0)
{ {
mysql_mutex_init(tpool_cache_mutex_key, &m_mtx, nullptr);
pthread_cond_init(&m_cv, nullptr);
for(size_t i= 0 ; i < size; i++) for(size_t i= 0 ; i < size; i++)
m_cache[i]= &m_base[i]; m_cache[i]= &m_base[i];
} }
~cache()
{
mysql_mutex_destroy(&m_mtx);
pthread_cond_destroy(&m_cv);
}
/** /**
Retrieve an item from cache. Waits for free item, if cache is Retrieve an item from cache. Waits for free item, if cache is
currently empty. currently empty.
...@@ -122,16 +135,17 @@ template<typename T> class cache ...@@ -122,16 +135,17 @@ template<typename T> class cache
*/ */
T* get() T* get()
{ {
std::unique_lock<std::mutex> lk(m_mtx); mysql_mutex_lock(&m_mtx);
while(is_empty()) while (is_empty())
m_cv.wait(lk); my_cond_wait(&m_cv, &m_mtx.m_mutex);
assert(m_pos < capacity()); assert(m_pos < capacity());
// return last element // return last element
return m_cache[m_pos++]; T *t= m_cache[m_pos++];
mysql_mutex_unlock(&m_mtx);
return t;
} }
mysql_mutex_t &mutex() { return m_mtx; }
std::mutex &mutex() { return m_mtx; }
/** /**
Put back an element to cache. Put back an element to cache.
...@@ -139,7 +153,7 @@ template<typename T> class cache ...@@ -139,7 +153,7 @@ template<typename T> class cache
*/ */
void put(T *ele) void put(T *ele)
{ {
std::unique_lock<std::mutex> lk(m_mtx); mysql_mutex_lock(&m_mtx);
assert(!is_full()); assert(!is_full());
// put element to the logical end of the array // put element to the logical end of the array
m_cache[--m_pos] = ele; m_cache[--m_pos] = ele;
...@@ -147,7 +161,8 @@ template<typename T> class cache ...@@ -147,7 +161,8 @@ template<typename T> class cache
/* Notify waiters when the cache becomes /* Notify waiters when the cache becomes
not empty, or when it becomes full */ not empty, or when it becomes full */
if (m_pos == 1 || (m_waiters && is_full())) if (m_pos == 1 || (m_waiters && is_full()))
m_cv.notify_all(); pthread_cond_broadcast(&m_cv);
mysql_mutex_unlock(&m_mtx);
} }
/** Check if pointer represents cached element */ /** Check if pointer represents cached element */
...@@ -157,16 +172,25 @@ template<typename T> class cache ...@@ -157,16 +172,25 @@ template<typename T> class cache
return ele >= &m_base[0] && ele <= &m_base[capacity() - 1]; return ele >= &m_base[0] && ele <= &m_base[capacity() - 1];
} }
/** Wait until cache is full.*/ /** Wait until cache is full
void wait() @param m cache mutex (locked) */
void wait(mysql_mutex_t &m)
{ {
std::unique_lock<std::mutex> lk(m_mtx); mysql_mutex_assert_owner(&m);
m_waiters++; m_waiters++;
while(!is_full()) while (!is_full())
m_cv.wait(lk); my_cond_wait(&m_cv, &m.m_mutex);
m_waiters--; m_waiters--;
} }
/* Wait until cache is full.*/
void wait()
{
mysql_mutex_lock(&m_mtx);
wait(m_mtx);
mysql_mutex_unlock(&m_mtx);
}
/** /**
@return approximate number of "borrowed" items. @return approximate number of "borrowed" items.
A "dirty" read, not used in any critical functionality. A "dirty" read, not used in any critical functionality.
......
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