forked from mirror/abool
Revert "Merge pull request #3 from barryz/add_flip_method"
Due to a regression to `SetToIf` introduced by `Toggle` This reverts commitd91eb651d5
, reversing changes made to9b9efcf221
.
This commit is contained in:
parent
9f5df6da9f
commit
fa0b8a912b
33
README.md
33
README.md
|
@ -20,7 +20,6 @@ cond.UnSet() // Sets to false
|
|||
cond.IsNotSet() // Returns true
|
||||
cond.SetTo(any) // Sets to whatever you want
|
||||
cond.SetToIf(new, old) // Sets to `new` only if the Boolean matches the `old`, returns whether succeeded
|
||||
cond.Toggle() // Inverts the boolean then returns the value before inverting
|
||||
|
||||
|
||||
// embedding
|
||||
|
@ -29,33 +28,27 @@ type Foo struct {
|
|||
}
|
||||
```
|
||||
|
||||
## Benchmark
|
||||
## Benchmark:
|
||||
|
||||
- Go 1.14.3
|
||||
- Linux 4.19.0
|
||||
- Go 1.6.2
|
||||
- OS X 10.11.4
|
||||
- Intel CPU (to be specified)
|
||||
|
||||
```bash
|
||||
goos: linux
|
||||
goarch: amd64
|
||||
|
||||
```
|
||||
# Read
|
||||
BenchmarkMutexRead-4 86662128 14.2 ns/op
|
||||
BenchmarkAtomicValueRead-4 1000000000 0.755 ns/op
|
||||
BenchmarkAtomicBoolRead-4 1000000000 0.720 ns/op # <--- This package
|
||||
|
||||
BenchmarkMutexRead-4 100000000 21.0 ns/op
|
||||
BenchmarkAtomicValueRead-4 200000000 6.30 ns/op
|
||||
BenchmarkAtomicBoolRead-4 300000000 4.21 ns/op # <--- This package
|
||||
|
||||
# Write
|
||||
BenchmarkMutexWrite-4 76237544 13.6 ns/op
|
||||
BenchmarkAtomicValueWrite-4 79471124 14.9 ns/op
|
||||
BenchmarkAtomicBoolWrite-4 178218270 6.73 ns/op # <--- This package
|
||||
BenchmarkMutexWrite-4 100000000 21.6 ns/op
|
||||
BenchmarkAtomicValueWrite-4 30000000 43.4 ns/op
|
||||
BenchmarkAtomicBoolWrite-4 200000000 9.87 ns/op # <--- This package
|
||||
|
||||
# CAS
|
||||
BenchmarkMutexCAS-4 29416574 34.7 ns/op
|
||||
BenchmarkAtomicBoolCAS-4 171900002 7.14 ns/op # <--- This package
|
||||
|
||||
# Toggle
|
||||
BenchmarkMutexToggle-4 35212117 34.5 ns/op
|
||||
BenchmarkAtomicBoolToggle-4 169871972 7.02 ns/op # <--- This package
|
||||
BenchmarkMutexCAS-4 30000000 44.9 ns/op
|
||||
BenchmarkAtomicBoolCAS-4 100000000 11.7 ns/op # <--- This package
|
||||
```
|
||||
|
||||
## Special thanks to contributors
|
||||
|
|
7
bool.go
7
bool.go
|
@ -38,7 +38,7 @@ func (ab *AtomicBool) UnSet() {
|
|||
|
||||
// IsSet returns whether the Boolean is true.
|
||||
func (ab *AtomicBool) IsSet() bool {
|
||||
return atomic.LoadInt32((*int32)(ab))&1 == 1
|
||||
return atomic.LoadInt32((*int32)(ab)) == 1
|
||||
}
|
||||
|
||||
// IsNotSet returns whether the Boolean is false.
|
||||
|
@ -55,11 +55,6 @@ func (ab *AtomicBool) SetTo(yes bool) {
|
|||
}
|
||||
}
|
||||
|
||||
// Toggle inverts the Boolean then returns the value before inverting.
|
||||
func (ab *AtomicBool) Toggle() bool {
|
||||
return atomic.AddInt32((*int32)(ab), 1)&1 == 0
|
||||
}
|
||||
|
||||
// SetToIf sets the Boolean to new only if the Boolean matches the old.
|
||||
// Returns whether the set was done.
|
||||
func (ab *AtomicBool) SetToIf(old, new bool) (set bool) {
|
||||
|
|
102
bool_test.go
102
bool_test.go
|
@ -2,7 +2,6 @@ package abool
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"math"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
"testing"
|
||||
|
@ -73,78 +72,10 @@ func TestSetTo(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestToggle(t *testing.T) {
|
||||
t.Parallel()
|
||||
v := New()
|
||||
|
||||
_ = v.Toggle()
|
||||
if !v.IsSet() {
|
||||
t.Fatal("AtomicBool.Toggle() to true failed")
|
||||
}
|
||||
|
||||
prev := v.Toggle()
|
||||
if v.IsSet() == prev {
|
||||
t.Fatal("AtomicBool.Toggle() to false failed")
|
||||
}
|
||||
}
|
||||
|
||||
func TestToogleMultipleTimes(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
v := New()
|
||||
pre := !v.IsSet()
|
||||
for i := 0; i < 100; i++ {
|
||||
v.SetTo(false)
|
||||
for j := 0; j < i; j++ {
|
||||
pre = v.Toggle()
|
||||
}
|
||||
|
||||
expected := i%2 != 0
|
||||
if v.IsSet() != expected {
|
||||
t.Fatalf("AtomicBool.Toogle() doesn't work after %d calls, expected: %v, got %v", i, expected, v.IsSet())
|
||||
}
|
||||
|
||||
if pre == v.IsSet() {
|
||||
t.Fatalf("AtomicBool.Toogle() returned wrong value at the %dth calls, expected: %v, got %v", i, !v.IsSet(), pre)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestToogleAfterOverflow(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
var value int32 = math.MaxInt32
|
||||
v := (*AtomicBool)(&value)
|
||||
|
||||
valueBeforeToggle := *(*int32)(v)
|
||||
|
||||
// test first toggle after overflow
|
||||
v.Toggle()
|
||||
expected := math.MaxInt32%2 == 0
|
||||
if v.IsSet() != expected {
|
||||
t.Fatalf("AtomicBool.Toogle() doesn't work after overflow, expected: %v, got %v", expected, v.IsSet())
|
||||
}
|
||||
|
||||
// make sure overflow happened
|
||||
var valueAfterToggle int32 = *(*int32)(v)
|
||||
if valueAfterToggle >= valueBeforeToggle {
|
||||
t.Fatalf("Overflow does not happen as expected, before %d, after: %d", valueBeforeToggle, valueAfterToggle)
|
||||
}
|
||||
|
||||
// test second toggle after overflow
|
||||
v.Toggle()
|
||||
expected = !expected
|
||||
if v.IsSet() != expected {
|
||||
t.Fatalf("AtomicBool.Toogle() doesn't work after the second call after overflow, expected: %v, got %v", expected, v.IsSet())
|
||||
}
|
||||
}
|
||||
|
||||
func TestRace(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
repeat := 10000
|
||||
var wg sync.WaitGroup
|
||||
wg.Add(repeat * 4)
|
||||
wg.Add(repeat * 3)
|
||||
v := New()
|
||||
|
||||
// Writer
|
||||
|
@ -170,15 +101,6 @@ func TestRace(t *testing.T) {
|
|||
wg.Done()
|
||||
}
|
||||
}()
|
||||
|
||||
// Reader And Writer
|
||||
go func() {
|
||||
for i := 0; i < repeat; i++ {
|
||||
v.Toggle()
|
||||
wg.Done()
|
||||
}
|
||||
}()
|
||||
|
||||
wg.Wait()
|
||||
}
|
||||
|
||||
|
@ -257,7 +179,6 @@ func ExampleAtomicBool() {
|
|||
cond.IsNotSet() // Returns true
|
||||
cond.SetTo(any) // Sets to whatever you want
|
||||
cond.SetToIf(new, old) // Sets to `new` only if the Boolean matches the `old`, returns whether succeeded
|
||||
cond.Toggle() // Inverts the boolean then returns the value before inverting
|
||||
}
|
||||
|
||||
// Benchmark Read
|
||||
|
@ -342,24 +263,3 @@ func BenchmarkAtomicBoolCAS(b *testing.B) {
|
|||
v.SetToIf(false, true)
|
||||
}
|
||||
}
|
||||
|
||||
// Benchmark toggle
|
||||
|
||||
func BenchmarkMutexToggle(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()
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkAtomicBoolToggle(b *testing.B) {
|
||||
v := New()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
v.Toggle()
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue