diff options
author | Dan Albert <danalbert@google.com> | 2016-02-24 13:48:45 -0800 |
---|---|---|
committer | Dan Albert <danalbert@google.com> | 2016-02-24 13:51:18 -0800 |
commit | b9de1157289455b0ca26daff519d4a0ddcd1fa13 (patch) | |
tree | 4c56cc0a34b91f17033a40a455f26652304f7b8d /gcc-4.8.1/libgo/go/sync | |
parent | 098157a754787181cfa10e71325832448ddcea98 (diff) | |
download | toolchain_gcc-b9de1157289455b0ca26daff519d4a0ddcd1fa13.tar.gz toolchain_gcc-b9de1157289455b0ca26daff519d4a0ddcd1fa13.tar.bz2 toolchain_gcc-b9de1157289455b0ca26daff519d4a0ddcd1fa13.zip |
Update 4.8.1 to 4.8.3.
My previous drop was the wrong version. The platform mingw is
currently using 4.8.3, not 4.8.1 (not sure how I got that wrong).
From ftp://ftp.gnu.org/gnu/gcc/gcc-4.8.3/gcc-4.8.3.tar.bz2.
Bug: http://b/26523949
Change-Id: Id85f1bdcbbaf78c7d0b5a69e74c798a08f341c35
Diffstat (limited to 'gcc-4.8.1/libgo/go/sync')
22 files changed, 0 insertions, 3370 deletions
diff --git a/gcc-4.8.1/libgo/go/sync/atomic/64bit_arm.go b/gcc-4.8.1/libgo/go/sync/atomic/64bit_arm.go deleted file mode 100644 index f070e78bd..000000000 --- a/gcc-4.8.1/libgo/go/sync/atomic/64bit_arm.go +++ /dev/null @@ -1,36 +0,0 @@ -// Copyright 2012 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 atomic - -func loadUint64(addr *uint64) (val uint64) { - for { - val = *addr - if CompareAndSwapUint64(addr, val, val) { - break - } - } - return -} - -func storeUint64(addr *uint64, val uint64) { - for { - old := *addr - if CompareAndSwapUint64(addr, old, val) { - break - } - } - return -} - -func addUint64(val *uint64, delta uint64) (new uint64) { - for { - old := *val - new = old + delta - if CompareAndSwapUint64(val, old, new) { - break - } - } - return -} diff --git a/gcc-4.8.1/libgo/go/sync/atomic/atomic.c b/gcc-4.8.1/libgo/go/sync/atomic/atomic.c deleted file mode 100644 index 32430df2b..000000000 --- a/gcc-4.8.1/libgo/go/sync/atomic/atomic.c +++ /dev/null @@ -1,270 +0,0 @@ -/* atomic.c -- implement atomic routines for Go. - - Copyright 2011 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. */ - -#include <stdint.h> - -#include "runtime.h" - -_Bool CompareAndSwapInt32 (int32_t *, int32_t, int32_t) - __asm__ (GOSYM_PREFIX "sync_atomic.CompareAndSwapInt32"); - -_Bool -CompareAndSwapInt32 (int32_t *val, int32_t old, int32_t new) -{ - return __sync_bool_compare_and_swap (val, old, new); -} - -_Bool CompareAndSwapInt64 (int64_t *, int64_t, int64_t) - __asm__ (GOSYM_PREFIX "sync_atomic.CompareAndSwapInt64"); - -_Bool -CompareAndSwapInt64 (int64_t *val, int64_t old, int64_t new) -{ - return __sync_bool_compare_and_swap (val, old, new); -} - -_Bool CompareAndSwapUint32 (uint32_t *, uint32_t, uint32_t) - __asm__ (GOSYM_PREFIX "sync_atomic.CompareAndSwapUint32"); - -_Bool -CompareAndSwapUint32 (uint32_t *val, uint32_t old, uint32_t new) -{ - return __sync_bool_compare_and_swap (val, old, new); -} - -_Bool CompareAndSwapUint64 (uint64_t *, uint64_t, uint64_t) - __asm__ (GOSYM_PREFIX "sync_atomic.CompareAndSwapUint64"); - -_Bool -CompareAndSwapUint64 (uint64_t *val, uint64_t old, uint64_t new) -{ - return __sync_bool_compare_and_swap (val, old, new); -} - -_Bool CompareAndSwapUintptr (uintptr_t *, uintptr_t, uintptr_t) - __asm__ (GOSYM_PREFIX "sync_atomic.CompareAndSwapUintptr"); - -_Bool -CompareAndSwapUintptr (uintptr_t *val, uintptr_t old, uintptr_t new) -{ - return __sync_bool_compare_and_swap (val, old, new); -} - -_Bool CompareAndSwapPointer (void **, void *, void *) - __asm__ (GOSYM_PREFIX "sync_atomic.CompareAndSwapPointer"); - -_Bool -CompareAndSwapPointer (void **val, void *old, void *new) -{ - return __sync_bool_compare_and_swap (val, old, new); -} - -int32_t AddInt32 (int32_t *, int32_t) - __asm__ (GOSYM_PREFIX "sync_atomic.AddInt32"); - -int32_t -AddInt32 (int32_t *val, int32_t delta) -{ - return __sync_add_and_fetch (val, delta); -} - -uint32_t AddUint32 (uint32_t *, uint32_t) - __asm__ (GOSYM_PREFIX "sync_atomic.AddUint32"); - -uint32_t -AddUint32 (uint32_t *val, uint32_t delta) -{ - return __sync_add_and_fetch (val, delta); -} - -int64_t AddInt64 (int64_t *, int64_t) - __asm__ (GOSYM_PREFIX "sync_atomic.AddInt64"); - -int64_t -AddInt64 (int64_t *val, int64_t delta) -{ - return __sync_add_and_fetch (val, delta); -} - -uint64_t AddUint64 (uint64_t *, uint64_t) - __asm__ (GOSYM_PREFIX "sync_atomic.AddUint64"); - -uint64_t -AddUint64 (uint64_t *val, uint64_t delta) -{ - return __sync_add_and_fetch (val, delta); -} - -uintptr_t AddUintptr (uintptr_t *, uintptr_t) - __asm__ (GOSYM_PREFIX "sync_atomic.AddUintptr"); - -uintptr_t -AddUintptr (uintptr_t *val, uintptr_t delta) -{ - return __sync_add_and_fetch (val, delta); -} - -int32_t LoadInt32 (int32_t *addr) - __asm__ (GOSYM_PREFIX "sync_atomic.LoadInt32"); - -int32_t -LoadInt32 (int32_t *addr) -{ - int32_t v; - - v = *addr; - while (! __sync_bool_compare_and_swap (addr, v, v)) - v = *addr; - return v; -} - -int64_t LoadInt64 (int64_t *addr) - __asm__ (GOSYM_PREFIX "sync_atomic.LoadInt64"); - -int64_t -LoadInt64 (int64_t *addr) -{ - int64_t v; - - v = *addr; - while (! __sync_bool_compare_and_swap (addr, v, v)) - v = *addr; - return v; -} - -uint32_t LoadUint32 (uint32_t *addr) - __asm__ (GOSYM_PREFIX "sync_atomic.LoadUint32"); - -uint32_t -LoadUint32 (uint32_t *addr) -{ - uint32_t v; - - v = *addr; - while (! __sync_bool_compare_and_swap (addr, v, v)) - v = *addr; - return v; -} - -uint64_t LoadUint64 (uint64_t *addr) - __asm__ (GOSYM_PREFIX "sync_atomic.LoadUint64"); - -uint64_t -LoadUint64 (uint64_t *addr) -{ - uint64_t v; - - v = *addr; - while (! __sync_bool_compare_and_swap (addr, v, v)) - v = *addr; - return v; -} - -uintptr_t LoadUintptr (uintptr_t *addr) - __asm__ (GOSYM_PREFIX "sync_atomic.LoadUintptr"); - -uintptr_t -LoadUintptr (uintptr_t *addr) -{ - uintptr_t v; - - v = *addr; - while (! __sync_bool_compare_and_swap (addr, v, v)) - v = *addr; - return v; -} - -void *LoadPointer (void **addr) - __asm__ (GOSYM_PREFIX "sync_atomic.LoadPointer"); - -void * -LoadPointer (void **addr) -{ - void *v; - - v = *addr; - while (! __sync_bool_compare_and_swap (addr, v, v)) - v = *addr; - return v; -} - -void StoreInt32 (int32_t *addr, int32_t val) - __asm__ (GOSYM_PREFIX "sync_atomic.StoreInt32"); - -void -StoreInt32 (int32_t *addr, int32_t val) -{ - int32_t v; - - v = *addr; - while (! __sync_bool_compare_and_swap (addr, v, val)) - v = *addr; -} - -void StoreInt64 (int64_t *addr, int64_t val) - __asm__ (GOSYM_PREFIX "sync_atomic.StoreInt64"); - -void -StoreInt64 (int64_t *addr, int64_t val) -{ - int64_t v; - - v = *addr; - while (! __sync_bool_compare_and_swap (addr, v, val)) - v = *addr; -} - -void StoreUint32 (uint32_t *addr, uint32_t val) - __asm__ (GOSYM_PREFIX "sync_atomic.StoreUint32"); - -void -StoreUint32 (uint32_t *addr, uint32_t val) -{ - uint32_t v; - - v = *addr; - while (! __sync_bool_compare_and_swap (addr, v, val)) - v = *addr; -} - -void StoreUint64 (uint64_t *addr, uint64_t val) - __asm__ (GOSYM_PREFIX "sync_atomic.StoreUint64"); - -void -StoreUint64 (uint64_t *addr, uint64_t val) -{ - uint64_t v; - - v = *addr; - while (! __sync_bool_compare_and_swap (addr, v, val)) - v = *addr; -} - -void StoreUintptr (uintptr_t *addr, uintptr_t val) - __asm__ (GOSYM_PREFIX "sync_atomic.StoreUintptr"); - -void -StoreUintptr (uintptr_t *addr, uintptr_t val) -{ - uintptr_t v; - - v = *addr; - while (! __sync_bool_compare_and_swap (addr, v, val)) - v = *addr; -} - -void StorePointer (void **addr, void *val) - __asm__ (GOSYM_PREFIX "sync_atomic.StorePointer"); - -void -StorePointer (void **addr, void *val) -{ - void *v; - - v = *addr; - while (! __sync_bool_compare_and_swap (addr, v, val)) - v = *addr; -} diff --git a/gcc-4.8.1/libgo/go/sync/atomic/atomic_test.go b/gcc-4.8.1/libgo/go/sync/atomic/atomic_test.go deleted file mode 100644 index 25be63b5a..000000000 --- a/gcc-4.8.1/libgo/go/sync/atomic/atomic_test.go +++ /dev/null @@ -1,1179 +0,0 @@ -// Copyright 2011 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 atomic_test - -import ( - "runtime" - . "sync/atomic" - "testing" - "unsafe" -) - -// Tests of correct behavior, without contention. -// (Does the function work as advertised?) -// -// Test that the Add functions add correctly. -// Test that the CompareAndSwap functions actually -// do the comparison and the swap correctly. -// -// The loop over power-of-two values is meant to -// ensure that the operations apply to the full word size. -// The struct fields x.before and x.after check that the -// operations do not extend past the full word size. - -const ( - magic32 = 0xdedbeef - magic64 = 0xdeddeadbeefbeef -) - -// Do the 64-bit functions panic? If so, don't bother testing. -var test64err = func() (err interface{}) { - defer func() { - err = recover() - }() - var x int64 - AddInt64(&x, 1) - return nil -}() - -func TestAddInt32(t *testing.T) { - var x struct { - before int32 - i int32 - after int32 - } - x.before = magic32 - x.after = magic32 - var j int32 - for delta := int32(1); delta+delta > delta; delta += delta { - k := AddInt32(&x.i, delta) - j += delta - if x.i != j || k != j { - t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k) - } - } - if x.before != magic32 || x.after != magic32 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32) - } -} - -func TestAddUint32(t *testing.T) { - var x struct { - before uint32 - i uint32 - after uint32 - } - x.before = magic32 - x.after = magic32 - var j uint32 - for delta := uint32(1); delta+delta > delta; delta += delta { - k := AddUint32(&x.i, delta) - j += delta - if x.i != j || k != j { - t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k) - } - } - if x.before != magic32 || x.after != magic32 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32) - } -} - -func TestAddInt64(t *testing.T) { - if test64err != nil { - t.Skipf("Skipping 64-bit tests: %v", test64err) - } - var x struct { - before int64 - i int64 - after int64 - } - x.before = magic64 - x.after = magic64 - var j int64 - for delta := int64(1); delta+delta > delta; delta += delta { - k := AddInt64(&x.i, delta) - j += delta - if x.i != j || k != j { - t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k) - } - } - if x.before != magic64 || x.after != magic64 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, int64(magic64), int64(magic64)) - } -} - -func TestAddUint64(t *testing.T) { - if test64err != nil { - t.Skipf("Skipping 64-bit tests: %v", test64err) - } - var x struct { - before uint64 - i uint64 - after uint64 - } - x.before = magic64 - x.after = magic64 - var j uint64 - for delta := uint64(1); delta+delta > delta; delta += delta { - k := AddUint64(&x.i, delta) - j += delta - if x.i != j || k != j { - t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k) - } - } - if x.before != magic64 || x.after != magic64 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64)) - } -} - -func TestAddUintptr(t *testing.T) { - var x struct { - before uintptr - i uintptr - after uintptr - } - var m uint64 = magic64 - magicptr := uintptr(m) - x.before = magicptr - x.after = magicptr - var j uintptr - for delta := uintptr(1); delta+delta > delta; delta += delta { - k := AddUintptr(&x.i, delta) - j += delta - if x.i != j || k != j { - t.Fatalf("delta=%d i=%d j=%d k=%d", delta, x.i, j, k) - } - } - if x.before != magicptr || x.after != magicptr { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr) - } -} - -func TestCompareAndSwapInt32(t *testing.T) { - var x struct { - before int32 - i int32 - after int32 - } - x.before = magic32 - x.after = magic32 - for val := int32(1); val+val > val; val += val { - x.i = val - if !CompareAndSwapInt32(&x.i, val, val+1) { - t.Fatalf("should have swapped %#x %#x", val, val+1) - } - if x.i != val+1 { - t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1) - } - x.i = val + 1 - if CompareAndSwapInt32(&x.i, val, val+2) { - t.Fatalf("should not have swapped %#x %#x", val, val+2) - } - if x.i != val+1 { - t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1) - } - } - if x.before != magic32 || x.after != magic32 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32) - } -} - -func TestCompareAndSwapUint32(t *testing.T) { - var x struct { - before uint32 - i uint32 - after uint32 - } - x.before = magic32 - x.after = magic32 - for val := uint32(1); val+val > val; val += val { - x.i = val - if !CompareAndSwapUint32(&x.i, val, val+1) { - t.Fatalf("should have swapped %#x %#x", val, val+1) - } - if x.i != val+1 { - t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1) - } - x.i = val + 1 - if CompareAndSwapUint32(&x.i, val, val+2) { - t.Fatalf("should not have swapped %#x %#x", val, val+2) - } - if x.i != val+1 { - t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1) - } - } - if x.before != magic32 || x.after != magic32 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32) - } -} - -func TestCompareAndSwapInt64(t *testing.T) { - if test64err != nil { - t.Skipf("Skipping 64-bit tests: %v", test64err) - } - var x struct { - before int64 - i int64 - after int64 - } - x.before = magic64 - x.after = magic64 - for val := int64(1); val+val > val; val += val { - x.i = val - if !CompareAndSwapInt64(&x.i, val, val+1) { - t.Fatalf("should have swapped %#x %#x", val, val+1) - } - if x.i != val+1 { - t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1) - } - x.i = val + 1 - if CompareAndSwapInt64(&x.i, val, val+2) { - t.Fatalf("should not have swapped %#x %#x", val, val+2) - } - if x.i != val+1 { - t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1) - } - } - if x.before != magic64 || x.after != magic64 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64)) - } -} - -func TestCompareAndSwapUint64(t *testing.T) { - if test64err != nil { - t.Skipf("Skipping 64-bit tests: %v", test64err) - } - var x struct { - before uint64 - i uint64 - after uint64 - } - x.before = magic64 - x.after = magic64 - for val := uint64(1); val+val > val; val += val { - x.i = val - if !CompareAndSwapUint64(&x.i, val, val+1) { - t.Fatalf("should have swapped %#x %#x", val, val+1) - } - if x.i != val+1 { - t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1) - } - x.i = val + 1 - if CompareAndSwapUint64(&x.i, val, val+2) { - t.Fatalf("should not have swapped %#x %#x", val, val+2) - } - if x.i != val+1 { - t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1) - } - } - if x.before != magic64 || x.after != magic64 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64)) - } -} - -func TestCompareAndSwapUintptr(t *testing.T) { - var x struct { - before uintptr - i uintptr - after uintptr - } - var m uint64 = magic64 - magicptr := uintptr(m) - x.before = magicptr - x.after = magicptr - for val := uintptr(1); val+val > val; val += val { - x.i = val - if !CompareAndSwapUintptr(&x.i, val, val+1) { - t.Fatalf("should have swapped %#x %#x", val, val+1) - } - if x.i != val+1 { - t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1) - } - x.i = val + 1 - if CompareAndSwapUintptr(&x.i, val, val+2) { - t.Fatalf("should not have swapped %#x %#x", val, val+2) - } - if x.i != val+1 { - t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1) - } - } - if x.before != magicptr || x.after != magicptr { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr) - } -} - -func TestCompareAndSwapPointer(t *testing.T) { - var x struct { - before uintptr - i unsafe.Pointer - after uintptr - } - var m uint64 = magic64 - magicptr := uintptr(m) - x.before = magicptr - x.after = magicptr - for val := uintptr(1); val+val > val; val += val { - x.i = unsafe.Pointer(val) - if !CompareAndSwapPointer(&x.i, unsafe.Pointer(val), unsafe.Pointer(val+1)) { - t.Fatalf("should have swapped %#x %#x", val, val+1) - } - if x.i != unsafe.Pointer(val+1) { - t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1) - } - x.i = unsafe.Pointer(val + 1) - if CompareAndSwapPointer(&x.i, unsafe.Pointer(val), unsafe.Pointer(val+2)) { - t.Fatalf("should not have swapped %#x %#x", val, val+2) - } - if x.i != unsafe.Pointer(val+1) { - t.Fatalf("wrong x.i after swap: x.i=%#x val+1=%#x", x.i, val+1) - } - } - if x.before != magicptr || x.after != magicptr { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr) - } -} - -func TestLoadInt32(t *testing.T) { - var x struct { - before int32 - i int32 - after int32 - } - x.before = magic32 - x.after = magic32 - for delta := int32(1); delta+delta > delta; delta += delta { - k := LoadInt32(&x.i) - if k != x.i { - t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k) - } - x.i += delta - } - if x.before != magic32 || x.after != magic32 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32) - } -} - -func TestLoadUint32(t *testing.T) { - var x struct { - before uint32 - i uint32 - after uint32 - } - x.before = magic32 - x.after = magic32 - for delta := uint32(1); delta+delta > delta; delta += delta { - k := LoadUint32(&x.i) - if k != x.i { - t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k) - } - x.i += delta - } - if x.before != magic32 || x.after != magic32 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32) - } -} - -func TestLoadInt64(t *testing.T) { - if test64err != nil { - t.Skipf("Skipping 64-bit tests: %v", test64err) - } - var x struct { - before int64 - i int64 - after int64 - } - x.before = magic64 - x.after = magic64 - for delta := int64(1); delta+delta > delta; delta += delta { - k := LoadInt64(&x.i) - if k != x.i { - t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k) - } - x.i += delta - } - if x.before != magic64 || x.after != magic64 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64)) - } -} - -func TestLoadUint64(t *testing.T) { - if test64err != nil { - t.Skipf("Skipping 64-bit tests: %v", test64err) - } - var x struct { - before uint64 - i uint64 - after uint64 - } - x.before = magic64 - x.after = magic64 - for delta := uint64(1); delta+delta > delta; delta += delta { - k := LoadUint64(&x.i) - if k != x.i { - t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k) - } - x.i += delta - } - if x.before != magic64 || x.after != magic64 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64)) - } -} - -func TestLoadUintptr(t *testing.T) { - var x struct { - before uintptr - i uintptr - after uintptr - } - var m uint64 = magic64 - magicptr := uintptr(m) - x.before = magicptr - x.after = magicptr - for delta := uintptr(1); delta+delta > delta; delta += delta { - k := LoadUintptr(&x.i) - if k != x.i { - t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k) - } - x.i += delta - } - if x.before != magicptr || x.after != magicptr { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr) - } -} - -func TestLoadPointer(t *testing.T) { - var x struct { - before uintptr - i unsafe.Pointer - after uintptr - } - var m uint64 = magic64 - magicptr := uintptr(m) - x.before = magicptr - x.after = magicptr - for delta := uintptr(1); delta+delta > delta; delta += delta { - k := LoadPointer(&x.i) - if k != x.i { - t.Fatalf("delta=%d i=%d k=%d", delta, x.i, k) - } - x.i = unsafe.Pointer(uintptr(x.i) + delta) - } - if x.before != magicptr || x.after != magicptr { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr) - } -} - -func TestStoreInt32(t *testing.T) { - var x struct { - before int32 - i int32 - after int32 - } - x.before = magic32 - x.after = magic32 - v := int32(0) - for delta := int32(1); delta+delta > delta; delta += delta { - StoreInt32(&x.i, v) - if x.i != v { - t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v) - } - v += delta - } - if x.before != magic32 || x.after != magic32 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32) - } -} - -func TestStoreUint32(t *testing.T) { - var x struct { - before uint32 - i uint32 - after uint32 - } - x.before = magic32 - x.after = magic32 - v := uint32(0) - for delta := uint32(1); delta+delta > delta; delta += delta { - StoreUint32(&x.i, v) - if x.i != v { - t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v) - } - v += delta - } - if x.before != magic32 || x.after != magic32 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magic32, magic32) - } -} - -func TestStoreInt64(t *testing.T) { - if test64err != nil { - t.Skipf("Skipping 64-bit tests: %v", test64err) - } - var x struct { - before int64 - i int64 - after int64 - } - x.before = magic64 - x.after = magic64 - v := int64(0) - for delta := int64(1); delta+delta > delta; delta += delta { - StoreInt64(&x.i, v) - if x.i != v { - t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v) - } - v += delta - } - if x.before != magic64 || x.after != magic64 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64)) - } -} - -func TestStoreUint64(t *testing.T) { - if test64err != nil { - t.Skipf("Skipping 64-bit tests: %v", test64err) - } - var x struct { - before uint64 - i uint64 - after uint64 - } - x.before = magic64 - x.after = magic64 - v := uint64(0) - for delta := uint64(1); delta+delta > delta; delta += delta { - StoreUint64(&x.i, v) - if x.i != v { - t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v) - } - v += delta - } - if x.before != magic64 || x.after != magic64 { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, uint64(magic64), uint64(magic64)) - } -} - -func TestStoreUintptr(t *testing.T) { - var x struct { - before uintptr - i uintptr - after uintptr - } - var m uint64 = magic64 - magicptr := uintptr(m) - x.before = magicptr - x.after = magicptr - v := uintptr(0) - for delta := uintptr(1); delta+delta > delta; delta += delta { - StoreUintptr(&x.i, v) - if x.i != v { - t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v) - } - v += delta - } - if x.before != magicptr || x.after != magicptr { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr) - } -} - -func TestStorePointer(t *testing.T) { - var x struct { - before uintptr - i unsafe.Pointer - after uintptr - } - var m uint64 = magic64 - magicptr := uintptr(m) - x.before = magicptr - x.after = magicptr - v := unsafe.Pointer(uintptr(0)) - for delta := uintptr(1); delta+delta > delta; delta += delta { - StorePointer(&x.i, unsafe.Pointer(v)) - if x.i != v { - t.Fatalf("delta=%d i=%d v=%d", delta, x.i, v) - } - v = unsafe.Pointer(uintptr(v) + delta) - } - if x.before != magicptr || x.after != magicptr { - t.Fatalf("wrong magic: %#x _ %#x != %#x _ %#x", x.before, x.after, magicptr, magicptr) - } -} - -// Tests of correct behavior, with contention. -// (Is the function atomic?) -// -// For each function, we write a "hammer" function that repeatedly -// uses the atomic operation to add 1 to a value. After running -// multiple hammers in parallel, check that we end with the correct -// total. - -var hammer32 = []struct { - name string - f func(*uint32, int) -}{ - {"AddInt32", hammerAddInt32}, - {"AddUint32", hammerAddUint32}, - {"AddUintptr", hammerAddUintptr32}, - {"CompareAndSwapInt32", hammerCompareAndSwapInt32}, - {"CompareAndSwapUint32", hammerCompareAndSwapUint32}, - {"CompareAndSwapUintptr", hammerCompareAndSwapUintptr32}, - {"CompareAndSwapPointer", hammerCompareAndSwapPointer32}, -} - -func init() { - var v uint64 = 1 << 50 - if uintptr(v) != 0 { - // 64-bit system; clear uintptr tests - hammer32[2].f = nil - hammer32[5].f = nil - hammer32[6].f = nil - } -} - -func hammerAddInt32(uaddr *uint32, count int) { - addr := (*int32)(unsafe.Pointer(uaddr)) - for i := 0; i < count; i++ { - AddInt32(addr, 1) - } -} - -func hammerAddUint32(addr *uint32, count int) { - for i := 0; i < count; i++ { - AddUint32(addr, 1) - } -} - -func hammerAddUintptr32(uaddr *uint32, count int) { - // only safe when uintptr is 32-bit. - // not called on 64-bit systems. - addr := (*uintptr)(unsafe.Pointer(uaddr)) - for i := 0; i < count; i++ { - AddUintptr(addr, 1) - } -} - -func hammerCompareAndSwapInt32(uaddr *uint32, count int) { - addr := (*int32)(unsafe.Pointer(uaddr)) - for i := 0; i < count; i++ { - for { - v := *addr - if CompareAndSwapInt32(addr, v, v+1) { - break - } - } - } -} - -func hammerCompareAndSwapUint32(addr *uint32, count int) { - for i := 0; i < count; i++ { - for { - v := *addr - if CompareAndSwapUint32(addr, v, v+1) { - break - } - } - } -} - -func hammerCompareAndSwapUintptr32(uaddr *uint32, count int) { - // only safe when uintptr is 32-bit. - // not called on 64-bit systems. - addr := (*uintptr)(unsafe.Pointer(uaddr)) - for i := 0; i < count; i++ { - for { - v := *addr - if CompareAndSwapUintptr(addr, v, v+1) { - break - } - } - } -} - -func hammerCompareAndSwapPointer32(uaddr *uint32, count int) { - // only safe when uintptr is 32-bit. - // not called on 64-bit systems. - addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr)) - for i := 0; i < count; i++ { - for { - v := *addr - if CompareAndSwapPointer(addr, v, unsafe.Pointer(uintptr(v)+1)) { - break - } - } - } -} - -func TestHammer32(t *testing.T) { - const p = 4 - n := 100000 - if testing.Short() { - n = 1000 - } - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(p)) - - for _, tt := range hammer32 { - if tt.f == nil { - continue - } - c := make(chan int) - var val uint32 - for i := 0; i < p; i++ { - go func() { - tt.f(&val, n) - c <- 1 - }() - } - for i := 0; i < p; i++ { - <-c - } - if val != uint32(n)*p { - t.Fatalf("%s: val=%d want %d", tt.name, val, n*p) - } - } -} - -var hammer64 = []struct { - name string - f func(*uint64, int) -}{ - {"AddInt64", hammerAddInt64}, - {"AddUint64", hammerAddUint64}, - {"AddUintptr", hammerAddUintptr64}, - {"CompareAndSwapInt64", hammerCompareAndSwapInt64}, - {"CompareAndSwapUint64", hammerCompareAndSwapUint64}, - {"CompareAndSwapUintptr", hammerCompareAndSwapUintptr64}, - {"CompareAndSwapPointer", hammerCompareAndSwapPointer64}, -} - -func init() { - var v uint64 = 1 << 50 - if uintptr(v) == 0 { - // 32-bit system; clear uintptr tests - hammer64[2].f = nil - hammer64[5].f = nil - hammer64[6].f = nil - } -} - -func hammerAddInt64(uaddr *uint64, count int) { - addr := (*int64)(unsafe.Pointer(uaddr)) - for i := 0; i < count; i++ { - AddInt64(addr, 1) - } -} - -func hammerAddUint64(addr *uint64, count int) { - for i := 0; i < count; i++ { - AddUint64(addr, 1) - } -} - -func hammerAddUintptr64(uaddr *uint64, count int) { - // only safe when uintptr is 64-bit. - // not called on 32-bit systems. - addr := (*uintptr)(unsafe.Pointer(uaddr)) - for i := 0; i < count; i++ { - AddUintptr(addr, 1) - } -} - -func hammerCompareAndSwapInt64(uaddr *uint64, count int) { - addr := (*int64)(unsafe.Pointer(uaddr)) - for i := 0; i < count; i++ { - for { - v := *addr - if CompareAndSwapInt64(addr, v, v+1) { - break - } - } - } -} - -func hammerCompareAndSwapUint64(addr *uint64, count int) { - for i := 0; i < count; i++ { - for { - v := *addr - if CompareAndSwapUint64(addr, v, v+1) { - break - } - } - } -} - -func hammerCompareAndSwapUintptr64(uaddr *uint64, count int) { - // only safe when uintptr is 64-bit. - // not called on 32-bit systems. - addr := (*uintptr)(unsafe.Pointer(uaddr)) - for i := 0; i < count; i++ { - for { - v := *addr - if CompareAndSwapUintptr(addr, v, v+1) { - break - } - } - } -} - -func hammerCompareAndSwapPointer64(uaddr *uint64, count int) { - // only safe when uintptr is 64-bit. - // not called on 32-bit systems. - addr := (*unsafe.Pointer)(unsafe.Pointer(uaddr)) - for i := 0; i < count; i++ { - for { - v := *addr - if CompareAndSwapPointer(addr, v, unsafe.Pointer(uintptr(v)+1)) { - break - } - } - } -} - -func TestHammer64(t *testing.T) { - if test64err != nil { - t.Skipf("Skipping 64-bit tests: %v", test64err) - } - const p = 4 - n := 100000 - if testing.Short() { - n = 1000 - } - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(p)) - - for _, tt := range hammer64 { - if tt.f == nil { - continue - } - c := make(chan int) - var val uint64 - for i := 0; i < p; i++ { - go func() { - tt.f(&val, n) - c <- 1 - }() - } - for i := 0; i < p; i++ { - <-c - } - if val != uint64(n)*p { - t.Fatalf("%s: val=%d want %d", tt.name, val, n*p) - } - } -} - -func hammerStoreLoadInt32(t *testing.T, paddr unsafe.Pointer) { - addr := (*int32)(paddr) - v := LoadInt32(addr) - vlo := v & ((1 << 16) - 1) - vhi := v >> 16 - if vlo != vhi { - t.Fatalf("Int32: %#x != %#x", vlo, vhi) - } - new := v + 1 + 1<<16 - if vlo == 1e4 { - new = 0 - } - StoreInt32(addr, new) -} - -func hammerStoreLoadUint32(t *testing.T, paddr unsafe.Pointer) { - addr := (*uint32)(paddr) - v := LoadUint32(addr) - vlo := v & ((1 << 16) - 1) - vhi := v >> 16 - if vlo != vhi { - t.Fatalf("Uint32: %#x != %#x", vlo, vhi) - } - new := v + 1 + 1<<16 - if vlo == 1e4 { - new = 0 - } - StoreUint32(addr, new) -} - -func hammerStoreLoadInt64(t *testing.T, paddr unsafe.Pointer) { - addr := (*int64)(paddr) - v := LoadInt64(addr) - vlo := v & ((1 << 32) - 1) - vhi := v >> 32 - if vlo != vhi { - t.Fatalf("Int64: %#x != %#x", vlo, vhi) - } - new := v + 1 + 1<<32 - StoreInt64(addr, new) -} - -func hammerStoreLoadUint64(t *testing.T, paddr unsafe.Pointer) { - addr := (*uint64)(paddr) - v := LoadUint64(addr) - vlo := v & ((1 << 32) - 1) - vhi := v >> 32 - if vlo != vhi { - t.Fatalf("Uint64: %#x != %#x", vlo, vhi) - } - new := v + 1 + 1<<32 - StoreUint64(addr, new) -} - -func hammerStoreLoadUintptr(t *testing.T, paddr unsafe.Pointer) { - addr := (*uintptr)(paddr) - var test64 uint64 = 1 << 50 - arch32 := uintptr(test64) == 0 - v := LoadUintptr(addr) - new := v - if arch32 { - vlo := v & ((1 << 16) - 1) - vhi := v >> 16 - if vlo != vhi { - t.Fatalf("Uintptr: %#x != %#x", vlo, vhi) - } - new = v + 1 + 1<<16 - if vlo == 1e4 { - new = 0 - } - } else { - vlo := v & ((1 << 32) - 1) - vhi := v >> 32 - if vlo != vhi { - t.Fatalf("Uintptr: %#x != %#x", vlo, vhi) - } - inc := uint64(1 + 1<<32) - new = v + uintptr(inc) - } - StoreUintptr(addr, new) -} - -func hammerStoreLoadPointer(t *testing.T, paddr unsafe.Pointer) { - addr := (*unsafe.Pointer)(paddr) - var test64 uint64 = 1 << 50 - arch32 := uintptr(test64) == 0 - v := uintptr(LoadPointer(addr)) - new := v - if arch32 { - vlo := v & ((1 << 16) - 1) - vhi := v >> 16 - if vlo != vhi { - t.Fatalf("Pointer: %#x != %#x", vlo, vhi) - } - new = v + 1 + 1<<16 - if vlo == 1e4 { - new = 0 - } - } else { - vlo := v & ((1 << 32) - 1) - vhi := v >> 32 - if vlo != vhi { - t.Fatalf("Pointer: %#x != %#x", vlo, vhi) - } - inc := uint64(1 + 1<<32) - new = v + uintptr(inc) - } - StorePointer(addr, unsafe.Pointer(new)) -} - -func TestHammerStoreLoad(t *testing.T) { - var tests []func(*testing.T, unsafe.Pointer) - tests = append(tests, hammerStoreLoadInt32, hammerStoreLoadUint32, - hammerStoreLoadUintptr, hammerStoreLoadPointer) - if test64err == nil { - tests = append(tests, hammerStoreLoadInt64, hammerStoreLoadUint64) - } - n := int(1e6) - if testing.Short() { - n = int(1e4) - } - const procs = 8 - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(procs)) - for _, tt := range tests { - c := make(chan int) - var val uint64 - for p := 0; p < procs; p++ { - go func() { - for i := 0; i < n; i++ { - tt(t, unsafe.Pointer(&val)) - } - c <- 1 - }() - } - for p := 0; p < procs; p++ { - <-c - } - } -} - -func TestStoreLoadSeqCst32(t *testing.T) { - if runtime.NumCPU() == 1 { - t.Skipf("Skipping test on %v processor machine", runtime.NumCPU()) - } - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) - N := int32(1e3) - if testing.Short() { - N = int32(1e2) - } - c := make(chan bool, 2) - X := [2]int32{} - ack := [2][3]int32{{-1, -1, -1}, {-1, -1, -1}} - for p := 0; p < 2; p++ { - go func(me int) { - he := 1 - me - for i := int32(1); i < N; i++ { - StoreInt32(&X[me], i) - my := LoadInt32(&X[he]) - StoreInt32(&ack[me][i%3], my) - for w := 1; LoadInt32(&ack[he][i%3]) == -1; w++ { - if w%1000 == 0 { - runtime.Gosched() - } - } - his := LoadInt32(&ack[he][i%3]) - if (my != i && my != i-1) || (his != i && his != i-1) { - t.Fatalf("invalid values: %d/%d (%d)", my, his, i) - } - if my != i && his != i { - t.Fatalf("store/load are not sequentially consistent: %d/%d (%d)", my, his, i) - } - StoreInt32(&ack[me][(i-1)%3], -1) - } - c <- true - }(p) - } - <-c - <-c -} - -func TestStoreLoadSeqCst64(t *testing.T) { - if runtime.NumCPU() == 1 { - t.Skipf("Skipping test on %v processor machine", runtime.NumCPU()) - } - if test64err != nil { - t.Skipf("Skipping 64-bit tests: %v", test64err) - } - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) - N := int64(1e3) - if testing.Short() { - N = int64(1e2) - } - c := make(chan bool, 2) - X := [2]int64{} - ack := [2][3]int64{{-1, -1, -1}, {-1, -1, -1}} - for p := 0; p < 2; p++ { - go func(me int) { - he := 1 - me - for i := int64(1); i < N; i++ { - StoreInt64(&X[me], i) - my := LoadInt64(&X[he]) - StoreInt64(&ack[me][i%3], my) - for w := 1; LoadInt64(&ack[he][i%3]) == -1; w++ { - if w%1000 == 0 { - runtime.Gosched() - } - } - his := LoadInt64(&ack[he][i%3]) - if (my != i && my != i-1) || (his != i && his != i-1) { - t.Fatalf("invalid values: %d/%d (%d)", my, his, i) - } - if my != i && his != i { - t.Fatalf("store/load are not sequentially consistent: %d/%d (%d)", my, his, i) - } - StoreInt64(&ack[me][(i-1)%3], -1) - } - c <- true - }(p) - } - <-c - <-c -} - -func TestStoreLoadRelAcq32(t *testing.T) { - if runtime.NumCPU() == 1 { - t.Skipf("Skipping test on %v processor machine", runtime.NumCPU()) - } - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) - N := int32(1e3) - if testing.Short() { - N = int32(1e2) - } - c := make(chan bool, 2) - type Data struct { - signal int32 - pad1 [128]int8 - data1 int32 - pad2 [128]int8 - data2 float32 - } - var X Data - for p := int32(0); p < 2; p++ { - go func(p int32) { - for i := int32(1); i < N; i++ { - if (i+p)%2 == 0 { - X.data1 = i - X.data2 = float32(i) - StoreInt32(&X.signal, i) - } else { - for w := 1; LoadInt32(&X.signal) != i; w++ { - if w%1000 == 0 { - runtime.Gosched() - } - } - d1 := X.data1 - d2 := X.data2 - if d1 != i || d2 != float32(i) { - t.Fatalf("incorrect data: %d/%d (%d)", d1, d2, i) - } - } - } - c <- true - }(p) - } - <-c - <-c -} - -func TestStoreLoadRelAcq64(t *testing.T) { - if runtime.NumCPU() == 1 { - t.Skipf("Skipping test on %v processor machine", runtime.NumCPU()) - } - if test64err != nil { - t.Skipf("Skipping 64-bit tests: %v", test64err) - } - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(4)) - N := int64(1e3) - if testing.Short() { - N = int64(1e2) - } - c := make(chan bool, 2) - type Data struct { - signal int64 - pad1 [128]int8 - data1 int64 - pad2 [128]int8 - data2 float64 - } - var X Data - for p := int64(0); p < 2; p++ { - go func(p int64) { - for i := int64(1); i < N; i++ { - if (i+p)%2 == 0 { - X.data1 = i - X.data2 = float64(i) - StoreInt64(&X.signal, i) - } else { - for w := 1; LoadInt64(&X.signal) != i; w++ { - if w%1000 == 0 { - runtime.Gosched() - } - } - d1 := X.data1 - d2 := X.data2 - if d1 != i || d2 != float64(i) { - t.Fatalf("incorrect data: %d/%d (%d)", d1, d2, i) - } - } - } - c <- true - }(p) - } - <-c - <-c -} diff --git a/gcc-4.8.1/libgo/go/sync/atomic/doc.go b/gcc-4.8.1/libgo/go/sync/atomic/doc.go deleted file mode 100644 index 27a12c984..000000000 --- a/gcc-4.8.1/libgo/go/sync/atomic/doc.go +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright 2011 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. - -// +build !race - -// Package atomic provides low-level atomic memory primitives -// useful for implementing synchronization algorithms. -// -// These functions require great care to be used correctly. -// Except for special, low-level applications, synchronization is better -// done with channels or the facilities of the sync package. -// Share memory by communicating; -// don't communicate by sharing memory. -// -// The compare-and-swap operation, implemented by the CompareAndSwapT -// functions, is the atomic equivalent of: -// -// if *addr == old { -// *addr = new -// return true -// } -// return false -// -// The add operation, implemented by the AddT functions, is the atomic -// equivalent of: -// -// *addr += delta -// return *addr -// -// The load and store operations, implemented by the LoadT and StoreT -// functions, are the atomic equivalents of "return *addr" and -// "*addr = val". -// -package atomic - -import ( - "unsafe" -) - -// BUG(rsc): On x86-32, the 64-bit functions use instructions unavailable before the Pentium MMX. -// -// On both ARM and x86-32, it is the caller's responsibility to arrange for 64-bit -// alignment of 64-bit words accessed atomically. The first word in a global -// variable or in an allocated struct or slice can be relied upon to be -// 64-bit aligned. - -// CompareAndSwapInt32 executes the compare-and-swap operation for an int32 value. -func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool) - -// CompareAndSwapInt64 executes the compare-and-swap operation for an int64 value. -func CompareAndSwapInt64(addr *int64, old, new int64) (swapped bool) - -// CompareAndSwapUint32 executes the compare-and-swap operation for a uint32 value. -func CompareAndSwapUint32(addr *uint32, old, new uint32) (swapped bool) - -// CompareAndSwapUint64 executes the compare-and-swap operation for a uint64 value. -func CompareAndSwapUint64(addr *uint64, old, new uint64) (swapped bool) - -// CompareAndSwapUintptr executes the compare-and-swap operation for a uintptr value. -func CompareAndSwapUintptr(addr *uintptr, old, new uintptr) (swapped bool) - -// CompareAndSwapPointer executes the compare-and-swap operation for a unsafe.Pointer value. -func CompareAndSwapPointer(addr *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool) - -// AddInt32 atomically adds delta to *addr and returns the new value. -func AddInt32(addr *int32, delta int32) (new int32) - -// AddUint32 atomically adds delta to *addr and returns the new value. -func AddUint32(addr *uint32, delta uint32) (new uint32) - -// AddInt64 atomically adds delta to *addr and returns the new value. -func AddInt64(addr *int64, delta int64) (new int64) - -// AddUint64 atomically adds delta to *addr and returns the new value. -func AddUint64(addr *uint64, delta uint64) (new uint64) - -// AddUintptr atomically adds delta to *addr and returns the new value. -func AddUintptr(addr *uintptr, delta uintptr) (new uintptr) - -// LoadInt32 atomically loads *addr. -func LoadInt32(addr *int32) (val int32) - -// LoadInt64 atomically loads *addr. -func LoadInt64(addr *int64) (val int64) - -// LoadUint32 atomically loads *addr. -func LoadUint32(addr *uint32) (val uint32) - -// LoadUint64 atomically loads *addr. -func LoadUint64(addr *uint64) (val uint64) - -// LoadUintptr atomically loads *addr. -func LoadUintptr(addr *uintptr) (val uintptr) - -// LoadPointer atomically loads *addr. -func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer) - -// StoreInt32 atomically stores val into *addr. -func StoreInt32(addr *int32, val int32) - -// StoreInt64 atomically stores val into *addr. -func StoreInt64(addr *int64, val int64) - -// StoreUint32 atomically stores val into *addr. -func StoreUint32(addr *uint32, val uint32) - -// StoreUint64 atomically stores val into *addr. -func StoreUint64(addr *uint64, val uint64) - -// StoreUintptr atomically stores val into *addr. -func StoreUintptr(addr *uintptr, val uintptr) - -// StorePointer atomically stores val into *addr. -func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer) - -// Helper for ARM. Linker will discard on other systems -func panic64() { - panic("sync/atomic: broken 64-bit atomic operations (buggy QEMU)") -} diff --git a/gcc-4.8.1/libgo/go/sync/atomic/race.go b/gcc-4.8.1/libgo/go/sync/atomic/race.go deleted file mode 100644 index 242bbf298..000000000 --- a/gcc-4.8.1/libgo/go/sync/atomic/race.go +++ /dev/null @@ -1,213 +0,0 @@ -// Copyright 2011 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. - -// +build race - -package atomic - -import ( - "runtime" - "unsafe" -) - -// We use runtime.RaceRead() inside of atomic operations to catch races -// between atomic and non-atomic operations. It will also catch races -// between Mutex.Lock() and mutex overwrite (mu = Mutex{}). Since we use -// only RaceRead() we won't catch races with non-atomic loads. -// Otherwise (if we use RaceWrite()) we will report races -// between atomic operations (false positives). - -var mtx uint32 = 1 // same for all - -func CompareAndSwapInt32(val *int32, old, new int32) bool { - return CompareAndSwapUint32((*uint32)(unsafe.Pointer(val)), uint32(old), uint32(new)) -} - -func CompareAndSwapUint32(val *uint32, old, new uint32) (swapped bool) { - swapped = false - runtime.RaceSemacquire(&mtx) - runtime.RaceRead(unsafe.Pointer(val)) - runtime.RaceAcquire(unsafe.Pointer(val)) - if *val == old { - *val = new - swapped = true - runtime.RaceReleaseMerge(unsafe.Pointer(val)) - } - runtime.RaceSemrelease(&mtx) - return -} - -func CompareAndSwapInt64(val *int64, old, new int64) bool { - return CompareAndSwapUint64((*uint64)(unsafe.Pointer(val)), uint64(old), uint64(new)) -} - -func CompareAndSwapUint64(val *uint64, old, new uint64) (swapped bool) { - swapped = false - runtime.RaceSemacquire(&mtx) - runtime.RaceRead(unsafe.Pointer(val)) - runtime.RaceAcquire(unsafe.Pointer(val)) - if *val == old { - *val = new - swapped = true - runtime.RaceReleaseMerge(unsafe.Pointer(val)) - } - runtime.RaceSemrelease(&mtx) - return -} - -func CompareAndSwapPointer(val *unsafe.Pointer, old, new unsafe.Pointer) (swapped bool) { - swapped = false - runtime.RaceSemacquire(&mtx) - runtime.RaceRead(unsafe.Pointer(val)) - runtime.RaceAcquire(unsafe.Pointer(val)) - if *val == old { - *val = new - swapped = true - runtime.RaceReleaseMerge(unsafe.Pointer(val)) - } - runtime.RaceSemrelease(&mtx) - return -} - -func CompareAndSwapUintptr(val *uintptr, old, new uintptr) (swapped bool) { - swapped = false - runtime.RaceSemacquire(&mtx) - runtime.RaceRead(unsafe.Pointer(val)) - runtime.RaceAcquire(unsafe.Pointer(val)) - if *val == old { - *val = new - swapped = true - runtime.RaceReleaseMerge(unsafe.Pointer(val)) - } - runtime.RaceSemrelease(&mtx) - return -} - -func AddInt32(val *int32, delta int32) int32 { - return int32(AddUint32((*uint32)(unsafe.Pointer(val)), uint32(delta))) -} - -func AddUint32(val *uint32, delta uint32) (new uint32) { - runtime.RaceSemacquire(&mtx) - runtime.RaceRead(unsafe.Pointer(val)) - runtime.RaceAcquire(unsafe.Pointer(val)) - *val = *val + delta - new = *val - runtime.RaceReleaseMerge(unsafe.Pointer(val)) - runtime.RaceSemrelease(&mtx) - - return -} - -func AddInt64(val *int64, delta int64) int64 { - return int64(AddUint64((*uint64)(unsafe.Pointer(val)), uint64(delta))) -} - -func AddUint64(val *uint64, delta uint64) (new uint64) { - runtime.RaceSemacquire(&mtx) - runtime.RaceRead(unsafe.Pointer(val)) - runtime.RaceAcquire(unsafe.Pointer(val)) - *val = *val + delta - new = *val - runtime.RaceReleaseMerge(unsafe.Pointer(val)) - runtime.RaceSemrelease(&mtx) - - return -} - -func AddUintptr(val *uintptr, delta uintptr) (new uintptr) { - runtime.RaceSemacquire(&mtx) - runtime.RaceRead(unsafe.Pointer(val)) - runtime.RaceAcquire(unsafe.Pointer(val)) - *val = *val + delta - new = *val - runtime.RaceReleaseMerge(unsafe.Pointer(val)) - runtime.RaceSemrelease(&mtx) - - return -} - -func LoadInt32(addr *int32) int32 { - return int32(LoadUint32((*uint32)(unsafe.Pointer(addr)))) -} - -func LoadUint32(addr *uint32) (val uint32) { - runtime.RaceSemacquire(&mtx) - runtime.RaceRead(unsafe.Pointer(addr)) - runtime.RaceAcquire(unsafe.Pointer(addr)) - val = *addr - runtime.RaceSemrelease(&mtx) - return -} - -func LoadInt64(addr *int64) int64 { - return int64(LoadUint64((*uint64)(unsafe.Pointer(addr)))) -} - -func LoadUint64(addr *uint64) (val uint64) { - runtime.RaceSemacquire(&mtx) - runtime.RaceRead(unsafe.Pointer(addr)) - runtime.RaceAcquire(unsafe.Pointer(addr)) - val = *addr - runtime.RaceSemrelease(&mtx) - return -} - -func LoadPointer(addr *unsafe.Pointer) (val unsafe.Pointer) { - runtime.RaceSemacquire(&mtx) - runtime.RaceRead(unsafe.Pointer(addr)) - runtime.RaceAcquire(unsafe.Pointer(addr)) - val = *addr - runtime.RaceSemrelease(&mtx) - return -} - -func LoadUintptr(addr *uintptr) (val uintptr) { - runtime.RaceSemacquire(&mtx) - runtime.RaceRead(unsafe.Pointer(addr)) - runtime.RaceAcquire(unsafe.Pointer(addr)) - val = *addr - runtime.RaceSemrelease(&mtx) - return -} - -func StoreInt32(addr *int32, val int32) { - StoreUint32((*uint32)(unsafe.Pointer(addr)), uint32(val)) -} - -func StoreUint32(addr *uint32, val uint32) { - runtime.RaceSemacquire(&mtx) - runtime.RaceRead(unsafe.Pointer(addr)) - *addr = val - runtime.RaceRelease(unsafe.Pointer(addr)) - runtime.RaceSemrelease(&mtx) -} - -func StoreInt64(addr *int64, val int64) { - StoreUint64((*uint64)(unsafe.Pointer(addr)), uint64(val)) -} - -func StoreUint64(addr *uint64, val uint64) { - runtime.RaceSemacquire(&mtx) - runtime.RaceRead(unsafe.Pointer(addr)) - *addr = val - runtime.RaceRelease(unsafe.Pointer(addr)) - runtime.RaceSemrelease(&mtx) -} - -func StorePointer(addr *unsafe.Pointer, val unsafe.Pointer) { - runtime.RaceSemacquire(&mtx) - runtime.RaceRead(unsafe.Pointer(addr)) - *addr = val - runtime.RaceRelease(unsafe.Pointer(addr)) - runtime.RaceSemrelease(&mtx) -} - -func StoreUintptr(addr *uintptr, val uintptr) { - runtime.RaceSemacquire(&mtx) - runtime.RaceRead(unsafe.Pointer(addr)) - *addr = val - runtime.RaceRelease(unsafe.Pointer(addr)) - runtime.RaceSemrelease(&mtx) -} diff --git a/gcc-4.8.1/libgo/go/sync/cas.c b/gcc-4.8.1/libgo/go/sync/cas.c deleted file mode 100644 index 7571c64dd..000000000 --- a/gcc-4.8.1/libgo/go/sync/cas.c +++ /dev/null @@ -1,17 +0,0 @@ -/* cas.c -- implement sync.cas for Go. - - Copyright 2009 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. */ - -#include <stdint.h> - -#include "runtime.h" - -_Bool cas (int32_t *, int32_t, int32_t) __asm__ (GOSYM_PREFIX "libgo_sync.sync.cas"); - -_Bool -cas (int32_t *ptr, int32_t old, int32_t new) -{ - return __sync_bool_compare_and_swap (ptr, old, new); -} diff --git a/gcc-4.8.1/libgo/go/sync/cond.go b/gcc-4.8.1/libgo/go/sync/cond.go deleted file mode 100644 index 491b98569..000000000 --- a/gcc-4.8.1/libgo/go/sync/cond.go +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright 2011 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 sync - -// Cond implements a condition variable, a rendezvous point -// for goroutines waiting for or announcing the occurrence -// of an event. -// -// Each Cond has an associated Locker L (often a *Mutex or *RWMutex), -// which must be held when changing the condition and -// when calling the Wait method. -type Cond struct { - L Locker // held while observing or changing the condition - m Mutex // held to avoid internal races - - // We must be careful to make sure that when Signal - // releases a semaphore, the corresponding acquire is - // executed by a goroutine that was already waiting at - // the time of the call to Signal, not one that arrived later. - // To ensure this, we segment waiting goroutines into - // generations punctuated by calls to Signal. Each call to - // Signal begins another generation if there are no goroutines - // left in older generations for it to wake. Because of this - // optimization (only begin another generation if there - // are no older goroutines left), we only need to keep track - // of the two most recent generations, which we call old - // and new. - oldWaiters int // number of waiters in old generation... - oldSema *uint32 // ... waiting on this semaphore - - newWaiters int // number of waiters in new generation... - newSema *uint32 // ... waiting on this semaphore -} - -// NewCond returns a new Cond with Locker l. -func NewCond(l Locker) *Cond { - return &Cond{L: l} -} - -// Wait atomically unlocks c.L and suspends execution -// of the calling goroutine. After later resuming execution, -// Wait locks c.L before returning. Unlike in other systems, -// Wait cannot return unless awoken by Broadcast or Signal. -// -// Because c.L is not locked when Wait first resumes, the caller -// typically cannot assume that the condition is true when -// Wait returns. Instead, the caller should Wait in a loop: -// -// c.L.Lock() -// for !condition() { -// c.Wait() -// } -// ... make use of condition ... -// c.L.Unlock() -// -func (c *Cond) Wait() { - if raceenabled { - raceDisable() - } - c.m.Lock() - if c.newSema == nil { - c.newSema = new(uint32) - } - s := c.newSema - c.newWaiters++ - c.m.Unlock() - if raceenabled { - raceEnable() - } - c.L.Unlock() - runtime_Semacquire(s) - c.L.Lock() -} - -// Signal wakes one goroutine waiting on c, if there is any. -// -// It is allowed but not required for the caller to hold c.L -// during the call. -func (c *Cond) Signal() { - if raceenabled { - raceDisable() - } - c.m.Lock() - if c.oldWaiters == 0 && c.newWaiters > 0 { - // Retire old generation; rename new to old. - c.oldWaiters = c.newWaiters - c.oldSema = c.newSema - c.newWaiters = 0 - c.newSema = nil - } - if c.oldWaiters > 0 { - c.oldWaiters-- - runtime_Semrelease(c.oldSema) - } - c.m.Unlock() - if raceenabled { - raceEnable() - } -} - -// Broadcast wakes all goroutines waiting on c. -// -// It is allowed but not required for the caller to hold c.L -// during the call. -func (c *Cond) Broadcast() { - if raceenabled { - raceDisable() - } - c.m.Lock() - // Wake both generations. - if c.oldWaiters > 0 { - for i := 0; i < c.oldWaiters; i++ { - runtime_Semrelease(c.oldSema) - } - c.oldWaiters = 0 - } - if c.newWaiters > 0 { - for i := 0; i < c.newWaiters; i++ { - runtime_Semrelease(c.newSema) - } - c.newWaiters = 0 - c.newSema = nil - } - c.m.Unlock() - if raceenabled { - raceEnable() - } -} diff --git a/gcc-4.8.1/libgo/go/sync/cond_test.go b/gcc-4.8.1/libgo/go/sync/cond_test.go deleted file mode 100644 index cefacb184..000000000 --- a/gcc-4.8.1/libgo/go/sync/cond_test.go +++ /dev/null @@ -1,126 +0,0 @@ -// Copyright 2011 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 sync_test - -import ( - . "sync" - "testing" -) - -func TestCondSignal(t *testing.T) { - var m Mutex - c := NewCond(&m) - n := 2 - running := make(chan bool, n) - awake := make(chan bool, n) - for i := 0; i < n; i++ { - go func() { - m.Lock() - running <- true - c.Wait() - awake <- true - m.Unlock() - }() - } - for i := 0; i < n; i++ { - <-running // Wait for everyone to run. - } - for n > 0 { - select { - case <-awake: - t.Fatal("goroutine not asleep") - default: - } - m.Lock() - c.Signal() - m.Unlock() - <-awake // Will deadlock if no goroutine wakes up - select { - case <-awake: - t.Fatal("too many goroutines awake") - default: - } - n-- - } - c.Signal() -} - -func TestCondSignalGenerations(t *testing.T) { - var m Mutex - c := NewCond(&m) - n := 100 - running := make(chan bool, n) - awake := make(chan int, n) - for i := 0; i < n; i++ { - go func(i int) { - m.Lock() - running <- true - c.Wait() - awake <- i - m.Unlock() - }(i) - if i > 0 { - a := <-awake - if a != i-1 { - t.Fatalf("wrong goroutine woke up: want %d, got %d", i-1, a) - } - } - <-running - m.Lock() - c.Signal() - m.Unlock() - } -} - -func TestCondBroadcast(t *testing.T) { - var m Mutex - c := NewCond(&m) - n := 200 - running := make(chan int, n) - awake := make(chan int, n) - exit := false - for i := 0; i < n; i++ { - go func(g int) { - m.Lock() - for !exit { - running <- g - c.Wait() - awake <- g - } - m.Unlock() - }(i) - } - for i := 0; i < n; i++ { - for i := 0; i < n; i++ { - <-running // Will deadlock unless n are running. - } - if i == n-1 { - m.Lock() - exit = true - m.Unlock() - } - select { - case <-awake: - t.Fatal("goroutine not asleep") - default: - } - m.Lock() - c.Broadcast() - m.Unlock() - seen := make([]bool, n) - for i := 0; i < n; i++ { - g := <-awake - if seen[g] { - t.Fatal("goroutine woke up twice") - } - seen[g] = true - } - } - select { - case <-running: - t.Fatal("goroutine did not exit") - default: - } - c.Broadcast() -} diff --git a/gcc-4.8.1/libgo/go/sync/example_test.go b/gcc-4.8.1/libgo/go/sync/example_test.go deleted file mode 100644 index 156492400..000000000 --- a/gcc-4.8.1/libgo/go/sync/example_test.go +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2012 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 sync_test - -import ( - "fmt" - "net/http" - "sync" -) - -// This example fetches several URLs concurrently, -// using a WaitGroup to block until all the fetches are complete. -func ExampleWaitGroup() { - var wg sync.WaitGroup - var urls = []string{ - "http://www.golang.org/", - "http://www.google.com/", - "http://www.somestupidname.com/", - } - for _, url := range urls { - // Increment the WaitGroup counter. - wg.Add(1) - // Launch a goroutine to fetch the URL. - go func(url string) { - // Fetch the URL. - http.Get(url) - // Decrement the counter. - wg.Done() - }(url) - } - // Wait for all HTTP fetches to complete. - wg.Wait() -} - -func ExampleOnce() { - var once sync.Once - onceBody := func() { - fmt.Printf("Only once\n") - } - done := make(chan bool) - for i := 0; i < 10; i++ { - go func() { - once.Do(onceBody) - done <- true - }() - } - for i := 0; i < 10; i++ { - <-done - } - // Output: - // Only once -} diff --git a/gcc-4.8.1/libgo/go/sync/export_test.go b/gcc-4.8.1/libgo/go/sync/export_test.go deleted file mode 100644 index fa5983a2d..000000000 --- a/gcc-4.8.1/libgo/go/sync/export_test.go +++ /dev/null @@ -1,9 +0,0 @@ -// Copyright 2012 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 sync - -// Export for testing. -var Runtime_Semacquire = runtime_Semacquire -var Runtime_Semrelease = runtime_Semrelease diff --git a/gcc-4.8.1/libgo/go/sync/mutex.go b/gcc-4.8.1/libgo/go/sync/mutex.go deleted file mode 100644 index b4629ebca..000000000 --- a/gcc-4.8.1/libgo/go/sync/mutex.go +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright 2009 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 sync provides basic synchronization primitives such as mutual -// exclusion locks. Other than the Once and WaitGroup types, most are intended -// for use by low-level library routines. Higher-level synchronization is -// better done via channels and communication. -// -// Values containing the types defined in this package should not be copied. -package sync - -import ( - "sync/atomic" - "unsafe" -) - -// A Mutex is a mutual exclusion lock. -// Mutexes can be created as part of other structures; -// the zero value for a Mutex is an unlocked mutex. -type Mutex struct { - state int32 - sema uint32 -} - -// A Locker represents an object that can be locked and unlocked. -type Locker interface { - Lock() - Unlock() -} - -const ( - mutexLocked = 1 << iota // mutex is locked - mutexWoken - mutexWaiterShift = iota -) - -// Lock locks m. -// If the lock is already in use, the calling goroutine -// blocks until the mutex is available. -func (m *Mutex) Lock() { - // Fast path: grab unlocked mutex. - if atomic.CompareAndSwapInt32(&m.state, 0, mutexLocked) { - if raceenabled { - raceAcquire(unsafe.Pointer(m)) - } - return - } - - awoke := false - for { - old := m.state - new := old | mutexLocked - if old&mutexLocked != 0 { - new = old + 1<<mutexWaiterShift - } - if awoke { - // The goroutine has been woken from sleep, - // so we need to reset the flag in either case. - new &^= mutexWoken - } - if atomic.CompareAndSwapInt32(&m.state, old, new) { - if old&mutexLocked == 0 { - break - } - runtime_Semacquire(&m.sema) - awoke = true - } - } - - if raceenabled { - raceAcquire(unsafe.Pointer(m)) - } -} - -// Unlock unlocks m. -// It is a run-time error if m is not locked on entry to Unlock. -// -// A locked Mutex is not associated with a particular goroutine. -// It is allowed for one goroutine to lock a Mutex and then -// arrange for another goroutine to unlock it. -func (m *Mutex) Unlock() { - if raceenabled { - raceRelease(unsafe.Pointer(m)) - } - - // Fast path: drop lock bit. - new := atomic.AddInt32(&m.state, -mutexLocked) - if (new+mutexLocked)&mutexLocked == 0 { - panic("sync: unlock of unlocked mutex") - } - - old := new - for { - // If there are no waiters or a goroutine has already - // been woken or grabbed the lock, no need to wake anyone. - if old>>mutexWaiterShift == 0 || old&(mutexLocked|mutexWoken) != 0 { - return - } - // Grab the right to wake someone. - new = (old - 1<<mutexWaiterShift) | mutexWoken - if atomic.CompareAndSwapInt32(&m.state, old, new) { - runtime_Semrelease(&m.sema) - return - } - old = m.state - } -} diff --git a/gcc-4.8.1/libgo/go/sync/mutex_test.go b/gcc-4.8.1/libgo/go/sync/mutex_test.go deleted file mode 100644 index bf78c6f60..000000000 --- a/gcc-4.8.1/libgo/go/sync/mutex_test.go +++ /dev/null @@ -1,166 +0,0 @@ -// Copyright 2009 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. - -// GOMAXPROCS=10 go test - -package sync_test - -import ( - "runtime" - . "sync" - "sync/atomic" - "testing" -) - -func HammerSemaphore(s *uint32, loops int, cdone chan bool) { - for i := 0; i < loops; i++ { - Runtime_Semacquire(s) - Runtime_Semrelease(s) - } - cdone <- true -} - -func TestSemaphore(t *testing.T) { - s := new(uint32) - *s = 1 - c := make(chan bool) - for i := 0; i < 10; i++ { - go HammerSemaphore(s, 1000, c) - } - for i := 0; i < 10; i++ { - <-c - } -} - -func BenchmarkUncontendedSemaphore(b *testing.B) { - s := new(uint32) - *s = 1 - HammerSemaphore(s, b.N, make(chan bool, 2)) -} - -func BenchmarkContendedSemaphore(b *testing.B) { - b.StopTimer() - s := new(uint32) - *s = 1 - c := make(chan bool) - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(2)) - b.StartTimer() - - go HammerSemaphore(s, b.N/2, c) - go HammerSemaphore(s, b.N/2, c) - <-c - <-c -} - -func HammerMutex(m *Mutex, loops int, cdone chan bool) { - for i := 0; i < loops; i++ { - m.Lock() - m.Unlock() - } - cdone <- true -} - -func TestMutex(t *testing.T) { - m := new(Mutex) - c := make(chan bool) - for i := 0; i < 10; i++ { - go HammerMutex(m, 1000, c) - } - for i := 0; i < 10; i++ { - <-c - } -} - -func TestMutexPanic(t *testing.T) { - defer func() { - if recover() == nil { - t.Fatalf("unlock of unlocked mutex did not panic") - } - }() - - var mu Mutex - mu.Lock() - mu.Unlock() - mu.Unlock() -} - -func BenchmarkMutexUncontended(b *testing.B) { - type PaddedMutex struct { - Mutex - pad [128]uint8 - } - const CallsPerSched = 1000 - procs := runtime.GOMAXPROCS(-1) - N := int32(b.N / CallsPerSched) - c := make(chan bool, procs) - for p := 0; p < procs; p++ { - go func() { - var mu PaddedMutex - for atomic.AddInt32(&N, -1) >= 0 { - runtime.Gosched() - for g := 0; g < CallsPerSched; g++ { - mu.Lock() - mu.Unlock() - } - } - c <- true - }() - } - for p := 0; p < procs; p++ { - <-c - } -} - -func benchmarkMutex(b *testing.B, slack, work bool) { - const ( - CallsPerSched = 1000 - LocalWork = 100 - GoroutineSlack = 10 - ) - procs := runtime.GOMAXPROCS(-1) - if slack { - procs *= GoroutineSlack - } - N := int32(b.N / CallsPerSched) - c := make(chan bool, procs) - var mu Mutex - for p := 0; p < procs; p++ { - go func() { - foo := 0 - for atomic.AddInt32(&N, -1) >= 0 { - runtime.Gosched() - for g := 0; g < CallsPerSched; g++ { - mu.Lock() - mu.Unlock() - if work { - for i := 0; i < LocalWork; i++ { - foo *= 2 - foo /= 2 - } - } - } - } - c <- foo == 42 - }() - } - for p := 0; p < procs; p++ { - <-c - } -} - -func BenchmarkMutex(b *testing.B) { - benchmarkMutex(b, false, false) -} - -func BenchmarkMutexSlack(b *testing.B) { - benchmarkMutex(b, true, false) -} - -func BenchmarkMutexWork(b *testing.B) { - benchmarkMutex(b, false, true) -} - -func BenchmarkMutexWorkSlack(b *testing.B) { - benchmarkMutex(b, true, true) -} diff --git a/gcc-4.8.1/libgo/go/sync/once.go b/gcc-4.8.1/libgo/go/sync/once.go deleted file mode 100644 index 1699e86a9..000000000 --- a/gcc-4.8.1/libgo/go/sync/once.go +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2009 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 sync - -import ( - "sync/atomic" -) - -// Once is an object that will perform exactly one action. -type Once struct { - m Mutex - done uint32 -} - -// Do calls the function f if and only if the method is being called for the -// first time with this receiver. In other words, given -// var once Once -// if once.Do(f) is called multiple times, only the first call will invoke f, -// even if f has a different value in each invocation. A new instance of -// Once is required for each function to execute. -// -// Do is intended for initialization that must be run exactly once. Since f -// is niladic, it may be necessary to use a function literal to capture the -// arguments to a function to be invoked by Do: -// config.once.Do(func() { config.init(filename) }) -// -// Because no call to Do returns until the one call to f returns, if f causes -// Do to be called, it will deadlock. -// -func (o *Once) Do(f func()) { - if atomic.LoadUint32(&o.done) == 1 { - return - } - // Slow-path. - o.m.Lock() - defer o.m.Unlock() - if o.done == 0 { - f() - atomic.StoreUint32(&o.done, 1) - } -} diff --git a/gcc-4.8.1/libgo/go/sync/once_test.go b/gcc-4.8.1/libgo/go/sync/once_test.go deleted file mode 100644 index 183069a1a..000000000 --- a/gcc-4.8.1/libgo/go/sync/once_test.go +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright 2009 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 sync_test - -import ( - "runtime" - . "sync" - "sync/atomic" - "testing" -) - -type one int - -func (o *one) Increment() { - *o++ -} - -func run(t *testing.T, once *Once, o *one, c chan bool) { - once.Do(func() { o.Increment() }) - if v := *o; v != 1 { - t.Errorf("once failed inside run: %d is not 1", v) - } - c <- true -} - -func TestOnce(t *testing.T) { - o := new(one) - once := new(Once) - c := make(chan bool) - const N = 10 - for i := 0; i < N; i++ { - go run(t, once, o, c) - } - for i := 0; i < N; i++ { - <-c - } - if *o != 1 { - t.Errorf("once failed outside run: %d is not 1", *o) - } -} - -func TestOncePanic(t *testing.T) { - once := new(Once) - for i := 0; i < 2; i++ { - func() { - defer func() { - if recover() == nil { - t.Fatalf("Once.Do() has not panic'ed") - } - }() - once.Do(func() { - panic("failed") - }) - }() - } - once.Do(func() {}) - once.Do(func() { - t.Fatalf("Once called twice") - }) -} - -func BenchmarkOnce(b *testing.B) { - const CallsPerSched = 1000 - procs := runtime.GOMAXPROCS(-1) - N := int32(b.N / CallsPerSched) - var once Once - f := func() {} - c := make(chan bool, procs) - for p := 0; p < procs; p++ { - go func() { - for atomic.AddInt32(&N, -1) >= 0 { - runtime.Gosched() - for g := 0; g < CallsPerSched; g++ { - once.Do(f) - } - } - c <- true - }() - } - for p := 0; p < procs; p++ { - <-c - } -} diff --git a/gcc-4.8.1/libgo/go/sync/race.go b/gcc-4.8.1/libgo/go/sync/race.go deleted file mode 100644 index d9431af6f..000000000 --- a/gcc-4.8.1/libgo/go/sync/race.go +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright 2012 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. - -// +build race - -package sync - -import ( - "runtime" - "unsafe" -) - -const raceenabled = true - -func raceAcquire(addr unsafe.Pointer) { - runtime.RaceAcquire(addr) -} - -func raceRelease(addr unsafe.Pointer) { - runtime.RaceRelease(addr) -} - -func raceReleaseMerge(addr unsafe.Pointer) { - runtime.RaceReleaseMerge(addr) -} - -func raceDisable() { - runtime.RaceDisable() -} - -func raceEnable() { - runtime.RaceEnable() -} diff --git a/gcc-4.8.1/libgo/go/sync/race0.go b/gcc-4.8.1/libgo/go/sync/race0.go deleted file mode 100644 index bef14f974..000000000 --- a/gcc-4.8.1/libgo/go/sync/race0.go +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright 2012 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. - -// +build !race - -package sync - -import ( - "unsafe" -) - -const raceenabled = false - -func raceAcquire(addr unsafe.Pointer) { -} - -func raceRelease(addr unsafe.Pointer) { -} - -func raceReleaseMerge(addr unsafe.Pointer) { -} - -func raceDisable() { -} - -func raceEnable() { -} diff --git a/gcc-4.8.1/libgo/go/sync/runtime.go b/gcc-4.8.1/libgo/go/sync/runtime.go deleted file mode 100644 index e99599c11..000000000 --- a/gcc-4.8.1/libgo/go/sync/runtime.go +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2012 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 sync - -// defined in package runtime - -// Semacquire waits until *s > 0 and then atomically decrements it. -// It is intended as a simple sleep primitive for use by the synchronization -// library and should not be used directly. -func runtime_Semacquire(s *uint32) - -// Semrelease atomically increments *s and notifies a waiting goroutine -// if one is blocked in Semacquire. -// It is intended as a simple wakeup primitive for use by the synchronization -// library and should not be used directly. -func runtime_Semrelease(s *uint32) diff --git a/gcc-4.8.1/libgo/go/sync/runtime_sema_test.go b/gcc-4.8.1/libgo/go/sync/runtime_sema_test.go deleted file mode 100644 index 57a8dbee7..000000000 --- a/gcc-4.8.1/libgo/go/sync/runtime_sema_test.go +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright 2009 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 sync_test - -import ( - "runtime" - . "sync" - "sync/atomic" - "testing" -) - -func BenchmarkSemaUncontended(b *testing.B) { - type PaddedSem struct { - sem uint32 - pad [32]uint32 - } - const CallsPerSched = 1000 - procs := runtime.GOMAXPROCS(-1) - N := int32(b.N / CallsPerSched) - c := make(chan bool, procs) - for p := 0; p < procs; p++ { - go func() { - sem := new(PaddedSem) - for atomic.AddInt32(&N, -1) >= 0 { - runtime.Gosched() - for g := 0; g < CallsPerSched; g++ { - Runtime_Semrelease(&sem.sem) - Runtime_Semacquire(&sem.sem) - } - } - c <- true - }() - } - for p := 0; p < procs; p++ { - <-c - } -} - -func benchmarkSema(b *testing.B, block, work bool) { - const CallsPerSched = 1000 - const LocalWork = 100 - procs := runtime.GOMAXPROCS(-1) - N := int32(b.N / CallsPerSched) - c := make(chan bool, procs) - c2 := make(chan bool, procs/2) - sem := uint32(0) - if block { - for p := 0; p < procs/2; p++ { - go func() { - Runtime_Semacquire(&sem) - c2 <- true - }() - } - } - for p := 0; p < procs; p++ { - go func() { - foo := 0 - for atomic.AddInt32(&N, -1) >= 0 { - runtime.Gosched() - for g := 0; g < CallsPerSched; g++ { - Runtime_Semrelease(&sem) - if work { - for i := 0; i < LocalWork; i++ { - foo *= 2 - foo /= 2 - } - } - Runtime_Semacquire(&sem) - } - } - c <- foo == 42 - Runtime_Semrelease(&sem) - }() - } - if block { - for p := 0; p < procs/2; p++ { - <-c2 - } - } - for p := 0; p < procs; p++ { - <-c - } -} - -func BenchmarkSemaSyntNonblock(b *testing.B) { - benchmarkSema(b, false, false) -} - -func BenchmarkSemaSyntBlock(b *testing.B) { - benchmarkSema(b, true, false) -} - -func BenchmarkSemaWorkNonblock(b *testing.B) { - benchmarkSema(b, false, true) -} - -func BenchmarkSemaWorkBlock(b *testing.B) { - benchmarkSema(b, true, true) -} diff --git a/gcc-4.8.1/libgo/go/sync/rwmutex.go b/gcc-4.8.1/libgo/go/sync/rwmutex.go deleted file mode 100644 index b494c6435..000000000 --- a/gcc-4.8.1/libgo/go/sync/rwmutex.go +++ /dev/null @@ -1,124 +0,0 @@ -// Copyright 2009 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 sync - -import ( - "sync/atomic" - "unsafe" -) - -// An RWMutex is a reader/writer mutual exclusion lock. -// The lock can be held by an arbitrary number of readers -// or a single writer. -// RWMutexes can be created as part of other -// structures; the zero value for a RWMutex is -// an unlocked mutex. -type RWMutex struct { - w Mutex // held if there are pending writers - writerSem uint32 // semaphore for writers to wait for completing readers - readerSem uint32 // semaphore for readers to wait for completing writers - readerCount int32 // number of pending readers - readerWait int32 // number of departing readers -} - -const rwmutexMaxReaders = 1 << 30 - -// RLock locks rw for reading. -func (rw *RWMutex) RLock() { - if raceenabled { - raceDisable() - } - if atomic.AddInt32(&rw.readerCount, 1) < 0 { - // A writer is pending, wait for it. - runtime_Semacquire(&rw.readerSem) - } - if raceenabled { - raceEnable() - raceAcquire(unsafe.Pointer(&rw.readerSem)) - } -} - -// RUnlock undoes a single RLock call; -// it does not affect other simultaneous readers. -// It is a run-time error if rw is not locked for reading -// on entry to RUnlock. -func (rw *RWMutex) RUnlock() { - if raceenabled { - raceReleaseMerge(unsafe.Pointer(&rw.writerSem)) - raceDisable() - } - if atomic.AddInt32(&rw.readerCount, -1) < 0 { - // A writer is pending. - if atomic.AddInt32(&rw.readerWait, -1) == 0 { - // The last reader unblocks the writer. - runtime_Semrelease(&rw.writerSem) - } - } - if raceenabled { - raceEnable() - } -} - -// Lock locks rw for writing. -// If the lock is already locked for reading or writing, -// Lock blocks until the lock is available. -// To ensure that the lock eventually becomes available, -// a blocked Lock call excludes new readers from acquiring -// the lock. -func (rw *RWMutex) Lock() { - if raceenabled { - raceDisable() - } - // First, resolve competition with other writers. - rw.w.Lock() - // Announce to readers there is a pending writer. - r := atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders - // Wait for active readers. - if r != 0 && atomic.AddInt32(&rw.readerWait, r) != 0 { - runtime_Semacquire(&rw.writerSem) - } - if raceenabled { - raceEnable() - raceAcquire(unsafe.Pointer(&rw.readerSem)) - raceAcquire(unsafe.Pointer(&rw.writerSem)) - } -} - -// Unlock unlocks rw for writing. It is a run-time error if rw is -// not locked for writing on entry to Unlock. -// -// As with Mutexes, a locked RWMutex is not associated with a particular -// goroutine. One goroutine may RLock (Lock) an RWMutex and then -// arrange for another goroutine to RUnlock (Unlock) it. -func (rw *RWMutex) Unlock() { - if raceenabled { - raceRelease(unsafe.Pointer(&rw.readerSem)) - raceRelease(unsafe.Pointer(&rw.writerSem)) - raceDisable() - } - - // Announce to readers there is no active writer. - r := atomic.AddInt32(&rw.readerCount, rwmutexMaxReaders) - // Unblock blocked readers, if any. - for i := 0; i < int(r); i++ { - runtime_Semrelease(&rw.readerSem) - } - // Allow other writers to proceed. - rw.w.Unlock() - if raceenabled { - raceEnable() - } -} - -// RLocker returns a Locker interface that implements -// the Lock and Unlock methods by calling rw.RLock and rw.RUnlock. -func (rw *RWMutex) RLocker() Locker { - return (*rlocker)(rw) -} - -type rlocker RWMutex - -func (r *rlocker) Lock() { (*RWMutex)(r).RLock() } -func (r *rlocker) Unlock() { (*RWMutex)(r).RUnlock() } diff --git a/gcc-4.8.1/libgo/go/sync/rwmutex_test.go b/gcc-4.8.1/libgo/go/sync/rwmutex_test.go deleted file mode 100644 index 39d5d6540..000000000 --- a/gcc-4.8.1/libgo/go/sync/rwmutex_test.go +++ /dev/null @@ -1,237 +0,0 @@ -// Copyright 2009 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. - -// GOMAXPROCS=10 go test - -package sync_test - -import ( - "fmt" - "runtime" - . "sync" - "sync/atomic" - "testing" -) - -func parallelReader(m *RWMutex, clocked, cunlock, cdone chan bool) { - m.RLock() - clocked <- true - <-cunlock - m.RUnlock() - cdone <- true -} - -func doTestParallelReaders(numReaders, gomaxprocs int) { - runtime.GOMAXPROCS(gomaxprocs) - var m RWMutex - clocked := make(chan bool) - cunlock := make(chan bool) - cdone := make(chan bool) - for i := 0; i < numReaders; i++ { - go parallelReader(&m, clocked, cunlock, cdone) - } - // Wait for all parallel RLock()s to succeed. - for i := 0; i < numReaders; i++ { - <-clocked - } - for i := 0; i < numReaders; i++ { - cunlock <- true - } - // Wait for the goroutines to finish. - for i := 0; i < numReaders; i++ { - <-cdone - } -} - -func TestParallelReaders(t *testing.T) { - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(-1)) - doTestParallelReaders(1, 4) - doTestParallelReaders(3, 4) - doTestParallelReaders(4, 2) -} - -func reader(rwm *RWMutex, num_iterations int, activity *int32, cdone chan bool) { - for i := 0; i < num_iterations; i++ { - rwm.RLock() - n := atomic.AddInt32(activity, 1) - if n < 1 || n >= 10000 { - panic(fmt.Sprintf("wlock(%d)\n", n)) - } - for i := 0; i < 100; i++ { - } - atomic.AddInt32(activity, -1) - rwm.RUnlock() - } - cdone <- true -} - -func writer(rwm *RWMutex, num_iterations int, activity *int32, cdone chan bool) { - for i := 0; i < num_iterations; i++ { - rwm.Lock() - n := atomic.AddInt32(activity, 10000) - if n != 10000 { - panic(fmt.Sprintf("wlock(%d)\n", n)) - } - for i := 0; i < 100; i++ { - } - atomic.AddInt32(activity, -10000) - rwm.Unlock() - } - cdone <- true -} - -func HammerRWMutex(gomaxprocs, numReaders, num_iterations int) { - runtime.GOMAXPROCS(gomaxprocs) - // Number of active readers + 10000 * number of active writers. - var activity int32 - var rwm RWMutex - cdone := make(chan bool) - go writer(&rwm, num_iterations, &activity, cdone) - var i int - for i = 0; i < numReaders/2; i++ { - go reader(&rwm, num_iterations, &activity, cdone) - } - go writer(&rwm, num_iterations, &activity, cdone) - for ; i < numReaders; i++ { - go reader(&rwm, num_iterations, &activity, cdone) - } - // Wait for the 2 writers and all readers to finish. - for i := 0; i < 2+numReaders; i++ { - <-cdone - } -} - -func TestRWMutex(t *testing.T) { - defer runtime.GOMAXPROCS(runtime.GOMAXPROCS(-1)) - n := 1000 - if testing.Short() { - n = 5 - } - HammerRWMutex(1, 1, n) - HammerRWMutex(1, 3, n) - HammerRWMutex(1, 10, n) - HammerRWMutex(4, 1, n) - HammerRWMutex(4, 3, n) - HammerRWMutex(4, 10, n) - HammerRWMutex(10, 1, n) - HammerRWMutex(10, 3, n) - HammerRWMutex(10, 10, n) - HammerRWMutex(10, 5, n) -} - -func TestRLocker(t *testing.T) { - var wl RWMutex - var rl Locker - wlocked := make(chan bool, 1) - rlocked := make(chan bool, 1) - rl = wl.RLocker() - n := 10 - go func() { - for i := 0; i < n; i++ { - rl.Lock() - rl.Lock() - rlocked <- true - wl.Lock() - wlocked <- true - } - }() - for i := 0; i < n; i++ { - <-rlocked - rl.Unlock() - select { - case <-wlocked: - t.Fatal("RLocker() didn't read-lock it") - default: - } - rl.Unlock() - <-wlocked - select { - case <-rlocked: - t.Fatal("RLocker() didn't respect the write lock") - default: - } - wl.Unlock() - } -} - -func BenchmarkRWMutexUncontended(b *testing.B) { - type PaddedRWMutex struct { - RWMutex - pad [32]uint32 - } - const CallsPerSched = 1000 - procs := runtime.GOMAXPROCS(-1) - N := int32(b.N / CallsPerSched) - c := make(chan bool, procs) - for p := 0; p < procs; p++ { - go func() { - var rwm PaddedRWMutex - for atomic.AddInt32(&N, -1) >= 0 { - runtime.Gosched() - for g := 0; g < CallsPerSched; g++ { - rwm.RLock() - rwm.RLock() - rwm.RUnlock() - rwm.RUnlock() - rwm.Lock() - rwm.Unlock() - } - } - c <- true - }() - } - for p := 0; p < procs; p++ { - <-c - } -} - -func benchmarkRWMutex(b *testing.B, localWork, writeRatio int) { - const CallsPerSched = 1000 - procs := runtime.GOMAXPROCS(-1) - N := int32(b.N / CallsPerSched) - c := make(chan bool, procs) - var rwm RWMutex - for p := 0; p < procs; p++ { - go func() { - foo := 0 - for atomic.AddInt32(&N, -1) >= 0 { - runtime.Gosched() - for g := 0; g < CallsPerSched; g++ { - foo++ - if foo%writeRatio == 0 { - rwm.Lock() - rwm.Unlock() - } else { - rwm.RLock() - for i := 0; i != localWork; i += 1 { - foo *= 2 - foo /= 2 - } - rwm.RUnlock() - } - } - } - c <- foo == 42 - }() - } - for p := 0; p < procs; p++ { - <-c - } -} - -func BenchmarkRWMutexWrite100(b *testing.B) { - benchmarkRWMutex(b, 0, 100) -} - -func BenchmarkRWMutexWrite10(b *testing.B) { - benchmarkRWMutex(b, 0, 10) -} - -func BenchmarkRWMutexWorkWrite100(b *testing.B) { - benchmarkRWMutex(b, 100, 100) -} - -func BenchmarkRWMutexWorkWrite10(b *testing.B) { - benchmarkRWMutex(b, 100, 10) -} diff --git a/gcc-4.8.1/libgo/go/sync/waitgroup.go b/gcc-4.8.1/libgo/go/sync/waitgroup.go deleted file mode 100644 index 9b0ffec58..000000000 --- a/gcc-4.8.1/libgo/go/sync/waitgroup.go +++ /dev/null @@ -1,107 +0,0 @@ -// Copyright 2011 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 sync - -import ( - "sync/atomic" - "unsafe" -) - -// A WaitGroup waits for a collection of goroutines to finish. -// The main goroutine calls Add to set the number of -// goroutines to wait for. Then each of the goroutines -// runs and calls Done when finished. At the same time, -// Wait can be used to block until all goroutines have finished. -type WaitGroup struct { - m Mutex - counter int32 - waiters int32 - sema *uint32 -} - -// WaitGroup creates a new semaphore each time the old semaphore -// is released. This is to avoid the following race: -// -// G1: Add(1) -// G1: go G2() -// G1: Wait() // Context switch after Unlock() and before Semacquire(). -// G2: Done() // Release semaphore: sema == 1, waiters == 0. G1 doesn't run yet. -// G3: Wait() // Finds counter == 0, waiters == 0, doesn't block. -// G3: Add(1) // Makes counter == 1, waiters == 0. -// G3: go G4() -// G3: Wait() // G1 still hasn't run, G3 finds sema == 1, unblocked! Bug. - -// Add adds delta, which may be negative, to the WaitGroup counter. -// If the counter becomes zero, all goroutines blocked on Wait() are released. -// If the counter goes negative, Add panics. -func (wg *WaitGroup) Add(delta int) { - if raceenabled { - raceReleaseMerge(unsafe.Pointer(wg)) - raceDisable() - defer raceEnable() - } - v := atomic.AddInt32(&wg.counter, int32(delta)) - if v < 0 { - panic("sync: negative WaitGroup counter") - } - if v > 0 || atomic.LoadInt32(&wg.waiters) == 0 { - return - } - wg.m.Lock() - for i := int32(0); i < wg.waiters; i++ { - runtime_Semrelease(wg.sema) - } - wg.waiters = 0 - wg.sema = nil - wg.m.Unlock() -} - -// Done decrements the WaitGroup counter. -func (wg *WaitGroup) Done() { - wg.Add(-1) -} - -// Wait blocks until the WaitGroup counter is zero. -func (wg *WaitGroup) Wait() { - if raceenabled { - raceDisable() - } - if atomic.LoadInt32(&wg.counter) == 0 { - if raceenabled { - raceEnable() - raceAcquire(unsafe.Pointer(wg)) - } - return - } - wg.m.Lock() - atomic.AddInt32(&wg.waiters, 1) - // This code is racing with the unlocked path in Add above. - // The code above modifies counter and then reads waiters. - // We must modify waiters and then read counter (the opposite order) - // to avoid missing an Add. - if atomic.LoadInt32(&wg.counter) == 0 { - atomic.AddInt32(&wg.waiters, -1) - if raceenabled { - raceEnable() - raceAcquire(unsafe.Pointer(wg)) - raceDisable() - } - wg.m.Unlock() - if raceenabled { - raceEnable() - } - return - } - if wg.sema == nil { - wg.sema = new(uint32) - } - s := wg.sema - wg.m.Unlock() - runtime_Semacquire(s) - if raceenabled { - raceEnable() - raceAcquire(unsafe.Pointer(wg)) - } -} diff --git a/gcc-4.8.1/libgo/go/sync/waitgroup_test.go b/gcc-4.8.1/libgo/go/sync/waitgroup_test.go deleted file mode 100644 index 84c4cfc37..000000000 --- a/gcc-4.8.1/libgo/go/sync/waitgroup_test.go +++ /dev/null @@ -1,165 +0,0 @@ -// Copyright 2011 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 sync_test - -import ( - "runtime" - . "sync" - "sync/atomic" - "testing" -) - -func testWaitGroup(t *testing.T, wg1 *WaitGroup, wg2 *WaitGroup) { - n := 16 - wg1.Add(n) - wg2.Add(n) - exited := make(chan bool, n) - for i := 0; i != n; i++ { - go func(i int) { - wg1.Done() - wg2.Wait() - exited <- true - }(i) - } - wg1.Wait() - for i := 0; i != n; i++ { - select { - case <-exited: - t.Fatal("WaitGroup released group too soon") - default: - } - wg2.Done() - } - for i := 0; i != n; i++ { - <-exited // Will block if barrier fails to unlock someone. - } -} - -func TestWaitGroup(t *testing.T) { - wg1 := &WaitGroup{} - wg2 := &WaitGroup{} - - // Run the same test a few times to ensure barrier is in a proper state. - for i := 0; i != 8; i++ { - testWaitGroup(t, wg1, wg2) - } -} - -func TestWaitGroupMisuse(t *testing.T) { - defer func() { - err := recover() - if err != "sync: negative WaitGroup counter" { - t.Fatalf("Unexpected panic: %#v", err) - } - }() - wg := &WaitGroup{} - wg.Add(1) - wg.Done() - wg.Done() - t.Fatal("Should panic") -} - -func BenchmarkWaitGroupUncontended(b *testing.B) { - type PaddedWaitGroup struct { - WaitGroup - pad [128]uint8 - } - const CallsPerSched = 1000 - procs := runtime.GOMAXPROCS(-1) - N := int32(b.N / CallsPerSched) - c := make(chan bool, procs) - for p := 0; p < procs; p++ { - go func() { - var wg PaddedWaitGroup - for atomic.AddInt32(&N, -1) >= 0 { - runtime.Gosched() - for g := 0; g < CallsPerSched; g++ { - wg.Add(1) - wg.Done() - wg.Wait() - } - } - c <- true - }() - } - for p := 0; p < procs; p++ { - <-c - } -} - -func benchmarkWaitGroupAddDone(b *testing.B, localWork int) { - const CallsPerSched = 1000 - procs := runtime.GOMAXPROCS(-1) - N := int32(b.N / CallsPerSched) - c := make(chan bool, procs) - var wg WaitGroup - for p := 0; p < procs; p++ { - go func() { - foo := 0 - for atomic.AddInt32(&N, -1) >= 0 { - runtime.Gosched() - for g := 0; g < CallsPerSched; g++ { - wg.Add(1) - for i := 0; i < localWork; i++ { - foo *= 2 - foo /= 2 - } - wg.Done() - } - } - c <- foo == 42 - }() - } - for p := 0; p < procs; p++ { - <-c - } -} - -func BenchmarkWaitGroupAddDone(b *testing.B) { - benchmarkWaitGroupAddDone(b, 0) -} - -func BenchmarkWaitGroupAddDoneWork(b *testing.B) { - benchmarkWaitGroupAddDone(b, 100) -} - -func benchmarkWaitGroupWait(b *testing.B, localWork int) { - const CallsPerSched = 1000 - procs := runtime.GOMAXPROCS(-1) - N := int32(b.N / CallsPerSched) - c := make(chan bool, procs) - var wg WaitGroup - wg.Add(procs) - for p := 0; p < procs; p++ { - go wg.Done() - } - for p := 0; p < procs; p++ { - go func() { - foo := 0 - for atomic.AddInt32(&N, -1) >= 0 { - runtime.Gosched() - for g := 0; g < CallsPerSched; g++ { - wg.Wait() - for i := 0; i < localWork; i++ { - foo *= 2 - foo /= 2 - } - } - } - c <- foo == 42 - }() - } - for p := 0; p < procs; p++ { - <-c - } -} - -func BenchmarkWaitGroupWait(b *testing.B) { - benchmarkWaitGroupWait(b, 0) -} - -func BenchmarkWaitGroupWaitWork(b *testing.B) { - benchmarkWaitGroupWait(b, 100) -} |