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.h102
1 files changed, 54 insertions, 48 deletions
diff --git a/storage/innobase/include/ut0counter.h b/storage/innobase/include/ut0counter.h
index 447484ba985..7c704988139 100644
--- a/storage/innobase/include/ut0counter.h
+++ b/storage/innobase/include/ut0counter.h
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 2012, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2012, 2015, Oracle and/or its affiliates. All Rights Reserved.
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
@@ -24,11 +24,11 @@ Counter utility class
Created 2012/04/12 by Sunny Bains
*******************************************************/
-#ifndef UT0COUNTER_H
-#define UT0COUNTER_H
+#ifndef ut0counter_h
+#define ut0counter_h
+#include <my_rdtsc.h>
#include "univ.i"
-#include <string.h>
#include "os0thread.h"
/** CPU cache line size */
@@ -40,7 +40,7 @@ Created 2012/04/12 by Sunny Bains
# endif /* CPU_LEVEL1_DCACHE_LINESIZE */
#else
# define CACHE_LINE_SIZE 64
-#endif /* UNIV_HOTBACKUP */
+#endif /* __powerpc__ */
/** Default number of slots to use in ib_counter_t */
#define IB_N_SLOTS 64
@@ -51,63 +51,67 @@ struct generic_indexer_t {
/** Default constructor/destructor should be OK. */
/** @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> {
- /** Default constructor/destructor should be OK. */
+/** 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 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();
- }
+ /** Default constructor/destructor should be OK. */
- return(cpu);
- }
-};
-#endif /* HAVE_SCHED_GETCPU */
+ enum { fast = 1 };
-/** 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> {
- /** Default constructor/destructor should are OK. */
+ /** @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 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(static_cast<size_t>(cnt.QuadPart));
+#endif /* !_WIN32 */
+ }
}
};
-/** For counters wher N=1 */
-template <typename Type, int N=1>
+/** For counters where N=1 */
+template <typename Type=ulint, int N=1>
struct single_indexer_t {
/** Default constructor/destructor should are OK. */
+ enum { fast = 0 };
+
/** @return offset within m_counter */
- size_t offset(size_t index) const UNIV_NOTHROW {
+ static size_t offset(size_t index) UNIV_NOTHROW
+ {
ut_ad(N == 1);
return((CACHE_LINE_SIZE / sizeof(Type)));
}
- /* @return 1 */
- size_t get_rnd_index() const UNIV_NOTHROW {
+ /** @return 1 */
+ static size_t get_rnd_index() UNIV_NOTHROW
+ {
ut_ad(N == 1);
return(1);
}
};
+#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
enough. Creates an array of counters and separates each element by the
@@ -115,7 +119,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>
class ib_counter_t {
public:
ib_counter_t() { memset(m_counter, 0x0, sizeof(m_counter)); }
@@ -125,6 +129,8 @@ public:
ut_ad(validate());
}
+ static bool is_fast() { return(Indexer<Type, N>::fast); }
+
bool validate() UNIV_NOTHROW {
#ifdef UNIV_DEBUG
size_t n = (CACHE_LINE_SIZE / sizeof(Type));
@@ -143,7 +149,7 @@ public:
void inc() UNIV_NOTHROW { add(1); }
/** If you can't use a good index id.
- * @param n - is the amount to increment */
+ @param n is the amount to increment */
void add(Type n) UNIV_NOTHROW {
size_t i = m_policy.offset(m_policy.get_rnd_index());
@@ -152,10 +158,10 @@ public:
m_counter[i] += n;
}
- /** Use this if you can use a unique indentifier, saves a
+ /** Use this if you can use a unique identifier, saves a
call to get_rnd_index().
- @param i - index into a slot
- @param n - amount to increment */
+ @param i index into a slot
+ @param n amount to increment */
void add(size_t index, Type n) UNIV_NOTHROW {
size_t i = m_policy.offset(index);
@@ -168,7 +174,7 @@ public:
void dec() UNIV_NOTHROW { sub(1); }
/** If you can't use a good index id.
- * @param - n is the amount to decrement */
+ @param n the amount to decrement */
void sub(Type n) UNIV_NOTHROW {
size_t i = m_policy.offset(m_policy.get_rnd_index());
@@ -177,10 +183,10 @@ public:
m_counter[i] -= n;
}
- /** Use this if you can use a unique indentifier, saves a
+ /** Use this if you can use a unique identifier, saves a
call to get_rnd_index().
- @param i - index into a slot
- @param n - amount to decrement */
+ @param i index into a slot
+ @param n amount to decrement */
void sub(size_t index, Type n) UNIV_NOTHROW {
size_t i = m_policy.offset(index);
@@ -208,4 +214,4 @@ private:
Type m_counter[(N + 1) * (CACHE_LINE_SIZE / sizeof(Type))];
};
-#endif /* UT0COUNTER_H */
+#endif /* ut0counter_h */