diff options
Diffstat (limited to 'src/pkg/sync/rwmutex.go')
-rw-r--r-- | src/pkg/sync/rwmutex.go | 128 |
1 files changed, 0 insertions, 128 deletions
diff --git a/src/pkg/sync/rwmutex.go b/src/pkg/sync/rwmutex.go deleted file mode 100644 index 3db541995..000000000 --- a/src/pkg/sync/rwmutex.go +++ /dev/null @@ -1,128 +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 { - _ = rw.w.state - 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 { - _ = rw.w.state - 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 { - _ = rw.w.state - 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 { - _ = rw.w.state - 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() } |