gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/sync/seqatomic/seqatomic_test.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package seqatomic 16 17 import ( 18 "sync/atomic" 19 "testing" 20 "time" 21 22 "gvisor.dev/gvisor/pkg/sync" 23 ) 24 25 func TestSeqAtomicLoadUncontended(t *testing.T) { 26 var seq sync.SeqCount 27 const want = 1 28 data := want 29 if got := SeqAtomicLoadInt(&seq, &data); got != want { 30 t.Errorf("SeqAtomicLoadInt: got %v, wanted %v", got, want) 31 } 32 } 33 34 func TestSeqAtomicLoadAfterWrite(t *testing.T) { 35 var seq sync.SeqCount 36 var data int 37 const want = 1 38 seq.BeginWrite() 39 data = want 40 seq.EndWrite() 41 if got := SeqAtomicLoadInt(&seq, &data); got != want { 42 t.Errorf("SeqAtomicLoadInt: got %v, wanted %v", got, want) 43 } 44 } 45 46 func TestSeqAtomicLoadDuringWrite(t *testing.T) { 47 var seq sync.SeqCount 48 var data int 49 const want = 1 50 seq.BeginWrite() 51 go func() { 52 time.Sleep(time.Second) 53 data = want 54 seq.EndWrite() 55 }() 56 if got := SeqAtomicLoadInt(&seq, &data); got != want { 57 t.Errorf("SeqAtomicLoadInt: got %v, wanted %v", got, want) 58 } 59 } 60 61 func TestSeqAtomicTryLoadUncontended(t *testing.T) { 62 var seq sync.SeqCount 63 const want = 1 64 data := want 65 epoch := seq.BeginRead() 66 if got, ok := SeqAtomicTryLoadInt(&seq, epoch, &data); !ok || got != want { 67 t.Errorf("SeqAtomicTryLoadInt: got (%v, %v), wanted (%v, true)", got, ok, want) 68 } 69 } 70 71 func TestSeqAtomicTryLoadDuringWrite(t *testing.T) { 72 var seq sync.SeqCount 73 var data int 74 epoch := seq.BeginRead() 75 seq.BeginWrite() 76 if got, ok := SeqAtomicTryLoadInt(&seq, epoch, &data); ok { 77 t.Errorf("SeqAtomicTryLoadInt: got (%v, true), wanted (_, false)", got) 78 } 79 seq.EndWrite() 80 } 81 82 func TestSeqAtomicTryLoadAfterWrite(t *testing.T) { 83 var seq sync.SeqCount 84 var data int 85 epoch := seq.BeginRead() 86 seq.BeginWrite() 87 seq.EndWrite() 88 if got, ok := SeqAtomicTryLoadInt(&seq, epoch, &data); ok { 89 t.Errorf("SeqAtomicTryLoadInt: got (%v, true), wanted (_, false)", got) 90 } 91 } 92 93 func BenchmarkSeqAtomicLoadIntUncontended(b *testing.B) { 94 var seq sync.SeqCount 95 const want = 42 96 data := want 97 b.RunParallel(func(pb *testing.PB) { 98 for pb.Next() { 99 if got := SeqAtomicLoadInt(&seq, &data); got != want { 100 b.Fatalf("SeqAtomicLoadInt: got %v, wanted %v", got, want) 101 } 102 } 103 }) 104 } 105 106 func BenchmarkSeqAtomicTryLoadIntUncontended(b *testing.B) { 107 var seq sync.SeqCount 108 const want = 42 109 data := want 110 b.RunParallel(func(pb *testing.PB) { 111 epoch := seq.BeginRead() 112 for pb.Next() { 113 if got, ok := SeqAtomicTryLoadInt(&seq, epoch, &data); !ok || got != want { 114 b.Fatalf("SeqAtomicTryLoadInt: got (%v, %v), wanted (%v, true)", got, ok, want) 115 } 116 } 117 }) 118 } 119 120 // For comparison: 121 func BenchmarkAtomicPointerLoadIntUncontended(b *testing.B) { 122 var a atomic.Pointer[int] 123 const want = 42 124 value := int(want) 125 a.Store(&value) 126 b.RunParallel(func(pb *testing.PB) { 127 for pb.Next() { 128 if got := a.Load(); *got != want { 129 b.Fatalf("atomic.Pointer[int].Load: got %v, wanted %v", got, want) 130 } 131 } 132 }) 133 }