From 3b8db5e93c4c02efbc313e17b2e796b0914a01fb Mon Sep 17 00:00:00 2001 From: Anton Tyurin Date: Thu, 15 Dec 2016 20:56:52 +0100 Subject: [PATCH] Implement Add/Sub for Float64 (#17) Signed-off-by: Anton Tiurin --- atomic.go | 16 ++++++++++++++++ atomic_test.go | 2 ++ stress_test.go | 2 ++ 3 files changed, 20 insertions(+) diff --git a/atomic.go b/atomic.go index 4e21010..cd4aaa2 100644 --- a/atomic.go +++ b/atomic.go @@ -278,6 +278,22 @@ func (f *Float64) Store(s float64) { atomic.StoreUint64(&f.v, math.Float64bits(s)) } +// Add atomically adds to the wrapped float64 and returns the new value. +func (f *Float64) Add(s float64) float64 { + for { + old := f.Load() + new := old + s + if f.CAS(old, new) { + return new + } + } +} + +// Sub atomically subtracts from the wrapped float64 and returns the new value. +func (f *Float64) Sub(s float64) float64 { + return f.Add(-s) +} + // CAS is an atomic compare-and-swap. func (f *Float64) CAS(old, new float64) bool { return atomic.CompareAndSwapUint64(&f.v, math.Float64bits(old), math.Float64bits(new)) diff --git a/atomic_test.go b/atomic_test.go index 5fef44a..c21b831 100644 --- a/atomic_test.go +++ b/atomic_test.go @@ -128,4 +128,6 @@ func TestFloat64(t *testing.T) { atom.Store(42.0) require.Equal(t, float64(42.0), atom.Load(), "Store didn't set the correct value.") + require.Equal(t, float64(42.5), atom.Add(0.5), "Add didn't work.") + require.Equal(t, float64(42.0), atom.Sub(0.5), "Sub didn't work.") } diff --git a/stress_test.go b/stress_test.go index a030a4a..4cf1e16 100644 --- a/stress_test.go +++ b/stress_test.go @@ -110,6 +110,8 @@ func TestStressFloat64(t *testing.T) { runStress(func() { atom.Load() atom.CAS(1.0, 0.1) + atom.Add(1.1) + atom.Sub(0.2) atom.Store(1.0) }) }