import (
"fmt"
+ "reflect"
"runtime"
"runtime/debug"
"strings"
}
}
+func TestSwapInt32Method(t *testing.T) {
+ var x struct {
+ before int32
+ i Int32
+ after int32
+ }
+ x.before = magic32
+ x.after = magic32
+ var j int32
+ for delta := int32(1); delta+delta > delta; delta += delta {
+ k := x.i.Swap(delta)
+ if x.i.Load() != delta || k != j {
+ t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i.Load(), j, k)
+ }
+ j = delta
+ }
+ if x.before != magic32 || x.after != magic32 {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
+ }
+}
+
func TestSwapUint32(t *testing.T) {
var x struct {
before uint32
}
}
+func TestSwapUint32Method(t *testing.T) {
+ var x struct {
+ before uint32
+ i Uint32
+ after uint32
+ }
+ x.before = magic32
+ x.after = magic32
+ var j uint32
+ for delta := uint32(1); delta+delta > delta; delta += delta {
+ k := x.i.Swap(delta)
+ if x.i.Load() != delta || k != j {
+ t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i.Load(), j, k)
+ }
+ j = delta
+ }
+ if x.before != magic32 || x.after != magic32 {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
+ }
+}
+
func TestSwapInt64(t *testing.T) {
if test64err != nil {
t.Skipf("Skipping 64-bit tests: %v", test64err)
i int64
after int64
}
+ magic64 := int64(magic64)
x.before = magic64
x.after = magic64
var j int64
j = delta
}
if x.before != magic64 || x.after != magic64 {
- t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
+ }
+}
+
+func TestSwapInt64Method(t *testing.T) {
+ if test64err != nil {
+ t.Skipf("Skipping 64-bit tests: %v", test64err)
+ }
+ var x struct {
+ before int64
+ i Int64
+ after int64
+ }
+ magic64 := int64(magic64)
+ x.before = magic64
+ x.after = magic64
+ var j int64
+ for delta := int64(1); delta+delta > delta; delta += delta {
+ k := x.i.Swap(delta)
+ if x.i.Load() != delta || k != j {
+ t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i.Load(), j, k)
+ }
+ j = delta
+ }
+ if x.before != magic64 || x.after != magic64 {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
}
}
i uint64
after uint64
}
+ magic64 := uint64(magic64)
x.before = magic64
x.after = magic64
var j uint64
j = delta
}
if x.before != magic64 || x.after != magic64 {
- t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
+ }
+}
+
+func TestSwapUint64Method(t *testing.T) {
+ if test64err != nil {
+ t.Skipf("Skipping 64-bit tests: %v", test64err)
+ }
+ var x struct {
+ before uint64
+ i Uint64
+ after uint64
+ }
+ magic64 := uint64(magic64)
+ x.before = magic64
+ x.after = magic64
+ var j uint64
+ for delta := uint64(1); delta+delta > delta; delta += delta {
+ k := x.i.Swap(delta)
+ if x.i.Load() != delta || k != j {
+ t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i.Load(), j, k)
+ }
+ j = delta
+ }
+ if x.before != magic64 || x.after != magic64 {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
}
}
}
}
+func TestSwapUintptrMethod(t *testing.T) {
+ var x struct {
+ before uintptr
+ i Uintptr
+ after uintptr
+ }
+ var m uint64 = magic64
+ magicptr := uintptr(m)
+ x.before = magicptr
+ x.after = magicptr
+ var j uintptr
+ for delta := uintptr(1); delta+delta > delta; delta += delta {
+ k := x.i.Swap(delta)
+ if x.i.Load() != delta || k != j {
+ t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i.Load(), j, k)
+ }
+ j = delta
+ }
+ if x.before != magicptr || x.after != magicptr {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
+ }
+}
+
var global [1024]byte
func testPointers() []unsafe.Pointer {
}
}
+func TestSwapPointerMethod(t *testing.T) {
+ var x struct {
+ before uintptr
+ i Pointer[byte]
+ after uintptr
+ }
+ var m uint64 = magic64
+ magicptr := uintptr(m)
+ x.before = magicptr
+ x.after = magicptr
+ var j *byte
+ for _, p := range testPointers() {
+ p := (*byte)(p)
+ k := x.i.Swap(p)
+ if x.i.Load() != p || k != j {
+ t.Fatalf("p=%p i=%p j=%p k=%p", p, x.i.Load(), j, k)
+ }
+ j = p
+ }
+ if x.before != magicptr || x.after != magicptr {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
+ }
+}
+
func TestAddInt32(t *testing.T) {
var x struct {
before int32
}
}
+func TestAddInt32Method(t *testing.T) {
+ var x struct {
+ before int32
+ i Int32
+ after int32
+ }
+ x.before = magic32
+ x.after = magic32
+ var j int32
+ for delta := int32(1); delta+delta > delta; delta += delta {
+ k := x.i.Add(delta)
+ j += delta
+ if x.i.Load() != j || k != j {
+ t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i.Load(), j, k)
+ }
+ }
+ if x.before != magic32 || x.after != magic32 {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
+ }
+}
+
func TestAddUint32(t *testing.T) {
var x struct {
before uint32
}
}
+func TestAddUint32Method(t *testing.T) {
+ var x struct {
+ before uint32
+ i Uint32
+ after uint32
+ }
+ x.before = magic32
+ x.after = magic32
+ var j uint32
+ for delta := uint32(1); delta+delta > delta; delta += delta {
+ k := x.i.Add(delta)
+ j += delta
+ if x.i.Load() != j || k != j {
+ t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i.Load(), j, k)
+ }
+ }
+ if x.before != magic32 || x.after != magic32 {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
+ }
+}
+
func TestAddInt64(t *testing.T) {
if test64err != nil {
t.Skipf("Skipping 64-bit tests: %v", test64err)
i int64
after int64
}
+ magic64 := int64(magic64)
x.before = magic64
x.after = magic64
var j int64
}
}
if x.before != magic64 || x.after != magic64 {
- t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, int64(magic64), int64(magic64))
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
+ }
+}
+
+func TestAddInt64Method(t *testing.T) {
+ if test64err != nil {
+ t.Skipf("Skipping 64-bit tests: %v", test64err)
+ }
+ var x struct {
+ before int64
+ i Int64
+ after int64
+ }
+ magic64 := int64(magic64)
+ x.before = magic64
+ x.after = magic64
+ var j int64
+ for delta := int64(1); delta+delta > delta; delta += delta {
+ k := x.i.Add(delta)
+ j += delta
+ if x.i.Load() != j || k != j {
+ t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i.Load(), j, k)
+ }
+ }
+ if x.before != magic64 || x.after != magic64 {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
}
}
i uint64
after uint64
}
+ magic64 := uint64(magic64)
x.before = magic64
x.after = magic64
var j uint64
}
}
if x.before != magic64 || x.after != magic64 {
- t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
+ }
+}
+
+func TestAddUint64Method(t *testing.T) {
+ if test64err != nil {
+ t.Skipf("Skipping 64-bit tests: %v", test64err)
+ }
+ var x struct {
+ before uint64
+ i Uint64
+ after uint64
+ }
+ magic64 := uint64(magic64)
+ x.before = magic64
+ x.after = magic64
+ var j uint64
+ for delta := uint64(1); delta+delta > delta; delta += delta {
+ k := x.i.Add(delta)
+ j += delta
+ if x.i.Load() != j || k != j {
+ t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i.Load(), j, k)
+ }
+ }
+ if x.before != magic64 || x.after != magic64 {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
}
}
}
}
+func TestAddUintptrMethod(t *testing.T) {
+ var x struct {
+ before uintptr
+ i Uintptr
+ after uintptr
+ }
+ var m uint64 = magic64
+ magicptr := uintptr(m)
+ x.before = magicptr
+ x.after = magicptr
+ var j uintptr
+ for delta := uintptr(1); delta+delta > delta; delta += delta {
+ k := x.i.Add(delta)
+ j += delta
+ if x.i.Load() != j || k != j {
+ t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i.Load(), j, k)
+ }
+ }
+ if x.before != magicptr || x.after != magicptr {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
+ }
+}
+
func TestCompareAndSwapInt32(t *testing.T) {
var x struct {
before int32
}
}
+func TestCompareAndSwapInt32Method(t *testing.T) {
+ var x struct {
+ before int32
+ i Int32
+ after int32
+ }
+ x.before = magic32
+ x.after = magic32
+ for val := int32(1); val+val > val; val += val {
+ x.i.Store(val)
+ if !x.i.CompareAndSwap(val, val+1) {
+ t.Fatalf("should have swapped %#x %#x", val, val+1)
+ }
+ if x.i.Load() != val+1 {
+ t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i.Load(), val+1)
+ }
+ x.i.Store(val + 1)
+ if x.i.CompareAndSwap(val, val+2) {
+ t.Fatalf("should not have swapped %#x %#x", val, val+2)
+ }
+ if x.i.Load() != val+1 {
+ t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i.Load(), val+1)
+ }
+ }
+ if x.before != magic32 || x.after != magic32 {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
+ }
+}
+
func TestCompareAndSwapUint32(t *testing.T) {
var x struct {
before uint32
}
}
+func TestCompareAndSwapUint32Method(t *testing.T) {
+ var x struct {
+ before uint32
+ i Uint32
+ after uint32
+ }
+ x.before = magic32
+ x.after = magic32
+ for val := uint32(1); val+val > val; val += val {
+ x.i.Store(val)
+ if !x.i.CompareAndSwap(val, val+1) {
+ t.Fatalf("should have swapped %#x %#x", val, val+1)
+ }
+ if x.i.Load() != val+1 {
+ t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i.Load(), val+1)
+ }
+ x.i.Store(val + 1)
+ if x.i.CompareAndSwap(val, val+2) {
+ t.Fatalf("should not have swapped %#x %#x", val, val+2)
+ }
+ if x.i.Load() != val+1 {
+ t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i.Load(), val+1)
+ }
+ }
+ if x.before != magic32 || x.after != magic32 {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
+ }
+}
+
func TestCompareAndSwapInt64(t *testing.T) {
if test64err != nil {
t.Skipf("Skipping 64-bit tests: %v", test64err)
i int64
after int64
}
+ magic64 := int64(magic64)
x.before = magic64
x.after = magic64
for val := int64(1); val+val > val; val += val {
}
}
if x.before != magic64 || x.after != magic64 {
- t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
+ }
+}
+
+func TestCompareAndSwapInt64Method(t *testing.T) {
+ if test64err != nil {
+ t.Skipf("Skipping 64-bit tests: %v", test64err)
+ }
+ var x struct {
+ before int64
+ i Int64
+ after int64
+ }
+ magic64 := int64(magic64)
+ x.before = magic64
+ x.after = magic64
+ for val := int64(1); val+val > val; val += val {
+ x.i.Store(val)
+ if !x.i.CompareAndSwap(val, val+1) {
+ t.Fatalf("should have swapped %#x %#x", val, val+1)
+ }
+ if x.i.Load() != val+1 {
+ t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i.Load(), val+1)
+ }
+ x.i.Store(val + 1)
+ if x.i.CompareAndSwap(val, val+2) {
+ t.Fatalf("should not have swapped %#x %#x", val, val+2)
+ }
+ if x.i.Load() != val+1 {
+ t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i.Load(), val+1)
+ }
+ }
+ if x.before != magic64 || x.after != magic64 {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
}
}
i uint64
after uint64
}
+ magic64 := uint64(magic64)
x.before = magic64
x.after = magic64
for val := uint64(1); val+val > val; val += val {
}
}
if x.before != magic64 || x.after != magic64 {
- t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
}
}
testCompareAndSwapUint64(t, CompareAndSwapUint64)
}
+func TestCompareAndSwapUint64Method(t *testing.T) {
+ if test64err != nil {
+ t.Skipf("Skipping 64-bit tests: %v", test64err)
+ }
+ var x struct {
+ before uint64
+ i Uint64
+ after uint64
+ }
+ magic64 := uint64(magic64)
+ x.before = magic64
+ x.after = magic64
+ for val := uint64(1); val+val > val; val += val {
+ x.i.Store(val)
+ if !x.i.CompareAndSwap(val, val+1) {
+ t.Fatalf("should have swapped %#x %#x", val, val+1)
+ }
+ if x.i.Load() != val+1 {
+ t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i.Load(), val+1)
+ }
+ x.i.Store(val + 1)
+ if x.i.CompareAndSwap(val, val+2) {
+ t.Fatalf("should not have swapped %#x %#x", val, val+2)
+ }
+ if x.i.Load() != val+1 {
+ t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i.Load(), val+1)
+ }
+ }
+ if x.before != magic64 || x.after != magic64 {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
+ }
+}
+
func TestCompareAndSwapUintptr(t *testing.T) {
var x struct {
before uintptr
}
}
+func TestCompareAndSwapUintptrMethod(t *testing.T) {
+ var x struct {
+ before uintptr
+ i Uintptr
+ after uintptr
+ }
+ var m uint64 = magic64
+ magicptr := uintptr(m)
+ x.before = magicptr
+ x.after = magicptr
+ for val := uintptr(1); val+val > val; val += val {
+ x.i.Store(val)
+ if !x.i.CompareAndSwap(val, val+1) {
+ t.Fatalf("should have swapped %#x %#x", val, val+1)
+ }
+ if x.i.Load() != val+1 {
+ t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i.Load(), val+1)
+ }
+ x.i.Store(val + 1)
+ if x.i.CompareAndSwap(val, val+2) {
+ t.Fatalf("should not have swapped %#x %#x", val, val+2)
+ }
+ if x.i.Load() != val+1 {
+ t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i.Load(), val+1)
+ }
+ }
+ if x.before != magicptr || x.after != magicptr {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uintptr(magicptr), uintptr(magicptr))
+ }
+}
+
func TestCompareAndSwapPointer(t *testing.T) {
var x struct {
before uintptr
}
}
+func TestCompareAndSwapPointerMethod(t *testing.T) {
+ var x struct {
+ before uintptr
+ i Pointer[byte]
+ after uintptr
+ }
+ var m uint64 = magic64
+ magicptr := uintptr(m)
+ x.before = magicptr
+ x.after = magicptr
+ q := new(byte)
+ for _, p := range testPointers() {
+ p := (*byte)(p)
+ x.i.Store(p)
+ if !x.i.CompareAndSwap(p, q) {
+ t.Fatalf("should have swapped %p %p", p, q)
+ }
+ if x.i.Load() != q {
+ t.Fatalf("wrong x.i after swap: x.i=%p want %p", x.i.Load(), q)
+ }
+ if x.i.CompareAndSwap(p, nil) {
+ t.Fatalf("should not have swapped %p nil", p)
+ }
+ if x.i.Load() != q {
+ t.Fatalf("wrong x.i after swap: x.i=%p want %p", x.i.Load(), q)
+ }
+ }
+ if x.before != magicptr || x.after != magicptr {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
+ }
+}
+
func TestLoadInt32(t *testing.T) {
var x struct {
before int32
}
}
+func TestLoadInt32Method(t *testing.T) {
+ var x struct {
+ before int32
+ i Int32
+ after int32
+ }
+ x.before = magic32
+ x.after = magic32
+ want := int32(0)
+ for delta := int32(1); delta+delta > delta; delta += delta {
+ k := x.i.Load()
+ if k != want {
+ t.Fatalf("delta=%d i=%d k=%d want=%d", delta, x.i.Load(), k, want)
+ }
+ x.i.Store(k + delta)
+ want = k + delta
+ }
+ if x.before != magic32 || x.after != magic32 {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
+ }
+}
+
func TestLoadUint32(t *testing.T) {
var x struct {
before uint32
}
}
+func TestLoadUint32Method(t *testing.T) {
+ var x struct {
+ before uint32
+ i Uint32
+ after uint32
+ }
+ x.before = magic32
+ x.after = magic32
+ want := uint32(0)
+ for delta := uint32(1); delta+delta > delta; delta += delta {
+ k := x.i.Load()
+ if k != want {
+ t.Fatalf("delta=%d i=%d k=%d want=%d", delta, x.i.Load(), k, want)
+ }
+ x.i.Store(k + delta)
+ want = k + delta
+ }
+ if x.before != magic32 || x.after != magic32 {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
+ }
+}
+
func TestLoadInt64(t *testing.T) {
if test64err != nil {
t.Skipf("Skipping 64-bit tests: %v", test64err)
i int64
after int64
}
+ magic64 := int64(magic64)
x.before = magic64
x.after = magic64
for delta := int64(1); delta+delta > delta; delta += delta {
x.i += delta
}
if x.before != magic64 || x.after != magic64 {
- t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
+ }
+}
+
+func TestLoadInt64Method(t *testing.T) {
+ if test64err != nil {
+ t.Skipf("Skipping 64-bit tests: %v", test64err)
+ }
+ var x struct {
+ before int64
+ i Int64
+ after int64
+ }
+ magic64 := int64(magic64)
+ x.before = magic64
+ x.after = magic64
+ want := int64(0)
+ for delta := int64(1); delta+delta > delta; delta += delta {
+ k := x.i.Load()
+ if k != want {
+ t.Fatalf("delta=%d i=%d k=%d want=%d", delta, x.i.Load(), k, want)
+ }
+ x.i.Store(k + delta)
+ want = k + delta
+ }
+ if x.before != magic64 || x.after != magic64 {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
}
}
i uint64
after uint64
}
+ magic64 := uint64(magic64)
x.before = magic64
x.after = magic64
for delta := uint64(1); delta+delta > delta; delta += delta {
x.i += delta
}
if x.before != magic64 || x.after != magic64 {
- t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
+ }
+}
+
+func TestLoadUint64Method(t *testing.T) {
+ if test64err != nil {
+ t.Skipf("Skipping 64-bit tests: %v", test64err)
+ }
+ var x struct {
+ before uint64
+ i Uint64
+ after uint64
+ }
+ magic64 := uint64(magic64)
+ x.before = magic64
+ x.after = magic64
+ want := uint64(0)
+ for delta := uint64(1); delta+delta > delta; delta += delta {
+ k := x.i.Load()
+ if k != want {
+ t.Fatalf("delta=%d i=%d k=%d want=%d", delta, x.i.Load(), k, want)
+ }
+ x.i.Store(k + delta)
+ want = k + delta
+ }
+ if x.before != magic64 || x.after != magic64 {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
}
}
}
}
+func TestLoadUintptrMethod(t *testing.T) {
+ var x struct {
+ before uintptr
+ i Uintptr
+ after uintptr
+ }
+ var m uint64 = magic64
+ magicptr := uintptr(m)
+ x.before = magicptr
+ x.after = magicptr
+ want := uintptr(0)
+ for delta := uintptr(1); delta+delta > delta; delta += delta {
+ k := x.i.Load()
+ if k != want {
+ t.Fatalf("delta=%d i=%d k=%d want=%d", delta, x.i.Load(), k, want)
+ }
+ x.i.Store(k + delta)
+ want = k + delta
+ }
+ if x.before != magicptr || x.after != magicptr {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
+ }
+}
+
func TestLoadPointer(t *testing.T) {
var x struct {
before uintptr
}
}
+func TestLoadPointerMethod(t *testing.T) {
+ var x struct {
+ before uintptr
+ i Pointer[byte]
+ after uintptr
+ }
+ var m uint64 = magic64
+ magicptr := uintptr(m)
+ x.before = magicptr
+ x.after = magicptr
+ for _, p := range testPointers() {
+ p := (*byte)(p)
+ x.i.Store(p)
+ k := x.i.Load()
+ if k != p {
+ t.Fatalf("p=%x k=%x", p, k)
+ }
+ }
+ if x.before != magicptr || x.after != magicptr {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
+ }
+}
+
func TestStoreInt32(t *testing.T) {
var x struct {
before int32
}
}
+func TestStoreInt32Method(t *testing.T) {
+ var x struct {
+ before int32
+ i Int32
+ after int32
+ }
+ x.before = magic32
+ x.after = magic32
+ v := int32(0)
+ for delta := int32(1); delta+delta > delta; delta += delta {
+ x.i.Store(v)
+ if x.i.Load() != v {
+ t.Fatalf("delta=%d i=%d v=%d", delta, x.i.Load(), v)
+ }
+ v += delta
+ }
+ if x.before != magic32 || x.after != magic32 {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
+ }
+}
+
func TestStoreUint32(t *testing.T) {
var x struct {
before uint32
}
}
+func TestStoreUint32Method(t *testing.T) {
+ var x struct {
+ before uint32
+ i Uint32
+ after uint32
+ }
+ x.before = magic32
+ x.after = magic32
+ v := uint32(0)
+ for delta := uint32(1); delta+delta > delta; delta += delta {
+ x.i.Store(v)
+ if x.i.Load() != v {
+ t.Fatalf("delta=%d i=%d v=%d", delta, x.i.Load(), v)
+ }
+ v += delta
+ }
+ if x.before != magic32 || x.after != magic32 {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
+ }
+}
+
func TestStoreInt64(t *testing.T) {
if test64err != nil {
t.Skipf("Skipping 64-bit tests: %v", test64err)
i int64
after int64
}
+ magic64 := int64(magic64)
x.before = magic64
x.after = magic64
v := int64(0)
v += delta
}
if x.before != magic64 || x.after != magic64 {
- t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
+ }
+}
+
+func TestStoreInt64Method(t *testing.T) {
+ var x struct {
+ before int64
+ i Int64
+ after int64
+ }
+ magic64 := int64(magic64)
+ x.before = magic64
+ x.after = magic64
+ v := int64(0)
+ for delta := int64(1); delta+delta > delta; delta += delta {
+ x.i.Store(v)
+ if x.i.Load() != v {
+ t.Fatalf("delta=%d i=%d v=%d", delta, x.i.Load(), v)
+ }
+ v += delta
+ }
+ if x.before != magic64 || x.after != magic64 {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
}
}
i uint64
after uint64
}
+ magic64 := uint64(magic64)
x.before = magic64
x.after = magic64
v := uint64(0)
v += delta
}
if x.before != magic64 || x.after != magic64 {
- t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
+ }
+}
+
+func TestStoreUint64Method(t *testing.T) {
+ if test64err != nil {
+ t.Skipf("Skipping 64-bit tests: %v", test64err)
+ }
+ var x struct {
+ before uint64
+ i Uint64
+ after uint64
+ }
+ magic64 := uint64(magic64)
+ x.before = magic64
+ x.after = magic64
+ v := uint64(0)
+ for delta := uint64(1); delta+delta > delta; delta += delta {
+ x.i.Store(v)
+ if x.i.Load() != v {
+ t.Fatalf("delta=%d i=%d v=%d", delta, x.i.Load(), v)
+ }
+ v += delta
+ }
+ if x.before != magic64 || x.after != magic64 {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
}
}
}
}
+func TestStoreUintptrMethod(t *testing.T) {
+ var x struct {
+ before uintptr
+ i Uintptr
+ after uintptr
+ }
+ var m uint64 = magic64
+ magicptr := uintptr(m)
+ x.before = magicptr
+ x.after = magicptr
+ v := uintptr(0)
+ for delta := uintptr(1); delta+delta > delta; delta += delta {
+ x.i.Store(v)
+ if x.i.Load() != v {
+ t.Fatalf("delta=%d i=%d v=%d", delta, x.i.Load(), v)
+ }
+ v += delta
+ }
+ if x.before != magicptr || x.after != magicptr {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
+ }
+}
+
func TestStorePointer(t *testing.T) {
var x struct {
before uintptr
}
}
+func TestStorePointerMethod(t *testing.T) {
+ var x struct {
+ before uintptr
+ i Pointer[byte]
+ after uintptr
+ }
+ var m uint64 = magic64
+ magicptr := uintptr(m)
+ x.before = magicptr
+ x.after = magicptr
+ for _, p := range testPointers() {
+ p := (*byte)(p)
+ x.i.Store(p)
+ if x.i.Load() != p {
+ t.Fatalf("x.i=%p p=%p", x.i.Load(), p)
+ }
+ }
+ if x.before != magicptr || x.after != magicptr {
+ t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
+ }
+}
+
// Tests of correct behavior, with contention.
// (Is the function atomic?)
//
"CompareAndSwapInt32": hammerCompareAndSwapInt32,
"CompareAndSwapUint32": hammerCompareAndSwapUint32,
"CompareAndSwapUintptr": hammerCompareAndSwapUintptr32,
+
+ "SwapInt32Method": hammerSwapInt32Method,
+ "SwapUint32Method": hammerSwapUint32Method,
+ "SwapUintptrMethod": hammerSwapUintptr32Method,
+ "AddInt32Method": hammerAddInt32Method,
+ "AddUint32Method": hammerAddUint32Method,
+ "AddUintptrMethod": hammerAddUintptr32Method,
+ "CompareAndSwapInt32Method": hammerCompareAndSwapInt32Method,
+ "CompareAndSwapUint32Method": hammerCompareAndSwapUint32Method,
+ "CompareAndSwapUintptrMethod": hammerCompareAndSwapUintptr32Method,
}
func init() {
delete(hammer32, "SwapUintptr")
delete(hammer32, "AddUintptr")
delete(hammer32, "CompareAndSwapUintptr")
+ delete(hammer32, "SwapUintptrMethod")
+ delete(hammer32, "AddUintptrMethod")
+ delete(hammer32, "CompareAndSwapUintptrMethod")
}
}
}
}
+func hammerSwapInt32Method(uaddr *uint32, count int) {
+ addr := (*Int32)(unsafe.Pointer(uaddr))
+ seed := int(uintptr(unsafe.Pointer(&count)))
+ for i := 0; i < count; i++ {
+ new := uint32(seed+i)<<16 | uint32(seed+i)<<16>>16
+ old := uint32(addr.Swap(int32(new)))
+ if old>>16 != old<<16>>16 {
+ panic(fmt.Sprintf("SwapInt32 is not atomic: %v", old))
+ }
+ }
+}
+
func hammerSwapUint32(addr *uint32, count int) {
seed := int(uintptr(unsafe.Pointer(&count)))
for i := 0; i < count; i++ {
}
}
+func hammerSwapUint32Method(uaddr *uint32, count int) {
+ addr := (*Uint32)(unsafe.Pointer(uaddr))
+ seed := int(uintptr(unsafe.Pointer(&count)))
+ for i := 0; i < count; i++ {
+ new := uint32(seed+i)<<16 | uint32(seed+i)<<16>>16
+ old := addr.Swap(new)
+ if old>>16 != old<<16>>16 {
+ panic(fmt.Sprintf("SwapUint32 is not atomic: %v", old))
+ }
+ }
+}
+
func hammerSwapUintptr32(uaddr *uint32, count int) {
// only safe when uintptr is 32-bit.
// not called on 64-bit systems.
}
}
+func hammerSwapUintptr32Method(uaddr *uint32, count int) {
+ // only safe when uintptr is 32-bit.
+ // not called on 64-bit systems.
+ addr := (*Uintptr)(unsafe.Pointer(uaddr))
+ seed := int(uintptr(unsafe.Pointer(&count)))
+ for i := 0; i < count; i++ {
+ new := uintptr(seed+i)<<16 | uintptr(seed+i)<<16>>16
+ old := addr.Swap(new)
+ if old>>16 != old<<16>>16 {
+ panic(fmt.Sprintf("Uintptr.Swap is not atomic: %#08x", old))
+ }
+ }
+}
+
func hammerAddInt32(uaddr *uint32, count int) {
addr := (*int32)(unsafe.Pointer(uaddr))
for i := 0; i < count; i++ {
}
}
+func hammerAddInt32Method(uaddr *uint32, count int) {
+ addr := (*Int32)(unsafe.Pointer(uaddr))
+ for i := 0; i < count; i++ {
+ addr.Add(1)
+ }
+}
+
func hammerAddUint32(addr *uint32, count int) {
for i := 0; i < count; i++ {
AddUint32(addr, 1)
}
}
+func hammerAddUint32Method(uaddr *uint32, count int) {
+ addr := (*Uint32)(unsafe.Pointer(uaddr))
+ for i := 0; i < count; i++ {
+ addr.Add(1)
+ }
+}
+
func hammerAddUintptr32(uaddr *uint32, count int) {
// only safe when uintptr is 32-bit.
// not called on 64-bit systems.
}
}
+func hammerAddUintptr32Method(uaddr *uint32, count int) {
+ // only safe when uintptr is 32-bit.
+ // not called on 64-bit systems.
+ addr := (*Uintptr)(unsafe.Pointer(uaddr))
+ for i := 0; i < count; i++ {
+ addr.Add(1)
+ }
+}
+
func hammerCompareAndSwapInt32(uaddr *uint32, count int) {
addr := (*int32)(unsafe.Pointer(uaddr))
for i := 0; i < count; i++ {
}
}
+func hammerCompareAndSwapInt32Method(uaddr *uint32, count int) {
+ addr := (*Int32)(unsafe.Pointer(uaddr))
+ for i := 0; i < count; i++ {
+ for {
+ v := addr.Load()
+ if addr.CompareAndSwap(v, v+1) {
+ break
+ }
+ }
+ }
+}
+
func hammerCompareAndSwapUint32(addr *uint32, count int) {
for i := 0; i < count; i++ {
for {
}
}
+func hammerCompareAndSwapUint32Method(uaddr *uint32, count int) {
+ addr := (*Uint32)(unsafe.Pointer(uaddr))
+ for i := 0; i < count; i++ {
+ for {
+ v := addr.Load()
+ if addr.CompareAndSwap(v, v+1) {
+ break
+ }
+ }
+ }
+}
+
func hammerCompareAndSwapUintptr32(uaddr *uint32, count int) {
// only safe when uintptr is 32-bit.
// not called on 64-bit systems.
}
}
+func hammerCompareAndSwapUintptr32Method(uaddr *uint32, count int) {
+ // only safe when uintptr is 32-bit.
+ // not called on 64-bit systems.
+ addr := (*Uintptr)(unsafe.Pointer(uaddr))
+ for i := 0; i < count; i++ {
+ for {
+ v := addr.Load()
+ if addr.CompareAndSwap(v, v+1) {
+ break
+ }
+ }
+ }
+}
+
func TestHammer32(t *testing.T) {
const p = 4
n := 100000
"CompareAndSwapInt64": hammerCompareAndSwapInt64,
"CompareAndSwapUint64": hammerCompareAndSwapUint64,
"CompareAndSwapUintptr": hammerCompareAndSwapUintptr64,
+
+ "SwapInt64Method": hammerSwapInt64Method,
+ "SwapUint64Method": hammerSwapUint64Method,
+ "SwapUintptrMethod": hammerSwapUintptr64Method,
+ "AddInt64Method": hammerAddInt64Method,
+ "AddUint64Method": hammerAddUint64Method,
+ "AddUintptrMethod": hammerAddUintptr64Method,
+ "CompareAndSwapInt64Method": hammerCompareAndSwapInt64Method,
+ "CompareAndSwapUint64Method": hammerCompareAndSwapUint64Method,
+ "CompareAndSwapUintptrMethod": hammerCompareAndSwapUintptr64Method,
}
func init() {
}
}
+func hammerSwapInt64Method(uaddr *uint64, count int) {
+ addr := (*Int64)(unsafe.Pointer(uaddr))
+ seed := int(uintptr(unsafe.Pointer(&count)))
+ for i := 0; i < count; i++ {
+ new := uint64(seed+i)<<32 | uint64(seed+i)<<32>>32
+ old := uint64(addr.Swap(int64(new)))
+ if old>>32 != old<<32>>32 {
+ panic(fmt.Sprintf("SwapInt64 is not atomic: %v", old))
+ }
+ }
+}
+
func hammerSwapUint64(addr *uint64, count int) {
seed := int(uintptr(unsafe.Pointer(&count)))
for i := 0; i < count; i++ {
}
}
+func hammerSwapUint64Method(uaddr *uint64, count int) {
+ addr := (*Uint64)(unsafe.Pointer(uaddr))
+ seed := int(uintptr(unsafe.Pointer(&count)))
+ for i := 0; i < count; i++ {
+ new := uint64(seed+i)<<32 | uint64(seed+i)<<32>>32
+ old := addr.Swap(new)
+ if old>>32 != old<<32>>32 {
+ panic(fmt.Sprintf("SwapUint64 is not atomic: %v", old))
+ }
+ }
+}
+
const arch32 = unsafe.Sizeof(uintptr(0)) == 4
func hammerSwapUintptr64(uaddr *uint64, count int) {
}
}
+func hammerSwapUintptr64Method(uaddr *uint64, count int) {
+ // only safe when uintptr is 64-bit.
+ // not called on 32-bit systems.
+ if !arch32 {
+ addr := (*Uintptr)(unsafe.Pointer(uaddr))
+ seed := int(uintptr(unsafe.Pointer(&count)))
+ for i := 0; i < count; i++ {
+ new := uintptr(seed+i)<<32 | uintptr(seed+i)<<32>>32
+ old := addr.Swap(new)
+ if old>>32 != old<<32>>32 {
+ panic(fmt.Sprintf("SwapUintptr is not atomic: %v", old))
+ }
+ }
+ }
+}
+
func hammerAddInt64(uaddr *uint64, count int) {
addr := (*int64)(unsafe.Pointer(uaddr))
for i := 0; i < count; i++ {
}
}
+func hammerAddInt64Method(uaddr *uint64, count int) {
+ addr := (*Int64)(unsafe.Pointer(uaddr))
+ for i := 0; i < count; i++ {
+ addr.Add(1)
+ }
+}
+
func hammerAddUint64(addr *uint64, count int) {
for i := 0; i < count; i++ {
AddUint64(addr, 1)
}
}
+func hammerAddUint64Method(uaddr *uint64, count int) {
+ addr := (*Uint64)(unsafe.Pointer(uaddr))
+ for i := 0; i < count; i++ {
+ addr.Add(1)
+ }
+}
+
func hammerAddUintptr64(uaddr *uint64, count int) {
// only safe when uintptr is 64-bit.
// not called on 32-bit systems.
}
}
+func hammerAddUintptr64Method(uaddr *uint64, count int) {
+ // only safe when uintptr is 64-bit.
+ // not called on 32-bit systems.
+ addr := (*Uintptr)(unsafe.Pointer(uaddr))
+ for i := 0; i < count; i++ {
+ addr.Add(1)
+ }
+}
+
func hammerCompareAndSwapInt64(uaddr *uint64, count int) {
addr := (*int64)(unsafe.Pointer(uaddr))
for i := 0; i < count; i++ {
}
}
+func hammerCompareAndSwapInt64Method(uaddr *uint64, count int) {
+ addr := (*Int64)(unsafe.Pointer(uaddr))
+ for i := 0; i < count; i++ {
+ for {
+ v := addr.Load()
+ if addr.CompareAndSwap(v, v+1) {
+ break
+ }
+ }
+ }
+}
+
func hammerCompareAndSwapUint64(addr *uint64, count int) {
for i := 0; i < count; i++ {
for {
}
}
+func hammerCompareAndSwapUint64Method(uaddr *uint64, count int) {
+ addr := (*Uint64)(unsafe.Pointer(uaddr))
+ for i := 0; i < count; i++ {
+ for {
+ v := addr.Load()
+ if addr.CompareAndSwap(v, v+1) {
+ break
+ }
+ }
+ }
+}
+
func hammerCompareAndSwapUintptr64(uaddr *uint64, count int) {
// only safe when uintptr is 64-bit.
// not called on 32-bit systems.
}
}
+func hammerCompareAndSwapUintptr64Method(uaddr *uint64, count int) {
+ // only safe when uintptr is 64-bit.
+ // not called on 32-bit systems.
+ addr := (*Uintptr)(unsafe.Pointer(uaddr))
+ for i := 0; i < count; i++ {
+ for {
+ v := addr.Load()
+ if addr.CompareAndSwap(v, v+1) {
+ break
+ }
+ }
+ }
+}
+
func TestHammer64(t *testing.T) {
if test64err != nil {
t.Skipf("Skipping 64-bit tests: %v", test64err)
StoreInt32(addr, new)
}
+func hammerStoreLoadInt32Method(t *testing.T, paddr unsafe.Pointer) {
+ addr := (*int32)(paddr)
+ v := LoadInt32(addr)
+ vlo := v & ((1 << 16) - 1)
+ vhi := v >> 16
+ if vlo != vhi {
+ t.Fatalf("Int32: %#x != %#x", vlo, vhi)
+ }
+ new := v + 1 + 1<<16
+ if vlo == 1e4 {
+ new = 0
+ }
+ StoreInt32(addr, new)
+}
+
func hammerStoreLoadUint32(t *testing.T, paddr unsafe.Pointer) {
addr := (*uint32)(paddr)
v := LoadUint32(addr)
StoreUint32(addr, new)
}
+func hammerStoreLoadUint32Method(t *testing.T, paddr unsafe.Pointer) {
+ addr := (*Uint32)(paddr)
+ v := addr.Load()
+ vlo := v & ((1 << 16) - 1)
+ vhi := v >> 16
+ if vlo != vhi {
+ t.Fatalf("Uint32: %#x != %#x", vlo, vhi)
+ }
+ new := v + 1 + 1<<16
+ if vlo == 1e4 {
+ new = 0
+ }
+ addr.Store(new)
+}
+
func hammerStoreLoadInt64(t *testing.T, paddr unsafe.Pointer) {
addr := (*int64)(paddr)
v := LoadInt64(addr)
StoreInt64(addr, new)
}
+func hammerStoreLoadInt64Method(t *testing.T, paddr unsafe.Pointer) {
+ addr := (*Int64)(paddr)
+ v := addr.Load()
+ vlo := v & ((1 << 32) - 1)
+ vhi := v >> 32
+ if vlo != vhi {
+ t.Fatalf("Int64: %#x != %#x", vlo, vhi)
+ }
+ new := v + 1 + 1<<32
+ addr.Store(new)
+}
+
func hammerStoreLoadUint64(t *testing.T, paddr unsafe.Pointer) {
addr := (*uint64)(paddr)
v := LoadUint64(addr)
StoreUint64(addr, new)
}
+func hammerStoreLoadUint64Method(t *testing.T, paddr unsafe.Pointer) {
+ addr := (*Uint64)(paddr)
+ v := addr.Load()
+ vlo := v & ((1 << 32) - 1)
+ vhi := v >> 32
+ if vlo != vhi {
+ t.Fatalf("Uint64: %#x != %#x", vlo, vhi)
+ }
+ new := v + 1 + 1<<32
+ addr.Store(new)
+}
+
func hammerStoreLoadUintptr(t *testing.T, paddr unsafe.Pointer) {
addr := (*uintptr)(paddr)
v := LoadUintptr(addr)
StoreUintptr(addr, new)
}
+//go:nocheckptr
+func hammerStoreLoadUintptrMethod(t *testing.T, paddr unsafe.Pointer) {
+ addr := (*Uintptr)(paddr)
+ v := addr.Load()
+ new := v
+ if arch32 {
+ vlo := v & ((1 << 16) - 1)
+ vhi := v >> 16
+ if vlo != vhi {
+ t.Fatalf("Uintptr: %#x != %#x", vlo, vhi)
+ }
+ new = v + 1 + 1<<16
+ if vlo == 1e4 {
+ new = 0
+ }
+ } else {
+ vlo := v & ((1 << 32) - 1)
+ vhi := v >> 32
+ if vlo != vhi {
+ t.Fatalf("Uintptr: %#x != %#x", vlo, vhi)
+ }
+ inc := uint64(1 + 1<<32)
+ new = v + uintptr(inc)
+ }
+ addr.Store(new)
+}
+
// This code is just testing that LoadPointer/StorePointer operate
// atomically; it's not actually calculating pointers.
//
StorePointer(addr, unsafe.Pointer(new))
}
+// This code is just testing that LoadPointer/StorePointer operate
+// atomically; it's not actually calculating pointers.
+//
+//go:nocheckptr
+func hammerStoreLoadPointerMethod(t *testing.T, paddr unsafe.Pointer) {
+ addr := (*Pointer[byte])(paddr)
+ v := uintptr(unsafe.Pointer(addr.Load()))
+ new := v
+ if arch32 {
+ vlo := v & ((1 << 16) - 1)
+ vhi := v >> 16
+ if vlo != vhi {
+ t.Fatalf("Pointer: %#x != %#x", vlo, vhi)
+ }
+ new = v + 1 + 1<<16
+ if vlo == 1e4 {
+ new = 0
+ }
+ } else {
+ vlo := v & ((1 << 32) - 1)
+ vhi := v >> 32
+ if vlo != vhi {
+ t.Fatalf("Pointer: %#x != %#x", vlo, vhi)
+ }
+ inc := uint64(1 + 1<<32)
+ new = v + uintptr(inc)
+ }
+ addr.Store((*byte)(unsafe.Pointer(new)))
+}
+
func TestHammerStoreLoad(t *testing.T) {
var tests []func(*testing.T, unsafe.Pointer)
tests = append(tests, hammerStoreLoadInt32, hammerStoreLoadUint32,
- hammerStoreLoadUintptr, hammerStoreLoadPointer)
+ hammerStoreLoadUintptr, hammerStoreLoadPointer,
+ hammerStoreLoadInt32Method, hammerStoreLoadUint32Method,
+ hammerStoreLoadUintptrMethod, hammerStoreLoadPointerMethod,
+ )
if test64err == nil {
- tests = append(tests, hammerStoreLoadInt64, hammerStoreLoadUint64)
+ tests = append(tests, hammerStoreLoadInt64, hammerStoreLoadUint64,
+ hammerStoreLoadInt64Method, hammerStoreLoadUint64Method,
+ )
}
n := int(1e6)
if testing.Short() {
p := (*uint64)(unsafe.Pointer(&x[1])) // misaligned
shouldPanic(t, "LoadUint64", func() { LoadUint64(p) })
+ shouldPanic(t, "LoadUint64Method", func() { (*Uint64)(unsafe.Pointer(p)).Load() })
shouldPanic(t, "StoreUint64", func() { StoreUint64(p, 1) })
+ shouldPanic(t, "StoreUint64Method", func() { (*Uint64)(unsafe.Pointer(p)).Store(1) })
shouldPanic(t, "CompareAndSwapUint64", func() { CompareAndSwapUint64(p, 1, 2) })
+ shouldPanic(t, "CompareAndSwapUint64Method", func() { (*Uint64)(unsafe.Pointer(p)).CompareAndSwap(1, 2) })
shouldPanic(t, "AddUint64", func() { AddUint64(p, 3) })
+ shouldPanic(t, "AddUint64Method", func() { (*Uint64)(unsafe.Pointer(p)).Add(3) })
+}
+
+func TestAutoAligned64(t *testing.T) {
+ var signed struct {
+ _ uint32
+ i Int64
+ }
+ if o := reflect.TypeOf(&signed).Elem().Field(1).Offset; o != 8 {
+ t.Fatalf("Int64 offset = %d, want 8", o)
+ }
+ if p := reflect.ValueOf(&signed).Elem().Field(1).Addr().Pointer(); p&7 != 0 {
+ t.Fatalf("Int64 pointer = %#x, want 8-aligned", p)
+ }
+
+ var unsigned struct {
+ _ uint32
+ i Uint64
+ }
+ if o := reflect.TypeOf(&unsigned).Elem().Field(1).Offset; o != 8 {
+ t.Fatalf("Uint64 offset = %d, want 8", o)
+ }
+ if p := reflect.ValueOf(&unsigned).Elem().Field(1).Addr().Pointer(); p&7 != 0 {
+ t.Fatalf("Int64 pointer = %#x, want 8-aligned", p)
+ }
}
func TestNilDeref(t *testing.T) {
funcs := [...]func(){
func() { CompareAndSwapInt32(nil, 0, 0) },
+ func() { (*Int32)(nil).CompareAndSwap(0, 0) },
func() { CompareAndSwapInt64(nil, 0, 0) },
+ func() { (*Int64)(nil).CompareAndSwap(0, 0) },
func() { CompareAndSwapUint32(nil, 0, 0) },
+ func() { (*Uint32)(nil).CompareAndSwap(0, 0) },
func() { CompareAndSwapUint64(nil, 0, 0) },
+ func() { (*Uint64)(nil).CompareAndSwap(0, 0) },
func() { CompareAndSwapUintptr(nil, 0, 0) },
+ func() { (*Uintptr)(nil).CompareAndSwap(0, 0) },
func() { CompareAndSwapPointer(nil, nil, nil) },
+ func() { (*Pointer[byte])(nil).CompareAndSwap(nil, nil) },
func() { SwapInt32(nil, 0) },
+ func() { (*Int32)(nil).Swap(0) },
func() { SwapUint32(nil, 0) },
+ func() { (*Uint32)(nil).Swap(0) },
func() { SwapInt64(nil, 0) },
+ func() { (*Int64)(nil).Swap(0) },
func() { SwapUint64(nil, 0) },
+ func() { (*Uint64)(nil).Swap(0) },
func() { SwapUintptr(nil, 0) },
+ func() { (*Uintptr)(nil).Swap(0) },
func() { SwapPointer(nil, nil) },
+ func() { (*Pointer[byte])(nil).Swap(nil) },
func() { AddInt32(nil, 0) },
+ func() { (*Int32)(nil).Add(0) },
func() { AddUint32(nil, 0) },
+ func() { (*Uint32)(nil).Add(0) },
func() { AddInt64(nil, 0) },
+ func() { (*Int64)(nil).Add(0) },
func() { AddUint64(nil, 0) },
+ func() { (*Uint64)(nil).Add(0) },
func() { AddUintptr(nil, 0) },
+ func() { (*Uintptr)(nil).Add(0) },
func() { LoadInt32(nil) },
+ func() { (*Int32)(nil).Load() },
func() { LoadInt64(nil) },
+ func() { (*Int64)(nil).Load() },
func() { LoadUint32(nil) },
+ func() { (*Uint32)(nil).Load() },
func() { LoadUint64(nil) },
+ func() { (*Uint64)(nil).Load() },
func() { LoadUintptr(nil) },
+ func() { (*Uintptr)(nil).Load() },
func() { LoadPointer(nil) },
+ func() { (*Pointer[byte])(nil).Load() },
func() { StoreInt32(nil, 0) },
+ func() { (*Int32)(nil).Store(0) },
func() { StoreInt64(nil, 0) },
+ func() { (*Int64)(nil).Store(0) },
func() { StoreUint32(nil, 0) },
+ func() { (*Uint32)(nil).Store(0) },
func() { StoreUint64(nil, 0) },
+ func() { (*Uint64)(nil).Store(0) },
func() { StoreUintptr(nil, 0) },
+ func() { (*Uintptr)(nil).Store(0) },
func() { StorePointer(nil, nil) },
+ func() { (*Pointer[byte])(nil).Store(nil) },
}
for _, f := range funcs {
func() {