diff options
Diffstat (limited to 'libgo/go/sync')
-rw-r--r-- | libgo/go/sync/map.go | 23 | ||||
-rw-r--r-- | libgo/go/sync/mutex.go | 6 | ||||
-rw-r--r-- | libgo/go/sync/mutex_test.go | 5 |
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) } |