1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
7 #include "rocksdb/statistics.h"
13 #include "monitoring/histogram.h"
14 #include "port/likely.h"
15 #include "port/port.h"
16 #include "util/core_local.h"
17 #include "util/mutexlock.h"
20 #define ROCKSDB_FIELD_UNUSED __attribute__((__unused__))
22 #define ROCKSDB_FIELD_UNUSED
26 #define STRINGIFY(x) #x
27 #define TOSTRING(x) STRINGIFY(x)
32 enum TickersInternal
: uint32_t {
33 INTERNAL_TICKER_ENUM_START
= TICKER_ENUM_MAX
,
34 INTERNAL_TICKER_ENUM_MAX
37 enum HistogramsInternal
: uint32_t {
38 INTERNAL_HISTOGRAM_START
= HISTOGRAM_ENUM_MAX
,
39 INTERNAL_HISTOGRAM_ENUM_MAX
42 class StatisticsImpl
: public Statistics
{
44 StatisticsImpl(std::shared_ptr
<Statistics
> stats
,
45 bool enable_internal_stats
);
46 virtual ~StatisticsImpl();
48 virtual uint64_t getTickerCount(uint32_t ticker_type
) const override
;
49 virtual void histogramData(uint32_t histogram_type
,
50 HistogramData
* const data
) const override
;
51 std::string
getHistogramString(uint32_t histogram_type
) const override
;
53 virtual void setTickerCount(uint32_t ticker_type
, uint64_t count
) override
;
54 virtual uint64_t getAndResetTickerCount(uint32_t ticker_type
) override
;
55 virtual void recordTick(uint32_t ticker_type
, uint64_t count
) override
;
56 virtual void measureTime(uint32_t histogram_type
, uint64_t value
) override
;
58 virtual Status
Reset() override
;
59 virtual std::string
ToString() const override
;
60 virtual bool HistEnabledForType(uint32_t type
) const override
;
63 // If non-nullptr, forwards updates to the object pointed to by `stats_`.
64 std::shared_ptr
<Statistics
> stats_
;
65 // TODO(ajkr): clean this up since there are no internal stats anymore
66 bool enable_internal_stats_
;
67 // Synchronizes anything that operates across other cores' local data,
68 // such that operations like Reset() can be performed atomically.
69 mutable port::Mutex aggregate_lock_
;
71 // The ticker/histogram data are stored in this structure, which we will store
72 // per-core. It is cache-aligned, so tickers/histograms belonging to different
73 // cores can never share the same cache line.
75 // Alignment attributes expand to nothing depending on the platform
76 struct ALIGN_AS(CACHE_LINE_SIZE
) StatisticsData
{
77 std::atomic_uint_fast64_t tickers_
[INTERNAL_TICKER_ENUM_MAX
] = {{0}};
78 HistogramImpl histograms_
[INTERNAL_HISTOGRAM_ENUM_MAX
];
79 #ifndef HAVE_ALIGNED_NEW
81 padding
[(CACHE_LINE_SIZE
-
82 (INTERNAL_TICKER_ENUM_MAX
* sizeof(std::atomic_uint_fast64_t
) +
83 INTERNAL_HISTOGRAM_ENUM_MAX
* sizeof(HistogramImpl
)) %
84 CACHE_LINE_SIZE
)] ROCKSDB_FIELD_UNUSED
;
86 void *operator new(size_t s
) { return port::cacheline_aligned_alloc(s
); }
87 void *operator new[](size_t s
) { return port::cacheline_aligned_alloc(s
); }
88 void operator delete(void *p
) { port::cacheline_aligned_free(p
); }
89 void operator delete[](void *p
) { port::cacheline_aligned_free(p
); }
92 static_assert(sizeof(StatisticsData
) % CACHE_LINE_SIZE
== 0, "Expected " TOSTRING(CACHE_LINE_SIZE
) "-byte aligned");
94 CoreLocalArray
<StatisticsData
> per_core_stats_
;
96 uint64_t getTickerCountLocked(uint32_t ticker_type
) const;
97 std::unique_ptr
<HistogramImpl
> getHistogramImplLocked(
98 uint32_t histogram_type
) const;
99 void setTickerCountLocked(uint32_t ticker_type
, uint64_t count
);
103 inline void MeasureTime(Statistics
* statistics
, uint32_t histogram_type
,
106 statistics
->measureTime(histogram_type
, value
);
110 inline void RecordTick(Statistics
* statistics
, uint32_t ticker_type
,
111 uint64_t count
= 1) {
113 statistics
->recordTick(ticker_type
, count
);
117 inline void SetTickerCount(Statistics
* statistics
, uint32_t ticker_type
,
120 statistics
->setTickerCount(ticker_type
, count
);