summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2018-10-11 08:16:08 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2018-10-11 08:16:08 +0300
commit07815d9555b099482f8877ec700bbc39d1d553dd (patch)
tree60df9098dabb0a465317135b9a6daabf4152d2e7
parent940f0c78a4c45536ddede5aaeeebcf36bda53251 (diff)
parent3c3c4ae22545d3242a8b7c4f2bec3bf2d245890a (diff)
downloadmariadb-git-07815d9555b099482f8877ec700bbc39d1d553dd.tar.gz
Merge 10.1 into 10.2
-rw-r--r--include/my_pthread.h2
-rw-r--r--mysql-test/suite/galera/disabled.def2
-rw-r--r--mysql-test/suite/galera/r/galera_drop_database.result17
-rw-r--r--mysql-test/suite/galera/r/galera_enum.result37
-rw-r--r--mysql-test/suite/galera/r/galera_pc_ignore_sb.result7
-rw-r--r--mysql-test/suite/galera/t/galera_drop_database.test65
-rw-r--r--mysql-test/suite/galera/t/galera_enum.test18
-rw-r--r--mysql-test/suite/galera/t/galera_pc_ignore_sb.test21
-rw-r--r--mysql-test/suite/rpl/t/rpl_parallel_optimistic_nobinlog.cnf1
-rw-r--r--mysql-test/suite/wsrep/t/variables.test2
-rw-r--r--sql/mysqld.cc16
-rw-r--r--sql/rpl_parallel.cc32
-rw-r--r--storage/innobase/include/ut0counter.h46
-rw-r--r--storage/xtradb/include/ut0counter.h46
14 files changed, 224 insertions, 88 deletions
diff --git a/include/my_pthread.h b/include/my_pthread.h
index 672bca5ab39..0504a5f3272 100644
--- a/include/my_pthread.h
+++ b/include/my_pthread.h
@@ -163,7 +163,7 @@ int pthread_cancel(pthread_t thread);
#define pthread_key(T,V) pthread_key_t V
#define my_pthread_getspecific_ptr(T,V) my_pthread_getspecific(T,(V))
#define my_pthread_setspecific_ptr(T,V) pthread_setspecific(T,(void*) (V))
-#define pthread_detach_this_thread() { pthread_t tmp=pthread_self() ; pthread_detach(tmp); }
+#define pthread_detach_this_thread()
#define pthread_handler_t EXTERNC void *
typedef void *(* pthread_handler)(void *);
diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def
index 1bdbb7a26a0..a8cb9bbafbf 100644
--- a/mysql-test/suite/galera/disabled.def
+++ b/mysql-test/suite/galera/disabled.def
@@ -41,3 +41,5 @@ galera_gc_fc_limit : MDEV-17061 Test failure on galera.galera_gc_fc_limit
partition : MDEV-13881 galera.partition failed in buildbot with wrong result
galera_as_slave_replication_budle : MDEV-15785 Test case galera_as_slave_replication_bundle caused debug assertion
galera_wan : MDEV-17259: Test failure on galera.galera_wan
+galera_pc_ignore_sb : MDEV-17357 Test failure on galera.galera_pc_ignore_sb
+galera_drop_database : test
diff --git a/mysql-test/suite/galera/r/galera_drop_database.result b/mysql-test/suite/galera/r/galera_drop_database.result
new file mode 100644
index 00000000000..79789da5a11
--- /dev/null
+++ b/mysql-test/suite/galera/r/galera_drop_database.result
@@ -0,0 +1,17 @@
+CREATE DATABASE fts;
+USE fts;
+CREATE TABLE fts_t1 (f1 INT PRIMARY KEY AUTO_INCREMENT, f2 VARCHAR(100), FULLTEXT (f2)) ENGINE=InnoDB;
+CREATE TABLE fts_t2 (f2 VARCHAR(100), FULLTEXT (f2)) ENGINE=InnoDB;
+CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB;
+INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+INSERT INTO fts_t1 (f2) SELECT 'foobarbaz' FROM ten AS a1, ten AS a2, ten AS a3;
+INSERT INTO fts_t2 (f2) SELECT 'foobarbaz' FROM ten AS a1, ten AS a2, ten AS a3;
+DROP TABLE ten;
+UPDATE fts_t1 SET f2 = 'abcd';
+UPDATE fts_t2 SET f2 = 'efjh';
+USE fts;
+DROP TABLE fts_t1;
+DROP TABLE fts_t2;
+SHOW TABLES;
+Tables_in_fts
+DROP DATABASE fts;
diff --git a/mysql-test/suite/galera/r/galera_enum.result b/mysql-test/suite/galera/r/galera_enum.result
index dcf31aa5948..a2a6317e2a0 100644
--- a/mysql-test/suite/galera/r/galera_enum.result
+++ b/mysql-test/suite/galera/r/galera_enum.result
@@ -6,25 +6,25 @@ INSERT IGNORE INTO t1 VALUES (0), (1), (2);
Warnings:
Warning 1265 Data truncated for column 'f1' at row 1
connection node_2;
-SELECT COUNT(*) = 6 FROM t1;
-COUNT(*) = 6
-1
-SELECT COUNT(*) = 2 FROM t1 where f1 = '';
-COUNT(*) = 2
-1
-SELECT COUNT(*) = 2 FROM t1 where f1 = 'one';
-COUNT(*) = 2
-1
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+6
+SELECT COUNT(*) FROM t1 where f1 = '';
+COUNT(*)
+2
+SELECT COUNT(*) FROM t1 where f1 = 'one';
+COUNT(*)
+2
DROP TABLE t1;
connection node_1;
CREATE TABLE t1 (f1 ENUM('', 'one', 'two', 'three', 'four') PRIMARY KEY) ENGINE=InnoDB;
INSERT INTO t1 VALUES (''), ('one'), ('two');
connection node_2;
-SELECT COUNT(*) = 3 FROM t1;
-COUNT(*) = 3
-1
-SELECT COUNT(*) = 1 FROM t1 WHERE f1 = '';
-COUNT(*) = 1
+SELECT COUNT(*) FROM t1;
+COUNT(*)
+3
+SELECT COUNT(*) FROM t1 WHERE f1 = '';
+COUNT(*)
1
connection node_1;
SET AUTOCOMMIT=OFF;
@@ -40,7 +40,12 @@ connection node_2;
COMMIT;
ERROR 40001: Deadlock: wsrep aborted transaction
connection node_1;
-SELECT COUNT(*) = 1 FROM t1 WHERE f1 = 'three';
-COUNT(*) = 1
+SELECT COUNT(*) FROM t1 WHERE f1 = 'three';
+COUNT(*)
1
+SELECT * FROM t1;
+f1
+one
+two
+three
DROP TABLE t1;
diff --git a/mysql-test/suite/galera/r/galera_pc_ignore_sb.result b/mysql-test/suite/galera/r/galera_pc_ignore_sb.result
index ee79d3c1f00..96ca12a9479 100644
--- a/mysql-test/suite/galera/r/galera_pc_ignore_sb.result
+++ b/mysql-test/suite/galera/r/galera_pc_ignore_sb.result
@@ -1,7 +1,9 @@
connection node_1;
connection node_2;
connection node_1;
-SET GLOBAL wsrep_provider_options = 'pc.ignore_sb=true';
+SET @wsrep_cluster_address_orig = @@GLOBAL.wsrep_cluster_address;
+SET @wsrep_provider_options_orig = @@GLOBAL.wsrep_provider_options;
+SET GLOBAL wsrep_provider_options ='pc.ignore_sb=true';
connection node_2;
Killing server ...
connection node_1;
@@ -15,6 +17,9 @@ SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABL
VARIABLE_VALUE = 'ON'
1
SET GLOBAL wsrep_cluster_address = '';
+SET GLOBAL wsrep_cluster_address = @wsrep_cluster_address_orig;
connection node_2;
+connection node_1;
+SET GLOBAL wsrep_provider_options = @wsrep_provider_options_orig;
disconnect node_2;
disconnect node_1;
diff --git a/mysql-test/suite/galera/t/galera_drop_database.test b/mysql-test/suite/galera/t/galera_drop_database.test
new file mode 100644
index 00000000000..47fe8315198
--- /dev/null
+++ b/mysql-test/suite/galera/t/galera_drop_database.test
@@ -0,0 +1,65 @@
+#
+# This test tests a DROP empty database
+#
+--source include/galera_cluster.inc
+--source include/have_innodb.inc
+
+# Save original auto_increment_offset values.
+--let $node_1=node_1
+--let $node_2=node_2
+--source include/auto_increment_offset_save.inc
+
+CREATE DATABASE fts;
+USE fts;
+CREATE TABLE fts_t1 (f1 INT PRIMARY KEY AUTO_INCREMENT, f2 VARCHAR(100), FULLTEXT (f2)) ENGINE=InnoDB;
+CREATE TABLE fts_t2 (f2 VARCHAR(100), FULLTEXT (f2)) ENGINE=InnoDB;
+
+# Insert 1K rows
+CREATE TABLE ten (f1 INTEGER) ENGINE=InnoDB;
+INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10);
+INSERT INTO fts_t1 (f2) SELECT 'foobarbaz' FROM ten AS a1, ten AS a2, ten AS a3;
+INSERT INTO fts_t2 (f2) SELECT 'foobarbaz' FROM ten AS a1, ten AS a2, ten AS a3;
+DROP TABLE ten;
+UPDATE fts_t1 SET f2 = 'abcd';
+UPDATE fts_t2 SET f2 = 'efjh';
+
+--connection node_2
+let $wsrep_cluster_address = `SELECT @@global.wsrep_node_incoming_address`;
+--source include/restart_mysqld.inc
+
+--connection node_1
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--let $galera_connection_name = node_2a
+--let $galera_server_number = 2
+--source include/galera_connect.inc
+--connection node_2a
+--source include/wait_until_ready.inc
+
+--connection node_1
+--let $restart_parameters = --wsrep-cluster-address=gcomm://$wsrep_cluster_address
+--source include/restart_mysqld.inc
+
+--connection node_2a
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
+--source include/wait_condition.inc
+
+--let $galera_connection_name = node_1a
+--let $galera_server_number = 1
+--source include/galera_connect.inc
+--connection node_1a
+--source include/wait_until_ready.inc
+
+USE fts;
+DROP TABLE fts_t1;
+DROP TABLE fts_t2;
+SHOW TABLES;
+DROP DATABASE fts;
+
+# Restore original auto_increment_offset values.
+--let $node_1=node_1a
+--let $node_2=node_2a
+--source include/auto_increment_offset_restore.inc
+
+--source include/galera_end.inc
diff --git a/mysql-test/suite/galera/t/galera_enum.test b/mysql-test/suite/galera/t/galera_enum.test
index 2497f717ef2..ecca615b2b2 100644
--- a/mysql-test/suite/galera/t/galera_enum.test
+++ b/mysql-test/suite/galera/t/galera_enum.test
@@ -17,9 +17,12 @@ INSERT INTO t1 VALUES ('one'), ('two');
INSERT IGNORE INTO t1 VALUES (0), (1), (2);
--connection node_2
-SELECT COUNT(*) = 6 FROM t1;
-SELECT COUNT(*) = 2 FROM t1 where f1 = '';
-SELECT COUNT(*) = 2 FROM t1 where f1 = 'one';
+--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t1';
+--source include/wait_condition.inc
+
+SELECT COUNT(*) FROM t1;
+SELECT COUNT(*) FROM t1 where f1 = '';
+SELECT COUNT(*) FROM t1 where f1 = 'one';
DROP TABLE t1;
@@ -33,8 +36,10 @@ CREATE TABLE t1 (f1 ENUM('', 'one', 'two', 'three', 'four') PRIMARY KEY) ENGINE=
INSERT INTO t1 VALUES (''), ('one'), ('two');
--connection node_2
-SELECT COUNT(*) = 3 FROM t1;
-SELECT COUNT(*) = 1 FROM t1 WHERE f1 = '';
+--let $wait_condition = SELECT COUNT(*) = 1 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t1';
+--source include/wait_condition.inc
+SELECT COUNT(*) FROM t1;
+SELECT COUNT(*) FROM t1 WHERE f1 = '';
# Conflict
@@ -57,6 +62,7 @@ COMMIT;
--connection node_1
-SELECT COUNT(*) = 1 FROM t1 WHERE f1 = 'three';
+SELECT COUNT(*) FROM t1 WHERE f1 = 'three';
+SELECT * FROM t1;
DROP TABLE t1;
diff --git a/mysql-test/suite/galera/t/galera_pc_ignore_sb.test b/mysql-test/suite/galera/t/galera_pc_ignore_sb.test
index f24ca5cd25b..c48ddc66bdf 100644
--- a/mysql-test/suite/galera/t/galera_pc_ignore_sb.test
+++ b/mysql-test/suite/galera/t/galera_pc_ignore_sb.test
@@ -11,10 +11,13 @@
--source include/auto_increment_offset_save.inc
--connection node_1
---let $wsrep_cluster_address_orig = `SELECT @@wsrep_cluster_address`
---let $wsrep_provider_options_orig = `SELECT @@wsrep_provider_options`
+SET @wsrep_cluster_address_orig = @@GLOBAL.wsrep_cluster_address;
+SET @wsrep_provider_options_orig = @@GLOBAL.wsrep_provider_options;
-SET GLOBAL wsrep_provider_options = 'pc.ignore_sb=true';
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'
+--source include/wait_condition.inc
+
+SET GLOBAL wsrep_provider_options ='pc.ignore_sb=true';
--connection node_2
--source include/kill_galera.inc
@@ -33,14 +36,18 @@ SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABL
# Reset the master and restart the slave so that post-test checks can run
SET GLOBAL wsrep_cluster_address = '';
---disable_query_log
---eval SET GLOBAL wsrep_cluster_address = '$wsrep_cluster_address_orig';
---eval SET GLOBAL wsrep_provider_options = '$wsrep_provider_options_orig';
---enable_query_log
+SET GLOBAL wsrep_cluster_address = @wsrep_cluster_address_orig;
--connection node_2
--source include/start_mysqld.inc
+
+--connection node_1
+--let $wait_condition = SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'
+--source include/wait_condition.inc
+
+SET GLOBAL wsrep_provider_options = @wsrep_provider_options_orig;
+
# Restore original auto_increment_offset values.
--source include/auto_increment_offset_restore.inc
diff --git a/mysql-test/suite/rpl/t/rpl_parallel_optimistic_nobinlog.cnf b/mysql-test/suite/rpl/t/rpl_parallel_optimistic_nobinlog.cnf
index 0ea0d951568..b85a84f6625 100644
--- a/mysql-test/suite/rpl/t/rpl_parallel_optimistic_nobinlog.cnf
+++ b/mysql-test/suite/rpl/t/rpl_parallel_optimistic_nobinlog.cnf
@@ -5,5 +5,6 @@ log-slave-updates=0
loose-innodb
[mysqld.2]
+slave-transaction-retries=100
log-slave-updates=0
loose-innodb
diff --git a/mysql-test/suite/wsrep/t/variables.test b/mysql-test/suite/wsrep/t/variables.test
index 15104b9b654..1a2ab2579a5 100644
--- a/mysql-test/suite/wsrep/t/variables.test
+++ b/mysql-test/suite/wsrep/t/variables.test
@@ -30,7 +30,7 @@ CALL mtr.add_suppression("WSREP: Could not open saved state file for reading.*")
--disable_result_log
--disable_query_log
eval SET GLOBAL wsrep_provider= '$WSREP_PROVIDER';
---let $galera_version=25.3.17
+--let $galera_version=25.3.24
source include/check_galera_version.inc;
--enable_result_log
--enable_query_log
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 784bfaa58b0..a79cf7eecde 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -4016,14 +4016,16 @@ static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific)
{
THD *thd= current_thd;
- if (is_thread_specific) /* If thread specific memory */
- {
- /*
- When thread specfic is set, both mysqld_server_initialized and thd
- must be set
- */
- DBUG_ASSERT(mysqld_server_initialized && thd);
+ /*
+ When thread specific is set, both mysqld_server_initialized and thd
+ must be set, and we check that with DBUG_ASSERT.
+ However, do not crash, if current_thd is NULL, in release version.
+ */
+ DBUG_ASSERT(!is_thread_specific || (mysqld_server_initialized && thd));
+
+ if (is_thread_specific && likely(thd)) /* If thread specific memory */
+ {
DBUG_PRINT("info", ("thd memory_used: %lld size: %lld",
(longlong) thd->status_var.local_memory_used,
size));
diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc
index 5d1e5418925..6340e4d7cc6 100644
--- a/sql/rpl_parallel.cc
+++ b/sql/rpl_parallel.cc
@@ -1659,21 +1659,31 @@ int rpl_parallel_resize_pool_if_no_slaves(void)
/**
- Resize pool if not active or busy (in which case we may be in
- resize to 0
+ Pool activation is preceeded by taking a "lock" of pool_mark_busy
+ which guarantees the number of running slaves drops to zero atomicly
+ with the number of pool workers.
+ This resolves race between the function caller thread and one
+ that may be attempting to deactivate the pool.
*/
-
int
rpl_parallel_activate_pool(rpl_parallel_thread_pool *pool)
{
- bool resize;
- mysql_mutex_lock(&pool->LOCK_rpl_thread_pool);
- resize= !pool->count || pool->busy;
- mysql_mutex_unlock(&pool->LOCK_rpl_thread_pool);
- if (resize)
- return rpl_parallel_change_thread_count(pool, opt_slave_parallel_threads,
- 0);
- return 0;
+ int rc= 0;
+
+ if ((rc= pool_mark_busy(pool, current_thd)))
+ return rc; // killed
+
+ if (!pool->count)
+ {
+ pool_mark_not_busy(pool);
+ rc= rpl_parallel_change_thread_count(pool, opt_slave_parallel_threads,
+ 0);
+ }
+ else
+ {
+ pool_mark_not_busy(pool);
+ }
+ return rc;
}
diff --git a/storage/innobase/include/ut0counter.h b/storage/innobase/include/ut0counter.h
index f1a9384667e..6e36f117fff 100644
--- a/storage/innobase/include/ut0counter.h
+++ b/storage/innobase/include/ut0counter.h
@@ -31,6 +31,7 @@ Created 2012/04/12 by Sunny Bains
#include <my_rdtsc.h>
#include "univ.i"
#include "os0thread.h"
+#include "my_atomic.h"
/** CPU cache line size */
#ifdef CPU_LEVEL1_DCACHE_LINESIZE
@@ -86,8 +87,8 @@ struct counter_indexer_t : public generic_indexer_t<Type, N> {
#define default_indexer_t counter_indexer_t
-/** Class for using fuzzy counters. The counter is not protected by any
-mutex and the results are not guaranteed to be 100% accurate but close
+/** Class for using fuzzy counters. The counter is relaxed atomic
+so the results are not guaranteed to be 100% accurate but close
enough. Creates an array of counters and separates each element by the
CACHE_LINE_SIZE bytes */
template <
@@ -96,20 +97,6 @@ template <
template<typename, int> class Indexer = default_indexer_t>
struct MY_ALIGNED(CACHE_LINE_SIZE) ib_counter_t
{
-#ifdef UNIV_DEBUG
- ~ib_counter_t()
- {
- size_t n = (CACHE_LINE_SIZE / sizeof(Type));
-
- /* Check that we aren't writing outside our defined bounds. */
- for (size_t i = 0; i < UT_ARR_SIZE(m_counter); i += n) {
- for (size_t j = 1; j < n - 1; ++j) {
- ut_ad(m_counter[i + j] == 0);
- }
- }
- }
-#endif /* UNIV_DEBUG */
-
/** Increment the counter by 1. */
void inc() UNIV_NOTHROW { add(1); }
@@ -129,15 +116,36 @@ struct MY_ALIGNED(CACHE_LINE_SIZE) ib_counter_t
ut_ad(i < UT_ARR_SIZE(m_counter));
- m_counter[i] += n;
+ if (sizeof(Type) == 8) {
+ my_atomic_add64_explicit(
+ reinterpret_cast<int64*>(&m_counter[i]),
+ static_cast<int64>(n), MY_MEMORY_ORDER_RELAXED);
+ } else if (sizeof(Type) == 4) {
+ my_atomic_add32_explicit(
+ reinterpret_cast<int32*>(&m_counter[i]),
+ static_cast<int32>(n), MY_MEMORY_ORDER_RELAXED);
+ }
+ compile_time_assert(sizeof(Type) == 8 || sizeof(Type) == 4);
}
- /* @return total value - not 100% accurate, since it is not atomic. */
+ /* @return total value - not 100% accurate, since it is relaxed atomic. */
operator Type() const UNIV_NOTHROW {
Type total = 0;
for (size_t i = 0; i < N; ++i) {
- total += m_counter[m_policy.offset(i)];
+ if (sizeof(Type) == 8) {
+ total += static_cast<
+ Type>(my_atomic_load64_explicit(
+ reinterpret_cast<int64*>(const_cast<Type*>(
+ &m_counter[m_policy.offset(i)])),
+ MY_MEMORY_ORDER_RELAXED));
+ } else if (sizeof(Type) == 4) {
+ total += static_cast<
+ Type>(my_atomic_load32_explicit(
+ reinterpret_cast<int32*>(const_cast<Type*>(
+ &m_counter[m_policy.offset(i)])),
+ MY_MEMORY_ORDER_RELAXED));
+ }
}
return(total);
diff --git a/storage/xtradb/include/ut0counter.h b/storage/xtradb/include/ut0counter.h
index 4f736428a17..8be0ec21ff8 100644
--- a/storage/xtradb/include/ut0counter.h
+++ b/storage/xtradb/include/ut0counter.h
@@ -31,6 +31,7 @@ Created 2012/04/12 by Sunny Bains
#include "univ.i"
#include <string.h>
#include "os0thread.h"
+#include "my_atomic.h"
/** CPU cache line size */
#ifndef UNIV_HOTBACKUP
@@ -91,8 +92,8 @@ struct thread_id_indexer_t : public generic_indexer_t<Type, N> {
}
};
-/** Class for using fuzzy counters. The counter is not protected by any
-mutex and the results are not guaranteed to be 100% accurate but close
+/** Class for using fuzzy counters. The counter is relaxed atomic
+so the results are not guaranteed to be 100% accurate but close
enough. Creates an array of counters and separates each element by the
CACHE_LINE_SIZE bytes */
template <
@@ -101,20 +102,6 @@ template <
template<typename, int> class Indexer = thread_id_indexer_t>
struct MY_ALIGNED(CACHE_LINE_SIZE) ib_counter_t
{
-#ifdef UNIV_DEBUG
- ~ib_counter_t()
- {
- size_t n = (CACHE_LINE_SIZE / sizeof(Type));
-
- /* Check that we aren't writing outside our defined bounds. */
- for (size_t i = 0; i < UT_ARR_SIZE(m_counter); i += n) {
- for (size_t j = 1; j < n - 1; ++j) {
- ut_ad(m_counter[i + j] == 0);
- }
- }
- }
-#endif /* UNIV_DEBUG */
-
/** Increment the counter by 1. */
void inc() UNIV_NOTHROW { add(1); }
@@ -134,15 +121,36 @@ struct MY_ALIGNED(CACHE_LINE_SIZE) ib_counter_t
ut_ad(i < UT_ARR_SIZE(m_counter));
- m_counter[i] += n;
+ if (sizeof(Type) == 8) {
+ my_atomic_add64_explicit(
+ reinterpret_cast<int64*>(&m_counter[i]),
+ static_cast<int64>(n), MY_MEMORY_ORDER_RELAXED);
+ } else if (sizeof(Type) == 4) {
+ my_atomic_add32_explicit(
+ reinterpret_cast<int32*>(&m_counter[i]),
+ static_cast<int32>(n), MY_MEMORY_ORDER_RELAXED);
+ }
+ compile_time_assert(sizeof(Type) == 8 || sizeof(Type) == 4);
}
- /* @return total value - not 100% accurate, since it is not atomic. */
+ /* @return total value - not 100% accurate, since it is relaxed atomic. */
operator Type() const UNIV_NOTHROW {
Type total = 0;
for (size_t i = 0; i < N; ++i) {
- total += m_counter[m_policy.offset(i)];
+ if (sizeof(Type) == 8) {
+ total += static_cast<
+ Type>(my_atomic_load64_explicit(
+ reinterpret_cast<int64*>(const_cast<Type*>(
+ &m_counter[m_policy.offset(i)])),
+ MY_MEMORY_ORDER_RELAXED));
+ } else if (sizeof(Type) == 4) {
+ total += static_cast<
+ Type>(my_atomic_load32_explicit(
+ reinterpret_cast<int32*>(const_cast<Type*>(
+ &m_counter[m_policy.offset(i)])),
+ MY_MEMORY_ORDER_RELAXED));
+ }
}
return(total);