Add a Sub method to atomics (#5)

* Add a Sub method to atomics

Fixes #3.

* Invert integer sign without multiplying
This commit is contained in:
Akshay Shah
2016-05-28 22:54:33 -07:00
parent be53a1df0f
commit 2051a605b9
3 changed files with 36 additions and 8 deletions

View File

@@ -42,6 +42,11 @@ func (i *Int32) Add(n int32) int32 {
return atomic.AddInt32(&i.int32, n)
}
// Sub atomically subtracts from the wrapped int32 and returns the new value.
func (i *Int32) Sub(n int32) int32 {
return atomic.AddInt32(&i.int32, -n)
}
// Inc atomically increments the wrapped int32 and returns the new value.
func (i *Int32) Inc() int32 {
return i.Add(1)
@@ -49,7 +54,7 @@ func (i *Int32) Inc() int32 {
// Dec atomically decrements the wrapped int32 and returns the new value.
func (i *Int32) Dec() int32 {
return i.Add(-1)
return i.Sub(1)
}
// CAS is an atomic compare-and-swap.
@@ -85,6 +90,11 @@ func (i *Int64) Add(n int64) int64 {
return atomic.AddInt64(&i.int64, n)
}
// Sub atomically subtracts from the wrapped int64 and returns the new value.
func (i *Int64) Sub(n int64) int64 {
return atomic.AddInt64(&i.int64, -n)
}
// Inc atomically increments the wrapped int64 and returns the new value.
func (i *Int64) Inc() int64 {
return i.Add(1)
@@ -92,7 +102,7 @@ func (i *Int64) Inc() int64 {
// Dec atomically decrements the wrapped int64 and returns the new value.
func (i *Int64) Dec() int64 {
return i.Add(-1)
return i.Sub(1)
}
// CAS is an atomic compare-and-swap.
@@ -128,6 +138,11 @@ func (i *Uint32) Add(n uint32) uint32 {
return atomic.AddUint32(&i.uint32, n)
}
// Sub atomically subtracts from the wrapped uint32 and returns the new value.
func (i *Uint32) Sub(n uint32) uint32 {
return atomic.AddUint32(&i.uint32, ^(n - 1))
}
// Inc atomically increments the wrapped uint32 and returns the new value.
func (i *Uint32) Inc() uint32 {
return i.Add(1)
@@ -135,7 +150,7 @@ func (i *Uint32) Inc() uint32 {
// Dec atomically decrements the wrapped int32 and returns the new value.
func (i *Uint32) Dec() uint32 {
return i.Add(^uint32(0))
return i.Sub(1)
}
// CAS is an atomic compare-and-swap.
@@ -171,6 +186,11 @@ func (i *Uint64) Add(n uint64) uint64 {
return atomic.AddUint64(&i.uint64, n)
}
// Sub atomically subtracts from the wrapped uint64 and returns the new value.
func (i *Uint64) Sub(n uint64) uint64 {
return atomic.AddUint64(&i.uint64, ^(n - 1))
}
// Inc atomically increments the wrapped uint64 and returns the new value.
func (i *Uint64) Inc() uint64 {
return i.Add(1)
@@ -178,7 +198,7 @@ func (i *Uint64) Inc() uint64 {
// Dec atomically decrements the wrapped uint64 and returns the new value.
func (i *Uint64) Dec() uint64 {
return i.Add(^uint64(0))
return i.Sub(1)
}
// CAS is an atomic compare-and-swap.

View File

@@ -30,7 +30,8 @@ func TestInt32(t *testing.T) {
atom := NewInt32(42)
require.Equal(t, int32(42), atom.Load(), "Load didn't work.")
require.Equal(t, int32(44), atom.Add(2), "Add didn't work.")
require.Equal(t, int32(46), atom.Add(4), "Add didn't work.")
require.Equal(t, int32(44), atom.Sub(2), "Sub didn't work.")
require.Equal(t, int32(45), atom.Inc(), "Inc didn't work.")
require.Equal(t, int32(44), atom.Dec(), "Dec didn't work.")
@@ -48,7 +49,8 @@ func TestInt64(t *testing.T) {
atom := NewInt64(42)
require.Equal(t, int64(42), atom.Load(), "Load didn't work.")
require.Equal(t, int64(44), atom.Add(2), "Add didn't work.")
require.Equal(t, int64(46), atom.Add(4), "Add didn't work.")
require.Equal(t, int64(44), atom.Sub(2), "Sub didn't work.")
require.Equal(t, int64(45), atom.Inc(), "Inc didn't work.")
require.Equal(t, int64(44), atom.Dec(), "Dec didn't work.")
@@ -66,7 +68,8 @@ func TestUint32(t *testing.T) {
atom := NewUint32(42)
require.Equal(t, uint32(42), atom.Load(), "Load didn't work.")
require.Equal(t, uint32(44), atom.Add(2), "Add didn't work.")
require.Equal(t, uint32(46), atom.Add(4), "Add didn't work.")
require.Equal(t, uint32(44), atom.Sub(2), "Sub didn't work.")
require.Equal(t, uint32(45), atom.Inc(), "Inc didn't work.")
require.Equal(t, uint32(44), atom.Dec(), "Dec didn't work.")
@@ -84,7 +87,8 @@ func TestUint64(t *testing.T) {
atom := NewUint64(42)
require.Equal(t, uint64(42), atom.Load(), "Load didn't work.")
require.Equal(t, uint64(44), atom.Add(2), "Add didn't work.")
require.Equal(t, uint64(46), atom.Add(4), "Add didn't work.")
require.Equal(t, uint64(44), atom.Sub(2), "Sub didn't work.")
require.Equal(t, uint64(45), atom.Inc(), "Inc didn't work.")
require.Equal(t, uint64(44), atom.Dec(), "Dec didn't work.")

View File

@@ -36,6 +36,7 @@ func TestStressInt32(t *testing.T) {
for j := 0; j < _iterations; j++ {
atom.Load()
atom.Add(1)
atom.Sub(2)
atom.Inc()
atom.Dec()
atom.CAS(1, 0)
@@ -54,6 +55,7 @@ func TestStressInt64(t *testing.T) {
for j := 0; j < _iterations; j++ {
atom.Load()
atom.Add(1)
atom.Sub(2)
atom.Inc()
atom.Dec()
atom.CAS(1, 0)
@@ -72,6 +74,7 @@ func TestStressUint32(t *testing.T) {
for j := 0; j < _iterations; j++ {
atom.Load()
atom.Add(1)
atom.Sub(2)
atom.Inc()
atom.Dec()
atom.CAS(1, 0)
@@ -90,6 +93,7 @@ func TestStressUint64(t *testing.T) {
for j := 0; j < _iterations; j++ {
atom.Load()
atom.Add(1)
atom.Sub(2)
atom.Inc()
atom.Dec()
atom.CAS(1, 0)