diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2018-10-11 08:16:08 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2018-10-11 08:16:08 +0300 |
commit | 07815d9555b099482f8877ec700bbc39d1d553dd (patch) | |
tree | 60df9098dabb0a465317135b9a6daabf4152d2e7 | |
parent | 940f0c78a4c45536ddede5aaeeebcf36bda53251 (diff) | |
parent | 3c3c4ae22545d3242a8b7c4f2bec3bf2d245890a (diff) | |
download | mariadb-git-07815d9555b099482f8877ec700bbc39d1d553dd.tar.gz |
Merge 10.1 into 10.2
-rw-r--r-- | include/my_pthread.h | 2 | ||||
-rw-r--r-- | mysql-test/suite/galera/disabled.def | 2 | ||||
-rw-r--r-- | mysql-test/suite/galera/r/galera_drop_database.result | 17 | ||||
-rw-r--r-- | mysql-test/suite/galera/r/galera_enum.result | 37 | ||||
-rw-r--r-- | mysql-test/suite/galera/r/galera_pc_ignore_sb.result | 7 | ||||
-rw-r--r-- | mysql-test/suite/galera/t/galera_drop_database.test | 65 | ||||
-rw-r--r-- | mysql-test/suite/galera/t/galera_enum.test | 18 | ||||
-rw-r--r-- | mysql-test/suite/galera/t/galera_pc_ignore_sb.test | 21 | ||||
-rw-r--r-- | mysql-test/suite/rpl/t/rpl_parallel_optimistic_nobinlog.cnf | 1 | ||||
-rw-r--r-- | mysql-test/suite/wsrep/t/variables.test | 2 | ||||
-rw-r--r-- | sql/mysqld.cc | 16 | ||||
-rw-r--r-- | sql/rpl_parallel.cc | 32 | ||||
-rw-r--r-- | storage/innobase/include/ut0counter.h | 46 | ||||
-rw-r--r-- | storage/xtradb/include/ut0counter.h | 46 |
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); |