diff --git a/nocmp_test.go b/nocmp_test.go index fe712a2..cd32489 100644 --- a/nocmp_test.go +++ b/nocmp_test.go @@ -60,6 +60,8 @@ func TestNocmpComparability(t *testing.T) { {desc: "Int32", give: Int32{}}, {desc: "Int64", give: Int64{}}, {desc: "String", give: String{}}, + {desc: "Uint8", give: Uint8{}}, + {desc: "Uint16", give: Uint16{}}, {desc: "Uint32", give: Uint32{}}, {desc: "Uint64", give: Uint64{}}, {desc: "Value", give: Value{}}, diff --git a/stress_test.go b/stress_test.go index 0ac7ac5..5189b06 100644 --- a/stress_test.go +++ b/stress_test.go @@ -40,6 +40,8 @@ var _stressTests = map[string]func() func(){ "i32": stressInt32, "i64/std": stressStdInt64, "i64": stressInt64, + "u8": stressUint8, + "u16": stressUint16, "u32/std": stressStdUint32, "u32": stressUint32, "u64/std": stressStdUint64, @@ -154,6 +156,34 @@ func stressInt64() func() { } } +func stressUint8() func() { + var atom Uint8 + return func() { + atom.Load() + atom.Add(1) + atom.Sub(2) + atom.Inc() + atom.Dec() + atom.CAS(1, 0) + atom.Swap(5) + atom.Store(1) + } +} + +func stressUint16() func() { + var atom Uint16 + return func() { + atom.Load() + atom.Add(1) + atom.Sub(2) + atom.Inc() + atom.Dec() + atom.CAS(1, 0) + atom.Swap(5) + atom.Store(1) + } +} + func stressStdUint32() func() { var atom uint32 return func() { diff --git a/uint16.go b/uint16.go new file mode 100644 index 0000000..61c3bbb --- /dev/null +++ b/uint16.go @@ -0,0 +1,88 @@ +// @generated Code generated by gen-atomicwrapper. + +// Copyright (c) 2020-2026 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "encoding/json" +) + +// Uint16 is an atomic type-safe wrapper for uint16 values. +type Uint16 struct { + _ nocmp // disallow non-atomic comparison + + v Uint32 +} + +var _zeroUint16 uint16 + +// NewUint16 creates a new Uint16. +func NewUint16(val uint16) *Uint16 { + x := &Uint16{} + if val != _zeroUint16 { + x.Store(val) + } + return x +} + +// Load atomically loads the wrapped uint16. +func (x *Uint16) Load() uint16 { + return unpackUint16(x.v.Load()) +} + +// Store atomically stores the passed uint16. +func (x *Uint16) Store(val uint16) { + x.v.Store(packUint16(val)) +} + +// CAS is an atomic compare-and-swap for uint16 values. +// +// Deprecated: Use CompareAndSwap. +func (x *Uint16) CAS(old, new uint16) (swapped bool) { + return x.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap for uint16 values. +func (x *Uint16) CompareAndSwap(old, new uint16) (swapped bool) { + return x.v.CompareAndSwap(packUint16(old), packUint16(new)) +} + +// Swap atomically stores the given uint16 and returns the old +// value. +func (x *Uint16) Swap(val uint16) (old uint16) { + return unpackUint16(x.v.Swap(packUint16(val))) +} + +// MarshalJSON encodes the wrapped uint16 into JSON. +func (x *Uint16) MarshalJSON() ([]byte, error) { + return json.Marshal(x.Load()) +} + +// UnmarshalJSON decodes a uint16 from JSON. +func (x *Uint16) UnmarshalJSON(b []byte) error { + var v uint16 + if err := json.Unmarshal(b, &v); err != nil { + return err + } + x.Store(v) + return nil +} diff --git a/uint16_ext.go b/uint16_ext.go new file mode 100644 index 0000000..4f40cc3 --- /dev/null +++ b/uint16_ext.go @@ -0,0 +1,81 @@ +// Copyright (c) 2020-2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "strconv" +) + +//go:generate bin/gen-atomicwrapper -name=Uint16 -type=uint16 -wrapped=Uint32 -pack=packUint16 -unpack=unpackUint16 -cas -swap -json -file=uint16.go + +func packUint16(n uint16) uint32 { + return uint32(n) +} + +func unpackUint16(n uint32) uint16 { + return uint16(n) +} + +// Add atomically adds to the wrapped uint16 and returns the new value. +func (i *Uint16) Add(delta uint16) uint16 { + for { + old := i.Load() + new := old + delta + if i.CompareAndSwap(old, new) { + return new + } + } +} + +// Sub atomically subtracts from the wrapped uint16 and returns the new value. +func (i *Uint16) Sub(delta uint16) uint16 { + return i.Add(-delta) +} + +// Inc atomically increments the wrapped uint16 and returns the new value. +func (i *Uint16) Inc() uint16 { + return i.Add(1) +} + +// Dec atomically decrements the wrapped uint16 and returns the new value. +func (i *Uint16) Dec() uint16 { + return i.Sub(1) +} + +// String encodes the wrapped value as a string. +func (i *Uint16) String() string { + return strconv.FormatUint(uint64(i.Load()), 10) +} + +// MarshalText encodes the wrapped uint16 into a textual form. +func (i *Uint16) MarshalText() ([]byte, error) { + return []byte(strconv.FormatUint(uint64(i.Load()), 10)), nil +} + +// UnmarshalText decodes text into the wrapped uint16. +func (i *Uint16) UnmarshalText(b []byte) error { + v, err := strconv.ParseUint(string(b), 10, 16) + if err != nil { + return err + } + i.Store(uint16(v)) + return nil +} diff --git a/uint16_test.go b/uint16_test.go new file mode 100644 index 0000000..fd83412 --- /dev/null +++ b/uint16_test.go @@ -0,0 +1,110 @@ +// Copyright (c) 2020-2026 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "encoding/json" + "math" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestUint16(t *testing.T) { + atom := NewUint16(42) + + require.Equal(t, uint16(42), atom.Load(), "Load didn't work.") + require.Equal(t, uint16(46), atom.Add(4), "Add didn't work.") + require.Equal(t, uint16(44), atom.Sub(2), "Sub didn't work.") + require.Equal(t, uint16(45), atom.Inc(), "Inc didn't work.") + require.Equal(t, uint16(44), atom.Dec(), "Dec didn't work.") + + require.True(t, atom.CAS(44, 0), "CAS didn't report a swap.") + require.Equal(t, uint16(0), atom.Load(), "CAS didn't set the correct value.") + + require.True(t, atom.CompareAndSwap(0, 1), "CompareAndSwap didn't report a swap.") + require.Equal(t, uint16(1), atom.Load(), "CompareAndSwap didn't set the correct value.") + + require.Equal(t, uint16(1), atom.Swap(2), "Swap didn't return the old value.") + require.Equal(t, uint16(2), atom.Load(), "Swap didn't set the correct value.") + + atom.Store(42) + require.Equal(t, uint16(42), atom.Load(), "Store didn't set the correct value.") + + t.Run("JSON/Marshal", func(t *testing.T) { + bytes, err := json.Marshal(atom) + require.NoError(t, err, "json.Marshal errored unexpectedly.") + require.Equal(t, []byte("42"), bytes, "json.Marshal encoded the wrong bytes.") + }) + + t.Run("JSON/Unmarshal", func(t *testing.T) { + err := json.Unmarshal([]byte("40"), &atom) + require.NoError(t, err, "json.Unmarshal errored unexpectedly.") + require.Equal(t, uint16(40), atom.Load(), "json.Unmarshal didn't set the correct value.") + }) + + t.Run("JSON/Unmarshal/Error", func(t *testing.T) { + err := json.Unmarshal([]byte(`"40"`), &atom) + require.Error(t, err, "json.Unmarshal didn't error as expected.") + assertErrorJSONUnmarshalType(t, err, + "json.Unmarshal failed with unexpected error %v, want UnmarshalTypeError.", err) + }) + + t.Run("Text/MarshalUnmarshal", func(t *testing.T) { + atom := NewUint16(42) + bytes, err := atom.MarshalText() + require.NoError(t, err) + require.Equal(t, []byte("42"), bytes) + + var atom2 Uint16 + err = atom2.UnmarshalText([]byte("40")) + require.NoError(t, err) + require.Equal(t, uint16(40), atom2.Load()) + + err = atom2.UnmarshalText([]byte("invalid")) + require.Error(t, err) + + err = atom2.UnmarshalText([]byte("65536")) + require.Error(t, err) + }) + + t.Run("String", func(t *testing.T) { + atom := NewUint16(math.MaxUint16) + assert.Equal(t, "65535", atom.String(), + "String() returned an unexpected value.") + }) + + t.Run("Wrapping", func(t *testing.T) { + atom := NewUint16(math.MaxUint16) + require.Equal(t, uint16(0), atom.Add(1), "Add didn't wrap around.") + require.Equal(t, uint16(math.MaxUint16), atom.Sub(1), "Sub didn't wrap around.") + require.Equal(t, uint16(0), atom.Inc(), "Inc didn't wrap around.") + require.Equal(t, uint16(math.MaxUint16), atom.Dec(), "Dec didn't wrap around.") + }) + + t.Run("Uninitialized", func(t *testing.T) { + var zeroAtom Uint16 + require.Equal(t, uint16(0), zeroAtom.Load()) + require.True(t, zeroAtom.CompareAndSwap(0, 10)) + require.Equal(t, uint16(10), zeroAtom.Load()) + }) +} diff --git a/uint8.go b/uint8.go new file mode 100644 index 0000000..1f39599 --- /dev/null +++ b/uint8.go @@ -0,0 +1,88 @@ +// @generated Code generated by gen-atomicwrapper. + +// Copyright (c) 2020-2026 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "encoding/json" +) + +// Uint8 is an atomic type-safe wrapper for uint8 values. +type Uint8 struct { + _ nocmp // disallow non-atomic comparison + + v Uint32 +} + +var _zeroUint8 uint8 + +// NewUint8 creates a new Uint8. +func NewUint8(val uint8) *Uint8 { + x := &Uint8{} + if val != _zeroUint8 { + x.Store(val) + } + return x +} + +// Load atomically loads the wrapped uint8. +func (x *Uint8) Load() uint8 { + return unpackUint8(x.v.Load()) +} + +// Store atomically stores the passed uint8. +func (x *Uint8) Store(val uint8) { + x.v.Store(packUint8(val)) +} + +// CAS is an atomic compare-and-swap for uint8 values. +// +// Deprecated: Use CompareAndSwap. +func (x *Uint8) CAS(old, new uint8) (swapped bool) { + return x.CompareAndSwap(old, new) +} + +// CompareAndSwap is an atomic compare-and-swap for uint8 values. +func (x *Uint8) CompareAndSwap(old, new uint8) (swapped bool) { + return x.v.CompareAndSwap(packUint8(old), packUint8(new)) +} + +// Swap atomically stores the given uint8 and returns the old +// value. +func (x *Uint8) Swap(val uint8) (old uint8) { + return unpackUint8(x.v.Swap(packUint8(val))) +} + +// MarshalJSON encodes the wrapped uint8 into JSON. +func (x *Uint8) MarshalJSON() ([]byte, error) { + return json.Marshal(x.Load()) +} + +// UnmarshalJSON decodes a uint8 from JSON. +func (x *Uint8) UnmarshalJSON(b []byte) error { + var v uint8 + if err := json.Unmarshal(b, &v); err != nil { + return err + } + x.Store(v) + return nil +} diff --git a/uint8_ext.go b/uint8_ext.go new file mode 100644 index 0000000..fec4cd2 --- /dev/null +++ b/uint8_ext.go @@ -0,0 +1,81 @@ +// Copyright (c) 2020-2023 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "strconv" +) + +//go:generate bin/gen-atomicwrapper -name=Uint8 -type=uint8 -wrapped=Uint32 -pack=packUint8 -unpack=unpackUint8 -cas -swap -json -file=uint8.go + +func packUint8(n uint8) uint32 { + return uint32(n) +} + +func unpackUint8(n uint32) uint8 { + return uint8(n) +} + +// Add atomically adds to the wrapped uint8 and returns the new value. +func (i *Uint8) Add(delta uint8) uint8 { + for { + old := i.Load() + new := old + delta + if i.CompareAndSwap(old, new) { + return new + } + } +} + +// Sub atomically subtracts from the wrapped uint8 and returns the new value. +func (i *Uint8) Sub(delta uint8) uint8 { + return i.Add(-delta) +} + +// Inc atomically increments the wrapped uint8 and returns the new value. +func (i *Uint8) Inc() uint8 { + return i.Add(1) +} + +// Dec atomically decrements the wrapped uint8 and returns the new value. +func (i *Uint8) Dec() uint8 { + return i.Sub(1) +} + +// String encodes the wrapped value as a string. +func (i *Uint8) String() string { + return strconv.FormatUint(uint64(i.Load()), 10) +} + +// MarshalText encodes the wrapped uint8 into a textual form. +func (i *Uint8) MarshalText() ([]byte, error) { + return []byte(strconv.FormatUint(uint64(i.Load()), 10)), nil +} + +// UnmarshalText decodes text into the wrapped uint8. +func (i *Uint8) UnmarshalText(b []byte) error { + v, err := strconv.ParseUint(string(b), 10, 8) + if err != nil { + return err + } + i.Store(uint8(v)) + return nil +} diff --git a/uint8_test.go b/uint8_test.go new file mode 100644 index 0000000..5fc2d24 --- /dev/null +++ b/uint8_test.go @@ -0,0 +1,110 @@ +// Copyright (c) 2020-2026 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +package atomic + +import ( + "encoding/json" + "math" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestUint8(t *testing.T) { + atom := NewUint8(42) + + require.Equal(t, uint8(42), atom.Load(), "Load didn't work.") + require.Equal(t, uint8(46), atom.Add(4), "Add didn't work.") + require.Equal(t, uint8(44), atom.Sub(2), "Sub didn't work.") + require.Equal(t, uint8(45), atom.Inc(), "Inc didn't work.") + require.Equal(t, uint8(44), atom.Dec(), "Dec didn't work.") + + require.True(t, atom.CAS(44, 0), "CAS didn't report a swap.") + require.Equal(t, uint8(0), atom.Load(), "CAS didn't set the correct value.") + + require.True(t, atom.CompareAndSwap(0, 1), "CompareAndSwap didn't report a swap.") + require.Equal(t, uint8(1), atom.Load(), "CompareAndSwap didn't set the correct value.") + + require.Equal(t, uint8(1), atom.Swap(2), "Swap didn't return the old value.") + require.Equal(t, uint8(2), atom.Load(), "Swap didn't set the correct value.") + + atom.Store(42) + require.Equal(t, uint8(42), atom.Load(), "Store didn't set the correct value.") + + t.Run("JSON/Marshal", func(t *testing.T) { + bytes, err := json.Marshal(atom) + require.NoError(t, err, "json.Marshal errored unexpectedly.") + require.Equal(t, []byte("42"), bytes, "json.Marshal encoded the wrong bytes.") + }) + + t.Run("JSON/Unmarshal", func(t *testing.T) { + err := json.Unmarshal([]byte("40"), &atom) + require.NoError(t, err, "json.Unmarshal errored unexpectedly.") + require.Equal(t, uint8(40), atom.Load(), "json.Unmarshal didn't set the correct value.") + }) + + t.Run("JSON/Unmarshal/Error", func(t *testing.T) { + err := json.Unmarshal([]byte(`"40"`), &atom) + require.Error(t, err, "json.Unmarshal didn't error as expected.") + assertErrorJSONUnmarshalType(t, err, + "json.Unmarshal failed with unexpected error %v, want UnmarshalTypeError.", err) + }) + + t.Run("Text/MarshalUnmarshal", func(t *testing.T) { + atom := NewUint8(42) + bytes, err := atom.MarshalText() + require.NoError(t, err) + require.Equal(t, []byte("42"), bytes) + + var atom2 Uint8 + err = atom2.UnmarshalText([]byte("40")) + require.NoError(t, err) + require.Equal(t, uint8(40), atom2.Load()) + + err = atom2.UnmarshalText([]byte("invalid")) + require.Error(t, err) + + err = atom2.UnmarshalText([]byte("256")) + require.Error(t, err) + }) + + t.Run("String", func(t *testing.T) { + atom := NewUint8(math.MaxUint8) + assert.Equal(t, "255", atom.String(), + "String() returned an unexpected value.") + }) + + t.Run("Wrapping", func(t *testing.T) { + atom := NewUint8(math.MaxUint8) + require.Equal(t, uint8(0), atom.Add(1), "Add didn't wrap around.") + require.Equal(t, uint8(math.MaxUint8), atom.Sub(1), "Sub didn't wrap around.") + require.Equal(t, uint8(0), atom.Inc(), "Inc didn't wrap around.") + require.Equal(t, uint8(math.MaxUint8), atom.Dec(), "Dec didn't wrap around.") + }) + + t.Run("Uninitialized", func(t *testing.T) { + var zeroAtom Uint8 + require.Equal(t, uint8(0), zeroAtom.Load()) + require.True(t, zeroAtom.CompareAndSwap(0, 10)) + require.Equal(t, uint8(10), zeroAtom.Load()) + }) +}