summaryrefslogtreecommitdiff
path: root/storage/innobase/include/ut0counter.h
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/include/ut0counter.h')
-rw-r--r--storage/innobase/include/ut0counter.h64
1 files changed, 31 insertions, 33 deletions
diff --git a/storage/innobase/include/ut0counter.h b/storage/innobase/include/ut0counter.h
index 646a5f367c2..d6589cc4fd3 100644
--- a/storage/innobase/include/ut0counter.h
+++ b/storage/innobase/include/ut0counter.h
@@ -1,7 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2015, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, 2019, MariaDB Corporation.
+Copyright (c) 2017, 2022, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -28,19 +28,9 @@ Created 2012/04/12 by Sunny Bains
#ifndef ut0counter_h
#define ut0counter_h
-#include "os0thread.h"
+#include "univ.i"
#include "my_rdtsc.h"
-/** CPU cache line size */
-#ifdef CPU_LEVEL1_DCACHE_LINESIZE
-# define CACHE_LINE_SIZE CPU_LEVEL1_DCACHE_LINESIZE
-#else
-# error CPU_LEVEL1_DCACHE_LINESIZE is undefined
-#endif /* CPU_LEVEL1_DCACHE_LINESIZE */
-
-/** Default number of slots to use in ib_counter_t */
-#define IB_N_SLOTS 64
-
/** Use the result of my_timer_cycles(), which mainly uses RDTSC for cycles
as a random value. See the comments for my_timer_cycles() */
/** @return result from RDTSC or similar functions. */
@@ -56,7 +46,7 @@ get_rnd_value()
/* We may go here if my_timer_cycles() returns 0,
so we have to have the plan B for the counter. */
#if !defined(_WIN32)
- return (size_t)os_thread_get_curr_id();
+ return (size_t)pthread_self();
#else
LARGE_INTEGER cnt;
QueryPerformanceCounter(&cnt);
@@ -65,14 +55,34 @@ get_rnd_value()
#endif /* !_WIN32 */
}
+/** Atomic which occupies whole CPU cache line.
+Note: We rely on the default constructor of std::atomic and
+do not explicitly initialize the contents. This works for us,
+because ib_counter_t is only intended for usage with global
+memory that is allocated from the .bss and thus guaranteed to
+be zero-initialized by the run-time environment.
+@see srv_stats */
+template <typename Type>
+struct ib_atomic_counter_element_t {
+ alignas(CPU_LEVEL1_DCACHE_LINESIZE) Atomic_relaxed<Type> value;
+};
+
+template <typename Type>
+struct ib_counter_element_t {
+ alignas(CPU_LEVEL1_DCACHE_LINESIZE) Type value;
+};
+
+
/** Class for using fuzzy counters. The counter is multi-instance 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 <typename Type, int N = IB_N_SLOTS>
+enough. */
+template <typename Type,
+ template <typename T> class Element = ib_atomic_counter_element_t,
+ int N = 128 >
struct ib_counter_t {
/** Increment the counter by 1. */
void inc() { add(1); }
+ ib_counter_t& operator++() { inc(); return *this; }
/** Increment the counter by 1.
@param[in] index a reasonably thread-unique identifier */
@@ -85,12 +95,12 @@ struct ib_counter_t {
/** Add to the counter.
@param[in] index a reasonably thread-unique identifier
@param[in] n amount to be added */
- void add(size_t index, Type n) {
+ TPOOL_SUPPRESS_TSAN void add(size_t index, Type n) {
index = index % N;
ut_ad(index < UT_ARR_SIZE(m_counter));
- m_counter[index].value.fetch_add(n, std::memory_order_relaxed);
+ m_counter[index].value += n;
}
/* @return total value - not 100% accurate, since it is relaxed atomic*/
@@ -98,28 +108,16 @@ struct ib_counter_t {
Type total = 0;
for (const auto &counter : m_counter) {
- total += counter.value.load(std::memory_order_relaxed);
+ total += counter.value;
}
return(total);
}
private:
- /** Atomic which occupies whole CPU cache line.
- Note: We rely on the default constructor of std::atomic and
- do not explicitly initialize the contents. This works for us,
- because ib_counter_t is only intended for usage with global
- memory that is allocated from the .bss and thus guaranteed to
- be zero-initialized by the run-time environment.
- @see srv_stats
- @see rw_lock_stats */
- struct ib_counter_element_t {
- MY_ALIGNED(CACHE_LINE_SIZE) std::atomic<Type> value;
- };
- static_assert(sizeof(ib_counter_element_t) == CACHE_LINE_SIZE, "");
-
+ static_assert(sizeof(Element<Type>) == CPU_LEVEL1_DCACHE_LINESIZE, "");
/** Array of counter elements */
- MY_ALIGNED(CACHE_LINE_SIZE) ib_counter_element_t m_counter[N];
+ alignas(CPU_LEVEL1_DCACHE_LINESIZE) Element<Type> m_counter[N];
};
#endif /* ut0counter_h */