forked from OSchip/llvm-project
Switch statistics to use relaxed updates to a std::atomic.
This removes usage of the hacky, incorrect, and TSan-unfriendly home-grown atomics. It should actually be more efficient in some cases. Based on our existing usage of <atomic>, all of this is portably available AFAICT. One small challenge is initializing the stastic, but I've tried a comparable sample out on MSVC (the most likely to complain here) and it seems to work. Will have to watch the build bots of course. llvm-svn: 271504
This commit is contained in:
parent
a30f684a67
commit
7ae684a8b4
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include "llvm/Support/Atomic.h"
|
#include "llvm/Support/Atomic.h"
|
||||||
#include "llvm/Support/Compiler.h"
|
#include "llvm/Support/Compiler.h"
|
||||||
|
#include <atomic>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
@ -38,10 +39,10 @@ class Statistic {
|
||||||
public:
|
public:
|
||||||
const char *Name;
|
const char *Name;
|
||||||
const char *Desc;
|
const char *Desc;
|
||||||
volatile llvm::sys::cas_flag Value;
|
std::atomic<unsigned> Value;
|
||||||
bool Initialized;
|
bool Initialized;
|
||||||
|
|
||||||
llvm::sys::cas_flag getValue() const { return Value; }
|
unsigned getValue() const { return Value.load(std::memory_order_relaxed); }
|
||||||
const char *getName() const { return Name; }
|
const char *getName() const { return Name; }
|
||||||
const char *getDesc() const { return Desc; }
|
const char *getDesc() const { return Desc; }
|
||||||
|
|
||||||
|
@ -52,51 +53,45 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Allow use of this class as the value itself.
|
// Allow use of this class as the value itself.
|
||||||
operator unsigned() const { return Value; }
|
operator unsigned() const { return getValue(); }
|
||||||
|
|
||||||
#if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
|
#if !defined(NDEBUG) || defined(LLVM_ENABLE_STATS)
|
||||||
const Statistic &operator=(unsigned Val) {
|
const Statistic &operator=(unsigned Val) {
|
||||||
Value = Val;
|
Value.store(Val, std::memory_order_relaxed);
|
||||||
return init();
|
return init();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Statistic &operator++() {
|
const Statistic &operator++() {
|
||||||
// FIXME: This function and all those that follow carefully use an
|
Value.fetch_add(1, std::memory_order_relaxed);
|
||||||
// atomic operation to update the value safely in the presence of
|
|
||||||
// concurrent accesses, but not to read the return value, so the
|
|
||||||
// return value is not thread safe.
|
|
||||||
sys::AtomicIncrement(&Value);
|
|
||||||
return init();
|
return init();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned operator++(int) {
|
unsigned operator++(int) {
|
||||||
init();
|
init();
|
||||||
unsigned OldValue = Value;
|
return Value.fetch_add(1, std::memory_order_relaxed);
|
||||||
sys::AtomicIncrement(&Value);
|
|
||||||
return OldValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Statistic &operator--() {
|
const Statistic &operator--() {
|
||||||
sys::AtomicDecrement(&Value);
|
Value.fetch_sub(1, std::memory_order_relaxed);
|
||||||
return init();
|
return init();
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned operator--(int) {
|
unsigned operator--(int) {
|
||||||
init();
|
init();
|
||||||
unsigned OldValue = Value;
|
return Value.fetch_sub(1, std::memory_order_relaxed);
|
||||||
sys::AtomicDecrement(&Value);
|
|
||||||
return OldValue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const Statistic &operator+=(const unsigned &V) {
|
const Statistic &operator+=(unsigned V) {
|
||||||
if (!V) return *this;
|
if (V == 0)
|
||||||
sys::AtomicAdd(&Value, V);
|
return *this;
|
||||||
|
Value.fetch_add(V, std::memory_order_relaxed);
|
||||||
return init();
|
return init();
|
||||||
}
|
}
|
||||||
|
|
||||||
const Statistic &operator-=(const unsigned &V) {
|
const Statistic &operator-=(unsigned V) {
|
||||||
if (!V) return *this;
|
if (V == 0)
|
||||||
sys::AtomicAdd(&Value, -V);
|
return *this;
|
||||||
|
Value.fetch_sub(V, std::memory_order_relaxed);
|
||||||
return init();
|
return init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,8 +140,8 @@ protected:
|
||||||
|
|
||||||
// STATISTIC - A macro to make definition of statistics really simple. This
|
// STATISTIC - A macro to make definition of statistics really simple. This
|
||||||
// automatically passes the DEBUG_TYPE of the file into the statistic.
|
// automatically passes the DEBUG_TYPE of the file into the statistic.
|
||||||
#define STATISTIC(VARNAME, DESC) \
|
#define STATISTIC(VARNAME, DESC) \
|
||||||
static llvm::Statistic VARNAME = { DEBUG_TYPE, DESC, 0, 0 }
|
static llvm::Statistic VARNAME = {DEBUG_TYPE, DESC, {0}, 0}
|
||||||
|
|
||||||
/// \brief Enable the collection and printing of statistics.
|
/// \brief Enable the collection and printing of statistics.
|
||||||
void EnableStatistics();
|
void EnableStatistics();
|
||||||
|
|
Loading…
Reference in New Issue