cachelib/common/AtomicCounter.h (54 lines of code) (raw):
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <atomic>
#include <cstdint>
#include "cachelib/common/FastStats.h"
namespace facebook {
namespace cachelib {
// Atomic counter for statistics using std::atomic
class AtomicCounter {
public:
AtomicCounter() = default;
explicit AtomicCounter(uint64_t init) : val_{init} {}
~AtomicCounter() = default;
AtomicCounter(const AtomicCounter& rhs)
: val_{rhs.val_.load(std::memory_order_relaxed)} {}
AtomicCounter& operator=(const AtomicCounter& rhs) {
val_ = rhs.val_.load(std::memory_order_relaxed);
return *this;
}
uint64_t get() const { return val_.load(std::memory_order_relaxed); }
void set(uint64_t n) { val_.store(n, std::memory_order_relaxed); }
uint64_t add_fetch(uint64_t n) {
return val_.fetch_add(n, std::memory_order_relaxed) + n;
}
void add(uint64_t n) { val_.fetch_add(n, std::memory_order_relaxed); }
uint64_t sub_fetch(uint64_t n) {
return val_.fetch_sub(n, std::memory_order_relaxed) - n;
}
void sub(uint64_t n) { val_.fetch_sub(n, std::memory_order_relaxed); }
void inc() { add(1); }
void dec() { sub(1); }
private:
std::atomic<uint64_t> val_{0};
};
// provides the same interface as the Counter, but uses a thread local
// approach. Does not provide atomic fetch_add and fetch_sub semantics.
class TLCounter {
public:
TLCounter() = default;
explicit TLCounter(uint64_t init) : val_{init} {}
~TLCounter() = default;
uint64_t get() const { return val_.getSnapshot(); }
void set(uint64_t n) { val_.tlStats() = n; }
uint64_t add_fetch(uint64_t) {
throw std::runtime_error("add_fetch not supported");
}
void add(uint64_t n) { val_.tlStats() += n; }
uint64_t sub_fetch(uint64_t) {
throw std::runtime_error("sub_fetch not supported");
}
void sub(uint64_t n) { val_.tlStats() -= n; }
void inc() { ++val_.tlStats(); }
void dec() { --val_.tlStats(); }
private:
util::FastStats<uint64_t> val_{};
};
} // namespace cachelib
} // namespace facebook