[metrics] Make metrics atomic am: c4adf54117
Original change: https://android-review.googlesource.com/c/platform/art/+/1446999
Change-Id: I1b5f488f54f83ee92ad131d86774733259f5c8c9
diff --git a/libartbase/base/metrics.h b/libartbase/base/metrics.h
index d4d00b9..51ea66f 100644
--- a/libartbase/base/metrics.h
+++ b/libartbase/base/metrics.h
@@ -20,6 +20,7 @@
#include <stdint.h>
#include <array>
+#include <atomic>
#include <ostream>
#include <string_view>
#include <vector>
@@ -135,13 +136,14 @@
static_assert(sizeof(*this) == sizeof(uint64_t));
}
- void AddOne() { value_++; }
- void Add(uint64_t value) { value_ += value; }
+ void AddOne() { Add(1u); }
+ void Add(uint64_t value) { value_.fetch_add(value, std::memory_order::memory_order_relaxed); }
- uint64_t Value() const { return value_; }
+ uint64_t Value() const { return value_.load(std::memory_order::memory_order_relaxed); }
private:
- uint64_t value_;
+ std::atomic<uint64_t> value_;
+ static_assert(std::atomic<uint64_t>::is_always_lock_free);
};
template <size_t num_buckets_, int64_t minimum_value_, int64_t maximum_value_>
@@ -157,11 +159,14 @@
void Add(int64_t value) {
const size_t i = FindBucketId(value);
- buckets_[i]++;
+ buckets_[i].fetch_add(1u, std::memory_order::memory_order_relaxed);
}
protected:
std::vector<uint32_t> GetBuckets() const {
+ // The loads from buckets_ will all be memory_order_seq_cst, which means they will be acquire
+ // loads. This is a stricter memory order than is needed, but this should not be a
+ // performance-critical section of code.
return std::vector<uint32_t>{buckets_.begin(), buckets_.end()};
}
@@ -180,9 +185,10 @@
return static_cast<size_t>(value - minimum_value_) * num_buckets_ / bucket_width;
}
- std::array<uint32_t, num_buckets_> buckets_;
+ std::array<std::atomic<uint32_t>, num_buckets_> buckets_;
friend class ArtMetrics;
+ static_assert(std::atomic<uint32_t>::is_always_lock_free);
};
/**