diff options
Diffstat (limited to 'storage/innobase/include/ut0counter.h')
-rw-r--r-- | storage/innobase/include/ut0counter.h | 102 |
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 */ |