Commit a50cb486 authored by Eugene Kosov's avatar Eugene Kosov

MDEV-24334 make monitor_set_tbl global variable thread-safe

Atomic_relaxed<T>: add fetch_or() and fetch_and()

innodb_init(): rely on a zero-initialization of a global variable

monitor_set_tbl: make Atomic_relaxed<ulint> array and use proper operations
for setting bit, unsetting bit and reading bit

Reviewed by: Marko Mäkelä
parent fccd8104
...@@ -13,6 +13,7 @@ ...@@ -13,6 +13,7 @@
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
#pragma once
#ifdef __cplusplus #ifdef __cplusplus
#include <atomic> #include <atomic>
/** /**
...@@ -50,6 +51,10 @@ template <typename Type> class Atomic_relaxed ...@@ -50,6 +51,10 @@ template <typename Type> class Atomic_relaxed
{ return m.fetch_sub(i, o); } { return m.fetch_sub(i, o); }
Type fetch_xor(const Type i, std::memory_order o= std::memory_order_relaxed) Type fetch_xor(const Type i, std::memory_order o= std::memory_order_relaxed)
{ return m.fetch_xor(i, o); } { return m.fetch_xor(i, o); }
Type fetch_and(const Type i, std::memory_order o= std::memory_order_relaxed)
{ return m.fetch_and(i, o); }
Type fetch_or(const Type i, std::memory_order o= std::memory_order_relaxed)
{ return m.fetch_or(i, o); }
bool compare_exchange_strong(Type& i1, const Type i2, bool compare_exchange_strong(Type& i1, const Type i2,
std::memory_order o1= std::memory_order_relaxed, std::memory_order o1= std::memory_order_relaxed,
std::memory_order o2= std::memory_order_relaxed) std::memory_order o2= std::memory_order_relaxed)
......
...@@ -4245,9 +4245,6 @@ static int innodb_init(void* p) ...@@ -4245,9 +4245,6 @@ static int innodb_init(void* p)
} }
#endif /* MYSQL_DYNAMIC_PLUGIN */ #endif /* MYSQL_DYNAMIC_PLUGIN */
/* Currently, monitor counter information are not persistent. */
memset(monitor_set_tbl, 0, sizeof monitor_set_tbl);
memset(innodb_counter_value, 0, sizeof innodb_counter_value); memset(innodb_counter_value, 0, sizeof innodb_counter_value);
/* Do this as late as possible so server is fully starts up, /* Do this as late as possible so server is fully starts up,
......
...@@ -498,18 +498,18 @@ enum mon_option_t { ...@@ -498,18 +498,18 @@ enum mon_option_t {
/** This "monitor_set_tbl" is a bitmap records whether a particular monitor /** This "monitor_set_tbl" is a bitmap records whether a particular monitor
counter has been turned on or off */ counter has been turned on or off */
extern ulint monitor_set_tbl[(NUM_MONITOR + NUM_BITS_ULINT - 1) / extern Atomic_relaxed<ulint>
NUM_BITS_ULINT]; monitor_set_tbl[(NUM_MONITOR + NUM_BITS_ULINT - 1) / NUM_BITS_ULINT];
/** Macros to turn on/off the control bit in monitor_set_tbl for a monitor /** Macros to turn on/off the control bit in monitor_set_tbl for a monitor
counter option. */ counter option. */
#define MONITOR_ON(monitor) \ #define MONITOR_ON(monitor) \
(monitor_set_tbl[unsigned(monitor) / NUM_BITS_ULINT] |= \ (monitor_set_tbl[unsigned(monitor) / NUM_BITS_ULINT].fetch_or( \
(ulint(1) << (unsigned(monitor) % NUM_BITS_ULINT))) (ulint(1) << (unsigned(monitor) % NUM_BITS_ULINT))))
#define MONITOR_OFF(monitor) \ #define MONITOR_OFF(monitor) \
(monitor_set_tbl[unsigned(monitor) / NUM_BITS_ULINT] &= \ (monitor_set_tbl[unsigned(monitor) / NUM_BITS_ULINT].fetch_and( \
~(ulint(1) << (unsigned(monitor) % NUM_BITS_ULINT))) ~(ulint(1) << (unsigned(monitor) % NUM_BITS_ULINT))))
/** Check whether the requested monitor is turned on/off */ /** Check whether the requested monitor is turned on/off */
#define MONITOR_IS_ON(monitor) \ #define MONITOR_IS_ON(monitor) \
......
...@@ -1424,8 +1424,8 @@ monitor_value_t innodb_counter_value[NUM_MONITOR]; ...@@ -1424,8 +1424,8 @@ monitor_value_t innodb_counter_value[NUM_MONITOR];
/* monitor_set_tbl is used to record and determine whether a monitor /* monitor_set_tbl is used to record and determine whether a monitor
has been turned on/off. */ has been turned on/off. */
ulint monitor_set_tbl[(NUM_MONITOR + NUM_BITS_ULINT Atomic_relaxed<ulint>
- 1) / NUM_BITS_ULINT]; monitor_set_tbl[(NUM_MONITOR + NUM_BITS_ULINT - 1) / NUM_BITS_ULINT];
/****************************************************************//** /****************************************************************//**
Get a monitor's "monitor_info" by its monitor id (index into the Get a monitor's "monitor_info" by its monitor id (index into the
......
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