summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Kosov <claprix@yandex.ru>2020-12-02 11:34:37 +0300
committerEugene Kosov <claprix@yandex.ru>2020-12-03 11:55:36 +0300
commita50cb4867a7f63bfc03b33bfb5be8d47d15ba64d (patch)
tree936cc262fa1829a982901ffed69f5bdde58739f0
parentfccd8104040aefa5e610159f219bf3e083af3eac (diff)
downloadmariadb-git-a50cb4867a7f63bfc03b33bfb5be8d47d15ba64d.tar.gz
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ä
-rw-r--r--include/my_atomic_wrapper.h5
-rw-r--r--storage/innobase/handler/ha_innodb.cc3
-rw-r--r--storage/innobase/include/srv0mon.h22
-rw-r--r--storage/innobase/srv/srv0mon.cc4
4 files changed, 18 insertions, 16 deletions
diff --git a/include/my_atomic_wrapper.h b/include/my_atomic_wrapper.h
index 64835e30ca7..c574fba4a8e 100644
--- a/include/my_atomic_wrapper.h
+++ b/include/my_atomic_wrapper.h
@@ -13,6 +13,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */
+#pragma once
#ifdef __cplusplus
#include <atomic>
/**
@@ -50,6 +51,10 @@ public:
{ return m.fetch_sub(i, o); }
Type fetch_xor(const Type i, std::memory_order o= std::memory_order_relaxed)
{ 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,
std::memory_order o1= std::memory_order_relaxed,
std::memory_order o2= std::memory_order_relaxed)
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index a9206df377c..345f2a37d5d 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -4245,9 +4245,6 @@ static int innodb_init(void* p)
}
#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);
/* Do this as late as possible so server is fully starts up,
diff --git a/storage/innobase/include/srv0mon.h b/storage/innobase/include/srv0mon.h
index 45f9ae3d5e9..58e36676398 100644
--- a/storage/innobase/include/srv0mon.h
+++ b/storage/innobase/include/srv0mon.h
@@ -498,23 +498,23 @@ enum mon_option_t {
/** This "monitor_set_tbl" is a bitmap records whether a particular monitor
counter has been turned on or off */
-extern ulint monitor_set_tbl[(NUM_MONITOR + NUM_BITS_ULINT - 1) /
- NUM_BITS_ULINT];
+extern Atomic_relaxed<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
counter option. */
-#define MONITOR_ON(monitor) \
- (monitor_set_tbl[unsigned(monitor) / NUM_BITS_ULINT] |= \
- (ulint(1) << (unsigned(monitor) % NUM_BITS_ULINT)))
+#define MONITOR_ON(monitor) \
+ (monitor_set_tbl[unsigned(monitor) / NUM_BITS_ULINT].fetch_or( \
+ (ulint(1) << (unsigned(monitor) % NUM_BITS_ULINT))))
-#define MONITOR_OFF(monitor) \
- (monitor_set_tbl[unsigned(monitor) / NUM_BITS_ULINT] &= \
- ~(ulint(1) << (unsigned(monitor) % NUM_BITS_ULINT)))
+#define MONITOR_OFF(monitor) \
+ (monitor_set_tbl[unsigned(monitor) / NUM_BITS_ULINT].fetch_and( \
+ ~(ulint(1) << (unsigned(monitor) % NUM_BITS_ULINT))))
/** Check whether the requested monitor is turned on/off */
-#define MONITOR_IS_ON(monitor) \
- (monitor_set_tbl[unsigned(monitor) / NUM_BITS_ULINT] & \
- (ulint(1) << (unsigned(monitor) % NUM_BITS_ULINT)))
+#define MONITOR_IS_ON(monitor) \
+ (monitor_set_tbl[unsigned(monitor) / NUM_BITS_ULINT] & \
+ (ulint(1) << (unsigned(monitor) % NUM_BITS_ULINT)))
/** The actual monitor counter array that records each monintor counter
value */
diff --git a/storage/innobase/srv/srv0mon.cc b/storage/innobase/srv/srv0mon.cc
index c759a5b75fe..e64d3b9f426 100644
--- a/storage/innobase/srv/srv0mon.cc
+++ b/storage/innobase/srv/srv0mon.cc
@@ -1424,8 +1424,8 @@ monitor_value_t innodb_counter_value[NUM_MONITOR];
/* monitor_set_tbl is used to record and determine whether a monitor
has been turned on/off. */
-ulint monitor_set_tbl[(NUM_MONITOR + NUM_BITS_ULINT
- - 1) / NUM_BITS_ULINT];
+Atomic_relaxed<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