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.
14 // Tests of correct behavior, without contention.
15 // (Does the function work as advertised?)
17 // Test that the Add functions add correctly.
18 // Test that the CompareAndSwap functions actually
19 // do the comparison and the swap correctly.
21 // The loop over power-of-two values is meant to
22 // ensure that the operations apply to the full word size.
23 // The struct fields x.before and x.after check that the
24 // operations do not extend past the full word size.
28 magic64 = 0xdeddeadbeefbeef
31 // Do the 64-bit functions panic? If so, don't bother testing.
32 var test64err = func() (err interface{}) {
41 func TestAddInt32(t *testing.T) {
50 for delta := int32(1); delta+delta > delta; delta += delta {
51 k := AddInt32(&x.i, delta)
53 if x.i != j || k != j {
54 t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
57 if x.before != magic32 || x.after != magic32 {
58 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
62 func TestAddUint32(t *testing.T) {
71 for delta := uint32(1); delta+delta > delta; delta += delta {
72 k := AddUint32(&x.i, delta)
74 if x.i != j || k != j {
75 t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
78 if x.before != magic32 || x.after != magic32 {
79 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
83 func TestAddInt64(t *testing.T) {
85 t.Skipf("Skipping 64-bit tests: %v", test64err)
95 for delta := int64(1); delta+delta > delta; delta += delta {
96 k := AddInt64(&x.i, delta)
98 if x.i != j || k != j {
99 t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
102 if x.before != magic64 || x.after != magic64 {
103 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, int64(magic64), int64(magic64))
107 func TestAddUint64(t *testing.T) {
108 if test64err != nil {
109 t.Skipf("Skipping 64-bit tests: %v", test64err)
119 for delta := uint64(1); delta+delta > delta; delta += delta {
120 k := AddUint64(&x.i, delta)
122 if x.i != j || k != j {
123 t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
126 if x.before != magic64 || x.after != magic64 {
127 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
131 func TestAddUintptr(t *testing.T) {
137 var m uint64 = magic64
138 magicptr := uintptr(m)
142 for delta := uintptr(1); delta+delta > delta; delta += delta {
143 k := AddUintptr(&x.i, delta)
145 if x.i != j || k != j {
146 t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k)
149 if x.before != magicptr || x.after != magicptr {
150 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
154 func TestCompareAndSwapInt32(t *testing.T) {
162 for val := int32(1); val+val > val; val += val {
164 if !CompareAndSwapInt32(&x.i, val, val+1) {
165 t.Fatalf("should have swapped %#x %#x", val, val+1)
168 t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
171 if CompareAndSwapInt32(&x.i, val, val+2) {
172 t.Fatalf("should not have swapped %#x %#x", val, val+2)
175 t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
178 if x.before != magic32 || x.after != magic32 {
179 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
183 func TestCompareAndSwapUint32(t *testing.T) {
191 for val := uint32(1); val+val > val; val += val {
193 if !CompareAndSwapUint32(&x.i, val, val+1) {
194 t.Fatalf("should have swapped %#x %#x", val, val+1)
197 t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
200 if CompareAndSwapUint32(&x.i, val, val+2) {
201 t.Fatalf("should not have swapped %#x %#x", val, val+2)
204 t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
207 if x.before != magic32 || x.after != magic32 {
208 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
212 func TestCompareAndSwapInt64(t *testing.T) {
213 if test64err != nil {
214 t.Skipf("Skipping 64-bit tests: %v", test64err)
223 for val := int64(1); val+val > val; val += val {
225 if !CompareAndSwapInt64(&x.i, val, val+1) {
226 t.Fatalf("should have swapped %#x %#x", val, val+1)
229 t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
232 if CompareAndSwapInt64(&x.i, val, val+2) {
233 t.Fatalf("should not have swapped %#x %#x", val, val+2)
236 t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
239 if x.before != magic64 || x.after != magic64 {
240 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
244 func TestCompareAndSwapUint64(t *testing.T) {
245 if test64err != nil {
246 t.Skipf("Skipping 64-bit tests: %v", test64err)
255 for val := uint64(1); val+val > val; val += val {
257 if !CompareAndSwapUint64(&x.i, val, val+1) {
258 t.Fatalf("should have swapped %#x %#x", val, val+1)
261 t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
264 if CompareAndSwapUint64(&x.i, val, val+2) {
265 t.Fatalf("should not have swapped %#x %#x", val, val+2)
268 t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
271 if x.before != magic64 || x.after != magic64 {
272 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
276 func TestCompareAndSwapUintptr(t *testing.T) {
282 var m uint64 = magic64
283 magicptr := uintptr(m)
286 for val := uintptr(1); val+val > val; val += val {
288 if !CompareAndSwapUintptr(&x.i, val, val+1) {
289 t.Fatalf("should have swapped %#x %#x", val, val+1)
292 t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
295 if CompareAndSwapUintptr(&x.i, val, val+2) {
296 t.Fatalf("should not have swapped %#x %#x", val, val+2)
299 t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
302 if x.before != magicptr || x.after != magicptr {
303 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
307 func TestCompareAndSwapPointer(t *testing.T) {
313 var m uint64 = magic64
314 magicptr := uintptr(m)
317 for val := uintptr(1); val+val > val; val += val {
318 x.i = unsafe.Pointer(val)
319 if !CompareAndSwapPointer(&x.i, unsafe.Pointer(val), unsafe.Pointer(val+1)) {
320 t.Fatalf("should have swapped %#x %#x", val, val+1)
322 if x.i != unsafe.Pointer(val+1) {
323 t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
325 x.i = unsafe.Pointer(val + 1)
326 if CompareAndSwapPointer(&x.i, unsafe.Pointer(val), unsafe.Pointer(val+2)) {
327 t.Fatalf("should not have swapped %#x %#x", val, val+2)
329 if x.i != unsafe.Pointer(val+1) {
330 t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1)
333 if x.before != magicptr || x.after != magicptr {
334 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
338 func TestLoadInt32(t *testing.T) {
346 for delta := int32(1); delta+delta > delta; delta += delta {
349 t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
353 if x.before != magic32 || x.after != magic32 {
354 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
358 func TestLoadUint32(t *testing.T) {
366 for delta := uint32(1); delta+delta > delta; delta += delta {
367 k := LoadUint32(&x.i)
369 t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
373 if x.before != magic32 || x.after != magic32 {
374 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
378 func TestLoadInt64(t *testing.T) {
379 if test64err != nil {
380 t.Skipf("Skipping 64-bit tests: %v", test64err)
389 for delta := int64(1); delta+delta > delta; delta += delta {
392 t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
396 if x.before != magic64 || x.after != magic64 {
397 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
401 func TestLoadUint64(t *testing.T) {
402 if test64err != nil {
403 t.Skipf("Skipping 64-bit tests: %v", test64err)
412 for delta := uint64(1); delta+delta > delta; delta += delta {
413 k := LoadUint64(&x.i)
415 t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
419 if x.before != magic64 || x.after != magic64 {
420 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
424 func TestLoadUintptr(t *testing.T) {
430 var m uint64 = magic64
431 magicptr := uintptr(m)
434 for delta := uintptr(1); delta+delta > delta; delta += delta {
435 k := LoadUintptr(&x.i)
437 t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
441 if x.before != magicptr || x.after != magicptr {
442 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
446 func TestLoadPointer(t *testing.T) {
452 var m uint64 = magic64
453 magicptr := uintptr(m)
456 for delta := uintptr(1); delta+delta > delta; delta += delta {
457 k := LoadPointer(&x.i)
459 t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k)
461 x.i = unsafe.Pointer(uintptr(x.i) + delta)
463 if x.before != magicptr || x.after != magicptr {
464 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
468 func TestStoreInt32(t *testing.T) {
477 for delta := int32(1); delta+delta > delta; delta += delta {
480 t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
484 if x.before != magic32 || x.after != magic32 {
485 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
489 func TestStoreUint32(t *testing.T) {
498 for delta := uint32(1); delta+delta > delta; delta += delta {
501 t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
505 if x.before != magic32 || x.after != magic32 {
506 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32)
510 func TestStoreInt64(t *testing.T) {
511 if test64err != nil {
512 t.Skipf("Skipping 64-bit tests: %v", test64err)
522 for delta := int64(1); delta+delta > delta; delta += delta {
525 t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
529 if x.before != magic64 || x.after != magic64 {
530 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
534 func TestStoreUint64(t *testing.T) {
535 if test64err != nil {
536 t.Skipf("Skipping 64-bit tests: %v", test64err)
546 for delta := uint64(1); delta+delta > delta; delta += delta {
549 t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
553 if x.before != magic64 || x.after != magic64 {
554 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64))
558 func TestStoreUintptr(t *testing.T) {
564 var m uint64 = magic64
565 magicptr := uintptr(m)
569 for delta := uintptr(1); delta+delta > delta; delta += delta {
570 StoreUintptr(&x.i, v)
572 t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
576 if x.before != magicptr || x.after != magicptr {
577 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
581 func TestStorePointer(t *testing.T) {
587 var m uint64 = magic64
588 magicptr := uintptr(m)
591 v := unsafe.Pointer(uintptr(0))
592 for delta := uintptr(1); delta+delta > delta; delta += delta {
593 StorePointer(&x.i, unsafe.Pointer(v))
595 t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v)
597 v = unsafe.Pointer(uintptr(v) + delta)
599 if x.before != magicptr || x.after != magicptr {
600 t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr)
604 // Tests of correct behavior, with contention.
605 // (Is the function atomic?)
607 // For each function, we write a "hammer" function that repeatedly
608 // uses the atomic operation to add 1 to a value. After running
609 // multiple hammers in parallel, check that we end with the correct
612 var hammer32 = []struct {
616 {"AddInt32", hammerAddInt32},
617 {"AddUint32", hammerAddUint32},
618 {"AddUintptr", hammerAddUintptr32},
619 {"CompareAndSwapInt32", hammerCompareAndSwapInt32},
620 {"CompareAndSwapUint32", hammerCompareAndSwapUint32},
621 {"CompareAndSwapUintptr", hammerCompareAndSwapUintptr32},
622 {"CompareAndSwapPointer", hammerCompareAndSwapPointer32},
626 var v uint64 = 1 << 50
628 // 64-bit system; clear uintptr tests
635 func hammerAddInt32(uaddr *uint32, count int) {
636 addr := (*int32)(unsafe.Pointer(uaddr))
637 for i := 0; i < count; i++ {
642 func hammerAddUint32(addr *uint32, count int) {
643 for i := 0; i < count; i++ {
648 func hammerAddUintptr32(uaddr *uint32, count int) {
649 // only safe when uintptr is 32-bit.
650 // not called on 64-bit systems.
651 addr := (*uintptr)(unsafe.Pointer(uaddr))
652 for i := 0; i < count; i++ {
657 func hammerCompareAndSwapInt32(uaddr *uint32, count int) {
658 addr := (*int32)(unsafe.Pointer(uaddr))
659 for i := 0; i < count; i++ {
662 if CompareAndSwapInt32(addr, v, v+1) {
669 func hammerCompareAndSwapUint32(addr *uint32, count int) {
670 for i := 0; i < count; i++ {
673 if CompareAndSwapUint32(addr, v, v+1) {
680 func hammerCompareAndSwapUintptr32(uaddr *uint32, count int) {
681 // only safe when uintptr is 32-bit.
682 // not called on 64-bit systems.
683 addr := (*uintptr)(unsafe.Pointer(uaddr))
684 for i := 0; i < count; i++ {
687 if CompareAndSwapUintptr(addr, v, v+1) {
694 func hammerCompareAndSwapPointer32(uaddr *uint32, count int) {
695 // only safe when uintptr is 32-bit.
696 // not called on 64-bit systems.
697 addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr))
698 for i := 0; i < count; i++ {
701 if CompareAndSwapPointer(addr, v, unsafe.Pointer(uintptr(v)+1)) {
708 func TestHammer32(t *testing.T) {
714 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(p))
716 for _, tt := range hammer32 {
722 for i := 0; i < p; i++ {
728 for i := 0; i < p; i++ {
731 if val != uint32(n)*p {
732 t.Fatalf("%s: val=%d want %d", tt.name, val, n*p)
737 var hammer64 = []struct {
741 {"AddInt64", hammerAddInt64},
742 {"AddUint64", hammerAddUint64},
743 {"AddUintptr", hammerAddUintptr64},
744 {"CompareAndSwapInt64", hammerCompareAndSwapInt64},
745 {"CompareAndSwapUint64", hammerCompareAndSwapUint64},
746 {"CompareAndSwapUintptr", hammerCompareAndSwapUintptr64},
747 {"CompareAndSwapPointer", hammerCompareAndSwapPointer64},
751 var v uint64 = 1 << 50
753 // 32-bit system; clear uintptr tests
760 func hammerAddInt64(uaddr *uint64, count int) {
761 addr := (*int64)(unsafe.Pointer(uaddr))
762 for i := 0; i < count; i++ {
767 func hammerAddUint64(addr *uint64, count int) {
768 for i := 0; i < count; i++ {
773 func hammerAddUintptr64(uaddr *uint64, count int) {
774 // only safe when uintptr is 64-bit.
775 // not called on 32-bit systems.
776 addr := (*uintptr)(unsafe.Pointer(uaddr))
777 for i := 0; i < count; i++ {
782 func hammerCompareAndSwapInt64(uaddr *uint64, count int) {
783 addr := (*int64)(unsafe.Pointer(uaddr))
784 for i := 0; i < count; i++ {
787 if CompareAndSwapInt64(addr, v, v+1) {
794 func hammerCompareAndSwapUint64(addr *uint64, count int) {
795 for i := 0; i < count; i++ {
798 if CompareAndSwapUint64(addr, v, v+1) {
805 func hammerCompareAndSwapUintptr64(uaddr *uint64, count int) {
806 // only safe when uintptr is 64-bit.
807 // not called on 32-bit systems.
808 addr := (*uintptr)(unsafe.Pointer(uaddr))
809 for i := 0; i < count; i++ {
812 if CompareAndSwapUintptr(addr, v, v+1) {
819 func hammerCompareAndSwapPointer64(uaddr *uint64, count int) {
820 // only safe when uintptr is 64-bit.
821 // not called on 32-bit systems.
822 addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr))
823 for i := 0; i < count; i++ {
826 if CompareAndSwapPointer(addr, v, unsafe.Pointer(uintptr(v)+1)) {
833 func TestHammer64(t *testing.T) {
834 if test64err != nil {
835 t.Skipf("Skipping 64-bit tests: %v", test64err)
842 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(p))
844 for _, tt := range hammer64 {
850 for i := 0; i < p; i++ {
856 for i := 0; i < p; i++ {
859 if val != uint64(n)*p {
860 t.Fatalf("%s: val=%d want %d", tt.name, val, n*p)
865 func hammerStoreLoadInt32(t *testing.T, paddr unsafe.Pointer) {
866 addr := (*int32)(paddr)
868 vlo := v & ((1 << 16) - 1)
871 t.Fatalf("Int32: %#x != %#x", vlo, vhi)
877 StoreInt32(addr, new)
880 func hammerStoreLoadUint32(t *testing.T, paddr unsafe.Pointer) {
881 addr := (*uint32)(paddr)
882 v := LoadUint32(addr)
883 vlo := v & ((1 << 16) - 1)
886 t.Fatalf("Uint32: %#x != %#x", vlo, vhi)
892 StoreUint32(addr, new)
895 func hammerStoreLoadInt64(t *testing.T, paddr unsafe.Pointer) {
896 addr := (*int64)(paddr)
898 vlo := v & ((1 << 32) - 1)
901 t.Fatalf("Int64: %#x != %#x", vlo, vhi)
904 StoreInt64(addr, new)
907 func hammerStoreLoadUint64(t *testing.T, paddr unsafe.Pointer) {
908 addr := (*uint64)(paddr)
909 v := LoadUint64(addr)
910 vlo := v & ((1 << 32) - 1)
913 t.Fatalf("Uint64: %#x != %#x", vlo, vhi)
916 StoreUint64(addr, new)
919 func hammerStoreLoadUintptr(t *testing.T, paddr unsafe.Pointer) {
920 addr := (*uintptr)(paddr)
921 var test64 uint64 = 1 << 50
922 arch32 := uintptr(test64) == 0
923 v := LoadUintptr(addr)
926 vlo := v & ((1 << 16) - 1)
929 t.Fatalf("Uintptr: %#x != %#x", vlo, vhi)
936 vlo := v & ((1 << 32) - 1)
939 t.Fatalf("Uintptr: %#x != %#x", vlo, vhi)
941 inc := uint64(1 + 1<<32)
942 new = v + uintptr(inc)
944 StoreUintptr(addr, new)
947 func hammerStoreLoadPointer(t *testing.T, paddr unsafe.Pointer) {
948 addr := (*unsafe.Pointer)(paddr)
949 var test64 uint64 = 1 << 50
950 arch32 := uintptr(test64) == 0
951 v := uintptr(LoadPointer(addr))
954 vlo := v & ((1 << 16) - 1)
957 t.Fatalf("Pointer: %#x != %#x", vlo, vhi)
964 vlo := v & ((1 << 32) - 1)
967 t.Fatalf("Pointer: %#x != %#x", vlo, vhi)
969 inc := uint64(1 + 1<<32)
970 new = v + uintptr(inc)
972 StorePointer(addr, unsafe.Pointer(new))
975 func TestHammerStoreLoad(t *testing.T) {
976 var tests []func(*testing.T, unsafe.Pointer)
977 tests = append(tests, hammerStoreLoadInt32, hammerStoreLoadUint32,
978 hammerStoreLoadUintptr, hammerStoreLoadPointer)
979 if test64err == nil {
980 tests = append(tests, hammerStoreLoadInt64, hammerStoreLoadUint64)
987 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(procs))
988 for _, tt := range tests {
991 for p := 0; p < procs; p++ {
993 for i := 0; i < n; i++ {
994 tt(t, unsafe.Pointer(&val))
999 for p := 0; p < procs; p++ {
1005 func TestStoreLoadSeqCst32(t *testing.T) {
1006 if runtime.NumCPU() == 1 {
1007 t.Skipf("Skipping test on %v processor machine", runtime.NumCPU())
1009 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
1011 if testing.Short() {
1014 c := make(chan bool, 2)
1016 ack := [2][3]int32{{-1, -1, -1}, {-1, -1, -1}}
1017 for p := 0; p < 2; p++ {
1020 for i := int32(1); i < N; i++ {
1021 StoreInt32(&X[me], i)
1022 my := LoadInt32(&X[he])
1023 StoreInt32(&ack[me][i%3], my)
1024 for w := 1; LoadInt32(&ack[he][i%3]) == -1; w++ {
1029 his := LoadInt32(&ack[he][i%3])
1030 if (my != i && my != i-1) || (his != i && his != i-1) {
1031 t.Fatalf("invalid values: %d/%d (%d)", my, his, i)
1033 if my != i && his != i {
1034 t.Fatalf("store/load are not sequentially consistent: %d/%d (%d)", my, his, i)
1036 StoreInt32(&ack[me][(i-1)%3], -1)
1045 func TestStoreLoadSeqCst64(t *testing.T) {
1046 if runtime.NumCPU() == 1 {
1047 t.Skipf("Skipping test on %v processor machine", runtime.NumCPU())
1049 if test64err != nil {
1050 t.Skipf("Skipping 64-bit tests: %v", test64err)
1052 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
1054 if testing.Short() {
1057 c := make(chan bool, 2)
1059 ack := [2][3]int64{{-1, -1, -1}, {-1, -1, -1}}
1060 for p := 0; p < 2; p++ {
1063 for i := int64(1); i < N; i++ {
1064 StoreInt64(&X[me], i)
1065 my := LoadInt64(&X[he])
1066 StoreInt64(&ack[me][i%3], my)
1067 for w := 1; LoadInt64(&ack[he][i%3]) == -1; w++ {
1072 his := LoadInt64(&ack[he][i%3])
1073 if (my != i && my != i-1) || (his != i && his != i-1) {
1074 t.Fatalf("invalid values: %d/%d (%d)", my, his, i)
1076 if my != i && his != i {
1077 t.Fatalf("store/load are not sequentially consistent: %d/%d (%d)", my, his, i)
1079 StoreInt64(&ack[me][(i-1)%3], -1)
1088 func TestStoreLoadRelAcq32(t *testing.T) {
1089 if runtime.NumCPU() == 1 {
1090 t.Skipf("Skipping test on %v processor machine", runtime.NumCPU())
1092 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
1094 if testing.Short() {
1097 c := make(chan bool, 2)
1106 for p := int32(0); p < 2; p++ {
1108 for i := int32(1); i < N; i++ {
1111 X.data2 = float32(i)
1112 StoreInt32(&X.signal, i)
1114 for w := 1; LoadInt32(&X.signal) != i; w++ {
1121 if d1 != i || d2 != float32(i) {
1122 t.Fatalf("incorrect data: %d/%d (%d)", d1, d2, i)
1133 func TestStoreLoadRelAcq64(t *testing.T) {
1134 if runtime.NumCPU() == 1 {
1135 t.Skipf("Skipping test on %v processor machine", runtime.NumCPU())
1137 if test64err != nil {
1138 t.Skipf("Skipping 64-bit tests: %v", test64err)
1140 defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4))
1142 if testing.Short() {
1145 c := make(chan bool, 2)
1154 for p := int64(0); p < 2; p++ {
1156 for i := int64(1); i < N; i++ {
1159 X.data2 = float64(i)
1160 StoreInt64(&X.signal, i)
1162 for w := 1; LoadInt64(&X.signal) != i; w++ {
1169 if d1 != i || d2 != float64(i) {
1170 t.Fatalf("incorrect data: %d/%d (%d)", d1, d2, i)