Add Flip method to flip boolean value

This commit is contained in:
barryz 2018-09-07 22:17:26 +08:00
parent 9b9efcf221
commit ae078ebcf7
3 changed files with 49 additions and 1 deletions

View File

@ -18,6 +18,7 @@ cond.IsSet() // Returns true
cond.UnSet() // Set to false cond.UnSet() // Set to false
cond.SetTo(true) // Set to whatever you want cond.SetTo(true) // Set to whatever you want
cond.SetToIf(false, true) // Set to true if it is false, returns false(not set) cond.SetToIf(false, true) // Set to true if it is false, returns false(not set)
cond.Flip() // Flip the boolean value, true to false, or false to ture
// embedding // embedding
@ -45,5 +46,9 @@ BenchmarkAtomicBoolWrite-4 200000000 9.87 ns/op # <--- This package
# CAS # CAS
BenchmarkMutexCAS-4 30000000 44.9 ns/op BenchmarkMutexCAS-4 30000000 44.9 ns/op
BenchmarkAtomicBoolCAS-4 100000000 11.7 ns/op # <--- This package BenchmarkAtomicBoolCAS-4 100000000 11.7 ns/op # <--- This package
# Flip
BenchmarkMutexFlip-4 50000000 29.7 ns/op
BenchmarkAtomicBoolFlip-4 200000000 8.65 ns/op # <--- This package
``` ```

View File

@ -49,6 +49,11 @@ func (ab *AtomicBool) SetTo(yes bool) {
} }
} }
// Flip flips the boolean value whether the value is set or not
func (ab *AtomicBool) Flip() {
atomic.StoreInt32((*int32)(ab), atomic.LoadInt32((*int32)(ab))^1)
}
// SetToIf sets the Boolean to new only if the Boolean matches the old // SetToIf sets the Boolean to new only if the Boolean matches the old
// Returns whether the set was done // Returns whether the set was done
func (ab *AtomicBool) SetToIf(old, new bool) (set bool) { func (ab *AtomicBool) SetToIf(old, new bool) (set bool) {

View File

@ -49,12 +49,18 @@ func TestBool(t *testing.T) {
if set := v.SetToIf(false, true); !set || !v.IsSet() { if set := v.SetToIf(false, true); !set || !v.IsSet() {
t.Fatal("AtomicBool.SetTo(false, true) failed") t.Fatal("AtomicBool.SetTo(false, true) failed")
} }
v.Flip() // expected false
if v.IsSet() {
t.Fatal("AtomicBool.Flip() failed")
}
} }
func TestRace(t *testing.T) { func TestRace(t *testing.T) {
repeat := 10000 repeat := 10000
var wg sync.WaitGroup var wg sync.WaitGroup
wg.Add(repeat * 3) wg.Add(repeat * 4)
v := New() v := New()
// Writer // Writer
@ -80,6 +86,15 @@ func TestRace(t *testing.T) {
wg.Done() wg.Done()
} }
}() }()
// Reader And Writer
go func() {
for i := 0; i < repeat; i++ {
v.Flip()
wg.Done()
}
}()
wg.Wait() wg.Wait()
} }
@ -89,6 +104,7 @@ func ExampleAtomicBool() {
cond.IsSet() // returns true cond.IsSet() // returns true
cond.UnSet() // set to false cond.UnSet() // set to false
cond.SetTo(true) // set to whatever you want cond.SetTo(true) // set to whatever you want
cond.Flip() // flips the boolean value
} }
// Benchmark Read // Benchmark Read
@ -174,3 +190,25 @@ func BenchmarkAtomicBoolCAS(b *testing.B) {
v.SetToIf(false, true) v.SetToIf(false, true)
} }
} }
// Benchmark flip boolean value
func BenchmarkMutexFlip(b *testing.B) {
var m sync.RWMutex
var v bool
b.ResetTimer()
for i := 0; i < b.N; i++ {
m.Lock()
v = !v
m.Unlock()
}
b.StopTimer()
}
func BenchmarkAtomicBoolFlip(b *testing.B) {
v := New()
b.ResetTimer()
for i := 0; i < b.N; i++ {
v.Flip()
}
}