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.h78
1 files changed, 41 insertions, 37 deletions
diff --git a/storage/innobase/include/ut0counter.h b/storage/innobase/include/ut0counter.h
index d2a6c1eb3e3..a04a674751c 100644
--- a/storage/innobase/include/ut0counter.h
+++ b/storage/innobase/include/ut0counter.h
@@ -1,7 +1,7 @@
/*****************************************************************************
-Copyright (c) 2012, Oracle and/or its affiliates. All Rights Reserved.
-Copyright (c) 2017, MariaDB Corporation.
+Copyright (c) 2012, 2015, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, 2018, 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
@@ -25,15 +25,20 @@ Counter utility class
Created 2012/04/12 by Sunny Bains
*******************************************************/
-#ifndef UT0COUNTER_H
-#define UT0COUNTER_H
+#ifndef ut0counter_h
+#define ut0counter_h
-#include "univ.i"
-#include <string.h>
#include "os0thread.h"
-#include "os0sync.h"
+#include "my_rdtsc.h"
#include "my_atomic.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
@@ -41,47 +46,46 @@ Created 2012/04/12 by Sunny Bains
template <typename Type, int N>
struct generic_indexer_t {
/** @return offset within m_counter */
- size_t offset(size_t index) const UNIV_NOTHROW {
+ static size_t offset(size_t index) UNIV_NOTHROW
+ {
return(((index % N) + 1) * (CACHE_LINE_SIZE / sizeof(Type)));
}
};
-#ifdef HAVE_SCHED_GETCPU
-#include <utmpx.h>
-/** Use the cpu id to index into the counter array. If it fails then
-use the thread id. */
-template <typename Type, int N>
-struct get_sched_indexer_t : public generic_indexer_t<Type, N> {
- /* @return result from sched_getcpu(), the thread id if it fails. */
- size_t get_rnd_index() const UNIV_NOTHROW {
-
- size_t cpu = sched_getcpu();
- if (cpu == -1) {
- cpu = (lint) os_thread_get_curr_id();
+/** Use the result of my_timer_cycles(), which mainly uses RDTSC for cycles,
+to index into the counter array. See the comments for my_timer_cycles() */
+template <typename Type=ulint, int N=1>
+struct counter_indexer_t : public generic_indexer_t<Type, N> {
+ /** @return result from RDTSC or similar functions. */
+ static size_t get_rnd_index() UNIV_NOTHROW
+ {
+ size_t c = static_cast<size_t>(my_timer_cycles());
+
+ if (c != 0) {
+ return(c);
+ } else {
+ /* 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()));
+#else
+ LARGE_INTEGER cnt;
+ QueryPerformanceCounter(&cnt);
+
+ return(static_cast<size_t>(cnt.QuadPart));
+#endif /* !_WIN32 */
}
-
- return(cpu);
- }
-};
-#endif /* HAVE_SCHED_GETCPU */
-
-/** Use the thread id to index into the counter array. */
-template <typename Type, int N>
-struct thread_id_indexer_t : public generic_indexer_t<Type, N> {
- /* @return a random number, currently we use the thread id. Where
- thread id is represented as a pointer, it may not work as
- effectively. */
- size_t get_rnd_index() const UNIV_NOTHROW {
- return((lint) os_thread_get_curr_id());
}
/** @return a random offset to the array */
- size_t get_rnd_offset() const UNIV_NOTHROW
+ static size_t get_rnd_offset() UNIV_NOTHROW
{
return(generic_indexer_t<Type, N>::offset(get_rnd_index()));
}
};
+#define default_indexer_t counter_indexer_t
+
/** 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
@@ -89,7 +93,7 @@ CACHE_LINE_SIZE bytes */
template <
typename Type,
int N = IB_N_SLOTS,
- template<typename, int> class Indexer = thread_id_indexer_t>
+ template<typename, int> class Indexer = default_indexer_t>
struct MY_ALIGNED(CACHE_LINE_SIZE) ib_counter_t
{
/** Increment the counter by 1. */
@@ -154,4 +158,4 @@ private:
Type m_counter[(N + 1) * (CACHE_LINE_SIZE / sizeof(Type))];
};
-#endif /* UT0COUNTER_H */
+#endif /* ut0counter_h */