Source file src/sync/atomic/atomic_test.go

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package atomic_test
     6  
     7  import (
     8  	"fmt"
     9  	"reflect"
    10  	"runtime"
    11  	"runtime/debug"
    12  	"strings"
    13  	. "sync/atomic"
    14  	"testing"
    15  	"unsafe"
    16  )
    17  
    18  // Tests of correct behavior, without contention.
    19  // (Does the function work as advertised?)
    20  //
    21  // Test that the Add functions add correctly.
    22  // Test that the CompareAndSwap functions actually
    23  // do the comparison and the swap correctly.
    24  //
    25  // The loop over power-of-two values is meant to
    26  // ensure that the operations apply to the full word size.
    27  // The struct fields x.before and x.after check that the
    28  // operations do not extend past the full word size.
    29  
    30  const (
    31  	magic32 = 0xdedbeef
    32  	magic64 = 0xdeddeadbeefbeef
    33  )
    34  
    35  func TestSwapInt32(t *testing.T) {
    36  	var x struct {
    37  		before int32
    38  		i      int32
    39  		after  int32
    40  	}
    41  	x.before = magic32
    42  	x.after = magic32
    43  	var j int32
    44  	for delta := int32(1); delta+delta > delta; delta += delta {
    45  		k := SwapInt32(&x.i, delta)
    46  		if x.i != delta || k != j {
    47  			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
    48  		}
    49  		j = delta
    50  	}
    51  	if x.before != magic32 || x.after != magic32 {
    52  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
    53  	}
    54  }
    55  
    56  func TestSwapInt32Method(t *testing.T) {
    57  	var x struct {
    58  		before int32
    59  		i      Int32
    60  		after  int32
    61  	}
    62  	x.before = magic32
    63  	x.after = magic32
    64  	var j int32
    65  	for delta := int32(1); delta+delta > delta; delta += delta {
    66  		k := x.i.Swap(delta)
    67  		if x.i.Load() != delta || k != j {
    68  			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i.Load(), j, k)
    69  		}
    70  		j = delta
    71  	}
    72  	if x.before != magic32 || x.after != magic32 {
    73  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
    74  	}
    75  }
    76  
    77  func TestSwapUint32(t *testing.T) {
    78  	var x struct {
    79  		before uint32
    80  		i      uint32
    81  		after  uint32
    82  	}
    83  	x.before = magic32
    84  	x.after = magic32
    85  	var j uint32
    86  	for delta := uint32(1); delta+delta > delta; delta += delta {
    87  		k := SwapUint32(&x.i, delta)
    88  		if x.i != delta || k != j {
    89  			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
    90  		}
    91  		j = delta
    92  	}
    93  	if x.before != magic32 || x.after != magic32 {
    94  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
    95  	}
    96  }
    97  
    98  func TestSwapUint32Method(t *testing.T) {
    99  	var x struct {
   100  		before uint32
   101  		i      Uint32
   102  		after  uint32
   103  	}
   104  	x.before = magic32
   105  	x.after = magic32
   106  	var j uint32
   107  	for delta := uint32(1); delta+delta > delta; delta += delta {
   108  		k := x.i.Swap(delta)
   109  		if x.i.Load() != delta || k != j {
   110  			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i.Load(), j, k)
   111  		}
   112  		j = delta
   113  	}
   114  	if x.before != magic32 || x.after != magic32 {
   115  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
   116  	}
   117  }
   118  
   119  func TestSwapInt64(t *testing.T) {
   120  	var x struct {
   121  		before int64
   122  		i      int64
   123  		after  int64
   124  	}
   125  	magic64 := int64(magic64)
   126  	x.before = magic64
   127  	x.after = magic64
   128  	var j int64
   129  	for delta := int64(1); delta+delta > delta; delta += delta {
   130  		k := SwapInt64(&x.i, delta)
   131  		if x.i != delta || k != j {
   132  			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
   133  		}
   134  		j = delta
   135  	}
   136  	if x.before != magic64 || x.after != magic64 {
   137  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
   138  	}
   139  }
   140  
   141  func TestSwapInt64Method(t *testing.T) {
   142  	var x struct {
   143  		before int64
   144  		i      Int64
   145  		after  int64
   146  	}
   147  	magic64 := int64(magic64)
   148  	x.before = magic64
   149  	x.after = magic64
   150  	var j int64
   151  	for delta := int64(1); delta+delta > delta; delta += delta {
   152  		k := x.i.Swap(delta)
   153  		if x.i.Load() != delta || k != j {
   154  			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i.Load(), j, k)
   155  		}
   156  		j = delta
   157  	}
   158  	if x.before != magic64 || x.after != magic64 {
   159  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
   160  	}
   161  }
   162  
   163  func TestSwapUint64(t *testing.T) {
   164  	var x struct {
   165  		before uint64
   166  		i      uint64
   167  		after  uint64
   168  	}
   169  	magic64 := uint64(magic64)
   170  	x.before = magic64
   171  	x.after = magic64
   172  	var j uint64
   173  	for delta := uint64(1); delta+delta > delta; delta += delta {
   174  		k := SwapUint64(&x.i, delta)
   175  		if x.i != delta || k != j {
   176  			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
   177  		}
   178  		j = delta
   179  	}
   180  	if x.before != magic64 || x.after != magic64 {
   181  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
   182  	}
   183  }
   184  
   185  func TestSwapUint64Method(t *testing.T) {
   186  	var x struct {
   187  		before uint64
   188  		i      Uint64
   189  		after  uint64
   190  	}
   191  	magic64 := uint64(magic64)
   192  	x.before = magic64
   193  	x.after = magic64
   194  	var j uint64
   195  	for delta := uint64(1); delta+delta > delta; delta += delta {
   196  		k := x.i.Swap(delta)
   197  		if x.i.Load() != delta || k != j {
   198  			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i.Load(), j, k)
   199  		}
   200  		j = delta
   201  	}
   202  	if x.before != magic64 || x.after != magic64 {
   203  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
   204  	}
   205  }
   206  
   207  func TestSwapUintptr(t *testing.T) {
   208  	var x struct {
   209  		before uintptr
   210  		i      uintptr
   211  		after  uintptr
   212  	}
   213  	var m uint64 = magic64
   214  	magicptr := uintptr(m)
   215  	x.before = magicptr
   216  	x.after = magicptr
   217  	var j uintptr
   218  	for delta := uintptr(1); delta+delta > delta; delta += delta {
   219  		k := SwapUintptr(&x.i, delta)
   220  		if x.i != delta || k != j {
   221  			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
   222  		}
   223  		j = delta
   224  	}
   225  	if x.before != magicptr || x.after != magicptr {
   226  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
   227  	}
   228  }
   229  
   230  func TestSwapUintptrMethod(t *testing.T) {
   231  	var x struct {
   232  		before uintptr
   233  		i      Uintptr
   234  		after  uintptr
   235  	}
   236  	var m uint64 = magic64
   237  	magicptr := uintptr(m)
   238  	x.before = magicptr
   239  	x.after = magicptr
   240  	var j uintptr
   241  	for delta := uintptr(1); delta+delta > delta; delta += delta {
   242  		k := x.i.Swap(delta)
   243  		if x.i.Load() != delta || k != j {
   244  			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i.Load(), j, k)
   245  		}
   246  		j = delta
   247  	}
   248  	if x.before != magicptr || x.after != magicptr {
   249  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
   250  	}
   251  }
   252  
   253  var global [1024]byte
   254  
   255  func testPointers() []unsafe.Pointer {
   256  	var pointers []unsafe.Pointer
   257  	// globals
   258  	for i := 0; i < 10; i++ {
   259  		pointers = append(pointers, unsafe.Pointer(&global[1<<i-1]))
   260  	}
   261  	// heap
   262  	pointers = append(pointers, unsafe.Pointer(new(byte)))
   263  	// nil
   264  	pointers = append(pointers, nil)
   265  	return pointers
   266  }
   267  
   268  func TestSwapPointer(t *testing.T) {
   269  	var x struct {
   270  		before uintptr
   271  		i      unsafe.Pointer
   272  		after  uintptr
   273  	}
   274  	var m uint64 = magic64
   275  	magicptr := uintptr(m)
   276  	x.before = magicptr
   277  	x.after = magicptr
   278  	var j unsafe.Pointer
   279  
   280  	for _, p := range testPointers() {
   281  		k := SwapPointer(&x.i, p)
   282  		if x.i != p || k != j {
   283  			t.Fatalf("p=%p i=%p j=%p k=%p", p, x.i, j, k)
   284  		}
   285  		j = p
   286  	}
   287  	if x.before != magicptr || x.after != magicptr {
   288  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
   289  	}
   290  }
   291  
   292  func TestSwapPointerMethod(t *testing.T) {
   293  	var x struct {
   294  		before uintptr
   295  		i      Pointer[byte]
   296  		after  uintptr
   297  	}
   298  	var m uint64 = magic64
   299  	magicptr := uintptr(m)
   300  	x.before = magicptr
   301  	x.after = magicptr
   302  	var j *byte
   303  	for _, p := range testPointers() {
   304  		p := (*byte)(p)
   305  		k := x.i.Swap(p)
   306  		if x.i.Load() != p || k != j {
   307  			t.Fatalf("p=%p i=%p j=%p k=%p", p, x.i.Load(), j, k)
   308  		}
   309  		j = p
   310  	}
   311  	if x.before != magicptr || x.after != magicptr {
   312  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
   313  	}
   314  }
   315  
   316  func TestAddInt32(t *testing.T) {
   317  	var x struct {
   318  		before int32
   319  		i      int32
   320  		after  int32
   321  	}
   322  	x.before = magic32
   323  	x.after = magic32
   324  	var j int32
   325  	for delta := int32(1); delta+delta > delta; delta += delta {
   326  		k := AddInt32(&x.i, delta)
   327  		j += delta
   328  		if x.i != j || k != j {
   329  			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
   330  		}
   331  	}
   332  	if x.before != magic32 || x.after != magic32 {
   333  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
   334  	}
   335  }
   336  
   337  func TestAddInt32Method(t *testing.T) {
   338  	var x struct {
   339  		before int32
   340  		i      Int32
   341  		after  int32
   342  	}
   343  	x.before = magic32
   344  	x.after = magic32
   345  	var j int32
   346  	for delta := int32(1); delta+delta > delta; delta += delta {
   347  		k := x.i.Add(delta)
   348  		j += delta
   349  		if x.i.Load() != j || k != j {
   350  			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i.Load(), j, k)
   351  		}
   352  	}
   353  	if x.before != magic32 || x.after != magic32 {
   354  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
   355  	}
   356  }
   357  
   358  func TestAddUint32(t *testing.T) {
   359  	var x struct {
   360  		before uint32
   361  		i      uint32
   362  		after  uint32
   363  	}
   364  	x.before = magic32
   365  	x.after = magic32
   366  	var j uint32
   367  	for delta := uint32(1); delta+delta > delta; delta += delta {
   368  		k := AddUint32(&x.i, delta)
   369  		j += delta
   370  		if x.i != j || k != j {
   371  			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
   372  		}
   373  	}
   374  	if x.before != magic32 || x.after != magic32 {
   375  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
   376  	}
   377  }
   378  
   379  func TestAddUint32Method(t *testing.T) {
   380  	var x struct {
   381  		before uint32
   382  		i      Uint32
   383  		after  uint32
   384  	}
   385  	x.before = magic32
   386  	x.after = magic32
   387  	var j uint32
   388  	for delta := uint32(1); delta+delta > delta; delta += delta {
   389  		k := x.i.Add(delta)
   390  		j += delta
   391  		if x.i.Load() != j || k != j {
   392  			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i.Load(), j, k)
   393  		}
   394  	}
   395  	if x.before != magic32 || x.after != magic32 {
   396  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
   397  	}
   398  }
   399  
   400  func TestAddInt64(t *testing.T) {
   401  	var x struct {
   402  		before int64
   403  		i      int64
   404  		after  int64
   405  	}
   406  	magic64 := int64(magic64)
   407  	x.before = magic64
   408  	x.after = magic64
   409  	var j int64
   410  	for delta := int64(1); delta+delta > delta; delta += delta {
   411  		k := AddInt64(&x.i, delta)
   412  		j += delta
   413  		if x.i != j || k != j {
   414  			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
   415  		}
   416  	}
   417  	if x.before != magic64 || x.after != magic64 {
   418  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
   419  	}
   420  }
   421  
   422  func TestAddInt64Method(t *testing.T) {
   423  	var x struct {
   424  		before int64
   425  		i      Int64
   426  		after  int64
   427  	}
   428  	magic64 := int64(magic64)
   429  	x.before = magic64
   430  	x.after = magic64
   431  	var j int64
   432  	for delta := int64(1); delta+delta > delta; delta += delta {
   433  		k := x.i.Add(delta)
   434  		j += delta
   435  		if x.i.Load() != j || k != j {
   436  			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i.Load(), j, k)
   437  		}
   438  	}
   439  	if x.before != magic64 || x.after != magic64 {
   440  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
   441  	}
   442  }
   443  
   444  func TestAddUint64(t *testing.T) {
   445  	var x struct {
   446  		before uint64
   447  		i      uint64
   448  		after  uint64
   449  	}
   450  	magic64 := uint64(magic64)
   451  	x.before = magic64
   452  	x.after = magic64
   453  	var j uint64
   454  	for delta := uint64(1); delta+delta > delta; delta += delta {
   455  		k := AddUint64(&x.i, delta)
   456  		j += delta
   457  		if x.i != j || k != j {
   458  			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
   459  		}
   460  	}
   461  	if x.before != magic64 || x.after != magic64 {
   462  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
   463  	}
   464  }
   465  
   466  func TestAddUint64Method(t *testing.T) {
   467  	var x struct {
   468  		before uint64
   469  		i      Uint64
   470  		after  uint64
   471  	}
   472  	magic64 := uint64(magic64)
   473  	x.before = magic64
   474  	x.after = magic64
   475  	var j uint64
   476  	for delta := uint64(1); delta+delta > delta; delta += delta {
   477  		k := x.i.Add(delta)
   478  		j += delta
   479  		if x.i.Load() != j || k != j {
   480  			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i.Load(), j, k)
   481  		}
   482  	}
   483  	if x.before != magic64 || x.after != magic64 {
   484  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
   485  	}
   486  }
   487  
   488  func TestAddUintptr(t *testing.T) {
   489  	var x struct {
   490  		before uintptr
   491  		i      uintptr
   492  		after  uintptr
   493  	}
   494  	var m uint64 = magic64
   495  	magicptr := uintptr(m)
   496  	x.before = magicptr
   497  	x.after = magicptr
   498  	var j uintptr
   499  	for delta := uintptr(1); delta+delta > delta; delta += delta {
   500  		k := AddUintptr(&x.i, delta)
   501  		j += delta
   502  		if x.i != j || k != j {
   503  			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
   504  		}
   505  	}
   506  	if x.before != magicptr || x.after != magicptr {
   507  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
   508  	}
   509  }
   510  
   511  func TestAddUintptrMethod(t *testing.T) {
   512  	var x struct {
   513  		before uintptr
   514  		i      Uintptr
   515  		after  uintptr
   516  	}
   517  	var m uint64 = magic64
   518  	magicptr := uintptr(m)
   519  	x.before = magicptr
   520  	x.after = magicptr
   521  	var j uintptr
   522  	for delta := uintptr(1); delta+delta > delta; delta += delta {
   523  		k := x.i.Add(delta)
   524  		j += delta
   525  		if x.i.Load() != j || k != j {
   526  			t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i.Load(), j, k)
   527  		}
   528  	}
   529  	if x.before != magicptr || x.after != magicptr {
   530  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
   531  	}
   532  }
   533  
   534  func TestAndInt32(t *testing.T) {
   535  	var x struct {
   536  		before int32
   537  		i      int32
   538  		after  int32
   539  	}
   540  	x.before = magic32
   541  	x.after = magic32
   542  	x.i = -1
   543  	j := x.i
   544  	for mask := int32(1); mask != 0; mask <<= 1 {
   545  		old := x.i
   546  		k := AndInt32(&x.i, ^mask)
   547  		j &= ^mask
   548  		if x.i != j || k != old {
   549  			t.Fatalf("mask=%d i=%d j=%d k=%d old=%d", mask, x.i, j, k, old)
   550  		}
   551  	}
   552  	if x.before != magic32 || x.after != magic32 {
   553  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
   554  	}
   555  }
   556  
   557  func TestAndInt32Method(t *testing.T) {
   558  	var x struct {
   559  		before int32
   560  		i      Int32
   561  		after  int32
   562  	}
   563  	x.before = magic32
   564  	x.after = magic32
   565  	x.i.Store(-1)
   566  	j := x.i.Load()
   567  	for mask := int32(1); mask != 0; mask <<= 1 {
   568  		old := x.i.Load()
   569  		k := x.i.And(^mask)
   570  		j &= ^mask
   571  		if x.i.Load() != j || k != old {
   572  			t.Fatalf("mask=%d i=%d j=%d k=%d old=%d", mask, x.i.Load(), j, k, old)
   573  		}
   574  	}
   575  	if x.before != magic32 || x.after != magic32 {
   576  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
   577  	}
   578  }
   579  
   580  func TestAndUint32(t *testing.T) {
   581  	var x struct {
   582  		before uint32
   583  		i      uint32
   584  		after  uint32
   585  	}
   586  	x.before = magic32
   587  	x.after = magic32
   588  	x.i = 0xffffffff
   589  	j := x.i
   590  	for mask := uint32(1); mask != 0; mask <<= 1 {
   591  		old := x.i
   592  		k := AndUint32(&x.i, ^mask)
   593  		j &= ^mask
   594  		if x.i != j || k != old {
   595  			t.Fatalf("mask=%d i=%d j=%d k=%d old=%d", mask, x.i, j, k, old)
   596  		}
   597  	}
   598  	if x.before != magic32 || x.after != magic32 {
   599  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
   600  	}
   601  }
   602  
   603  func TestAndUint32Method(t *testing.T) {
   604  	var x struct {
   605  		before uint32
   606  		i      Uint32
   607  		after  uint32
   608  	}
   609  	x.before = magic32
   610  	x.after = magic32
   611  	x.i.Store(0xffffffff)
   612  	j := x.i.Load()
   613  	for mask := uint32(1); mask != 0; mask <<= 1 {
   614  		old := x.i.Load()
   615  		k := x.i.And(^mask)
   616  		j &= ^mask
   617  		if x.i.Load() != j || k != old {
   618  			t.Fatalf("mask=%d i=%d j=%d k=%d old=%d", mask, x.i.Load(), j, k, old)
   619  		}
   620  	}
   621  	if x.before != magic32 || x.after != magic32 {
   622  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
   623  	}
   624  }
   625  
   626  func TestAndInt64(t *testing.T) {
   627  	var x struct {
   628  		before int64
   629  		i      int64
   630  		after  int64
   631  	}
   632  	magic64 := int64(magic64)
   633  	x.before = magic64
   634  	x.after = magic64
   635  	x.i = -1
   636  	j := x.i
   637  	for mask := int64(1); mask != 0; mask <<= 1 {
   638  		old := x.i
   639  		k := AndInt64(&x.i, ^mask)
   640  		j &= ^mask
   641  		if x.i != j || k != old {
   642  			t.Fatalf("mask=%d i=%d j=%d k=%d old=%d", mask, x.i, j, k, old)
   643  		}
   644  	}
   645  	if x.before != magic64 || x.after != magic64 {
   646  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
   647  	}
   648  }
   649  
   650  func TestAndInt64Method(t *testing.T) {
   651  	var x struct {
   652  		before int64
   653  		i      Int64
   654  		after  int64
   655  	}
   656  	magic64 := int64(magic64)
   657  	x.before = magic64
   658  	x.after = magic64
   659  	x.i.Store(-1)
   660  	j := x.i.Load()
   661  	for mask := int64(1); mask != 0; mask <<= 1 {
   662  		old := x.i.Load()
   663  		k := x.i.And(^mask)
   664  		j &= ^mask
   665  		if x.i.Load() != j || k != old {
   666  			t.Fatalf("mask=%d i=%d j=%d k=%d old=%d", mask, x.i.Load(), j, k, old)
   667  		}
   668  	}
   669  	if x.before != magic64 || x.after != magic64 {
   670  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
   671  	}
   672  }
   673  
   674  func TestAndUint64(t *testing.T) {
   675  	var x struct {
   676  		before uint64
   677  		i      uint64
   678  		after  uint64
   679  	}
   680  	magic64 := uint64(magic64)
   681  	x.before = magic64
   682  	x.after = magic64
   683  	x.i = 0xfffffffffffffff
   684  	j := x.i
   685  	for mask := uint64(1); mask != 0; mask <<= 1 {
   686  		old := x.i
   687  		k := AndUint64(&x.i, ^mask)
   688  		j &= ^mask
   689  		if x.i != j || k != old {
   690  			t.Fatalf("mask=%d i=%d j=%d k=%d old=%d", mask, x.i, j, k, old)
   691  		}
   692  	}
   693  	if x.before != magic64 || x.after != magic64 {
   694  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
   695  	}
   696  }
   697  
   698  func TestAndUint64Method(t *testing.T) {
   699  	var x struct {
   700  		before uint64
   701  		i      Uint64
   702  		after  uint64
   703  	}
   704  	magic64 := uint64(magic64)
   705  	x.before = magic64
   706  	x.after = magic64
   707  	x.i.Store(0xfffffffffffffff)
   708  	j := x.i.Load()
   709  	for mask := uint64(1); mask != 0; mask <<= 1 {
   710  		old := x.i.Load()
   711  		k := x.i.And(^mask)
   712  		j &= ^mask
   713  		if x.i.Load() != j || k != old {
   714  			t.Fatalf("mask=%d i=%d j=%d k=%d old=%d", mask, x.i.Load(), j, k, old)
   715  		}
   716  	}
   717  	if x.before != magic64 || x.after != magic64 {
   718  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
   719  	}
   720  }
   721  
   722  func TestAndUintptr(t *testing.T) {
   723  	var x struct {
   724  		before uintptr
   725  		i      uintptr
   726  		after  uintptr
   727  	}
   728  	var m uint64 = magic64
   729  	magicptr := uintptr(m)
   730  	x.before = magicptr
   731  	x.after = magicptr
   732  	x.i = ^uintptr(0)
   733  	j := x.i
   734  	for mask := uintptr(1); mask != 0; mask <<= 1 {
   735  		old := x.i
   736  		k := AndUintptr(&x.i, ^mask)
   737  		j &= ^mask
   738  		if x.i != j || k != old {
   739  			t.Fatalf("mask=%d i=%d j=%d k=%d old=%d", mask, x.i, j, k, old)
   740  		}
   741  	}
   742  	if x.before != magicptr || x.after != magicptr {
   743  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
   744  	}
   745  }
   746  
   747  func TestAndUintptrMethod(t *testing.T) {
   748  	var x struct {
   749  		before uintptr
   750  		i      Uintptr
   751  		after  uintptr
   752  	}
   753  	var m uint64 = magic64
   754  	magicptr := uintptr(m)
   755  	x.before = magicptr
   756  	x.after = magicptr
   757  	x.i.Store(^uintptr(0))
   758  	j := x.i.Load()
   759  	for mask := uintptr(1); mask != 0; mask <<= 1 {
   760  		old := x.i.Load()
   761  		k := x.i.And(^mask)
   762  		j &= ^mask
   763  		if x.i.Load() != j || k != old {
   764  			t.Fatalf("mask=%d i=%d j=%d k=%d old=%d", mask, x.i.Load(), j, k, old)
   765  		}
   766  	}
   767  	if x.before != magicptr || x.after != magicptr {
   768  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
   769  	}
   770  }
   771  
   772  func TestOrInt32(t *testing.T) {
   773  	var x struct {
   774  		before int32
   775  		i      int32
   776  		after  int32
   777  	}
   778  	x.before = magic32
   779  	x.after = magic32
   780  	var j int32
   781  	for mask := int32(1); mask != 0; mask <<= 1 {
   782  		old := x.i
   783  		k := OrInt32(&x.i, mask)
   784  		j |= mask
   785  		if x.i != j || k != old {
   786  			t.Fatalf("mask=%d i=%d j=%d k=%d old=%d", mask, x.i, j, k, old)
   787  		}
   788  	}
   789  	if x.before != magic32 || x.after != magic32 {
   790  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
   791  	}
   792  }
   793  
   794  func TestOrInt32Method(t *testing.T) {
   795  	var x struct {
   796  		before int32
   797  		i      Int32
   798  		after  int32
   799  	}
   800  	x.before = magic32
   801  	x.after = magic32
   802  	var j int32
   803  	for mask := int32(1); mask != 0; mask <<= 1 {
   804  		old := x.i.Load()
   805  		k := x.i.Or(mask)
   806  		j |= mask
   807  		if x.i.Load() != j || k != old {
   808  			t.Fatalf("mask=%d i=%d j=%d k=%d old=%d", mask, x.i.Load(), j, k, old)
   809  		}
   810  	}
   811  	if x.before != magic32 || x.after != magic32 {
   812  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
   813  	}
   814  }
   815  
   816  func TestOrUint32(t *testing.T) {
   817  	var x struct {
   818  		before uint32
   819  		i      uint32
   820  		after  uint32
   821  	}
   822  	x.before = magic32
   823  	x.after = magic32
   824  	var j uint32
   825  	for mask := uint32(1); mask != 0; mask <<= 1 {
   826  		old := x.i
   827  		k := OrUint32(&x.i, mask)
   828  		j |= mask
   829  		if x.i != j || k != old {
   830  			t.Fatalf("mask=%d i=%d j=%d k=%d old=%d", mask, x.i, j, k, old)
   831  		}
   832  	}
   833  	if x.before != magic32 || x.after != magic32 {
   834  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
   835  	}
   836  }
   837  
   838  func TestOrUint32Method(t *testing.T) {
   839  	var x struct {
   840  		before uint32
   841  		i      Uint32
   842  		after  uint32
   843  	}
   844  	x.before = magic32
   845  	x.after = magic32
   846  	var j uint32
   847  	for mask := uint32(1); mask != 0; mask <<= 1 {
   848  		old := x.i.Load()
   849  		k := x.i.Or(mask)
   850  		j |= mask
   851  		if x.i.Load() != j || k != old {
   852  			t.Fatalf("mask=%d i=%d j=%d k=%d old=%d", mask, x.i.Load(), j, k, old)
   853  		}
   854  	}
   855  	if x.before != magic32 || x.after != magic32 {
   856  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
   857  	}
   858  }
   859  
   860  func TestOrInt64(t *testing.T) {
   861  	var x struct {
   862  		before int64
   863  		i      int64
   864  		after  int64
   865  	}
   866  	magic64 := int64(magic64)
   867  	x.before = magic64
   868  	x.after = magic64
   869  	var j int64
   870  	for mask := int64(1); mask != 0; mask <<= 1 {
   871  		old := x.i
   872  		k := OrInt64(&x.i, mask)
   873  		j |= mask
   874  		if x.i != j || k != old {
   875  			t.Fatalf("mask=%d i=%d j=%d k=%d old=%d", mask, x.i, j, k, old)
   876  		}
   877  	}
   878  	if x.before != magic64 || x.after != magic64 {
   879  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
   880  	}
   881  }
   882  
   883  func TestOrInt64Method(t *testing.T) {
   884  	var x struct {
   885  		before int64
   886  		i      Int64
   887  		after  int64
   888  	}
   889  	magic64 := int64(magic64)
   890  	x.before = magic64
   891  	x.after = magic64
   892  	var j int64
   893  	for mask := int64(1); mask != 0; mask <<= 1 {
   894  		old := x.i.Load()
   895  		k := x.i.Or(mask)
   896  		j |= mask
   897  		if x.i.Load() != j || k != old {
   898  			t.Fatalf("mask=%d i=%d j=%d k=%d old=%d", mask, x.i.Load(), j, k, old)
   899  		}
   900  	}
   901  	if x.before != magic64 || x.after != magic64 {
   902  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
   903  	}
   904  }
   905  
   906  func TestOrUint64(t *testing.T) {
   907  	var x struct {
   908  		before uint64
   909  		i      uint64
   910  		after  uint64
   911  	}
   912  	magic64 := uint64(magic64)
   913  	x.before = magic64
   914  	x.after = magic64
   915  	var j uint64
   916  	for mask := uint64(1); mask != 0; mask <<= 1 {
   917  		old := x.i
   918  		k := OrUint64(&x.i, mask)
   919  		j |= mask
   920  		if x.i != j || k != old {
   921  			t.Fatalf("mask=%d i=%d j=%d k=%d old=%d", mask, x.i, j, k, old)
   922  		}
   923  	}
   924  	if x.before != magic64 || x.after != magic64 {
   925  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
   926  	}
   927  }
   928  
   929  func TestOrUint64Method(t *testing.T) {
   930  	var x struct {
   931  		before uint64
   932  		i      Uint64
   933  		after  uint64
   934  	}
   935  	magic64 := uint64(magic64)
   936  	x.before = magic64
   937  	x.after = magic64
   938  	var j uint64
   939  	for mask := uint64(1); mask != 0; mask <<= 1 {
   940  		old := x.i.Load()
   941  		k := x.i.Or(mask)
   942  		j |= mask
   943  		if x.i.Load() != j || k != old {
   944  			t.Fatalf("mask=%d i=%d j=%d k=%d old=%d", mask, x.i.Load(), j, k, old)
   945  		}
   946  	}
   947  	if x.before != magic64 || x.after != magic64 {
   948  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
   949  	}
   950  }
   951  
   952  func TestOrUintptr(t *testing.T) {
   953  	var x struct {
   954  		before uintptr
   955  		i      uintptr
   956  		after  uintptr
   957  	}
   958  	var m uint64 = magic64
   959  	magicptr := uintptr(m)
   960  	x.before = magicptr
   961  	x.after = magicptr
   962  	var j uintptr
   963  	for mask := uintptr(1); mask != 0; mask <<= 1 {
   964  		old := x.i
   965  		k := OrUintptr(&x.i, mask)
   966  		j |= mask
   967  		if x.i != j || k != old {
   968  			t.Fatalf("mask=%d i=%d j=%d k=%d old=%d", mask, x.i, j, k, old)
   969  		}
   970  	}
   971  	if x.before != magicptr || x.after != magicptr {
   972  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
   973  	}
   974  }
   975  
   976  func TestOrUintptrMethod(t *testing.T) {
   977  	var x struct {
   978  		before uintptr
   979  		i      Uintptr
   980  		after  uintptr
   981  	}
   982  	var m uint64 = magic64
   983  	magicptr := uintptr(m)
   984  	x.before = magicptr
   985  	x.after = magicptr
   986  	var j uintptr
   987  	for mask := uintptr(1); mask != 0; mask <<= 1 {
   988  		old := x.i.Load()
   989  		k := x.i.Or(mask)
   990  		j |= mask
   991  		if x.i.Load() != j || k != old {
   992  			t.Fatalf("mask=%d i=%d j=%d k=%d old=%d", mask, x.i.Load(), j, k, old)
   993  		}
   994  	}
   995  	if x.before != magicptr || x.after != magicptr {
   996  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
   997  	}
   998  }
   999  
  1000  func TestCompareAndSwapInt32(t *testing.T) {
  1001  	var x struct {
  1002  		before int32
  1003  		i      int32
  1004  		after  int32
  1005  	}
  1006  	x.before = magic32
  1007  	x.after = magic32
  1008  	for val := int32(1); val+val > val; val += val {
  1009  		x.i = val
  1010  		if !CompareAndSwapInt32(&x.i, val, val+1) {
  1011  			t.Fatalf("should have swapped %#x %#x", val, val+1)
  1012  		}
  1013  		if x.i != val+1 {
  1014  			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
  1015  		}
  1016  		x.i = val + 1
  1017  		if CompareAndSwapInt32(&x.i, val, val+2) {
  1018  			t.Fatalf("should not have swapped %#x %#x", val, val+2)
  1019  		}
  1020  		if x.i != val+1 {
  1021  			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
  1022  		}
  1023  	}
  1024  	if x.before != magic32 || x.after != magic32 {
  1025  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
  1026  	}
  1027  }
  1028  
  1029  func TestCompareAndSwapInt32Method(t *testing.T) {
  1030  	var x struct {
  1031  		before int32
  1032  		i      Int32
  1033  		after  int32
  1034  	}
  1035  	x.before = magic32
  1036  	x.after = magic32
  1037  	for val := int32(1); val+val > val; val += val {
  1038  		x.i.Store(val)
  1039  		if !x.i.CompareAndSwap(val, val+1) {
  1040  			t.Fatalf("should have swapped %#x %#x", val, val+1)
  1041  		}
  1042  		if x.i.Load() != val+1 {
  1043  			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i.Load(), val+1)
  1044  		}
  1045  		x.i.Store(val + 1)
  1046  		if x.i.CompareAndSwap(val, val+2) {
  1047  			t.Fatalf("should not have swapped %#x %#x", val, val+2)
  1048  		}
  1049  		if x.i.Load() != val+1 {
  1050  			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i.Load(), val+1)
  1051  		}
  1052  	}
  1053  	if x.before != magic32 || x.after != magic32 {
  1054  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
  1055  	}
  1056  }
  1057  
  1058  func TestCompareAndSwapUint32(t *testing.T) {
  1059  	var x struct {
  1060  		before uint32
  1061  		i      uint32
  1062  		after  uint32
  1063  	}
  1064  	x.before = magic32
  1065  	x.after = magic32
  1066  	for val := uint32(1); val+val > val; val += val {
  1067  		x.i = val
  1068  		if !CompareAndSwapUint32(&x.i, val, val+1) {
  1069  			t.Fatalf("should have swapped %#x %#x", val, val+1)
  1070  		}
  1071  		if x.i != val+1 {
  1072  			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
  1073  		}
  1074  		x.i = val + 1
  1075  		if CompareAndSwapUint32(&x.i, val, val+2) {
  1076  			t.Fatalf("should not have swapped %#x %#x", val, val+2)
  1077  		}
  1078  		if x.i != val+1 {
  1079  			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
  1080  		}
  1081  	}
  1082  	if x.before != magic32 || x.after != magic32 {
  1083  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
  1084  	}
  1085  }
  1086  
  1087  func TestCompareAndSwapUint32Method(t *testing.T) {
  1088  	var x struct {
  1089  		before uint32
  1090  		i      Uint32
  1091  		after  uint32
  1092  	}
  1093  	x.before = magic32
  1094  	x.after = magic32
  1095  	for val := uint32(1); val+val > val; val += val {
  1096  		x.i.Store(val)
  1097  		if !x.i.CompareAndSwap(val, val+1) {
  1098  			t.Fatalf("should have swapped %#x %#x", val, val+1)
  1099  		}
  1100  		if x.i.Load() != val+1 {
  1101  			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i.Load(), val+1)
  1102  		}
  1103  		x.i.Store(val + 1)
  1104  		if x.i.CompareAndSwap(val, val+2) {
  1105  			t.Fatalf("should not have swapped %#x %#x", val, val+2)
  1106  		}
  1107  		if x.i.Load() != val+1 {
  1108  			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i.Load(), val+1)
  1109  		}
  1110  	}
  1111  	if x.before != magic32 || x.after != magic32 {
  1112  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
  1113  	}
  1114  }
  1115  
  1116  func TestCompareAndSwapInt64(t *testing.T) {
  1117  	var x struct {
  1118  		before int64
  1119  		i      int64
  1120  		after  int64
  1121  	}
  1122  	magic64 := int64(magic64)
  1123  	x.before = magic64
  1124  	x.after = magic64
  1125  	for val := int64(1); val+val > val; val += val {
  1126  		x.i = val
  1127  		if !CompareAndSwapInt64(&x.i, val, val+1) {
  1128  			t.Fatalf("should have swapped %#x %#x", val, val+1)
  1129  		}
  1130  		if x.i != val+1 {
  1131  			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
  1132  		}
  1133  		x.i = val + 1
  1134  		if CompareAndSwapInt64(&x.i, val, val+2) {
  1135  			t.Fatalf("should not have swapped %#x %#x", val, val+2)
  1136  		}
  1137  		if x.i != val+1 {
  1138  			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
  1139  		}
  1140  	}
  1141  	if x.before != magic64 || x.after != magic64 {
  1142  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
  1143  	}
  1144  }
  1145  
  1146  func TestCompareAndSwapInt64Method(t *testing.T) {
  1147  	var x struct {
  1148  		before int64
  1149  		i      Int64
  1150  		after  int64
  1151  	}
  1152  	magic64 := int64(magic64)
  1153  	x.before = magic64
  1154  	x.after = magic64
  1155  	for val := int64(1); val+val > val; val += val {
  1156  		x.i.Store(val)
  1157  		if !x.i.CompareAndSwap(val, val+1) {
  1158  			t.Fatalf("should have swapped %#x %#x", val, val+1)
  1159  		}
  1160  		if x.i.Load() != val+1 {
  1161  			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i.Load(), val+1)
  1162  		}
  1163  		x.i.Store(val + 1)
  1164  		if x.i.CompareAndSwap(val, val+2) {
  1165  			t.Fatalf("should not have swapped %#x %#x", val, val+2)
  1166  		}
  1167  		if x.i.Load() != val+1 {
  1168  			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i.Load(), val+1)
  1169  		}
  1170  	}
  1171  	if x.before != magic64 || x.after != magic64 {
  1172  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
  1173  	}
  1174  }
  1175  
  1176  func testCompareAndSwapUint64(t *testing.T, cas func(*uint64, uint64, uint64) bool) {
  1177  	var x struct {
  1178  		before uint64
  1179  		i      uint64
  1180  		after  uint64
  1181  	}
  1182  	magic64 := uint64(magic64)
  1183  	x.before = magic64
  1184  	x.after = magic64
  1185  	for val := uint64(1); val+val > val; val += val {
  1186  		x.i = val
  1187  		if !cas(&x.i, val, val+1) {
  1188  			t.Fatalf("should have swapped %#x %#x", val, val+1)
  1189  		}
  1190  		if x.i != val+1 {
  1191  			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
  1192  		}
  1193  		x.i = val + 1
  1194  		if cas(&x.i, val, val+2) {
  1195  			t.Fatalf("should not have swapped %#x %#x", val, val+2)
  1196  		}
  1197  		if x.i != val+1 {
  1198  			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
  1199  		}
  1200  	}
  1201  	if x.before != magic64 || x.after != magic64 {
  1202  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
  1203  	}
  1204  }
  1205  
  1206  func TestCompareAndSwapUint64(t *testing.T) {
  1207  	testCompareAndSwapUint64(t, CompareAndSwapUint64)
  1208  }
  1209  
  1210  func TestCompareAndSwapUint64Method(t *testing.T) {
  1211  	var x struct {
  1212  		before uint64
  1213  		i      Uint64
  1214  		after  uint64
  1215  	}
  1216  	magic64 := uint64(magic64)
  1217  	x.before = magic64
  1218  	x.after = magic64
  1219  	for val := uint64(1); val+val > val; val += val {
  1220  		x.i.Store(val)
  1221  		if !x.i.CompareAndSwap(val, val+1) {
  1222  			t.Fatalf("should have swapped %#x %#x", val, val+1)
  1223  		}
  1224  		if x.i.Load() != val+1 {
  1225  			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i.Load(), val+1)
  1226  		}
  1227  		x.i.Store(val + 1)
  1228  		if x.i.CompareAndSwap(val, val+2) {
  1229  			t.Fatalf("should not have swapped %#x %#x", val, val+2)
  1230  		}
  1231  		if x.i.Load() != val+1 {
  1232  			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i.Load(), val+1)
  1233  		}
  1234  	}
  1235  	if x.before != magic64 || x.after != magic64 {
  1236  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
  1237  	}
  1238  }
  1239  
  1240  func TestCompareAndSwapUintptr(t *testing.T) {
  1241  	var x struct {
  1242  		before uintptr
  1243  		i      uintptr
  1244  		after  uintptr
  1245  	}
  1246  	var m uint64 = magic64
  1247  	magicptr := uintptr(m)
  1248  	x.before = magicptr
  1249  	x.after = magicptr
  1250  	for val := uintptr(1); val+val > val; val += val {
  1251  		x.i = val
  1252  		if !CompareAndSwapUintptr(&x.i, val, val+1) {
  1253  			t.Fatalf("should have swapped %#x %#x", val, val+1)
  1254  		}
  1255  		if x.i != val+1 {
  1256  			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
  1257  		}
  1258  		x.i = val + 1
  1259  		if CompareAndSwapUintptr(&x.i, val, val+2) {
  1260  			t.Fatalf("should not have swapped %#x %#x", val, val+2)
  1261  		}
  1262  		if x.i != val+1 {
  1263  			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
  1264  		}
  1265  	}
  1266  	if x.before != magicptr || x.after != magicptr {
  1267  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
  1268  	}
  1269  }
  1270  
  1271  func TestCompareAndSwapUintptrMethod(t *testing.T) {
  1272  	var x struct {
  1273  		before uintptr
  1274  		i      Uintptr
  1275  		after  uintptr
  1276  	}
  1277  	var m uint64 = magic64
  1278  	magicptr := uintptr(m)
  1279  	x.before = magicptr
  1280  	x.after = magicptr
  1281  	for val := uintptr(1); val+val > val; val += val {
  1282  		x.i.Store(val)
  1283  		if !x.i.CompareAndSwap(val, val+1) {
  1284  			t.Fatalf("should have swapped %#x %#x", val, val+1)
  1285  		}
  1286  		if x.i.Load() != val+1 {
  1287  			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i.Load(), val+1)
  1288  		}
  1289  		x.i.Store(val + 1)
  1290  		if x.i.CompareAndSwap(val, val+2) {
  1291  			t.Fatalf("should not have swapped %#x %#x", val, val+2)
  1292  		}
  1293  		if x.i.Load() != val+1 {
  1294  			t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i.Load(), val+1)
  1295  		}
  1296  	}
  1297  	if x.before != magicptr || x.after != magicptr {
  1298  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uintptr(magicptr), uintptr(magicptr))
  1299  	}
  1300  }
  1301  
  1302  func TestCompareAndSwapPointer(t *testing.T) {
  1303  	var x struct {
  1304  		before uintptr
  1305  		i      unsafe.Pointer
  1306  		after  uintptr
  1307  	}
  1308  	var m uint64 = magic64
  1309  	magicptr := uintptr(m)
  1310  	x.before = magicptr
  1311  	x.after = magicptr
  1312  	q := unsafe.Pointer(new(byte))
  1313  	for _, p := range testPointers() {
  1314  		x.i = p
  1315  		if !CompareAndSwapPointer(&x.i, p, q) {
  1316  			t.Fatalf("should have swapped %p %p", p, q)
  1317  		}
  1318  		if x.i != q {
  1319  			t.Fatalf("wrong x.i after swap: x.i=%p want %p", x.i, q)
  1320  		}
  1321  		if CompareAndSwapPointer(&x.i, p, nil) {
  1322  			t.Fatalf("should not have swapped %p nil", p)
  1323  		}
  1324  		if x.i != q {
  1325  			t.Fatalf("wrong x.i after swap: x.i=%p want %p", x.i, q)
  1326  		}
  1327  	}
  1328  	if x.before != magicptr || x.after != magicptr {
  1329  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
  1330  	}
  1331  }
  1332  
  1333  func TestCompareAndSwapPointerMethod(t *testing.T) {
  1334  	var x struct {
  1335  		before uintptr
  1336  		i      Pointer[byte]
  1337  		after  uintptr
  1338  	}
  1339  	var m uint64 = magic64
  1340  	magicptr := uintptr(m)
  1341  	x.before = magicptr
  1342  	x.after = magicptr
  1343  	q := new(byte)
  1344  	for _, p := range testPointers() {
  1345  		p := (*byte)(p)
  1346  		x.i.Store(p)
  1347  		if !x.i.CompareAndSwap(p, q) {
  1348  			t.Fatalf("should have swapped %p %p", p, q)
  1349  		}
  1350  		if x.i.Load() != q {
  1351  			t.Fatalf("wrong x.i after swap: x.i=%p want %p", x.i.Load(), q)
  1352  		}
  1353  		if x.i.CompareAndSwap(p, nil) {
  1354  			t.Fatalf("should not have swapped %p nil", p)
  1355  		}
  1356  		if x.i.Load() != q {
  1357  			t.Fatalf("wrong x.i after swap: x.i=%p want %p", x.i.Load(), q)
  1358  		}
  1359  	}
  1360  	if x.before != magicptr || x.after != magicptr {
  1361  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
  1362  	}
  1363  }
  1364  
  1365  func TestLoadInt32(t *testing.T) {
  1366  	var x struct {
  1367  		before int32
  1368  		i      int32
  1369  		after  int32
  1370  	}
  1371  	x.before = magic32
  1372  	x.after = magic32
  1373  	for delta := int32(1); delta+delta > delta; delta += delta {
  1374  		k := LoadInt32(&x.i)
  1375  		if k != x.i {
  1376  			t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
  1377  		}
  1378  		x.i += delta
  1379  	}
  1380  	if x.before != magic32 || x.after != magic32 {
  1381  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
  1382  	}
  1383  }
  1384  
  1385  func TestLoadInt32Method(t *testing.T) {
  1386  	var x struct {
  1387  		before int32
  1388  		i      Int32
  1389  		after  int32
  1390  	}
  1391  	x.before = magic32
  1392  	x.after = magic32
  1393  	want := int32(0)
  1394  	for delta := int32(1); delta+delta > delta; delta += delta {
  1395  		k := x.i.Load()
  1396  		if k != want {
  1397  			t.Fatalf("delta=%d i=%d k=%d want=%d", delta, x.i.Load(), k, want)
  1398  		}
  1399  		x.i.Store(k + delta)
  1400  		want = k + delta
  1401  	}
  1402  	if x.before != magic32 || x.after != magic32 {
  1403  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
  1404  	}
  1405  }
  1406  
  1407  func TestLoadUint32(t *testing.T) {
  1408  	var x struct {
  1409  		before uint32
  1410  		i      uint32
  1411  		after  uint32
  1412  	}
  1413  	x.before = magic32
  1414  	x.after = magic32
  1415  	for delta := uint32(1); delta+delta > delta; delta += delta {
  1416  		k := LoadUint32(&x.i)
  1417  		if k != x.i {
  1418  			t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
  1419  		}
  1420  		x.i += delta
  1421  	}
  1422  	if x.before != magic32 || x.after != magic32 {
  1423  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
  1424  	}
  1425  }
  1426  
  1427  func TestLoadUint32Method(t *testing.T) {
  1428  	var x struct {
  1429  		before uint32
  1430  		i      Uint32
  1431  		after  uint32
  1432  	}
  1433  	x.before = magic32
  1434  	x.after = magic32
  1435  	want := uint32(0)
  1436  	for delta := uint32(1); delta+delta > delta; delta += delta {
  1437  		k := x.i.Load()
  1438  		if k != want {
  1439  			t.Fatalf("delta=%d i=%d k=%d want=%d", delta, x.i.Load(), k, want)
  1440  		}
  1441  		x.i.Store(k + delta)
  1442  		want = k + delta
  1443  	}
  1444  	if x.before != magic32 || x.after != magic32 {
  1445  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
  1446  	}
  1447  }
  1448  
  1449  func TestLoadInt64(t *testing.T) {
  1450  	var x struct {
  1451  		before int64
  1452  		i      int64
  1453  		after  int64
  1454  	}
  1455  	magic64 := int64(magic64)
  1456  	x.before = magic64
  1457  	x.after = magic64
  1458  	for delta := int64(1); delta+delta > delta; delta += delta {
  1459  		k := LoadInt64(&x.i)
  1460  		if k != x.i {
  1461  			t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
  1462  		}
  1463  		x.i += delta
  1464  	}
  1465  	if x.before != magic64 || x.after != magic64 {
  1466  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
  1467  	}
  1468  }
  1469  
  1470  func TestLoadInt64Method(t *testing.T) {
  1471  	var x struct {
  1472  		before int64
  1473  		i      Int64
  1474  		after  int64
  1475  	}
  1476  	magic64 := int64(magic64)
  1477  	x.before = magic64
  1478  	x.after = magic64
  1479  	want := int64(0)
  1480  	for delta := int64(1); delta+delta > delta; delta += delta {
  1481  		k := x.i.Load()
  1482  		if k != want {
  1483  			t.Fatalf("delta=%d i=%d k=%d want=%d", delta, x.i.Load(), k, want)
  1484  		}
  1485  		x.i.Store(k + delta)
  1486  		want = k + delta
  1487  	}
  1488  	if x.before != magic64 || x.after != magic64 {
  1489  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
  1490  	}
  1491  }
  1492  
  1493  func TestLoadUint64(t *testing.T) {
  1494  	var x struct {
  1495  		before uint64
  1496  		i      uint64
  1497  		after  uint64
  1498  	}
  1499  	magic64 := uint64(magic64)
  1500  	x.before = magic64
  1501  	x.after = magic64
  1502  	for delta := uint64(1); delta+delta > delta; delta += delta {
  1503  		k := LoadUint64(&x.i)
  1504  		if k != x.i {
  1505  			t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
  1506  		}
  1507  		x.i += delta
  1508  	}
  1509  	if x.before != magic64 || x.after != magic64 {
  1510  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
  1511  	}
  1512  }
  1513  
  1514  func TestLoadUint64Method(t *testing.T) {
  1515  	var x struct {
  1516  		before uint64
  1517  		i      Uint64
  1518  		after  uint64
  1519  	}
  1520  	magic64 := uint64(magic64)
  1521  	x.before = magic64
  1522  	x.after = magic64
  1523  	want := uint64(0)
  1524  	for delta := uint64(1); delta+delta > delta; delta += delta {
  1525  		k := x.i.Load()
  1526  		if k != want {
  1527  			t.Fatalf("delta=%d i=%d k=%d want=%d", delta, x.i.Load(), k, want)
  1528  		}
  1529  		x.i.Store(k + delta)
  1530  		want = k + delta
  1531  	}
  1532  	if x.before != magic64 || x.after != magic64 {
  1533  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
  1534  	}
  1535  }
  1536  
  1537  func TestLoadUintptr(t *testing.T) {
  1538  	var x struct {
  1539  		before uintptr
  1540  		i      uintptr
  1541  		after  uintptr
  1542  	}
  1543  	var m uint64 = magic64
  1544  	magicptr := uintptr(m)
  1545  	x.before = magicptr
  1546  	x.after = magicptr
  1547  	for delta := uintptr(1); delta+delta > delta; delta += delta {
  1548  		k := LoadUintptr(&x.i)
  1549  		if k != x.i {
  1550  			t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
  1551  		}
  1552  		x.i += delta
  1553  	}
  1554  	if x.before != magicptr || x.after != magicptr {
  1555  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
  1556  	}
  1557  }
  1558  
  1559  func TestLoadUintptrMethod(t *testing.T) {
  1560  	var x struct {
  1561  		before uintptr
  1562  		i      Uintptr
  1563  		after  uintptr
  1564  	}
  1565  	var m uint64 = magic64
  1566  	magicptr := uintptr(m)
  1567  	x.before = magicptr
  1568  	x.after = magicptr
  1569  	want := uintptr(0)
  1570  	for delta := uintptr(1); delta+delta > delta; delta += delta {
  1571  		k := x.i.Load()
  1572  		if k != want {
  1573  			t.Fatalf("delta=%d i=%d k=%d want=%d", delta, x.i.Load(), k, want)
  1574  		}
  1575  		x.i.Store(k + delta)
  1576  		want = k + delta
  1577  	}
  1578  	if x.before != magicptr || x.after != magicptr {
  1579  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
  1580  	}
  1581  }
  1582  
  1583  func TestLoadPointer(t *testing.T) {
  1584  	var x struct {
  1585  		before uintptr
  1586  		i      unsafe.Pointer
  1587  		after  uintptr
  1588  	}
  1589  	var m uint64 = magic64
  1590  	magicptr := uintptr(m)
  1591  	x.before = magicptr
  1592  	x.after = magicptr
  1593  	for _, p := range testPointers() {
  1594  		x.i = p
  1595  		k := LoadPointer(&x.i)
  1596  		if k != p {
  1597  			t.Fatalf("p=%x k=%x", p, k)
  1598  		}
  1599  	}
  1600  	if x.before != magicptr || x.after != magicptr {
  1601  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
  1602  	}
  1603  }
  1604  
  1605  func TestLoadPointerMethod(t *testing.T) {
  1606  	var x struct {
  1607  		before uintptr
  1608  		i      Pointer[byte]
  1609  		after  uintptr
  1610  	}
  1611  	var m uint64 = magic64
  1612  	magicptr := uintptr(m)
  1613  	x.before = magicptr
  1614  	x.after = magicptr
  1615  	for _, p := range testPointers() {
  1616  		p := (*byte)(p)
  1617  		x.i.Store(p)
  1618  		k := x.i.Load()
  1619  		if k != p {
  1620  			t.Fatalf("p=%x k=%x", p, k)
  1621  		}
  1622  	}
  1623  	if x.before != magicptr || x.after != magicptr {
  1624  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
  1625  	}
  1626  }
  1627  
  1628  func TestStoreInt32(t *testing.T) {
  1629  	var x struct {
  1630  		before int32
  1631  		i      int32
  1632  		after  int32
  1633  	}
  1634  	x.before = magic32
  1635  	x.after = magic32
  1636  	v := int32(0)
  1637  	for delta := int32(1); delta+delta > delta; delta += delta {
  1638  		StoreInt32(&x.i, v)
  1639  		if x.i != v {
  1640  			t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
  1641  		}
  1642  		v += delta
  1643  	}
  1644  	if x.before != magic32 || x.after != magic32 {
  1645  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
  1646  	}
  1647  }
  1648  
  1649  func TestStoreInt32Method(t *testing.T) {
  1650  	var x struct {
  1651  		before int32
  1652  		i      Int32
  1653  		after  int32
  1654  	}
  1655  	x.before = magic32
  1656  	x.after = magic32
  1657  	v := int32(0)
  1658  	for delta := int32(1); delta+delta > delta; delta += delta {
  1659  		x.i.Store(v)
  1660  		if x.i.Load() != v {
  1661  			t.Fatalf("delta=%d i=%d v=%d", delta, x.i.Load(), v)
  1662  		}
  1663  		v += delta
  1664  	}
  1665  	if x.before != magic32 || x.after != magic32 {
  1666  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
  1667  	}
  1668  }
  1669  
  1670  func TestStoreUint32(t *testing.T) {
  1671  	var x struct {
  1672  		before uint32
  1673  		i      uint32
  1674  		after  uint32
  1675  	}
  1676  	x.before = magic32
  1677  	x.after = magic32
  1678  	v := uint32(0)
  1679  	for delta := uint32(1); delta+delta > delta; delta += delta {
  1680  		StoreUint32(&x.i, v)
  1681  		if x.i != v {
  1682  			t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
  1683  		}
  1684  		v += delta
  1685  	}
  1686  	if x.before != magic32 || x.after != magic32 {
  1687  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
  1688  	}
  1689  }
  1690  
  1691  func TestStoreUint32Method(t *testing.T) {
  1692  	var x struct {
  1693  		before uint32
  1694  		i      Uint32
  1695  		after  uint32
  1696  	}
  1697  	x.before = magic32
  1698  	x.after = magic32
  1699  	v := uint32(0)
  1700  	for delta := uint32(1); delta+delta > delta; delta += delta {
  1701  		x.i.Store(v)
  1702  		if x.i.Load() != v {
  1703  			t.Fatalf("delta=%d i=%d v=%d", delta, x.i.Load(), v)
  1704  		}
  1705  		v += delta
  1706  	}
  1707  	if x.before != magic32 || x.after != magic32 {
  1708  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
  1709  	}
  1710  }
  1711  
  1712  func TestStoreInt64(t *testing.T) {
  1713  	var x struct {
  1714  		before int64
  1715  		i      int64
  1716  		after  int64
  1717  	}
  1718  	magic64 := int64(magic64)
  1719  	x.before = magic64
  1720  	x.after = magic64
  1721  	v := int64(0)
  1722  	for delta := int64(1); delta+delta > delta; delta += delta {
  1723  		StoreInt64(&x.i, v)
  1724  		if x.i != v {
  1725  			t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
  1726  		}
  1727  		v += delta
  1728  	}
  1729  	if x.before != magic64 || x.after != magic64 {
  1730  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
  1731  	}
  1732  }
  1733  
  1734  func TestStoreInt64Method(t *testing.T) {
  1735  	var x struct {
  1736  		before int64
  1737  		i      Int64
  1738  		after  int64
  1739  	}
  1740  	magic64 := int64(magic64)
  1741  	x.before = magic64
  1742  	x.after = magic64
  1743  	v := int64(0)
  1744  	for delta := int64(1); delta+delta > delta; delta += delta {
  1745  		x.i.Store(v)
  1746  		if x.i.Load() != v {
  1747  			t.Fatalf("delta=%d i=%d v=%d", delta, x.i.Load(), v)
  1748  		}
  1749  		v += delta
  1750  	}
  1751  	if x.before != magic64 || x.after != magic64 {
  1752  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
  1753  	}
  1754  }
  1755  
  1756  func TestStoreUint64(t *testing.T) {
  1757  	var x struct {
  1758  		before uint64
  1759  		i      uint64
  1760  		after  uint64
  1761  	}
  1762  	magic64 := uint64(magic64)
  1763  	x.before = magic64
  1764  	x.after = magic64
  1765  	v := uint64(0)
  1766  	for delta := uint64(1); delta+delta > delta; delta += delta {
  1767  		StoreUint64(&x.i, v)
  1768  		if x.i != v {
  1769  			t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
  1770  		}
  1771  		v += delta
  1772  	}
  1773  	if x.before != magic64 || x.after != magic64 {
  1774  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
  1775  	}
  1776  }
  1777  
  1778  func TestStoreUint64Method(t *testing.T) {
  1779  	var x struct {
  1780  		before uint64
  1781  		i      Uint64
  1782  		after  uint64
  1783  	}
  1784  	magic64 := uint64(magic64)
  1785  	x.before = magic64
  1786  	x.after = magic64
  1787  	v := uint64(0)
  1788  	for delta := uint64(1); delta+delta > delta; delta += delta {
  1789  		x.i.Store(v)
  1790  		if x.i.Load() != v {
  1791  			t.Fatalf("delta=%d i=%d v=%d", delta, x.i.Load(), v)
  1792  		}
  1793  		v += delta
  1794  	}
  1795  	if x.before != magic64 || x.after != magic64 {
  1796  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic64, magic64)
  1797  	}
  1798  }
  1799  
  1800  func TestStoreUintptr(t *testing.T) {
  1801  	var x struct {
  1802  		before uintptr
  1803  		i      uintptr
  1804  		after  uintptr
  1805  	}
  1806  	var m uint64 = magic64
  1807  	magicptr := uintptr(m)
  1808  	x.before = magicptr
  1809  	x.after = magicptr
  1810  	v := uintptr(0)
  1811  	for delta := uintptr(1); delta+delta > delta; delta += delta {
  1812  		StoreUintptr(&x.i, v)
  1813  		if x.i != v {
  1814  			t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
  1815  		}
  1816  		v += delta
  1817  	}
  1818  	if x.before != magicptr || x.after != magicptr {
  1819  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
  1820  	}
  1821  }
  1822  
  1823  func TestStoreUintptrMethod(t *testing.T) {
  1824  	var x struct {
  1825  		before uintptr
  1826  		i      Uintptr
  1827  		after  uintptr
  1828  	}
  1829  	var m uint64 = magic64
  1830  	magicptr := uintptr(m)
  1831  	x.before = magicptr
  1832  	x.after = magicptr
  1833  	v := uintptr(0)
  1834  	for delta := uintptr(1); delta+delta > delta; delta += delta {
  1835  		x.i.Store(v)
  1836  		if x.i.Load() != v {
  1837  			t.Fatalf("delta=%d i=%d v=%d", delta, x.i.Load(), v)
  1838  		}
  1839  		v += delta
  1840  	}
  1841  	if x.before != magicptr || x.after != magicptr {
  1842  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
  1843  	}
  1844  }
  1845  
  1846  func TestStorePointer(t *testing.T) {
  1847  	var x struct {
  1848  		before uintptr
  1849  		i      unsafe.Pointer
  1850  		after  uintptr
  1851  	}
  1852  	var m uint64 = magic64
  1853  	magicptr := uintptr(m)
  1854  	x.before = magicptr
  1855  	x.after = magicptr
  1856  	for _, p := range testPointers() {
  1857  		StorePointer(&x.i, p)
  1858  		if x.i != p {
  1859  			t.Fatalf("x.i=%p p=%p", x.i, p)
  1860  		}
  1861  	}
  1862  	if x.before != magicptr || x.after != magicptr {
  1863  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
  1864  	}
  1865  }
  1866  
  1867  func TestStorePointerMethod(t *testing.T) {
  1868  	var x struct {
  1869  		before uintptr
  1870  		i      Pointer[byte]
  1871  		after  uintptr
  1872  	}
  1873  	var m uint64 = magic64
  1874  	magicptr := uintptr(m)
  1875  	x.before = magicptr
  1876  	x.after = magicptr
  1877  	for _, p := range testPointers() {
  1878  		p := (*byte)(p)
  1879  		x.i.Store(p)
  1880  		if x.i.Load() != p {
  1881  			t.Fatalf("x.i=%p p=%p", x.i.Load(), p)
  1882  		}
  1883  	}
  1884  	if x.before != magicptr || x.after != magicptr {
  1885  		t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
  1886  	}
  1887  }
  1888  
  1889  // Tests of correct behavior, with contention.
  1890  // (Is the function atomic?)
  1891  //
  1892  // For each function, we write a "hammer" function that repeatedly
  1893  // uses the atomic operation to add 1 to a value. After running
  1894  // multiple hammers in parallel, check that we end with the correct
  1895  // total.
  1896  // Swap can't add 1, so it uses a different scheme.
  1897  // The functions repeatedly generate a pseudo-random number such that
  1898  // low bits are equal to high bits, swap, check that the old value
  1899  // has low and high bits equal.
  1900  
  1901  var hammer32 = map[string]func(*uint32, int){
  1902  	"SwapInt32":             hammerSwapInt32,
  1903  	"SwapUint32":            hammerSwapUint32,
  1904  	"SwapUintptr":           hammerSwapUintptr32,
  1905  	"AddInt32":              hammerAddInt32,
  1906  	"AddUint32":             hammerAddUint32,
  1907  	"AddUintptr":            hammerAddUintptr32,
  1908  	"CompareAndSwapInt32":   hammerCompareAndSwapInt32,
  1909  	"CompareAndSwapUint32":  hammerCompareAndSwapUint32,
  1910  	"CompareAndSwapUintptr": hammerCompareAndSwapUintptr32,
  1911  
  1912  	"SwapInt32Method":             hammerSwapInt32Method,
  1913  	"SwapUint32Method":            hammerSwapUint32Method,
  1914  	"SwapUintptrMethod":           hammerSwapUintptr32Method,
  1915  	"AddInt32Method":              hammerAddInt32Method,
  1916  	"AddUint32Method":             hammerAddUint32Method,
  1917  	"AddUintptrMethod":            hammerAddUintptr32Method,
  1918  	"CompareAndSwapInt32Method":   hammerCompareAndSwapInt32Method,
  1919  	"CompareAndSwapUint32Method":  hammerCompareAndSwapUint32Method,
  1920  	"CompareAndSwapUintptrMethod": hammerCompareAndSwapUintptr32Method,
  1921  }
  1922  
  1923  func init() {
  1924  	var v uint64 = 1 << 50
  1925  	if uintptr(v) != 0 {
  1926  		// 64-bit system; clear uintptr tests
  1927  		delete(hammer32, "SwapUintptr")
  1928  		delete(hammer32, "AddUintptr")
  1929  		delete(hammer32, "CompareAndSwapUintptr")
  1930  		delete(hammer32, "SwapUintptrMethod")
  1931  		delete(hammer32, "AddUintptrMethod")
  1932  		delete(hammer32, "CompareAndSwapUintptrMethod")
  1933  	}
  1934  }
  1935  
  1936  func hammerSwapInt32(uaddr *uint32, count int) {
  1937  	addr := (*int32)(unsafe.Pointer(uaddr))
  1938  	seed := int(uintptr(unsafe.Pointer(&count)))
  1939  	for i := 0; i < count; i++ {
  1940  		new := uint32(seed+i)<<16 | uint32(seed+i)<<16>>16
  1941  		old := uint32(SwapInt32(addr, int32(new)))
  1942  		if old>>16 != old<<16>>16 {
  1943  			panic(fmt.Sprintf("SwapInt32 is not atomic: %v", old))
  1944  		}
  1945  	}
  1946  }
  1947  
  1948  func hammerSwapInt32Method(uaddr *uint32, count int) {
  1949  	addr := (*Int32)(unsafe.Pointer(uaddr))
  1950  	seed := int(uintptr(unsafe.Pointer(&count)))
  1951  	for i := 0; i < count; i++ {
  1952  		new := uint32(seed+i)<<16 | uint32(seed+i)<<16>>16
  1953  		old := uint32(addr.Swap(int32(new)))
  1954  		if old>>16 != old<<16>>16 {
  1955  			panic(fmt.Sprintf("SwapInt32 is not atomic: %v", old))
  1956  		}
  1957  	}
  1958  }
  1959  
  1960  func hammerSwapUint32(addr *uint32, count int) {
  1961  	seed := int(uintptr(unsafe.Pointer(&count)))
  1962  	for i := 0; i < count; i++ {
  1963  		new := uint32(seed+i)<<16 | uint32(seed+i)<<16>>16
  1964  		old := SwapUint32(addr, new)
  1965  		if old>>16 != old<<16>>16 {
  1966  			panic(fmt.Sprintf("SwapUint32 is not atomic: %v", old))
  1967  		}
  1968  	}
  1969  }
  1970  
  1971  func hammerSwapUint32Method(uaddr *uint32, count int) {
  1972  	addr := (*Uint32)(unsafe.Pointer(uaddr))
  1973  	seed := int(uintptr(unsafe.Pointer(&count)))
  1974  	for i := 0; i < count; i++ {
  1975  		new := uint32(seed+i)<<16 | uint32(seed+i)<<16>>16
  1976  		old := addr.Swap(new)
  1977  		if old>>16 != old<<16>>16 {
  1978  			panic(fmt.Sprintf("SwapUint32 is not atomic: %v", old))
  1979  		}
  1980  	}
  1981  }
  1982  
  1983  func hammerSwapUintptr32(uaddr *uint32, count int) {
  1984  	// only safe when uintptr is 32-bit.
  1985  	// not called on 64-bit systems.
  1986  	addr := (*uintptr)(unsafe.Pointer(uaddr))
  1987  	seed := int(uintptr(unsafe.Pointer(&count)))
  1988  	for i := 0; i < count; i++ {
  1989  		new := uintptr(seed+i)<<16 | uintptr(seed+i)<<16>>16
  1990  		old := SwapUintptr(addr, new)
  1991  		if old>>16 != old<<16>>16 {
  1992  			panic(fmt.Sprintf("SwapUintptr is not atomic: %#08x", old))
  1993  		}
  1994  	}
  1995  }
  1996  
  1997  func hammerSwapUintptr32Method(uaddr *uint32, count int) {
  1998  	// only safe when uintptr is 32-bit.
  1999  	// not called on 64-bit systems.
  2000  	addr := (*Uintptr)(unsafe.Pointer(uaddr))
  2001  	seed := int(uintptr(unsafe.Pointer(&count)))
  2002  	for i := 0; i < count; i++ {
  2003  		new := uintptr(seed+i)<<16 | uintptr(seed+i)<<16>>16
  2004  		old := addr.Swap(new)
  2005  		if old>>16 != old<<16>>16 {
  2006  			panic(fmt.Sprintf("Uintptr.Swap is not atomic: %#08x", old))
  2007  		}
  2008  	}
  2009  }
  2010  
  2011  func hammerAddInt32(uaddr *uint32, count int) {
  2012  	addr := (*int32)(unsafe.Pointer(uaddr))
  2013  	for i := 0; i < count; i++ {
  2014  		AddInt32(addr, 1)
  2015  	}
  2016  }
  2017  
  2018  func hammerAddInt32Method(uaddr *uint32, count int) {
  2019  	addr := (*Int32)(unsafe.Pointer(uaddr))
  2020  	for i := 0; i < count; i++ {
  2021  		addr.Add(1)
  2022  	}
  2023  }
  2024  
  2025  func hammerAddUint32(addr *uint32, count int) {
  2026  	for i := 0; i < count; i++ {
  2027  		AddUint32(addr, 1)
  2028  	}
  2029  }
  2030  
  2031  func hammerAddUint32Method(uaddr *uint32, count int) {
  2032  	addr := (*Uint32)(unsafe.Pointer(uaddr))
  2033  	for i := 0; i < count; i++ {
  2034  		addr.Add(1)
  2035  	}
  2036  }
  2037  
  2038  func hammerAddUintptr32(uaddr *uint32, count int) {
  2039  	// only safe when uintptr is 32-bit.
  2040  	// not called on 64-bit systems.
  2041  	addr := (*uintptr)(unsafe.Pointer(uaddr))
  2042  	for i := 0; i < count; i++ {
  2043  		AddUintptr(addr, 1)
  2044  	}
  2045  }
  2046  
  2047  func hammerAddUintptr32Method(uaddr *uint32, count int) {
  2048  	// only safe when uintptr is 32-bit.
  2049  	// not called on 64-bit systems.
  2050  	addr := (*Uintptr)(unsafe.Pointer(uaddr))
  2051  	for i := 0; i < count; i++ {
  2052  		addr.Add(1)
  2053  	}
  2054  }
  2055  
  2056  func hammerCompareAndSwapInt32(uaddr *uint32, count int) {
  2057  	addr := (*int32)(unsafe.Pointer(uaddr))
  2058  	for i := 0; i < count; i++ {
  2059  		for {
  2060  			v := LoadInt32(addr)
  2061  			if CompareAndSwapInt32(addr, v, v+1) {
  2062  				break
  2063  			}
  2064  		}
  2065  	}
  2066  }
  2067  
  2068  func hammerCompareAndSwapInt32Method(uaddr *uint32, count int) {
  2069  	addr := (*Int32)(unsafe.Pointer(uaddr))
  2070  	for i := 0; i < count; i++ {
  2071  		for {
  2072  			v := addr.Load()
  2073  			if addr.CompareAndSwap(v, v+1) {
  2074  				break
  2075  			}
  2076  		}
  2077  	}
  2078  }
  2079  
  2080  func hammerCompareAndSwapUint32(addr *uint32, count int) {
  2081  	for i := 0; i < count; i++ {
  2082  		for {
  2083  			v := LoadUint32(addr)
  2084  			if CompareAndSwapUint32(addr, v, v+1) {
  2085  				break
  2086  			}
  2087  		}
  2088  	}
  2089  }
  2090  
  2091  func hammerCompareAndSwapUint32Method(uaddr *uint32, count int) {
  2092  	addr := (*Uint32)(unsafe.Pointer(uaddr))
  2093  	for i := 0; i < count; i++ {
  2094  		for {
  2095  			v := addr.Load()
  2096  			if addr.CompareAndSwap(v, v+1) {
  2097  				break
  2098  			}
  2099  		}
  2100  	}
  2101  }
  2102  
  2103  func hammerCompareAndSwapUintptr32(uaddr *uint32, count int) {
  2104  	// only safe when uintptr is 32-bit.
  2105  	// not called on 64-bit systems.
  2106  	addr := (*uintptr)(unsafe.Pointer(uaddr))
  2107  	for i := 0; i < count; i++ {
  2108  		for {
  2109  			v := LoadUintptr(addr)
  2110  			if CompareAndSwapUintptr(addr, v, v+1) {
  2111  				break
  2112  			}
  2113  		}
  2114  	}
  2115  }
  2116  
  2117  func hammerCompareAndSwapUintptr32Method(uaddr *uint32, count int) {
  2118  	// only safe when uintptr is 32-bit.
  2119  	// not called on 64-bit systems.
  2120  	addr := (*Uintptr)(unsafe.Pointer(uaddr))
  2121  	for i := 0; i < count; i++ {
  2122  		for {
  2123  			v := addr.Load()
  2124  			if addr.CompareAndSwap(v, v+1) {
  2125  				break
  2126  			}
  2127  		}
  2128  	}
  2129  }
  2130  
  2131  func TestHammer32(t *testing.T) {
  2132  	const p = 4
  2133  	n := 100000
  2134  	if testing.Short() {
  2135  		n = 1000
  2136  	}
  2137  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(p))
  2138  
  2139  	for name, testf := range hammer32 {
  2140  		c := make(chan int)
  2141  		var val uint32
  2142  		for i := 0; i < p; i++ {
  2143  			go func() {
  2144  				defer func() {
  2145  					if err := recover(); err != nil {
  2146  						t.Error(err.(string))
  2147  					}
  2148  					c <- 1
  2149  				}()
  2150  				testf(&val, n)
  2151  			}()
  2152  		}
  2153  		for i := 0; i < p; i++ {
  2154  			<-c
  2155  		}
  2156  		if !strings.HasPrefix(name, "Swap") && val != uint32(n)*p {
  2157  			t.Fatalf("%s: val=%d want %d", name, val, n*p)
  2158  		}
  2159  	}
  2160  }
  2161  
  2162  var hammer64 = map[string]func(*uint64, int){
  2163  	"SwapInt64":             hammerSwapInt64,
  2164  	"SwapUint64":            hammerSwapUint64,
  2165  	"SwapUintptr":           hammerSwapUintptr64,
  2166  	"AddInt64":              hammerAddInt64,
  2167  	"AddUint64":             hammerAddUint64,
  2168  	"AddUintptr":            hammerAddUintptr64,
  2169  	"CompareAndSwapInt64":   hammerCompareAndSwapInt64,
  2170  	"CompareAndSwapUint64":  hammerCompareAndSwapUint64,
  2171  	"CompareAndSwapUintptr": hammerCompareAndSwapUintptr64,
  2172  
  2173  	"SwapInt64Method":             hammerSwapInt64Method,
  2174  	"SwapUint64Method":            hammerSwapUint64Method,
  2175  	"SwapUintptrMethod":           hammerSwapUintptr64Method,
  2176  	"AddInt64Method":              hammerAddInt64Method,
  2177  	"AddUint64Method":             hammerAddUint64Method,
  2178  	"AddUintptrMethod":            hammerAddUintptr64Method,
  2179  	"CompareAndSwapInt64Method":   hammerCompareAndSwapInt64Method,
  2180  	"CompareAndSwapUint64Method":  hammerCompareAndSwapUint64Method,
  2181  	"CompareAndSwapUintptrMethod": hammerCompareAndSwapUintptr64Method,
  2182  }
  2183  
  2184  func init() {
  2185  	var v uint64 = 1 << 50
  2186  	if uintptr(v) == 0 {
  2187  		// 32-bit system; clear uintptr tests
  2188  		delete(hammer64, "SwapUintptr")
  2189  		delete(hammer64, "SwapUintptrMethod")
  2190  		delete(hammer64, "AddUintptr")
  2191  		delete(hammer64, "AddUintptrMethod")
  2192  		delete(hammer64, "CompareAndSwapUintptr")
  2193  		delete(hammer64, "CompareAndSwapUintptrMethod")
  2194  	}
  2195  }
  2196  
  2197  func hammerSwapInt64(uaddr *uint64, count int) {
  2198  	addr := (*int64)(unsafe.Pointer(uaddr))
  2199  	seed := int(uintptr(unsafe.Pointer(&count)))
  2200  	for i := 0; i < count; i++ {
  2201  		new := uint64(seed+i)<<32 | uint64(seed+i)<<32>>32
  2202  		old := uint64(SwapInt64(addr, int64(new)))
  2203  		if old>>32 != old<<32>>32 {
  2204  			panic(fmt.Sprintf("SwapInt64 is not atomic: %v", old))
  2205  		}
  2206  	}
  2207  }
  2208  
  2209  func hammerSwapInt64Method(uaddr *uint64, count int) {
  2210  	addr := (*Int64)(unsafe.Pointer(uaddr))
  2211  	seed := int(uintptr(unsafe.Pointer(&count)))
  2212  	for i := 0; i < count; i++ {
  2213  		new := uint64(seed+i)<<32 | uint64(seed+i)<<32>>32
  2214  		old := uint64(addr.Swap(int64(new)))
  2215  		if old>>32 != old<<32>>32 {
  2216  			panic(fmt.Sprintf("SwapInt64 is not atomic: %v", old))
  2217  		}
  2218  	}
  2219  }
  2220  
  2221  func hammerSwapUint64(addr *uint64, count int) {
  2222  	seed := int(uintptr(unsafe.Pointer(&count)))
  2223  	for i := 0; i < count; i++ {
  2224  		new := uint64(seed+i)<<32 | uint64(seed+i)<<32>>32
  2225  		old := SwapUint64(addr, new)
  2226  		if old>>32 != old<<32>>32 {
  2227  			panic(fmt.Sprintf("SwapUint64 is not atomic: %v", old))
  2228  		}
  2229  	}
  2230  }
  2231  
  2232  func hammerSwapUint64Method(uaddr *uint64, count int) {
  2233  	addr := (*Uint64)(unsafe.Pointer(uaddr))
  2234  	seed := int(uintptr(unsafe.Pointer(&count)))
  2235  	for i := 0; i < count; i++ {
  2236  		new := uint64(seed+i)<<32 | uint64(seed+i)<<32>>32
  2237  		old := addr.Swap(new)
  2238  		if old>>32 != old<<32>>32 {
  2239  			panic(fmt.Sprintf("SwapUint64 is not atomic: %v", old))
  2240  		}
  2241  	}
  2242  }
  2243  
  2244  const arch32 = unsafe.Sizeof(uintptr(0)) == 4
  2245  
  2246  func hammerSwapUintptr64(uaddr *uint64, count int) {
  2247  	// only safe when uintptr is 64-bit.
  2248  	// not called on 32-bit systems.
  2249  	if !arch32 {
  2250  		addr := (*uintptr)(unsafe.Pointer(uaddr))
  2251  		seed := int(uintptr(unsafe.Pointer(&count)))
  2252  		for i := 0; i < count; i++ {
  2253  			new := uintptr(seed+i)<<32 | uintptr(seed+i)<<32>>32
  2254  			old := SwapUintptr(addr, new)
  2255  			if old>>32 != old<<32>>32 {
  2256  				panic(fmt.Sprintf("SwapUintptr is not atomic: %v", old))
  2257  			}
  2258  		}
  2259  	}
  2260  }
  2261  
  2262  func hammerSwapUintptr64Method(uaddr *uint64, count int) {
  2263  	// only safe when uintptr is 64-bit.
  2264  	// not called on 32-bit systems.
  2265  	if !arch32 {
  2266  		addr := (*Uintptr)(unsafe.Pointer(uaddr))
  2267  		seed := int(uintptr(unsafe.Pointer(&count)))
  2268  		for i := 0; i < count; i++ {
  2269  			new := uintptr(seed+i)<<32 | uintptr(seed+i)<<32>>32
  2270  			old := addr.Swap(new)
  2271  			if old>>32 != old<<32>>32 {
  2272  				panic(fmt.Sprintf("SwapUintptr is not atomic: %v", old))
  2273  			}
  2274  		}
  2275  	}
  2276  }
  2277  
  2278  func hammerAddInt64(uaddr *uint64, count int) {
  2279  	addr := (*int64)(unsafe.Pointer(uaddr))
  2280  	for i := 0; i < count; i++ {
  2281  		AddInt64(addr, 1)
  2282  	}
  2283  }
  2284  
  2285  func hammerAddInt64Method(uaddr *uint64, count int) {
  2286  	addr := (*Int64)(unsafe.Pointer(uaddr))
  2287  	for i := 0; i < count; i++ {
  2288  		addr.Add(1)
  2289  	}
  2290  }
  2291  
  2292  func hammerAddUint64(addr *uint64, count int) {
  2293  	for i := 0; i < count; i++ {
  2294  		AddUint64(addr, 1)
  2295  	}
  2296  }
  2297  
  2298  func hammerAddUint64Method(uaddr *uint64, count int) {
  2299  	addr := (*Uint64)(unsafe.Pointer(uaddr))
  2300  	for i := 0; i < count; i++ {
  2301  		addr.Add(1)
  2302  	}
  2303  }
  2304  
  2305  func hammerAddUintptr64(uaddr *uint64, count int) {
  2306  	// only safe when uintptr is 64-bit.
  2307  	// not called on 32-bit systems.
  2308  	addr := (*uintptr)(unsafe.Pointer(uaddr))
  2309  	for i := 0; i < count; i++ {
  2310  		AddUintptr(addr, 1)
  2311  	}
  2312  }
  2313  
  2314  func hammerAddUintptr64Method(uaddr *uint64, count int) {
  2315  	// only safe when uintptr is 64-bit.
  2316  	// not called on 32-bit systems.
  2317  	addr := (*Uintptr)(unsafe.Pointer(uaddr))
  2318  	for i := 0; i < count; i++ {
  2319  		addr.Add(1)
  2320  	}
  2321  }
  2322  
  2323  func hammerCompareAndSwapInt64(uaddr *uint64, count int) {
  2324  	addr := (*int64)(unsafe.Pointer(uaddr))
  2325  	for i := 0; i < count; i++ {
  2326  		for {
  2327  			v := LoadInt64(addr)
  2328  			if CompareAndSwapInt64(addr, v, v+1) {
  2329  				break
  2330  			}
  2331  		}
  2332  	}
  2333  }
  2334  
  2335  func hammerCompareAndSwapInt64Method(uaddr *uint64, count int) {
  2336  	addr := (*Int64)(unsafe.Pointer(uaddr))
  2337  	for i := 0; i < count; i++ {
  2338  		for {
  2339  			v := addr.Load()
  2340  			if addr.CompareAndSwap(v, v+1) {
  2341  				break
  2342  			}
  2343  		}
  2344  	}
  2345  }
  2346  
  2347  func hammerCompareAndSwapUint64(addr *uint64, count int) {
  2348  	for i := 0; i < count; i++ {
  2349  		for {
  2350  			v := LoadUint64(addr)
  2351  			if CompareAndSwapUint64(addr, v, v+1) {
  2352  				break
  2353  			}
  2354  		}
  2355  	}
  2356  }
  2357  
  2358  func hammerCompareAndSwapUint64Method(uaddr *uint64, count int) {
  2359  	addr := (*Uint64)(unsafe.Pointer(uaddr))
  2360  	for i := 0; i < count; i++ {
  2361  		for {
  2362  			v := addr.Load()
  2363  			if addr.CompareAndSwap(v, v+1) {
  2364  				break
  2365  			}
  2366  		}
  2367  	}
  2368  }
  2369  
  2370  func hammerCompareAndSwapUintptr64(uaddr *uint64, count int) {
  2371  	// only safe when uintptr is 64-bit.
  2372  	// not called on 32-bit systems.
  2373  	addr := (*uintptr)(unsafe.Pointer(uaddr))
  2374  	for i := 0; i < count; i++ {
  2375  		for {
  2376  			v := LoadUintptr(addr)
  2377  			if CompareAndSwapUintptr(addr, v, v+1) {
  2378  				break
  2379  			}
  2380  		}
  2381  	}
  2382  }
  2383  
  2384  func hammerCompareAndSwapUintptr64Method(uaddr *uint64, count int) {
  2385  	// only safe when uintptr is 64-bit.
  2386  	// not called on 32-bit systems.
  2387  	addr := (*Uintptr)(unsafe.Pointer(uaddr))
  2388  	for i := 0; i < count; i++ {
  2389  		for {
  2390  			v := addr.Load()
  2391  			if addr.CompareAndSwap(v, v+1) {
  2392  				break
  2393  			}
  2394  		}
  2395  	}
  2396  }
  2397  
  2398  func TestHammer64(t *testing.T) {
  2399  	const p = 4
  2400  	n := 100000
  2401  	if testing.Short() {
  2402  		n = 1000
  2403  	}
  2404  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(p))
  2405  
  2406  	for name, testf := range hammer64 {
  2407  		c := make(chan int)
  2408  		var val uint64
  2409  		for i := 0; i < p; i++ {
  2410  			go func() {
  2411  				defer func() {
  2412  					if err := recover(); err != nil {
  2413  						t.Error(err.(string))
  2414  					}
  2415  					c <- 1
  2416  				}()
  2417  				testf(&val, n)
  2418  			}()
  2419  		}
  2420  		for i := 0; i < p; i++ {
  2421  			<-c
  2422  		}
  2423  		if !strings.HasPrefix(name, "Swap") && val != uint64(n)*p {
  2424  			t.Fatalf("%s: val=%d want %d", name, val, n*p)
  2425  		}
  2426  	}
  2427  }
  2428  
  2429  func hammerStoreLoadInt32(t *testing.T, paddr unsafe.Pointer) {
  2430  	addr := (*int32)(paddr)
  2431  	v := LoadInt32(addr)
  2432  	vlo := v & ((1 << 16) - 1)
  2433  	vhi := v >> 16
  2434  	if vlo != vhi {
  2435  		t.Fatalf("Int32: %#x != %#x", vlo, vhi)
  2436  	}
  2437  	new := v + 1 + 1<<16
  2438  	if vlo == 1e4 {
  2439  		new = 0
  2440  	}
  2441  	StoreInt32(addr, new)
  2442  }
  2443  
  2444  func hammerStoreLoadInt32Method(t *testing.T, paddr unsafe.Pointer) {
  2445  	addr := (*int32)(paddr)
  2446  	v := LoadInt32(addr)
  2447  	vlo := v & ((1 << 16) - 1)
  2448  	vhi := v >> 16
  2449  	if vlo != vhi {
  2450  		t.Fatalf("Int32: %#x != %#x", vlo, vhi)
  2451  	}
  2452  	new := v + 1 + 1<<16
  2453  	if vlo == 1e4 {
  2454  		new = 0
  2455  	}
  2456  	StoreInt32(addr, new)
  2457  }
  2458  
  2459  func hammerStoreLoadUint32(t *testing.T, paddr unsafe.Pointer) {
  2460  	addr := (*uint32)(paddr)
  2461  	v := LoadUint32(addr)
  2462  	vlo := v & ((1 << 16) - 1)
  2463  	vhi := v >> 16
  2464  	if vlo != vhi {
  2465  		t.Fatalf("Uint32: %#x != %#x", vlo, vhi)
  2466  	}
  2467  	new := v + 1 + 1<<16
  2468  	if vlo == 1e4 {
  2469  		new = 0
  2470  	}
  2471  	StoreUint32(addr, new)
  2472  }
  2473  
  2474  func hammerStoreLoadUint32Method(t *testing.T, paddr unsafe.Pointer) {
  2475  	addr := (*Uint32)(paddr)
  2476  	v := addr.Load()
  2477  	vlo := v & ((1 << 16) - 1)
  2478  	vhi := v >> 16
  2479  	if vlo != vhi {
  2480  		t.Fatalf("Uint32: %#x != %#x", vlo, vhi)
  2481  	}
  2482  	new := v + 1 + 1<<16
  2483  	if vlo == 1e4 {
  2484  		new = 0
  2485  	}
  2486  	addr.Store(new)
  2487  }
  2488  
  2489  func hammerStoreLoadInt64(t *testing.T, paddr unsafe.Pointer) {
  2490  	addr := (*int64)(paddr)
  2491  	v := LoadInt64(addr)
  2492  	vlo := v & ((1 << 32) - 1)
  2493  	vhi := v >> 32
  2494  	if vlo != vhi {
  2495  		t.Fatalf("Int64: %#x != %#x", vlo, vhi)
  2496  	}
  2497  	new := v + 1 + 1<<32
  2498  	StoreInt64(addr, new)
  2499  }
  2500  
  2501  func hammerStoreLoadInt64Method(t *testing.T, paddr unsafe.Pointer) {
  2502  	addr := (*Int64)(paddr)
  2503  	v := addr.Load()
  2504  	vlo := v & ((1 << 32) - 1)
  2505  	vhi := v >> 32
  2506  	if vlo != vhi {
  2507  		t.Fatalf("Int64: %#x != %#x", vlo, vhi)
  2508  	}
  2509  	new := v + 1 + 1<<32
  2510  	addr.Store(new)
  2511  }
  2512  
  2513  func hammerStoreLoadUint64(t *testing.T, paddr unsafe.Pointer) {
  2514  	addr := (*uint64)(paddr)
  2515  	v := LoadUint64(addr)
  2516  	vlo := v & ((1 << 32) - 1)
  2517  	vhi := v >> 32
  2518  	if vlo != vhi {
  2519  		t.Fatalf("Uint64: %#x != %#x", vlo, vhi)
  2520  	}
  2521  	new := v + 1 + 1<<32
  2522  	StoreUint64(addr, new)
  2523  }
  2524  
  2525  func hammerStoreLoadUint64Method(t *testing.T, paddr unsafe.Pointer) {
  2526  	addr := (*Uint64)(paddr)
  2527  	v := addr.Load()
  2528  	vlo := v & ((1 << 32) - 1)
  2529  	vhi := v >> 32
  2530  	if vlo != vhi {
  2531  		t.Fatalf("Uint64: %#x != %#x", vlo, vhi)
  2532  	}
  2533  	new := v + 1 + 1<<32
  2534  	addr.Store(new)
  2535  }
  2536  
  2537  func hammerStoreLoadUintptr(t *testing.T, paddr unsafe.Pointer) {
  2538  	addr := (*uintptr)(paddr)
  2539  	v := LoadUintptr(addr)
  2540  	new := v
  2541  	if arch32 {
  2542  		vlo := v & ((1 << 16) - 1)
  2543  		vhi := v >> 16
  2544  		if vlo != vhi {
  2545  			t.Fatalf("Uintptr: %#x != %#x", vlo, vhi)
  2546  		}
  2547  		new = v + 1 + 1<<16
  2548  		if vlo == 1e4 {
  2549  			new = 0
  2550  		}
  2551  	} else {
  2552  		vlo := v & ((1 << 32) - 1)
  2553  		vhi := v >> 32
  2554  		if vlo != vhi {
  2555  			t.Fatalf("Uintptr: %#x != %#x", vlo, vhi)
  2556  		}
  2557  		inc := uint64(1 + 1<<32)
  2558  		new = v + uintptr(inc)
  2559  	}
  2560  	StoreUintptr(addr, new)
  2561  }
  2562  
  2563  //go:nocheckptr
  2564  func hammerStoreLoadUintptrMethod(t *testing.T, paddr unsafe.Pointer) {
  2565  	addr := (*Uintptr)(paddr)
  2566  	v := addr.Load()
  2567  	new := v
  2568  	if arch32 {
  2569  		vlo := v & ((1 << 16) - 1)
  2570  		vhi := v >> 16
  2571  		if vlo != vhi {
  2572  			t.Fatalf("Uintptr: %#x != %#x", vlo, vhi)
  2573  		}
  2574  		new = v + 1 + 1<<16
  2575  		if vlo == 1e4 {
  2576  			new = 0
  2577  		}
  2578  	} else {
  2579  		vlo := v & ((1 << 32) - 1)
  2580  		vhi := v >> 32
  2581  		if vlo != vhi {
  2582  			t.Fatalf("Uintptr: %#x != %#x", vlo, vhi)
  2583  		}
  2584  		inc := uint64(1 + 1<<32)
  2585  		new = v + uintptr(inc)
  2586  	}
  2587  	addr.Store(new)
  2588  }
  2589  
  2590  // This code is just testing that LoadPointer/StorePointer operate
  2591  // atomically; it's not actually calculating pointers.
  2592  //
  2593  //go:nocheckptr
  2594  func hammerStoreLoadPointer(t *testing.T, paddr unsafe.Pointer) {
  2595  	addr := (*unsafe.Pointer)(paddr)
  2596  	v := uintptr(LoadPointer(addr))
  2597  	new := v
  2598  	if arch32 {
  2599  		vlo := v & ((1 << 16) - 1)
  2600  		vhi := v >> 16
  2601  		if vlo != vhi {
  2602  			t.Fatalf("Pointer: %#x != %#x", vlo, vhi)
  2603  		}
  2604  		new = v + 1 + 1<<16
  2605  		if vlo == 1e4 {
  2606  			new = 0
  2607  		}
  2608  	} else {
  2609  		vlo := v & ((1 << 32) - 1)
  2610  		vhi := v >> 32
  2611  		if vlo != vhi {
  2612  			t.Fatalf("Pointer: %#x != %#x", vlo, vhi)
  2613  		}
  2614  		inc := uint64(1 + 1<<32)
  2615  		new = v + uintptr(inc)
  2616  	}
  2617  	StorePointer(addr, unsafe.Pointer(new))
  2618  }
  2619  
  2620  // This code is just testing that LoadPointer/StorePointer operate
  2621  // atomically; it's not actually calculating pointers.
  2622  //
  2623  //go:nocheckptr
  2624  func hammerStoreLoadPointerMethod(t *testing.T, paddr unsafe.Pointer) {
  2625  	addr := (*Pointer[byte])(paddr)
  2626  	v := uintptr(unsafe.Pointer(addr.Load()))
  2627  	new := v
  2628  	if arch32 {
  2629  		vlo := v & ((1 << 16) - 1)
  2630  		vhi := v >> 16
  2631  		if vlo != vhi {
  2632  			t.Fatalf("Pointer: %#x != %#x", vlo, vhi)
  2633  		}
  2634  		new = v + 1 + 1<<16
  2635  		if vlo == 1e4 {
  2636  			new = 0
  2637  		}
  2638  	} else {
  2639  		vlo := v & ((1 << 32) - 1)
  2640  		vhi := v >> 32
  2641  		if vlo != vhi {
  2642  			t.Fatalf("Pointer: %#x != %#x", vlo, vhi)
  2643  		}
  2644  		inc := uint64(1 + 1<<32)
  2645  		new = v + uintptr(inc)
  2646  	}
  2647  	addr.Store((*byte)(unsafe.Pointer(new)))
  2648  }
  2649  
  2650  func TestHammerStoreLoad(t *testing.T) {
  2651  	tests := []func(*testing.T, unsafe.Pointer){
  2652  		hammerStoreLoadInt32, hammerStoreLoadUint32,
  2653  		hammerStoreLoadUintptr, hammerStoreLoadPointer,
  2654  		hammerStoreLoadInt32Method, hammerStoreLoadUint32Method,
  2655  		hammerStoreLoadUintptrMethod, hammerStoreLoadPointerMethod,
  2656  		hammerStoreLoadInt64, hammerStoreLoadUint64,
  2657  		hammerStoreLoadInt64Method, hammerStoreLoadUint64Method,
  2658  	}
  2659  	n := int(1e6)
  2660  	if testing.Short() {
  2661  		n = int(1e4)
  2662  	}
  2663  	const procs = 8
  2664  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(procs))
  2665  	// Disable the GC because hammerStoreLoadPointer invokes
  2666  	// write barriers on values that aren't real pointers.
  2667  	defer debug.SetGCPercent(debug.SetGCPercent(-1))
  2668  	// Ensure any in-progress GC is finished.
  2669  	runtime.GC()
  2670  	for _, tt := range tests {
  2671  		c := make(chan int)
  2672  		var val uint64
  2673  		for p := 0; p < procs; p++ {
  2674  			go func() {
  2675  				for i := 0; i < n; i++ {
  2676  					tt(t, unsafe.Pointer(&val))
  2677  				}
  2678  				c <- 1
  2679  			}()
  2680  		}
  2681  		for p := 0; p < procs; p++ {
  2682  			<-c
  2683  		}
  2684  	}
  2685  }
  2686  
  2687  func TestStoreLoadSeqCst32(t *testing.T) {
  2688  	if runtime.NumCPU() == 1 {
  2689  		t.Skipf("Skipping test on %v processor machine", runtime.NumCPU())
  2690  	}
  2691  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
  2692  	N := int32(1e3)
  2693  	if testing.Short() {
  2694  		N = int32(1e2)
  2695  	}
  2696  	c := make(chan bool, 2)
  2697  	X := [2]int32{}
  2698  	ack := [2][3]int32{{-1, -1, -1}, {-1, -1, -1}}
  2699  	for p := 0; p < 2; p++ {
  2700  		go func(me int) {
  2701  			he := 1 - me
  2702  			for i := int32(1); i < N; i++ {
  2703  				StoreInt32(&X[me], i)
  2704  				my := LoadInt32(&X[he])
  2705  				StoreInt32(&ack[me][i%3], my)
  2706  				for w := 1; LoadInt32(&ack[he][i%3]) == -1; w++ {
  2707  					if w%1000 == 0 {
  2708  						runtime.Gosched()
  2709  					}
  2710  				}
  2711  				his := LoadInt32(&ack[he][i%3])
  2712  				if (my != i && my != i-1) || (his != i && his != i-1) {
  2713  					t.Errorf("invalid values: %d/%d (%d)", my, his, i)
  2714  					break
  2715  				}
  2716  				if my != i && his != i {
  2717  					t.Errorf("store/load are not sequentially consistent: %d/%d (%d)", my, his, i)
  2718  					break
  2719  				}
  2720  				StoreInt32(&ack[me][(i-1)%3], -1)
  2721  			}
  2722  			c <- true
  2723  		}(p)
  2724  	}
  2725  	<-c
  2726  	<-c
  2727  }
  2728  
  2729  func TestStoreLoadSeqCst64(t *testing.T) {
  2730  	if runtime.NumCPU() == 1 {
  2731  		t.Skipf("Skipping test on %v processor machine", runtime.NumCPU())
  2732  	}
  2733  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
  2734  	N := int64(1e3)
  2735  	if testing.Short() {
  2736  		N = int64(1e2)
  2737  	}
  2738  	c := make(chan bool, 2)
  2739  	X := [2]int64{}
  2740  	ack := [2][3]int64{{-1, -1, -1}, {-1, -1, -1}}
  2741  	for p := 0; p < 2; p++ {
  2742  		go func(me int) {
  2743  			he := 1 - me
  2744  			for i := int64(1); i < N; i++ {
  2745  				StoreInt64(&X[me], i)
  2746  				my := LoadInt64(&X[he])
  2747  				StoreInt64(&ack[me][i%3], my)
  2748  				for w := 1; LoadInt64(&ack[he][i%3]) == -1; w++ {
  2749  					if w%1000 == 0 {
  2750  						runtime.Gosched()
  2751  					}
  2752  				}
  2753  				his := LoadInt64(&ack[he][i%3])
  2754  				if (my != i && my != i-1) || (his != i && his != i-1) {
  2755  					t.Errorf("invalid values: %d/%d (%d)", my, his, i)
  2756  					break
  2757  				}
  2758  				if my != i && his != i {
  2759  					t.Errorf("store/load are not sequentially consistent: %d/%d (%d)", my, his, i)
  2760  					break
  2761  				}
  2762  				StoreInt64(&ack[me][(i-1)%3], -1)
  2763  			}
  2764  			c <- true
  2765  		}(p)
  2766  	}
  2767  	<-c
  2768  	<-c
  2769  }
  2770  
  2771  func TestStoreLoadRelAcq32(t *testing.T) {
  2772  	if runtime.NumCPU() == 1 {
  2773  		t.Skipf("Skipping test on %v processor machine", runtime.NumCPU())
  2774  	}
  2775  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
  2776  	N := int32(1e3)
  2777  	if testing.Short() {
  2778  		N = int32(1e2)
  2779  	}
  2780  	c := make(chan bool, 2)
  2781  	type Data struct {
  2782  		signal int32
  2783  		pad1   [128]int8
  2784  		data1  int32
  2785  		pad2   [128]int8
  2786  		data2  float32
  2787  	}
  2788  	var X Data
  2789  	for p := int32(0); p < 2; p++ {
  2790  		go func(p int32) {
  2791  			for i := int32(1); i < N; i++ {
  2792  				if (i+p)%2 == 0 {
  2793  					X.data1 = i
  2794  					X.data2 = float32(i)
  2795  					StoreInt32(&X.signal, i)
  2796  				} else {
  2797  					for w := 1; LoadInt32(&X.signal) != i; w++ {
  2798  						if w%1000 == 0 {
  2799  							runtime.Gosched()
  2800  						}
  2801  					}
  2802  					d1 := X.data1
  2803  					d2 := X.data2
  2804  					if d1 != i || d2 != float32(i) {
  2805  						t.Errorf("incorrect data: %d/%g (%d)", d1, d2, i)
  2806  						break
  2807  					}
  2808  				}
  2809  			}
  2810  			c <- true
  2811  		}(p)
  2812  	}
  2813  	<-c
  2814  	<-c
  2815  }
  2816  
  2817  func TestStoreLoadRelAcq64(t *testing.T) {
  2818  	if runtime.NumCPU() == 1 {
  2819  		t.Skipf("Skipping test on %v processor machine", runtime.NumCPU())
  2820  	}
  2821  	defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
  2822  	N := int64(1e3)
  2823  	if testing.Short() {
  2824  		N = int64(1e2)
  2825  	}
  2826  	c := make(chan bool, 2)
  2827  	type Data struct {
  2828  		signal int64
  2829  		pad1   [128]int8
  2830  		data1  int64
  2831  		pad2   [128]int8
  2832  		data2  float64
  2833  	}
  2834  	var X Data
  2835  	for p := int64(0); p < 2; p++ {
  2836  		go func(p int64) {
  2837  			for i := int64(1); i < N; i++ {
  2838  				if (i+p)%2 == 0 {
  2839  					X.data1 = i
  2840  					X.data2 = float64(i)
  2841  					StoreInt64(&X.signal, i)
  2842  				} else {
  2843  					for w := 1; LoadInt64(&X.signal) != i; w++ {
  2844  						if w%1000 == 0 {
  2845  							runtime.Gosched()
  2846  						}
  2847  					}
  2848  					d1 := X.data1
  2849  					d2 := X.data2
  2850  					if d1 != i || d2 != float64(i) {
  2851  						t.Errorf("incorrect data: %d/%g (%d)", d1, d2, i)
  2852  						break
  2853  					}
  2854  				}
  2855  			}
  2856  			c <- true
  2857  		}(p)
  2858  	}
  2859  	<-c
  2860  	<-c
  2861  }
  2862  
  2863  func shouldPanic(t *testing.T, name string, f func()) {
  2864  	defer func() {
  2865  		// Check that all GC maps are sane.
  2866  		runtime.GC()
  2867  
  2868  		err := recover()
  2869  		want := "unaligned 64-bit atomic operation"
  2870  		if err == nil {
  2871  			t.Errorf("%s did not panic", name)
  2872  		} else if s, _ := err.(string); s != want {
  2873  			t.Errorf("%s: wanted panic %q, got %q", name, want, err)
  2874  		}
  2875  	}()
  2876  	f()
  2877  }
  2878  
  2879  func TestUnaligned64(t *testing.T) {
  2880  	// Unaligned 64-bit atomics on 32-bit systems are
  2881  	// a continual source of pain. Test that on 32-bit systems they crash
  2882  	// instead of failing silently.
  2883  	if !arch32 {
  2884  		t.Skip("test only runs on 32-bit systems")
  2885  	}
  2886  
  2887  	x := make([]uint32, 4)
  2888  	p := (*uint64)(unsafe.Pointer(&x[1])) // misaligned
  2889  
  2890  	shouldPanic(t, "LoadUint64", func() { LoadUint64(p) })
  2891  	shouldPanic(t, "LoadUint64Method", func() { (*Uint64)(unsafe.Pointer(p)).Load() })
  2892  	shouldPanic(t, "StoreUint64", func() { StoreUint64(p, 1) })
  2893  	shouldPanic(t, "StoreUint64Method", func() { (*Uint64)(unsafe.Pointer(p)).Store(1) })
  2894  	shouldPanic(t, "CompareAndSwapUint64", func() { CompareAndSwapUint64(p, 1, 2) })
  2895  	shouldPanic(t, "CompareAndSwapUint64Method", func() { (*Uint64)(unsafe.Pointer(p)).CompareAndSwap(1, 2) })
  2896  	shouldPanic(t, "AddUint64", func() { AddUint64(p, 3) })
  2897  	shouldPanic(t, "AddUint64Method", func() { (*Uint64)(unsafe.Pointer(p)).Add(3) })
  2898  }
  2899  
  2900  func TestAutoAligned64(t *testing.T) {
  2901  	var signed struct {
  2902  		_ uint32
  2903  		i Int64
  2904  	}
  2905  	if o := reflect.TypeOf(&signed).Elem().Field(1).Offset; o != 8 {
  2906  		t.Fatalf("Int64 offset = %d, want 8", o)
  2907  	}
  2908  	if p := reflect.ValueOf(&signed).Elem().Field(1).Addr().Pointer(); p&7 != 0 {
  2909  		t.Fatalf("Int64 pointer = %#x, want 8-aligned", p)
  2910  	}
  2911  
  2912  	var unsigned struct {
  2913  		_ uint32
  2914  		i Uint64
  2915  	}
  2916  	if o := reflect.TypeOf(&unsigned).Elem().Field(1).Offset; o != 8 {
  2917  		t.Fatalf("Uint64 offset = %d, want 8", o)
  2918  	}
  2919  	if p := reflect.ValueOf(&unsigned).Elem().Field(1).Addr().Pointer(); p&7 != 0 {
  2920  		t.Fatalf("Int64 pointer = %#x, want 8-aligned", p)
  2921  	}
  2922  }
  2923  
  2924  func TestNilDeref(t *testing.T) {
  2925  	funcs := [...]func(){
  2926  		func() { CompareAndSwapInt32(nil, 0, 0) },
  2927  		func() { (*Int32)(nil).CompareAndSwap(0, 0) },
  2928  		func() { CompareAndSwapInt64(nil, 0, 0) },
  2929  		func() { (*Int64)(nil).CompareAndSwap(0, 0) },
  2930  		func() { CompareAndSwapUint32(nil, 0, 0) },
  2931  		func() { (*Uint32)(nil).CompareAndSwap(0, 0) },
  2932  		func() { CompareAndSwapUint64(nil, 0, 0) },
  2933  		func() { (*Uint64)(nil).CompareAndSwap(0, 0) },
  2934  		func() { CompareAndSwapUintptr(nil, 0, 0) },
  2935  		func() { (*Uintptr)(nil).CompareAndSwap(0, 0) },
  2936  		func() { CompareAndSwapPointer(nil, nil, nil) },
  2937  		func() { (*Pointer[byte])(nil).CompareAndSwap(nil, nil) },
  2938  		func() { SwapInt32(nil, 0) },
  2939  		func() { (*Int32)(nil).Swap(0) },
  2940  		func() { SwapUint32(nil, 0) },
  2941  		func() { (*Uint32)(nil).Swap(0) },
  2942  		func() { SwapInt64(nil, 0) },
  2943  		func() { (*Int64)(nil).Swap(0) },
  2944  		func() { SwapUint64(nil, 0) },
  2945  		func() { (*Uint64)(nil).Swap(0) },
  2946  		func() { SwapUintptr(nil, 0) },
  2947  		func() { (*Uintptr)(nil).Swap(0) },
  2948  		func() { SwapPointer(nil, nil) },
  2949  		func() { (*Pointer[byte])(nil).Swap(nil) },
  2950  		func() { AddInt32(nil, 0) },
  2951  		func() { (*Int32)(nil).Add(0) },
  2952  		func() { AddUint32(nil, 0) },
  2953  		func() { (*Uint32)(nil).Add(0) },
  2954  		func() { AddInt64(nil, 0) },
  2955  		func() { (*Int64)(nil).Add(0) },
  2956  		func() { AddUint64(nil, 0) },
  2957  		func() { (*Uint64)(nil).Add(0) },
  2958  		func() { AddUintptr(nil, 0) },
  2959  		func() { (*Uintptr)(nil).Add(0) },
  2960  		func() { LoadInt32(nil) },
  2961  		func() { (*Int32)(nil).Load() },
  2962  		func() { LoadInt64(nil) },
  2963  		func() { (*Int64)(nil).Load() },
  2964  		func() { LoadUint32(nil) },
  2965  		func() { (*Uint32)(nil).Load() },
  2966  		func() { LoadUint64(nil) },
  2967  		func() { (*Uint64)(nil).Load() },
  2968  		func() { LoadUintptr(nil) },
  2969  		func() { (*Uintptr)(nil).Load() },
  2970  		func() { LoadPointer(nil) },
  2971  		func() { (*Pointer[byte])(nil).Load() },
  2972  		func() { StoreInt32(nil, 0) },
  2973  		func() { (*Int32)(nil).Store(0) },
  2974  		func() { StoreInt64(nil, 0) },
  2975  		func() { (*Int64)(nil).Store(0) },
  2976  		func() { StoreUint32(nil, 0) },
  2977  		func() { (*Uint32)(nil).Store(0) },
  2978  		func() { StoreUint64(nil, 0) },
  2979  		func() { (*Uint64)(nil).Store(0) },
  2980  		func() { StoreUintptr(nil, 0) },
  2981  		func() { (*Uintptr)(nil).Store(0) },
  2982  		func() { StorePointer(nil, nil) },
  2983  		func() { (*Pointer[byte])(nil).Store(nil) },
  2984  	}
  2985  	for _, f := range funcs {
  2986  		func() {
  2987  			defer func() {
  2988  				runtime.GC()
  2989  				recover()
  2990  			}()
  2991  			f()
  2992  		}()
  2993  	}
  2994  }
  2995  
  2996  // Test that this compiles.
  2997  // When atomic.Pointer used _ [0]T, it did not.
  2998  type List struct {
  2999  	Next Pointer[List]
  3000  }
  3001  

View as plain text