diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2016-07-22 18:15:38 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2016-07-22 18:15:38 +0000 |
commit | 22b955cca564a9a3a5b8c9d9dd1e295b7943c128 (patch) | |
tree | abdbd898676e1f853fca2d7e031d105d7ebcf676 /libgo/go/sync/cond.go | |
parent | 9d04a3af4c6491536badf6bde9707c907e4d196b (diff) | |
download | gcc-22b955cca564a9a3a5b8c9d9dd1e295b7943c128.zip gcc-22b955cca564a9a3a5b8c9d9dd1e295b7943c128.tar.gz gcc-22b955cca564a9a3a5b8c9d9dd1e295b7943c128.tar.bz2 |
libgo: update to go1.7rc3
Reviewed-on: https://go-review.googlesource.com/25150
From-SVN: r238662
Diffstat (limited to 'libgo/go/sync/cond.go')
-rw-r--r-- | libgo/go/sync/cond.go | 63 |
1 files changed, 21 insertions, 42 deletions
diff --git a/libgo/go/sync/cond.go b/libgo/go/sync/cond.go index 0aefcda..c070d9d 100644 --- a/libgo/go/sync/cond.go +++ b/libgo/go/sync/cond.go @@ -5,7 +5,6 @@ package sync import ( - "internal/race" "sync/atomic" "unsafe" ) @@ -21,11 +20,12 @@ import ( // A Cond can be created as part of other structures. // A Cond must not be copied after first use. type Cond struct { + noCopy noCopy + // L is held while observing or changing the condition L Locker - sema syncSema - waiters uint32 // number of waiters + notify notifyList checker copyChecker } @@ -35,13 +35,13 @@ func NewCond(l Locker) *Cond { } // 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, +// 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: +// Wait returns. Instead, the caller should Wait in a loop: // // c.L.Lock() // for !condition() { @@ -52,15 +52,9 @@ func NewCond(l Locker) *Cond { // func (c *Cond) Wait() { c.checker.check() - if race.Enabled { - race.Disable() - } - atomic.AddUint32(&c.waiters, 1) - if race.Enabled { - race.Enable() - } + t := runtime_notifyListAdd(&c.notify) c.L.Unlock() - runtime_Syncsemacquire(&c.sema) + runtime_notifyListWait(&c.notify, t) c.L.Lock() } @@ -69,7 +63,8 @@ func (c *Cond) Wait() { // It is allowed but not required for the caller to hold c.L // during the call. func (c *Cond) Signal() { - c.signalImpl(false) + c.checker.check() + runtime_notifyListNotifyOne(&c.notify) } // Broadcast wakes all goroutines waiting on c. @@ -77,34 +72,8 @@ func (c *Cond) Signal() { // It is allowed but not required for the caller to hold c.L // during the call. func (c *Cond) Broadcast() { - c.signalImpl(true) -} - -func (c *Cond) signalImpl(all bool) { c.checker.check() - if race.Enabled { - race.Disable() - } - for { - old := atomic.LoadUint32(&c.waiters) - if old == 0 { - if race.Enabled { - race.Enable() - } - return - } - new := old - 1 - if all { - new = 0 - } - if atomic.CompareAndSwapUint32(&c.waiters, old, new) { - if race.Enabled { - race.Enable() - } - runtime_Syncsemrelease(&c.sema, old-new) - return - } - } + runtime_notifyListNotifyAll(&c.notify) } // copyChecker holds back pointer to itself to detect object copying. @@ -117,3 +86,13 @@ func (c *copyChecker) check() { panic("sync.Cond is copied") } } + +// noCopy may be embedded into structs which must not be copied +// after the first use. +// +// See https://github.com/golang/go/issues/8005#issuecomment-190753527 +// for details. +type noCopy struct{} + +// Lock is a no-op used by -copylocks checker from `go vet`. +func (*noCopy) Lock() {} |