gitee.com/go-spring2/spring-base@v1.1.3/atomic/pointer_test.go (about) 1 /* 2 * Copyright 2012-2019 the original author or authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * https://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package atomic_test 18 19 import ( 20 "errors" 21 "testing" 22 "unsafe" 23 24 "gitee.com/go-spring2/spring-base/assert" 25 "gitee.com/go-spring2/spring-base/atomic" 26 "gitee.com/go-spring2/spring-base/json" 27 ) 28 29 type properties struct { 30 Data int 31 } 32 33 func BenchmarkPointer(b *testing.B) { 34 35 // Pointer and Value have almost same access performance. 36 // BenchmarkPointer/value-8 47710915 25.72 ns/op 37 // BenchmarkPointer/pointer-8 44618223 25.78 ns/op 38 39 b.Run("pointer", func(b *testing.B) { 40 var p atomic.Pointer 41 for i := 0; i < b.N; i++ { 42 p.Store(unsafe.Pointer(&properties{Data: 1})) 43 prop := (*properties)(p.Load()) 44 if prop.Data != 1 { 45 b.Fatal(errors.New("prop data should be 1")) 46 } 47 } 48 }) 49 50 b.Run("value", func(b *testing.B) { 51 var p atomic.Value 52 for i := 0; i < b.N; i++ { 53 p.Store(&properties{Data: 2}) 54 prop := p.Load().(*properties) 55 if prop.Data != 2 { 56 b.Fatal(errors.New("prop data should be 2")) 57 } 58 } 59 }) 60 } 61 62 func TestPointer(t *testing.T) { 63 64 // atomic.Pointer and unsafe.Pointer occupy the same space 65 assert.Equal(t, unsafe.Sizeof(atomic.Pointer{}), uintptr(8+8)) 66 67 var p atomic.Pointer 68 assert.Equal(t, p.Load(), unsafe.Pointer(nil)) 69 70 s1 := &properties{Data: 1} 71 p.Store(unsafe.Pointer(s1)) 72 assert.Equal(t, p.Load(), unsafe.Pointer(s1)) 73 74 s2 := &properties{Data: 2} 75 old := p.Swap(unsafe.Pointer(s2)) 76 assert.Equal(t, old, unsafe.Pointer(s1)) 77 assert.Equal(t, p.Load(), unsafe.Pointer(s2)) 78 79 s3 := &properties{Data: 3} 80 swapped := p.CompareAndSwap(unsafe.Pointer(s2), unsafe.Pointer(s3)) 81 assert.True(t, swapped) 82 assert.Equal(t, p.Load(), unsafe.Pointer(s3)) 83 84 swapped = p.CompareAndSwap(unsafe.Pointer(s2), unsafe.Pointer(s3)) 85 assert.False(t, swapped) 86 assert.Equal(t, p.Load(), unsafe.Pointer(s3)) 87 88 p.SetMarshalJSON(func(pointer unsafe.Pointer) ([]byte, error) { 89 s := (*properties)(pointer) 90 return json.Marshal(s) 91 }) 92 93 bytes, _ := json.Marshal(&p) 94 assert.Equal(t, string(bytes), `{"Data":3}`) 95 }