aboutsummaryrefslogtreecommitdiff
path: root/libgo/go/sync
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2018-01-17 14:20:29 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2018-01-17 14:20:29 +0000
commitc6d6367f848cfd8381aba41e035c5e7e873667c5 (patch)
treea218e98243463fc27f5053b4444e2544c63cd57a /libgo/go/sync
parent9bff0086915f544fa648ea81131f035cb9ce79a4 (diff)
downloadgcc-c6d6367f848cfd8381aba41e035c5e7e873667c5.zip
gcc-c6d6367f848cfd8381aba41e035c5e7e873667c5.tar.gz
gcc-c6d6367f848cfd8381aba41e035c5e7e873667c5.tar.bz2
libgo: update to Go1.10beta2 release
Reviewed-on: https://go-review.googlesource.com/87897 From-SVN: r256794
Diffstat (limited to 'libgo/go/sync')
-rw-r--r--libgo/go/sync/map.go23
-rw-r--r--libgo/go/sync/mutex.go6
-rw-r--r--libgo/go/sync/mutex_test.go5
3 files changed, 19 insertions, 15 deletions
diff --git a/libgo/go/sync/map.go b/libgo/go/sync/map.go
index 083f4a5..c4a0dc4 100644
--- a/libgo/go/sync/map.go
+++ b/libgo/go/sync/map.go
@@ -9,20 +9,21 @@ import (
"unsafe"
)
-// Map is a concurrent map with amortized-constant-time loads, stores, and deletes.
-// It is safe for multiple goroutines to call a Map's methods concurrently.
+// Map is like a Go map[interface{}]interface{} but is safe for concurrent use
+// by multiple goroutines without additional locking or coordination.
+// Loads, stores, and deletes run in amortized constant time.
//
-// It is optimized for use in concurrent loops with keys that are
-// stable over time, and either few steady-state stores, or stores
-// localized to one goroutine per key.
+// The Map type is specialized. Most code should use a plain Go map instead,
+// with separate locking or coordination, for better type safety and to make it
+// easier to maintain other invariants along with the map content.
//
-// For use cases that do not share these attributes, it will likely have
-// comparable or worse performance and worse type safety than an ordinary
-// map paired with a read-write mutex.
+// The Map type is optimized for two common use cases: (1) when the entry for a given
+// key is only ever written once but read many times, as in caches that only grow,
+// or (2) when multiple goroutines read, write, and overwrite entries for disjoint
+// sets of keys. In these two cases, use of a Map may significantly reduce lock
+// contention compared to a Go map paired with a separate Mutex or RWMutex.
//
-// The zero Map is valid and empty.
-//
-// A Map must not be copied after first use.
+// The zero Map is empty and ready for use. A Map must not be copied after first use.
type Map struct {
mu Mutex
diff --git a/libgo/go/sync/mutex.go b/libgo/go/sync/mutex.go
index 1232c62..4c5582c 100644
--- a/libgo/go/sync/mutex.go
+++ b/libgo/go/sync/mutex.go
@@ -118,7 +118,7 @@ func (m *Mutex) Lock() {
// The goroutine has been woken from sleep,
// so we need to reset the flag in either case.
if new&mutexWoken == 0 {
- panic("sync: inconsistent mutex state")
+ throw("sync: inconsistent mutex state")
}
new &^= mutexWoken
}
@@ -140,7 +140,7 @@ func (m *Mutex) Lock() {
// inconsistent state: mutexLocked is not set and we are still
// accounted as waiter. Fix that.
if old&(mutexLocked|mutexWoken) != 0 || old>>mutexWaiterShift == 0 {
- panic("sync: inconsistent mutex state")
+ throw("sync: inconsistent mutex state")
}
delta := int32(mutexLocked - 1<<mutexWaiterShift)
if !starving || old>>mutexWaiterShift == 1 {
@@ -181,7 +181,7 @@ func (m *Mutex) Unlock() {
// Fast path: drop lock bit.
new := atomic.AddInt32(&m.state, -mutexLocked)
if (new+mutexLocked)&mutexLocked == 0 {
- panic("sync: unlock of unlocked mutex")
+ throw("sync: unlock of unlocked mutex")
}
if new&mutexStarving == 0 {
old := new
diff --git a/libgo/go/sync/mutex_test.go b/libgo/go/sync/mutex_test.go
index 784471d..5214684 100644
--- a/libgo/go/sync/mutex_test.go
+++ b/libgo/go/sync/mutex_test.go
@@ -155,7 +155,10 @@ func init() {
if len(os.Args) == 3 && os.Args[1] == "TESTMISUSE" {
for _, test := range misuseTests {
if test.name == os.Args[2] {
- test.f()
+ func() {
+ defer func() { recover() }()
+ test.f()
+ }()
fmt.Printf("test completed\n")
os.Exit(0)
}