Skip to content

Commit 7c013e0

Browse files
authored
Add atomic bool in util (alibaba#80)
* Add atomic bool in util
1 parent c0363c1 commit 7c013e0

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

util/atomic.go

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package util
2+
3+
import "sync/atomic"
4+
5+
func IncrementAndGetInt64(v *int64) int64 {
6+
old := int64(0)
7+
for {
8+
old = atomic.LoadInt64(v)
9+
if atomic.CompareAndSwapInt64(v, old, old+1) {
10+
break
11+
}
12+
}
13+
return old + 1
14+
}
15+
16+
type AtomicBool struct {
17+
// default 0, means false
18+
flag int32
19+
}
20+
21+
func (b *AtomicBool) CompareAndSet(old, new bool) bool {
22+
if old == new {
23+
return true
24+
}
25+
var oldInt, newInt int32
26+
if old {
27+
oldInt = 1
28+
}
29+
if new {
30+
newInt = 1
31+
}
32+
return atomic.CompareAndSwapInt32(&(b.flag), oldInt, newInt)
33+
}
34+
35+
func (b *AtomicBool) Set(value bool) {
36+
i := int32(0)
37+
if value {
38+
i = 1
39+
}
40+
atomic.StoreInt32(&(b.flag), int32(i))
41+
}
42+
43+
func (b *AtomicBool) Get() bool {
44+
if atomic.LoadInt32(&(b.flag)) != 0 {
45+
return true
46+
}
47+
return false
48+
}

util/atomic_test.go

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
package util
2+
3+
import (
4+
"fmt"
5+
"github.com/stretchr/testify/assert"
6+
"sync"
7+
"testing"
8+
)
9+
10+
func TestAtomicBool_CompareAndSet(t *testing.T) {
11+
b := &AtomicBool{}
12+
b.Set(true)
13+
ok := b.CompareAndSet(true, false)
14+
assert.True(t, ok, "CompareAndSet execute failed.")
15+
b.Set(false)
16+
ok = b.CompareAndSet(true, false)
17+
assert.True(t, !ok, "CompareAndSet execute failed.")
18+
}
19+
20+
func TestAtomicBool_GetAndSet(t *testing.T) {
21+
b := &AtomicBool{}
22+
assert.True(t, b.Get() == false, "default value is not false.")
23+
b.Set(true)
24+
assert.True(t, b.Get() == true, "the value is false, expect true.")
25+
}
26+
27+
func TestIncrementAndGetInt64(t *testing.T) {
28+
n := int64(0)
29+
wg := &sync.WaitGroup{}
30+
wg.Add(100)
31+
for i := 0; i < 100; i++ {
32+
go func(g *sync.WaitGroup) {
33+
IncrementAndGetInt64(&n)
34+
wg.Done()
35+
}(wg)
36+
}
37+
wg.Wait()
38+
assert.True(t, n == 100, fmt.Sprintf("current n is %d, expect 100.", n))
39+
}

0 commit comments

Comments
 (0)