Commit 5e685567 authored by mlippautz's avatar mlippautz Committed by Commit bot

[base] Add Decrement and assignment operators to AtomicNumber

AtomicNumber should make dealing with atomic counters easier. This is not the
case with size_t, as we cannot properly use the Increment() method for negative
numbers.

With this CL we can use AtomicNumber<size_t> and have proper decrements.

R=jochen@chromium.org

Review-Url: https://codereview.chromium.org/2215693002
Cr-Commit-Position: refs/heads/master@{#38407}
parent 6cebf7d9
...@@ -19,12 +19,18 @@ class AtomicNumber { ...@@ -19,12 +19,18 @@ class AtomicNumber {
AtomicNumber() : value_(0) {} AtomicNumber() : value_(0) {}
explicit AtomicNumber(T initial) : value_(initial) {} explicit AtomicNumber(T initial) : value_(initial) {}
// Returns the newly set value. // Returns the value after incrementing.
V8_INLINE T Increment(T increment) { V8_INLINE T Increment(T increment) {
return static_cast<T>(base::Barrier_AtomicIncrement( return static_cast<T>(base::Barrier_AtomicIncrement(
&value_, static_cast<base::AtomicWord>(increment))); &value_, static_cast<base::AtomicWord>(increment)));
} }
// Returns the value after decrementing.
V8_INLINE T Decrement(T decrement) {
return static_cast<T>(base::Barrier_AtomicIncrement(
&value_, -static_cast<base::AtomicWord>(decrement)));
}
V8_INLINE T Value() { return static_cast<T>(base::Acquire_Load(&value_)); } V8_INLINE T Value() { return static_cast<T>(base::Acquire_Load(&value_)); }
V8_INLINE void SetValue(T new_value) { V8_INLINE void SetValue(T new_value) {
...@@ -36,6 +42,9 @@ class AtomicNumber { ...@@ -36,6 +42,9 @@ class AtomicNumber {
return value; return value;
} }
V8_INLINE T operator+=(T value) { return Increment(value); }
V8_INLINE T operator-=(T value) { return Decrement(value); }
private: private:
STATIC_ASSERT(sizeof(T) <= sizeof(base::AtomicWord)); STATIC_ASSERT(sizeof(T) <= sizeof(base::AtomicWord));
......
...@@ -58,6 +58,29 @@ TEST(AtomicNumber, Increment) { ...@@ -58,6 +58,29 @@ TEST(AtomicNumber, Increment) {
EXPECT_EQ(std::numeric_limits<size_t>::max(), c.Value()); EXPECT_EQ(std::numeric_limits<size_t>::max(), c.Value());
} }
TEST(AtomicNumber, Decrement) {
AtomicNumber<size_t> a(std::numeric_limits<size_t>::max());
a.Increment(1);
EXPECT_EQ(0, a.Value());
a.Decrement(1);
EXPECT_EQ(std::numeric_limits<size_t>::max(), a.Value());
}
TEST(AtomicNumber, OperatorAdditionAssignment) {
AtomicNumber<size_t> a(0u);
AtomicNumber<size_t> b(std::numeric_limits<size_t>::max());
a += b.Value();
EXPECT_EQ(a.Value(), b.Value());
EXPECT_EQ(b.Value(), std::numeric_limits<size_t>::max());
}
TEST(AtomicNumber, OperatorSubtractionAssignment) {
AtomicNumber<size_t> a(std::numeric_limits<size_t>::max());
AtomicNumber<size_t> b(std::numeric_limits<size_t>::max());
a -= b.Value();
EXPECT_EQ(a.Value(), 0u);
EXPECT_EQ(b.Value(), std::numeric_limits<size_t>::max());
}
namespace { namespace {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment