1
0
mirror of https://github.com/golang/go synced 2024-11-20 03:34:40 -07:00
go/src/runtime/atomic_test.go
Srdjan Petrovic 6ad33be2d9 runtime: implement xadduintptr and update system mstats using it
The motivation is that sysAlloc/Free() currently aren't safe to be
called without a valid G, because arm's xadd64() uses locks that require
a valid G.

The solution here was proposed by Dmitry Vyukov: use xadduintptr()
instead of xadd64(), until arm can support xadd64 on all of its
architectures (not a trivial task for arm).

Change-Id: I250252079357ea2e4360e1235958b1c22051498f
Reviewed-on: https://go-review.googlesource.com/9002
Reviewed-by: Dmitry Vyukov <dvyukov@google.com>
2015-04-24 16:53:26 +00:00

67 lines
1.6 KiB
Go

// Copyright 2015 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package runtime_test
import (
"runtime"
"testing"
"unsafe"
)
func runParallel(N, iter int, f func()) {
defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(int(N)))
done := make(chan bool)
for i := 0; i < N; i++ {
go func() {
for j := 0; j < iter; j++ {
f()
}
done <- true
}()
}
for i := 0; i < N; i++ {
<-done
}
}
func TestXadduintptr(t *testing.T) {
const N = 20
const iter = 100000
inc := uintptr(100)
total := uintptr(0)
runParallel(N, iter, func() {
runtime.Xadduintptr(&total, inc)
})
if want := uintptr(N * iter * inc); want != total {
t.Fatalf("xadduintpr error, want %d, got %d", want, total)
}
total = 0
runParallel(N, iter, func() {
runtime.Xadduintptr(&total, inc)
runtime.Xadduintptr(&total, uintptr(-int64(inc)))
})
if total != 0 {
t.Fatalf("xadduintpr total error, want %d, got %d", 0, total)
}
}
// Tests that xadduintptr correctly updates 64-bit values. The place where
// we actually do so is mstats.go, functions mSysStat{Inc,Dec}.
func TestXadduintptrOnUint64(t *testing.T) {
if runtime.BigEndian != 0 {
// On big endian architectures, we never use xadduintptr to update
// 64-bit values and hence we skip the test. (Note that functions
// mSysStat{Inc,Dec} in mstats.go have explicit checks for
// big-endianness.)
return
}
const inc = 100
val := uint64(0)
runtime.Xadduintptr((*uintptr)(unsafe.Pointer(&val)), inc)
if inc != val {
t.Fatalf("xadduintptr should increase lower-order bits, want %d, got %d", inc, val)
}
}