aboutsummaryrefslogtreecommitdiffhomepage
path: root/testdata/atomic.go
blob: 4d5ced301fbd17d68f5b6111268f2f06a329b7be (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package main

import (
	"sync/atomic"
	"unsafe"

	"runtime/volatile"
)

func main() {
	i32 := int32(-5)
	println("AddInt32:", atomic.AddInt32(&i32, 8), i32)

	i64 := int64(-5)
	println("AddInt64:", atomic.AddInt64(&i64, 8), i64)

	u32 := uint32(5)
	println("AddUint32:", atomic.AddUint32(&u32, 8), u32)

	u64 := uint64(5)
	println("AddUint64:", atomic.AddUint64(&u64, 8), u64)

	uptr := uintptr(5)
	println("AddUintptr:", uint64(atomic.AddUintptr(&uptr, 8)), uint64(uptr))

	println("SwapInt32:", atomic.SwapInt32(&i32, 33), i32)
	println("SwapInt64:", atomic.SwapInt64(&i64, 33), i64)
	println("SwapUint32:", atomic.SwapUint32(&u32, 33), u32)
	println("SwapUint64:", atomic.SwapUint64(&u64, 33), u64)
	println("SwapUintptr:", uint64(atomic.SwapUintptr(&uptr, 33)), uint64(uptr))
	ptr := unsafe.Pointer(&i32)
	println("SwapPointer:", atomic.SwapPointer(&ptr, unsafe.Pointer(&u32)) == unsafe.Pointer(&i32), ptr == unsafe.Pointer(&u32))

	i32 = int32(-5)
	println("CompareAndSwapInt32:", atomic.CompareAndSwapInt32(&i32, 5, 3), i32)
	println("CompareAndSwapInt32:", atomic.CompareAndSwapInt32(&i32, -5, 3), i32)

	i64 = int64(-5)
	println("CompareAndSwapInt64:", atomic.CompareAndSwapInt64(&i64, 5, 3), i64)
	println("CompareAndSwapInt64:", atomic.CompareAndSwapInt64(&i64, -5, 3), i64)

	u32 = uint32(5)
	println("CompareAndSwapUint32:", atomic.CompareAndSwapUint32(&u32, 4, 3), u32)
	println("CompareAndSwapUint32:", atomic.CompareAndSwapUint32(&u32, 5, 3), u32)

	u64 = uint64(5)
	println("CompareAndSwapUint64:", atomic.CompareAndSwapUint64(&u64, 4, 3), u64)
	println("CompareAndSwapUint64:", atomic.CompareAndSwapUint64(&u64, 5, 3), u64)

	uptr = uintptr(5)
	println("CompareAndSwapUintptr:", atomic.CompareAndSwapUintptr(&uptr, 4, 3), uint64(uptr))
	println("CompareAndSwapUintptr:", atomic.CompareAndSwapUintptr(&uptr, 5, 3), uint64(uptr))

	ptr = unsafe.Pointer(&i32)
	println("CompareAndSwapPointer:", atomic.CompareAndSwapPointer(&ptr, unsafe.Pointer(&u32), unsafe.Pointer(&i64)), ptr == unsafe.Pointer(&i32))
	println("CompareAndSwapPointer:", atomic.CompareAndSwapPointer(&ptr, unsafe.Pointer(&i32), unsafe.Pointer(&i64)), ptr == unsafe.Pointer(&i64))

	println("LoadInt32:", atomic.LoadInt32(&i32))
	println("LoadInt64:", atomic.LoadInt64(&i64))
	println("LoadUint32:", atomic.LoadUint32(&u32))
	println("LoadUint64:", atomic.LoadUint64(&u64))
	println("LoadUintptr:", uint64(atomic.LoadUintptr(&uptr)))
	println("LoadPointer:", atomic.LoadPointer(&ptr) == unsafe.Pointer(&i64))

	atomic.StoreInt32(&i32, -20)
	println("StoreInt32:", i32)

	atomic.StoreInt64(&i64, -20)
	println("StoreInt64:", i64)

	atomic.StoreUint32(&u32, 20)
	println("StoreUint32:", u32)

	atomic.StoreUint64(&u64, 20)
	println("StoreUint64:", u64)

	atomic.StoreUintptr(&uptr, 20)
	println("StoreUintptr:", uint64(uptr))

	atomic.StorePointer(&ptr, unsafe.Pointer(&uptr))
	println("StorePointer:", ptr == unsafe.Pointer(&uptr))

	// test atomic.Value load/store operations
	testValue(int(3), int(-2))
	testValue("", "foobar", "baz")

	// Test atomic and volatile operations as deferred values.
	testDefer()
}

func testValue(values ...interface{}) {
	var av atomic.Value
	for _, val := range values {
		av.Store(val)
		loadedVal := av.Load()
		if loadedVal != val {
			println("val store/load didn't work, expected", val, "but got", loadedVal)
		}
	}
}

func testDefer() {
	n1 := int32(5)
	n2 := uint32(6)
	defer func() {
		println("deferred atomic add:", n1)
		println("deferred volatile store:", n2)
	}()
	defer atomic.AddInt32(&n1, 3)
	defer volatile.StoreUint32(&n2, 22)
}